diff --git a/workflow/api.go b/workflow/api.go index 7a40196b..f51a98d8 100644 --- a/workflow/api.go +++ b/workflow/api.go @@ -35,7 +35,7 @@ func (workflow *WorkFlow) SetupAPIs() error { Path: filepath.Join("/", workflow.Name, name), Method: "POST", Process: custAPI.Process, - In: []string{workflow.Name, "$query.data_id", ":payload"}, + In: []string{workflow.Name, "$session.user_id", "$query.data_id", ":payload"}, Out: gou.Out{ Status: 200, Type: "application/json", diff --git a/workflow/process.go b/workflow/process.go index c9b28d4e..4f584471 100644 --- a/workflow/process.go +++ b/workflow/process.go @@ -16,6 +16,7 @@ import "github.com/yaoapp/gou" func init() { // 注册处理器 gou.RegisterProcessHandler("xiang.workflow.Find", ProcessFind) + gou.RegisterProcessHandler("xiang.workflow.Setting", ProcessSetting) gou.RegisterProcessHandler("xiang.workflow.Open", ProcessOpen) gou.RegisterProcessHandler("xiang.workflow.Save", ProcessSave) gou.RegisterProcessHandler("xiang.workflow.Next", ProcessNext) @@ -44,6 +45,15 @@ func ProcessOpen(process *gou.Process) interface{} { return wflow.Open(process.ArgsInt(1), process.Args[2]) } +// ProcessSetting xiang.workflow.Setting 读取工作流配置 +// args: [工作流名称*, 当前用户ID*, 关联数据ID*] +// return: map[string]interface{} 工作流配置 +func ProcessSetting(process *gou.Process) interface{} { + process.ValidateArgNums(3) + wflow := Select(process.ArgsString(0)) + return wflow.Setting(process.ArgsInt(1), process.Args[2]) +} + // ProcessSave xiang.workflow.Save 保存工作流节点信息 // args: [工作流名称*, 当前用户ID*, 节点名称*, 关联数据ID*, 输入数据*, 输出数据] (输入数据: {"data":{}, "form":{}} data 关联数据记录信息, form 工作流body表单信息, 输出数据: {"foo":"bar"} ) // return: map[string]interface{} 工作流数据记录 diff --git a/workflow/process_test.go b/workflow/process_test.go index a4bd81bc..89b5a0f4 100644 --- a/workflow/process_test.go +++ b/workflow/process_test.go @@ -43,6 +43,30 @@ func TestProcessFind(t *testing.T) { capsule.Query().From("xiang_workflow").Truncate() } +func TestProcessSetting(t *testing.T) { + assignFlow := Select("assign") + wflow := assignFlow.Save(1, "选择商务负责人", 1, Input{ + Data: map[string]interface{}{"id": 1, "name": "云主机"}, + Form: map[string]interface{}{"biz_id": 1, "name": "张良明"}, + }) + id := any.Of(wflow["id"]).CInt() + assignFlow.Next(1, id, map[string]interface{}{ + "项目名称": "测试项目", + "商务负责人名称": "林明波", + }) + + args := []interface{}{"assign", 1, 1} + res := gou.NewProcess("xiang.workflow.Setting", args...).Run() + data := any.Of(res).Map().MapStrAny.Dot() + assert.Equal(t, 2, data.Get("nodes.2.source")) + assert.Equal(t, 2, data.Get("nodes.3.source")) + assert.Equal(t, "assign", data.Get("name")) + assert.Equal(t, "指派商务负责人", data.Get("label")) + + // 清理数据 + capsule.Query().From("xiang_workflow").Truncate() +} + func TestProcessOpen(t *testing.T) { assignFlow := Select("assign") wflow := assignFlow.Save(1, "选择商务负责人", 1, Input{ diff --git a/workflow/workflow.go b/workflow/workflow.go index 2ec94153..ca406ffd 100644 --- a/workflow/workflow.go +++ b/workflow/workflow.go @@ -97,9 +97,6 @@ func (workflow *WorkFlow) Reload() *WorkFlow { return new } -// Setting 返回配置信息 -func (workflow *WorkFlow) Setting(id int) {} - // Find 读取给定ID的工作流 // uid 当前处理人ID, id 数据ID func (workflow *WorkFlow) Find(id int) map[string]interface{} { @@ -159,6 +156,29 @@ func (workflow *WorkFlow) Open(uid int, id interface{}) map[string]interface{} { } } +// Setting 返回配置信息 +// uid 当前处理人ID, id 数据ID +func (workflow *WorkFlow) Setting(uid int, id interface{}) map[string]interface{} { + wflow := workflow.Open(1, 1) + data := maps.MapStr{ + "$in": wflow["input"], + "$input": wflow["input"], + "$out": wflow["output"], + "$outupt": wflow["output"], + "$data": wflow["output"], + } + + nodes := workflow.FlowNodes(data.Dot()) + return map[string]interface{}{ + "nodes": nodes, + "actions": workflow.Actions, + "name": workflow.Name, + "version": workflow.Version, + "label": workflow.Label, + "decription": workflow.Decription, + } +} + // Save 保存工作流节点数据 此版本使用Like实现 // uid 当前处理人ID, id 数据ID func (workflow *WorkFlow) Save(uid int, name string, id interface{}, input Input, outputs ...map[string]interface{}) map[string]interface{} { @@ -430,6 +450,45 @@ func (workflow *WorkFlow) IsLastNode(name string) bool { return workflow.Nodes[length-1].Name == name } +// FlowNodes 转换为 flow +func (workflow *WorkFlow) FlowNodes(data map[string]interface{}) []map[string]interface{} { + res := []map[string]interface{}{} + nodes, err := jsoniter.Marshal(workflow.Nodes) + if err != nil { + exception.New("JSON解析错误 %s", 500, nodes).Throw() + } + + err = jsoniter.Unmarshal(nodes, &res) + if err != nil { + exception.New("JSON解析错误 %s", 500, nodes).Throw() + } + + nameMaps := map[string]int{} + for i, node := range workflow.Nodes { + nameMaps[node.Name] = i + } + + for i, node := range res { + v := gshare.Bind(node, data) + if v, ok := v.(map[string]interface{}); ok { + res[i] = v + } + res[i]["id"] = i + 1 + res[i]["label"] = res[i]["name"] + delete(res[i], "user") + delete(res[i], "next") + if workflow.Nodes[i].Next != nil { + for _, next := range workflow.Nodes[i].Next { + name := next.Goto + if id, has := nameMaps[name]; has { + res[id]["source"] = i + 1 + } + } + } + } + return res +} + // Len 节点数量 func (workflow *WorkFlow) Len() int { return len(workflow.Nodes) diff --git a/workflow/workflow_test.go b/workflow/workflow_test.go index 63c045a3..3faf84ed 100644 --- a/workflow/workflow_test.go +++ b/workflow/workflow_test.go @@ -269,6 +269,29 @@ func TestClose(t *testing.T) { capsule.Query().From("xiang_workflow").Truncate() } +func TestSetting(t *testing.T) { + assignFlow := Select("assign") + wflow := assignFlow.Save(1, "选择商务负责人", 1, Input{ + Data: map[string]interface{}{"id": 1, "name": "云主机"}, + Form: map[string]interface{}{"biz_id": 1, "name": "张良明"}, + }) + id := any.Of(wflow["id"]).CInt() + assignFlow.Next(1, id, map[string]interface{}{ + "项目名称": "测试项目", + "商务负责人名称": "林明波", + }) + + setting := assignFlow.Setting(1, 1) + data := maps.Of(setting).Dot() + assert.Equal(t, 2, data.Get("nodes.2.source")) + assert.Equal(t, 2, data.Get("nodes.3.source")) + assert.Equal(t, "assign", data.Get("name")) + assert.Equal(t, "指派商务负责人", data.Get("label")) + + // 清理数据 + capsule.Query().From("xiang_workflow").Truncate() +} + func check(t *testing.T) { keys := []string{} for key, workflow := range WorkFlows {