[add] Goto & 修复一些BUG
This commit is contained in:
parent
9b59d3188e
commit
d6268c41af
3 changed files with 114 additions and 32 deletions
|
|
@ -128,6 +128,19 @@ func ArrayUnique(columns []interface{}) []interface{} {
|
|||
return res
|
||||
}
|
||||
|
||||
// ArrayStringUnique 数组排重
|
||||
func ArrayStringUnique(columns []string) []string {
|
||||
res := []string{}
|
||||
m := make(map[string]bool)
|
||||
for _, key := range columns {
|
||||
if _, ok := m[key]; !ok {
|
||||
m[key] = true
|
||||
res = append(res, key)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// OfArrayPluckValue Any 转 ArrayPluckValue
|
||||
func OfArrayPluckValue(any interface{}) ArrayPluckValue {
|
||||
content, err := jsoniter.Marshal(any)
|
||||
|
|
|
|||
|
|
@ -136,12 +136,19 @@ func (workflow *WorkFlow) Open(uid int, id interface{}) map[string]interface{} {
|
|||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
|
||||
if workflow.Len() == 0 {
|
||||
exception.New("工作流没有任何节点", 400).Throw()
|
||||
}
|
||||
|
||||
users := map[string]interface{}{}
|
||||
users[workflow.Nodes[0].Name] = uid
|
||||
return map[string]interface{}{
|
||||
"name": workflow.Name,
|
||||
"data_id": id,
|
||||
"node_name": workflow.Nodes[0].Name,
|
||||
"user_id": uid,
|
||||
"users": []interface{}{uid},
|
||||
"users": users,
|
||||
"status": "进行中",
|
||||
"node_status": "进行中",
|
||||
"input": map[string]interface{}{},
|
||||
|
|
@ -171,7 +178,8 @@ func (workflow *WorkFlow) Save(uid int, name string, id interface{}, input Input
|
|||
"node_name": name,
|
||||
"user_id": uid,
|
||||
}
|
||||
users := []interface{}{uid}
|
||||
users := map[string]interface{}{}
|
||||
users[name] = uid
|
||||
output := map[string]interface{}{}
|
||||
nodeInput := map[string]interface{}{}
|
||||
nodeInput[name] = input
|
||||
|
|
@ -200,6 +208,29 @@ func (workflow *WorkFlow) Save(uid int, name string, id interface{}, input Input
|
|||
func (workflow *WorkFlow) Status(uid int, id int, output map[string]interface{}) {
|
||||
}
|
||||
|
||||
// Goto 工作流跳转
|
||||
func (workflow *WorkFlow) Goto(uid int, id int, name string, output map[string]interface{}) map[string]interface{} {
|
||||
wflow := workflow.Find(id)
|
||||
users := map[string]interface{}{}
|
||||
curr, _ := workflow.pickNode(wflow["node_name"].(string))
|
||||
users[curr.Name] = uid
|
||||
node, _ := workflow.pickNode(name)
|
||||
output = workflow.MergeData(wflow["output"], output)
|
||||
users = workflow.MergeUsers(wflow["users"], users)
|
||||
nodeUID := node.GetUID(users)
|
||||
mod := gou.Select("xiang.workflow")
|
||||
mod.Save(map[string]interface{}{
|
||||
"id": wflow["id"],
|
||||
"output": output,
|
||||
"node_name": name,
|
||||
"node_status": "进行中",
|
||||
"user_id": nodeUID,
|
||||
"users": users,
|
||||
"user_ids": workflow.UserIDs(users),
|
||||
})
|
||||
return workflow.Find(id)
|
||||
}
|
||||
|
||||
// Next 下一个工作流
|
||||
// uid 当前处理人ID, id 工作流ID
|
||||
func (workflow *WorkFlow) Next(uid int, id int, output map[string]interface{}) map[string]interface{} {
|
||||
|
|
@ -209,8 +240,10 @@ func (workflow *WorkFlow) Next(uid int, id int, output map[string]interface{}) m
|
|||
exception.New("流程数据异常: 当前节点信息错误", 500).Ctx(currNode).Throw()
|
||||
}
|
||||
|
||||
users := map[string]interface{}{}
|
||||
users[currNode] = uid
|
||||
output = workflow.MergeData(wflow["output"], output)
|
||||
users := workflow.MergeUsers(wflow["users"], []interface{}{uid})
|
||||
|
||||
// 读取下一个节点
|
||||
data := map[string]interface{}{
|
||||
"$in": wflow["input"],
|
||||
|
|
@ -220,13 +253,15 @@ func (workflow *WorkFlow) Next(uid int, id int, output map[string]interface{}) m
|
|||
"$data": output,
|
||||
}
|
||||
nextNode := workflow.nextNode(currNode, data)
|
||||
nextUID := nextNode.GetUID()
|
||||
nextUID := nextNode.MakeUID()
|
||||
users[nextNode.Name] = nextUID
|
||||
|
||||
// 更新数据
|
||||
users = workflow.MergeUsers(wflow["users"], users)
|
||||
mod := gou.Select("xiang.workflow")
|
||||
mod.Save(map[string]interface{}{
|
||||
"id": wflow["id"],
|
||||
"output": wflow["output"],
|
||||
"output": output,
|
||||
"node_name": nextNode.Name,
|
||||
"node_status": "进行中",
|
||||
"user_id": nextUID,
|
||||
|
|
@ -236,27 +271,36 @@ func (workflow *WorkFlow) Next(uid int, id int, output map[string]interface{}) m
|
|||
return workflow.Find(id)
|
||||
}
|
||||
|
||||
// GetUID 根据条件选择节点处理人
|
||||
func (node *Node) GetUID() int {
|
||||
// GetUID 读取节点相关人
|
||||
func (node *Node) GetUID(users interface{}) int {
|
||||
if users, ok := users.(map[string]interface{}); ok {
|
||||
if uid, has := users[node.Name]; has {
|
||||
return any.Of(uid).CInt()
|
||||
}
|
||||
}
|
||||
return node.MakeUID()
|
||||
}
|
||||
|
||||
// MakeUID 根据条件选择节点处理人
|
||||
func (node *Node) MakeUID() int {
|
||||
res := gou.NewProcess(node.User.Process, node.User.Args...).Run()
|
||||
return any.Of(res).CInt()
|
||||
}
|
||||
|
||||
// nextNode 查找下一个节点
|
||||
func (workflow *WorkFlow) nextNode(currentNode string, data map[string]interface{}) *Node {
|
||||
var curr *Node
|
||||
nextIndex := -1
|
||||
func (workflow *WorkFlow) pickNode(name string) (*Node, int) {
|
||||
for i, node := range workflow.Nodes {
|
||||
if node.Name == currentNode {
|
||||
nextIndex = i + 1
|
||||
curr = &node
|
||||
break
|
||||
if node.Name == name {
|
||||
return &node, i
|
||||
}
|
||||
}
|
||||
if nextIndex < 0 {
|
||||
exception.New("流程数据异常: 未找到工作流节点", 500).Ctx(currentNode).Throw()
|
||||
}
|
||||
exception.New("流程数据异常: 未找到节点 %s", 500, name).Throw()
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
// nextNode 查找下一个节点
|
||||
func (workflow *WorkFlow) nextNode(currentNode string, data map[string]interface{}) *Node {
|
||||
curr, index := workflow.pickNode(currentNode)
|
||||
nextIndex := index + 1
|
||||
if nextIndex == workflow.Len() {
|
||||
exception.New("流程数据异常: 当前节点为最后一个节点", 500).Ctx(currentNode).Throw()
|
||||
}
|
||||
|
|
@ -311,30 +355,32 @@ func (workflow *WorkFlow) Conditions(conds []helper.Condition, data map[string]i
|
|||
}
|
||||
|
||||
// UserIDs 读取用户ID
|
||||
func (workflow *WorkFlow) UserIDs(users []interface{}) string {
|
||||
func (workflow *WorkFlow) UserIDs(users map[string]interface{}) string {
|
||||
userIDs := []string{}
|
||||
for _, u := range users {
|
||||
userIDs = append(userIDs, fmt.Sprintf("|%d|", u))
|
||||
}
|
||||
userIDs = helper.ArrayStringUnique(userIDs)
|
||||
return strings.Join(userIDs, ",")
|
||||
}
|
||||
|
||||
// MergeUsers 合并数据
|
||||
func (workflow *WorkFlow) MergeUsers(data interface{}, new interface{}) []interface{} {
|
||||
res, ok := data.([]interface{})
|
||||
func (workflow *WorkFlow) MergeUsers(data interface{}, new interface{}) map[string]interface{} {
|
||||
res, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return []interface{}{}
|
||||
return map[string]interface{}{}
|
||||
}
|
||||
if new, ok := new.([]interface{}); ok {
|
||||
for _, value := range new {
|
||||
data = append(res, value)
|
||||
if new, ok := new.(map[string]interface{}); ok {
|
||||
for name, value := range new {
|
||||
res[name] = value
|
||||
}
|
||||
}
|
||||
return helper.ArrayUnique(res)
|
||||
return res
|
||||
}
|
||||
|
||||
// MergeData 合并数据
|
||||
func (workflow *WorkFlow) MergeData(data interface{}, new interface{}) map[string]interface{} {
|
||||
|
||||
res, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return map[string]interface{}{}
|
||||
|
|
@ -344,7 +390,6 @@ func (workflow *WorkFlow) MergeData(data interface{}, new interface{}) map[strin
|
|||
for key, value := range new {
|
||||
res[key] = value
|
||||
}
|
||||
res = new
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -355,9 +400,6 @@ func (workflow *WorkFlow) IsLastNode(name string) bool {
|
|||
return workflow.Nodes[length-1].Name == name
|
||||
}
|
||||
|
||||
// Goto 工作流跳转
|
||||
func (workflow *WorkFlow) Goto(uid int, id int, node string, output map[string]interface{}) {}
|
||||
|
||||
// Len 节点数量
|
||||
func (workflow *WorkFlow) Len() int {
|
||||
return len(workflow.Nodes)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ func TestOpen(t *testing.T) {
|
|||
assert.Equal(t, "进行中", data.Get("node_status"))
|
||||
assert.Equal(t, "进行中", data.Get("status"))
|
||||
assert.Equal(t, int64(1), data.Get("user_id"))
|
||||
assert.Equal(t, []interface{}{float64(1)}, data.Get("users"))
|
||||
assert.Equal(t, float64(1), data.Get("users.选择商务负责人"))
|
||||
|
||||
// 清理数据
|
||||
capsule.Query().From("xiang_workflow").Truncate()
|
||||
|
|
@ -117,7 +117,7 @@ func TestOpenEmpty(t *testing.T) {
|
|||
assert.Equal(t, "进行中", data.Get("node_status"))
|
||||
assert.Equal(t, "进行中", data.Get("status"))
|
||||
assert.Equal(t, 1, data.Get("user_id"))
|
||||
assert.Equal(t, []interface{}{1}, data.Get("users"))
|
||||
assert.Equal(t, 1, data.Get("users.选择商务负责人"))
|
||||
}
|
||||
|
||||
func TestNext(t *testing.T) {
|
||||
|
|
@ -175,6 +175,33 @@ func TestNextWhen(t *testing.T) {
|
|||
capsule.Query().From("xiang_workflow").Truncate()
|
||||
}
|
||||
|
||||
func TestGoto(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{}{
|
||||
"项目名称": "测试项目",
|
||||
"商务负责人名称": "林明波",
|
||||
})
|
||||
|
||||
wflow = assignFlow.Goto(2, id, "选择商务负责人", map[string]interface{}{"审批结果": "驳回"})
|
||||
data := maps.Of(wflow).Dot()
|
||||
assert.Equal(t, true, data.Has("id"))
|
||||
assert.Equal(t, "assign", data.Get("name"))
|
||||
assert.Equal(t, "选择商务负责人", data.Get("node_name"))
|
||||
assert.Equal(t, "进行中", data.Get("node_status"))
|
||||
assert.Equal(t, "进行中", data.Get("status"))
|
||||
assert.Equal(t, int64(1), data.Get("user_id"))
|
||||
assert.Equal(t, float64(1), data.Get("users.选择商务负责人"))
|
||||
assert.Equal(t, float64(2), data.Get("users.项目负责人审批"))
|
||||
|
||||
// 清理数据
|
||||
capsule.Query().From("xiang_workflow").Truncate()
|
||||
}
|
||||
|
||||
func check(t *testing.T) {
|
||||
keys := []string{}
|
||||
for key, workflow := range WorkFlows {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue