Merge pull request #259 from trheyi/main

[add] form widget upload api and process
This commit is contained in:
Max 2022-11-15 20:23:02 +08:00 committed by GitHub
commit b5fc871d9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 110 additions and 2 deletions

View file

@ -22,6 +22,11 @@ var processActionDefaults = map[string]*action.Process{
Guard: "bearer-jwt",
Default: []interface{}{nil, nil, nil},
},
"Upload": {
Name: "yao.form.Upload",
Guard: "bearer-jwt",
Default: []interface{}{nil, nil, nil},
},
"Find": {
Name: "yao.form.Find",
Guard: "bearer-jwt",
@ -60,6 +65,10 @@ func (act *ActionDSL) SetDefaultProcess() {
Merge(processActionDefaults["Component"]).
SetHandler(processHandler)
act.Upload = action.ProcessOf(act.Upload).
Merge(processActionDefaults["Upload"]).
SetHandler(processHandler)
act.Find = action.ProcessOf(act.Find).
WithBefore(act.BeforeFind).WithAfter(act.AfterFind).
Merge(processActionDefaults["Find"]).

View file

@ -51,6 +51,8 @@ func (form *DSL) getAction(path string) (*action.Process, error) {
return form.Action.Setting, nil
case "/api/__yao/form/:id/component/:xpath/:method":
return form.Action.Component, nil
case "/api/__yao/form/:id/upload/:xpath/:method":
return form.Action.Upload, nil
case "/api/__yao/form/:id/find/:primary":
return form.Action.Find, nil
case "/api/__yao/form/:id/save":
@ -114,6 +116,18 @@ func exportAPI() error {
}
http.Paths = append(http.Paths, path)
// POST /api/__yao/table/:id/upload/:xpath/:method -> Default process: yao.form.Upload $param.id $param.xpath $param.method $file.file
path = gou.Path{
Label: "Upload",
Description: "Upload",
Path: "/:id/upload/:xpath/:method",
Method: "POST",
Process: "yao.form.Upload",
In: []string{"$param.id", "$param.xpath", "$param.method", "$file.file"},
Out: gou.Out{Status: 200, Type: "application/json"},
}
http.Paths = append(http.Paths, path)
// POST /api/__yao/form/:id/save -> Default process: yao.form.Save $param.id :payload
path = gou.Path{
Label: "Save",

View file

@ -240,6 +240,11 @@ func (dsl *DSL) Xgen() (map[string]interface{}, error) {
setting["config"] = dsl.Config
for _, cProp := range dsl.CProps {
err := cProp.Replace(setting, func(cProp component.CloudPropsDSL) interface{} {
if cProp.Type == "Upload" {
return fmt.Sprintf("/api/__yao/form/%s%s", dsl.ID, cProp.UploadPath())
}
return map[string]interface{}{
"api": fmt.Sprintf("/api/__yao/form/%s%s", dsl.ID, cProp.Path()),
"params": cProp.Query,

View file

@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/fs"
"github.com/yaoapp/yao/i18n"
"github.com/yaoapp/yao/model"
"github.com/yaoapp/yao/runtime"
@ -36,6 +37,12 @@ func prepare(t *testing.T, language ...string) {
i18n.Load(config.Conf)
share.DBConnect(config.Conf.DB) // removed later
// load fs
err = fs.Load(config.Conf)
if err != nil {
t.Fatal(err)
}
// load scripts
err = script.Load(config.Conf)
if err != nil {

View file

@ -12,6 +12,7 @@ func exportProcess() {
gou.RegisterProcessHandler("yao.form.setting", processSetting)
gou.RegisterProcessHandler("yao.form.xgen", processXgen)
gou.RegisterProcessHandler("yao.form.component", processComponent)
gou.RegisterProcessHandler("yao.form.upload", processUpload)
gou.RegisterProcessHandler("yao.form.find", processFind)
gou.RegisterProcessHandler("yao.form.save", processSave)
gou.RegisterProcessHandler("yao.form.create", processCreate)
@ -59,6 +60,35 @@ func processComponent(process *gou.Process) interface{} {
return res
}
func processUpload(process *gou.Process) interface{} {
process.ValidateArgNums(4)
form := MustGet(process)
xpath := process.ArgsString(1)
method := process.ArgsString(2)
key := fmt.Sprintf("%s.$%s", xpath, method)
// get cloud props
cProp, has := form.CProps[key]
if !has {
exception.New("%s does not exist", 400, key).Throw()
}
// $file.file
tmpfile, ok := process.Args[3].(gou.UploadFile)
if !ok {
exception.New("parameters error: %v", 400, process.Args[3]).Throw()
}
// execute upload
res, err := cProp.ExecUpload(process, tmpfile)
if err != nil {
exception.New(err.Error(), 500).Throw()
}
return res
}
func processSetting(process *gou.Process) interface{} {
form := MustGet(process)
process.Args = append(process.Args, process.Args[0]) // formle name

View file

@ -3,6 +3,7 @@ package form
import (
"fmt"
"net/url"
"os"
"testing"
"github.com/stretchr/testify/assert"
@ -156,6 +157,27 @@ func TestProcessComponent(t *testing.T) {
assert.Equal(t, "checked", pets[1]["status"])
}
func TestProcessUpload(t *testing.T) {
load(t)
clear(t)
testData(t)
args := []interface{}{
"pet",
"fields.form.相关图片.edit.props",
"api",
gou.UploadFile{TempFile: tempFile(t)},
}
res, err := gou.NewProcess("yao.form.Upload", args...).Exec()
if err != nil {
t.Fatal(err)
}
file, ok := res.(string)
assert.True(t, ok)
assert.NotEmpty(t, file)
}
func TestProcessComponentError(t *testing.T) {
load(t)
clear(t)
@ -182,6 +204,7 @@ func TestProcessSetting(t *testing.T) {
data := any.Of(res).MapStr().Dot()
assert.Equal(t, "/api/__yao/form/pet/component/fields.form."+url.QueryEscape("状态")+".edit.props.xProps/remote", data.Get("fields.form.状态.edit.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/form/pet/upload/fields.form."+url.QueryEscape("相关图片")+".edit.props/api", data.Get("fields.form.相关图片.edit.props.api"))
}
func TestProcessXgen(t *testing.T) {
@ -196,6 +219,7 @@ func TestProcessXgen(t *testing.T) {
data := any.Of(res).MapStr().Dot()
assert.Equal(t, "/api/__yao/form/pet/component/fields.form."+url.QueryEscape("状态")+".edit.props.xProps/remote", data.Get("fields.form.状态.edit.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/form/pet/upload/fields.form."+url.QueryEscape("相关图片")+".edit.props/api", data.Get("fields.form.相关图片.edit.props.api"))
}
func load(t *testing.T) {
@ -222,6 +246,21 @@ func testData(t *testing.T) {
}
}
func tempFile(t *testing.T) string {
file, err := os.CreateTemp("", "unit-test")
if err != nil {
t.Fatal(err)
}
defer file.Close()
_, err = file.Write([]byte("HELLO"))
if err != nil {
t.Fatal(err)
}
return file.Name()
}
func clear(t *testing.T) {
for _, m := range gou.Models {
err := m.DropTable()

View file

@ -26,6 +26,7 @@ type ActionDSL struct {
Bind *BindActionDSL `json:"bind,omitempty"`
Setting *action.Process `json:"setting,omitempty"`
Component *action.Process `json:"component,omitempty"`
Upload *action.Process `json:"upload,omitempty"`
Find *action.Process `json:"find,omitempty"`
Save *action.Process `json:"save,omitempty"`
Update *action.Process `json:"update,omitempty"`

View file

@ -154,10 +154,10 @@ func exportAPI() error {
}
http.Paths = append(http.Paths, path)
// POST /api/__yao/table/:id/upload/:xpath/:method -> Default process: yao.table.Component $param.id $param.xpath $param.method $file.file
// POST /api/__yao/table/:id/upload/:xpath/:method -> Default process: yao.table.Upload $param.id $param.xpath $param.method $file.file
path = gou.Path{
Label: "Upload",
Description: "Component",
Description: "Upload",
Path: "/:id/upload/:xpath/:method",
Method: "POST",
Process: "yao.table.Upload",

View file

@ -383,6 +383,7 @@ func TestProcessSetting(t *testing.T) {
assert.Equal(t, "查看详情2", data.Get("header.preset.import.actions[1].title"))
assert.Equal(t, "/api/__yao/table/pet/component/fields.table."+url.QueryEscape("入院状态")+".view.props.xProps/remote", data.Get("fields.table.入院状态.view.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/table/pet/component/fields.table."+url.QueryEscape("入院状态")+".edit.props.xProps/remote", data.Get("fields.table.入院状态.edit.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/table/pet/upload/fields.table."+url.QueryEscape("相关图片")+".edit.props/api", data.Get("fields.table.相关图片.edit.props.api"))
}
func TestProcessXgen(t *testing.T) {
@ -401,6 +402,8 @@ func TestProcessXgen(t *testing.T) {
assert.Equal(t, "查看详情2", data.Get("header.preset.import.actions[1].title"))
assert.Equal(t, "/api/__yao/table/pet/component/fields.table."+url.QueryEscape("入院状态")+".view.props.xProps/remote", data.Get("fields.table.入院状态.view.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/table/pet/component/fields.table."+url.QueryEscape("入院状态")+".edit.props.xProps/remote", data.Get("fields.table.入院状态.edit.props.xProps.remote.api"))
assert.Equal(t, "/api/__yao/table/pet/upload/fields.table."+url.QueryEscape("相关图片")+".edit.props/api", data.Get("fields.table.相关图片.edit.props.api"))
}
func load(t *testing.T) {