From f2f43e7f968275405bc2c40e37cb9cbd02d7ff08 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 17 Nov 2022 12:50:41 +0800 Subject: [PATCH] [remove] workfow table --- data/bindata.go | 133 ++++----- workflow/api.go | 107 -------- workflow/api_test.go | 12 - workflow/process.go | 151 ---------- workflow/process_test.go | 233 ---------------- workflow/types.go | 53 ---- workflow/workflow.go | 514 ----------------------------------- workflow/workflow_test.go | 296 -------------------- yao/models/workflow.mod.json | 133 --------- 9 files changed, 55 insertions(+), 1577 deletions(-) delete mode 100644 workflow/api.go delete mode 100644 workflow/api_test.go delete mode 100644 workflow/process.go delete mode 100644 workflow/process_test.go delete mode 100644 workflow/types.go delete mode 100644 workflow/workflow.go delete mode 100644 workflow/workflow_test.go delete mode 100644 yao/models/workflow.mod.json diff --git a/data/bindata.go b/data/bindata.go index b9c0a5ed..4bd9146d 100644 --- a/data/bindata.go +++ b/data/bindata.go @@ -49,7 +49,6 @@ // .tmp/data/yao/models/README.md // .tmp/data/yao/models/menu.mod.json // .tmp/data/yao/models/user.mod.json -// .tmp/data/yao/models/workflow.mod.json // .tmp/data/yao/tables/README.md // .tmp/data/yao/tables/menu.tab.json // .tmp/data/yao/tables/user.tab.json @@ -231,7 +230,7 @@ func initAppJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/app.json", size: 325, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/app.json", size: 325, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -251,7 +250,7 @@ func initChartsDashboardChartJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/charts/dashboard.chart.json", size: 8471, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/charts/dashboard.chart.json", size: 8471, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -271,7 +270,7 @@ func initFlowsAppMenuFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/flows/app/menu.flow.json", size: 1327, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/flows/app/menu.flow.json", size: 1327, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -291,7 +290,7 @@ func initFormsPetFormJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/forms/pet.form.json", size: 87, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/forms/pet.form.json", size: 87, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -311,7 +310,7 @@ func initLangsZhCnGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/langs/zh-cn/global.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/langs/zh-cn/global.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -331,7 +330,7 @@ func initLangsZhHkLangsGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/langs/zh-hk/langs/global.yml", size: 88, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/langs/zh-hk/langs/global.yml", size: 88, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -351,7 +350,7 @@ func initLoginsAdminLoginJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/logins/admin.login.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/logins/admin.login.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -371,7 +370,7 @@ func initLoginsUserLoginJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/logins/user.login.json", size: 272, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/logins/user.login.json", size: 272, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -391,7 +390,7 @@ func initModelsPetModJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/models/pet.mod.json", size: 1418, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/models/pet.mod.json", size: 1418, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -411,7 +410,7 @@ func initPublicIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/index.html", size: 1373, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/public/index.html", size: 1373, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -431,7 +430,7 @@ func initScriptsDemoJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/demo.js", size: 334, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/scripts/demo.js", size: 334, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -451,7 +450,7 @@ func initScriptsStatJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/stat.js", size: 2235, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/scripts/stat.js", size: 2235, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -471,7 +470,7 @@ func initTablesPetTabJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/tables/pet.tab.json", size: 118, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "init/tables/pet.tab.json", size: 118, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -491,7 +490,7 @@ func publicIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "public/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "public/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -511,7 +510,7 @@ func uiIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -531,7 +530,7 @@ func xgenSetupIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xgen/setup/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "xgen/setup/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -551,7 +550,7 @@ func xgenV09IndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xgen/v0.9/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "xgen/v0.9/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -571,7 +570,7 @@ func xgenV10IndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xgen/v1.0/index.html", size: 50, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "xgen/v1.0/index.html", size: 50, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -591,7 +590,7 @@ func xgenV10Layouts__indexAsyncJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xgen/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "xgen/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -611,7 +610,7 @@ func xgenV10UmiJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "xgen/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "xgen/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -631,7 +630,7 @@ func yaoApisReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -651,7 +650,7 @@ func yaoApisChartHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -671,7 +670,7 @@ func yaoApisImportHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -691,7 +690,7 @@ func yaoApisPageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -711,7 +710,7 @@ func yaoApisStorageHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/storage.http.json", size: 1026, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/storage.http.json", size: 1026, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -731,7 +730,7 @@ func yaoApisTableHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/table.http.json", size: 3213, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/table.http.json", size: 3213, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -751,7 +750,7 @@ func yaoApisUserHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -771,7 +770,7 @@ func yaoApisXiangHttpJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -791,7 +790,7 @@ func yaoDataAppJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/app.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/app.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -811,7 +810,7 @@ func yaoDataIcons404Png() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -831,7 +830,7 @@ func yaoDataIconsIconIcns() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -851,7 +850,7 @@ func yaoDataIconsIconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -871,7 +870,7 @@ func yaoDataIconsIconPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -891,7 +890,7 @@ func yaoDataIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -911,7 +910,7 @@ func yaoFieldsModelTransJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14959, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14959, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -931,7 +930,7 @@ func yaoFlowsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -951,7 +950,7 @@ func yaoFlowsAdminGuardFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/flows/admin/guard.flow.json", size: 559, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/flows/admin/guard.flow.json", size: 559, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -971,7 +970,7 @@ func yaoFlowsMenuFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -991,7 +990,7 @@ func yaoFlowsUserFindFlowJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/flows/user/find.flow.json", size: 328, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/flows/user/find.flow.json", size: 328, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1011,7 +1010,7 @@ func yaoLangsEnUsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1031,7 +1030,7 @@ func yaoLangsZhCnGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1051,7 +1050,7 @@ func yaoLangsZhCnLoginsAdminLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1071,7 +1070,7 @@ func yaoLangsZhCnLoginsUserLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1091,7 +1090,7 @@ func yaoLangsZhHkGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1111,7 +1110,7 @@ func yaoLangsZhHkLoginsAdminLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1131,7 +1130,7 @@ func yaoLangsZhHkLoginsUserLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1151,7 +1150,7 @@ func yaoModelsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1171,7 +1170,7 @@ func yaoModelsMenuModJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/menu.mod.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/models/menu.mod.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1191,27 +1190,7 @@ func yaoModelsUserModJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/user.mod.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _yaoModelsWorkflowModJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x55\xcd\x4e\xdb\x4c\x14\xdd\xe7\x29\x46\xb3\xe2\x93\xf2\x09\xa9\x12\x9b\x2c\x2b\x36\xa8\xfb\x6e\x2a\x14\x19\x3c\x31\x6e\xed\x71\x14\x8f\x0b\x28\xb2\x44\x28\xa1\x94\x90\x36\x52\x82\x50\x45\x84\x48\x5b\x4a\x54\x95\x84\xf2\x53\xd2\x40\xda\x97\xf1\xd8\xe6\x2d\x2a\x8f\x63\xc7\x49\x6d\x23\x68\x44\x55\xa9\xab\xc4\x77\xce\xcc\x39\xf7\xde\x33\x73\xf3\x09\x00\x20\xe6\x64\x04\x53\x00\xd2\x8b\x03\xa3\x57\x37\xcf\x0b\x30\xe9\x84\x09\x37\x27\x39\x71\x07\x13\x40\x2d\x89\x1c\x16\xd2\x8b\x4a\xee\x59\x46\x52\x16\x19\x14\x00\x38\xaf\xc8\x32\xc2\x64\xe8\x18\x73\xfb\xd8\x2c\xb7\xec\x46\xd3\x03\x21\x2c\x88\x98\x1d\x32\x83\xb1\x32\xfd\x10\x26\x00\xd0\x19\xd7\xbc\x22\x69\x32\x56\x61\x0a\x3c\x61\xd0\x3c\x80\x12\x37\x87\x24\x86\x9d\x86\xc9\x01\xbd\xc8\x3b\x5f\x64\x39\x8b\xfa\x6b\xee\x09\xa0\x2f\x13\x04\x36\xd2\x4a\xd9\x3a\x3c\xee\x93\x47\x68\x1c\xc5\x78\x34\xec\xd7\x8f\x7a\x74\x2a\xc9\x89\x58\x18\xc4\x25\x84\x05\xb2\x00\x53\xe0\xc1\xd4\x94\x1f\x14\x31\x8f\x96\x60\x0a\x90\x9c\x86\xfc\xe0\x73\x4e\x12\x79\x8e\x88\x4a\x20\xc9\xa0\x6a\x06\x92\x11\x59\x50\x78\x87\xc8\x21\x54\x32\x3e\x11\x5b\xe5\x72\x02\xdb\xeb\xa9\x98\x4d\x0e\xef\x55\x55\x4e\x60\x2a\xf3\x79\x11\x67\x35\xa2\xeb\xd6\x97\x4b\xba\x57\xba\xae\xbd\xb5\xdb\xed\x24\xc8\xe7\x59\x65\x74\x9d\x76\x6b\x76\xfb\xc0\xe8\x74\xe9\xd1\x8e\xf5\xf9\xa3\xd1\x39\x81\xfe\x49\x7a\xff\xdf\x2c\xfb\x8d\x2c\xad\xdb\x5a\x73\xff\xa5\xdd\x5e\x0f\x2f\x70\xf1\xd4\x2e\xd4\x82\xb0\x24\x18\x8a\x35\x1b\x74\xaf\x64\x37\x9a\xe6\xfe\x95\xd3\xe0\xd1\xfa\xf3\x1c\xe1\xd2\x4e\xaf\x47\x5b\x30\x27\x0a\x33\x98\x20\x01\xe5\x60\x7c\xc5\xb1\x26\x49\x7d\x07\x3b\xf1\xf8\x7c\xec\xcd\x55\x6b\xf5\x5b\x78\x26\xbd\x2a\x7d\x55\x76\x01\x91\x6e\x51\x78\x94\x1e\xb7\x65\xee\x90\x80\xb5\xf9\xd5\x5c\x29\xdc\x98\xc6\x28\x6c\x28\x0d\x95\x70\x44\x53\x7f\x4d\x04\x61\x4d\x1e\x44\x79\x94\xe1\x34\x89\x9d\x6c\xd6\x3f\xd1\xab\x15\x7a\x58\x1a\xac\x2a\x59\xc7\xe9\xcc\xac\x81\x55\x00\xed\x1f\xbb\x76\x63\xcb\xe8\x1c\x39\x1f\xf4\xe2\x84\xb6\xb6\xcc\x8d\xca\xc0\xc9\x7f\xf9\xdd\x49\xde\x24\x6d\xa8\x86\xc3\xc2\x6e\x55\xa7\x48\xd5\x46\xa7\x4c\xeb\x4d\xbb\xd5\xa1\x6f\xda\xf6\xd6\x0b\xba\x7b\x16\xa6\x1d\xf8\x64\x93\x3e\xd3\xe4\x80\xe6\xb6\x8f\x81\x6b\x2d\xfa\x61\xcd\xaa\xac\x1b\xdd\x6e\x8c\xfd\x42\x30\x9e\xf7\x34\x15\xe5\xee\xf1\xc2\xfb\x4a\x66\xa6\xd5\x50\xc1\xd6\x6e\x87\x16\x4f\x03\x30\xba\xb1\x63\x37\x9a\x13\x56\xad\x69\x74\x5f\x9b\xef\x57\xac\xb3\x77\xff\x45\xa6\x11\x72\x7f\xee\xe9\x21\x88\x6f\xc3\x48\x56\xe1\xfa\x43\xc4\x3f\x55\x15\x0c\xef\x26\xc8\x7d\xef\xc3\x4d\x51\x59\x73\x1f\x24\xfb\x7b\x95\x16\x0f\x5c\xe4\xc4\x23\xb4\xfc\xff\x63\x4e\xd2\x50\x48\x79\x99\xcd\xc7\x2a\xcf\xad\x85\x75\x59\x35\xf7\xea\xf1\x22\x83\xc8\x58\x91\x8a\x46\xc6\xad\xd2\xac\x96\x8d\x5e\xdd\x6e\x1d\xd3\xde\x76\xa8\xca\x70\x80\xa7\x68\x41\x54\x89\x92\x5b\xbe\xa3\xa4\x08\x4d\x31\xc3\xc6\x3c\x2f\x58\xcd\x52\xd4\x98\xf9\x03\x13\xa6\xff\x51\x3c\xbd\xde\x39\xfa\x37\x6e\x7e\xab\x68\x91\x29\x8c\x63\xf6\x4c\x0e\x08\xa3\xa6\x50\x02\x00\xa6\xc5\x6d\x1e\x62\xe9\xb8\x01\xdf\x13\x79\x00\x89\x28\x23\x95\x70\x72\x56\xf5\xda\x0b\xa0\xaa\x64\x48\x9a\x47\x12\x22\xc8\x8b\x02\x3d\xa1\x27\x7e\x06\x00\x00\xff\xff\x85\x12\x29\x3f\x05\x0d\x00\x00") - -func yaoModelsWorkflowModJsonBytes() ([]byte, error) { - return bindataRead( - _yaoModelsWorkflowModJson, - "yao/models/workflow.mod.json", - ) -} - -func yaoModelsWorkflowModJson() (*asset, error) { - bytes, err := yaoModelsWorkflowModJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "yao/models/workflow.mod.json", size: 3333, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/models/user.mod.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1231,7 +1210,7 @@ func yaoTablesReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1251,7 +1230,7 @@ func yaoTablesMenuTabJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/tables/menu.tab.json", size: 10471, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/tables/menu.tab.json", size: 10471, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1271,7 +1250,7 @@ func yaoTablesUserTabJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/tables/user.tab.json", size: 2357, mode: os.FileMode(420), modTime: time.Unix(1668659457, 0)} + info := bindataFileInfo{name: "yao/tables/user.tab.json", size: 2357, mode: os.FileMode(420), modTime: time.Unix(1668660458, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1377,7 +1356,6 @@ var _bindata = map[string]func() (*asset, error){ "yao/models/README.md": yaoModelsReadmeMd, "yao/models/menu.mod.json": yaoModelsMenuModJson, "yao/models/user.mod.json": yaoModelsUserModJson, - "yao/models/workflow.mod.json": yaoModelsWorkflowModJson, "yao/tables/README.md": yaoTablesReadmeMd, "yao/tables/menu.tab.json": yaoTablesMenuTabJson, "yao/tables/user.tab.json": yaoTablesUserTabJson, @@ -1538,10 +1516,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ }}, }}, "models": {nil, map[string]*bintree{ - "README.md": {yaoModelsReadmeMd, map[string]*bintree{}}, - "menu.mod.json": {yaoModelsMenuModJson, map[string]*bintree{}}, - "user.mod.json": {yaoModelsUserModJson, map[string]*bintree{}}, - "workflow.mod.json": {yaoModelsWorkflowModJson, map[string]*bintree{}}, + "README.md": {yaoModelsReadmeMd, map[string]*bintree{}}, + "menu.mod.json": {yaoModelsMenuModJson, map[string]*bintree{}}, + "user.mod.json": {yaoModelsUserModJson, map[string]*bintree{}}, }}, "tables": {nil, map[string]*bintree{ "README.md": {yaoTablesReadmeMd, map[string]*bintree{}}, diff --git a/workflow/api.go b/workflow/api.go deleted file mode 100644 index f51a98d8..00000000 --- a/workflow/api.go +++ /dev/null @@ -1,107 +0,0 @@ -package workflow - -import ( - "path/filepath" - - jsoniter "github.com/json-iterator/go" - "github.com/yaoapp/gou" -) - -// API: -// 读取工作流 GET /api/xiang/workflow/<工作流名称>/find/:id -// 读取工作流 GET /api/xiang/workflow/<工作流名称>/open/:data_id -// 读取工作流配置 GET /api/xiang/workflow/<工作流名称>/setting/:data_id -// 调用自定义API POST /api/xiang/workflow/<工作流名称>/<自定义API路由> - -// SetupAPIs 注册API -func (workflow *WorkFlow) SetupAPIs() error { - api := &gou.HTTP{ - Name: "工作流接口", - Version: "1.0.0", - Description: "工作流接口 API", - Group: "xiang/workflow", - Guard: "bearer-jwt", - Paths: []gou.Path{}, - } - - workflow.AddAPI(api, workflow.apiFind()) - workflow.AddAPI(api, workflow.apiOpen()) - workflow.AddAPI(api, workflow.apiSetting()) - - for name, custAPI := range workflow.APIs { - workflow.AddAPI(api, gou.Path{ - Label: custAPI.Label, - Description: custAPI.Description, - Path: filepath.Join("/", workflow.Name, name), - Method: "POST", - Process: custAPI.Process, - In: []string{workflow.Name, "$session.user_id", "$query.data_id", ":payload"}, - Out: gou.Out{ - Status: 200, - Type: "application/json", - }, - }) - } - - // 注册API - source, err := jsoniter.Marshal(api) - if err != nil { - return err - } - - gou.LoadAPI(string(source), "xiang.workflow."+workflow.Name) - return nil -} - -// AddAPI 添加API -func (workflow *WorkFlow) AddAPI(api *gou.HTTP, path gou.Path) { - api.Paths = append(api.Paths, path) -} - -// apiFind 使用ID读取工作流 -func (workflow *WorkFlow) apiFind() gou.Path { - return gou.Path{ - Label: "读取工作流", - Description: "使用工作流ID读取工作流", - Path: filepath.Join("/", workflow.Name, "find", ":id"), - Method: "GET", - Process: "xiang.workflow.Find", - In: []string{workflow.Name, "$param.id"}, - Out: gou.Out{ - Status: 200, - Type: "application/json", - }, - } -} - -// apiOpen 使用用户ID和数据ID 读取工作流 -func (workflow *WorkFlow) apiOpen() gou.Path { - return gou.Path{ - Label: "读取工作流", - Description: "使用数据ID读取工作流", - Path: filepath.Join("/", workflow.Name, "open", ":data_id"), - Method: "GET", - Process: "xiang.workflow.Open", - In: []string{workflow.Name, "$session.user_id", "$param.data_id"}, - Out: gou.Out{ - Status: 200, - Type: "application/json", - }, - } -} - -// apiSetting 读取工作流配置 -func (workflow *WorkFlow) apiSetting() gou.Path { - return gou.Path{ - Label: "读取工作流配置", - Description: "使用数据ID读取工作流配置", - Path: filepath.Join("/", workflow.Name, "setting", ":data_id"), - Method: "GET", - Process: "xiang.workflow.Setting", - In: []string{workflow.Name, "$session.user_id", "$param.data_id"}, - Out: gou.Out{ - Status: 200, - Type: "application/json", - }, - } -} diff --git a/workflow/api_test.go b/workflow/api_test.go deleted file mode 100644 index ae40c968..00000000 --- a/workflow/api_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package workflow - -// Workflow will be removed from engine - -// func TestSetupAPIs(t *testing.T) { -// assignFlow := Select("assign") -// assignFlow.SetupAPIs() - -// api := gou.SelectAPI("xiang.workflow.assign") -// assert.Equal(t, "xiang.workflow.assign", api.Name) -// assert.Equal(t, 10, len(api.HTTP.Paths)) -// } diff --git a/workflow/process.go b/workflow/process.go deleted file mode 100644 index 25db1c76..00000000 --- a/workflow/process.go +++ /dev/null @@ -1,151 +0,0 @@ -package workflow - -import "github.com/yaoapp/gou" - -// WARNING: the Workflow widget will be removed from yao engine - -// Process -// 读取工作流 xiang.workflow.Find(name, workflow_id) -// 读取工作流 xiang.workflow.Open(name, uid, data_id) -// 保存工作流 xiang.workflow.Save(name, uid, node_name, data_id, input, ...output) -// 进入下一个节点 xiang.workflow.Next(name, uid, workflow_id, output) -// 跳转到指定节点 xiang.workflow.Goto(name, uid, workflow_id, node_name, output) -// 更新工作流状态 xiang.workflow.Status(name, uid, workflow_id, status_name, output) -// 标记结束流程 xiang.workflow.Done(name, uid, workflow_id, output) -// 标记关闭流程 xiang.workflow.Close(name, uid, workflow_id, output) -// 标记重置流程 xiang.workflow.Reset(name, uid, workflow_id, output) - -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) - gou.RegisterProcessHandler("xiang.workflow.Goto", ProcessGoto) - gou.RegisterProcessHandler("xiang.workflow.Status", ProcessStatus) - gou.RegisterProcessHandler("xiang.workflow.Done", ProcessDone) - gou.RegisterProcessHandler("xiang.workflow.Close", ProcessClose) - gou.RegisterProcessHandler("xiang.workflow.Reset", ProcessReset) -} - -// ProcessFind xiang.workflow.Find 读取工作流 -// -// args: [工作流名称*, 工作流ID*] -// -// return: map[string]interface{} 工作流数据记录 -func ProcessFind(process *gou.Process) interface{} { - process.ValidateArgNums(2) - wflow := Select(process.ArgsString(0)) - return wflow.Find(process.ArgsInt(1)) -} - -// ProcessOpen xiang.workflow.Open 读取工作流 -// -// args: [工作流名称*, 当前用户ID*, 关联数据ID*] -// -// return: map[string]interface{} 工作流数据记录 -func ProcessOpen(process *gou.Process) interface{} { - process.ValidateArgNums(3) - wflow := Select(process.ArgsString(0)) - 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{} 工作流数据记录 -func ProcessSave(process *gou.Process) interface{} { - process.ValidateArgNums(5) - wflow := Select(process.ArgsString(0)) - input := InputOf(process.ArgsMap(4)) - output := map[string]interface{}{} - if process.NumOfArgsIs(6) { - output = process.ArgsMap(5) - } - return wflow.Save(process.ArgsInt(1), process.ArgsString(2), process.Args[3], input, output) -} - -// ProcessNext xiang.workflow.Next 进入下一个节点 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessNext(process *gou.Process) interface{} { - process.ValidateArgNums(4) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(3) - return wflow.Next(process.ArgsInt(1), process.ArgsInt(2), output) -} - -// ProcessGoto xiang.workflow.Goto 跳转到指定节点 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 节点名称*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessGoto(process *gou.Process) interface{} { - process.ValidateArgNums(5) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(4) - return wflow.Goto(process.ArgsInt(1), process.ArgsInt(2), process.ArgsString(3), output) -} - -// ProcessStatus xiang.workflow.Status 更新工作流状态 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 状态名称*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessStatus(process *gou.Process) interface{} { - process.ValidateArgNums(5) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(4) - return wflow.Status(process.ArgsInt(1), process.ArgsInt(2), process.ArgsString(3), output) -} - -// ProcessDone xiang.workflow.Done 标记结束流程 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessDone(process *gou.Process) interface{} { - process.ValidateArgNums(4) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(3) - return wflow.Done(process.ArgsInt(1), process.ArgsInt(2), output) -} - -// ProcessClose xiang.workflow.Close 标记关闭流程 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessClose(process *gou.Process) interface{} { - process.ValidateArgNums(4) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(3) - return wflow.Close(process.ArgsInt(1), process.ArgsInt(2), output) -} - -// ProcessReset xiang.workflow.Reset 标记重置流程 -// -// args: [工作流名称*, 当前用户ID*, 工作流ID*, 输出数据*] (输出数据: {"foo":"bar"} ) -// -// return: map[string]interface{} 工作流数据记录 -func ProcessReset(process *gou.Process) interface{} { - process.ValidateArgNums(4) - wflow := Select(process.ArgsString(0)) - output := process.ArgsMap(3) - return wflow.Reset(process.ArgsInt(1), process.ArgsInt(2), output) -} diff --git a/workflow/process_test.go b/workflow/process_test.go deleted file mode 100644 index 4ca12b69..00000000 --- a/workflow/process_test.go +++ /dev/null @@ -1,233 +0,0 @@ -package workflow - -// WARNING: the Workflow widget will be removed from yao engine - -// func init() { -// share.DBConnect(config.Conf.DB) -// share.Load(config.Conf) -// model.Load(config.Conf) -// engineModels := path.Join(os.Getenv("YAO_DEV"), "yao", "models") -// model.LoadFrom(engineModels, "xiang.") -// query.Load(config.Conf) -// flow.Load(config.Conf) -// Load(config.Conf) -// } - -// func TestProcessFind(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": "张良明"}, -// }) - -// args := []interface{}{"assign", wflow["id"]} -// res := gou.NewProcess("xiang.workflow.Find", args...).Run() - -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) - -// // 清理数据 -// 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{ -// Data: map[string]interface{}{"id": 1, "name": "云主机"}, -// Form: map[string]interface{}{"biz_id": 1, "name": "张良明"}, -// }) - -// args := []interface{}{"assign", 1, 1} -// res := gou.NewProcess("xiang.workflow.Open", args...).Run() - -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessSave(t *testing.T) { -// args := []interface{}{"assign", -// 1, "选择商务负责人", 1, -// map[string]interface{}{ -// "data": map[string]interface{}{"id": 1, "name": "云主机"}, -// "form": map[string]interface{}{"biz_id": 1, "name": "张良明"}, -// }, -// map[string]interface{}{"foo": "bar"}, -// } -// res := gou.NewProcess("xiang.workflow.Save", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, int64(1), data.Get("id")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessNext(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": "张良明"}, -// }) - -// args := []interface{}{"assign", -// 1, wflow["id"], map[string]interface{}{ -// "项目名称": "测试项目", -// "商务负责人名称": "林明波", -// }, -// } -// res := gou.NewProcess("xiang.workflow.Next", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "项目负责人审批", data.Get("node_name")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessGoto(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", -// 2, id, "选择商务负责人", -// map[string]interface{}{"审批结果": "驳回"}, -// } -// res := gou.NewProcess("xiang.workflow.Goto", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "选择商务负责人", data.Get("node_name")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessStatus(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", -// 2, id, "已完成", map[string]interface{}{"关闭原因": "测试完成"}, -// } -// res := gou.NewProcess("xiang.workflow.Status", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "已完成", data.Get("status")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessDone(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", -// 2, id, map[string]interface{}{"关闭原因": "测试完成"}, -// } -// res := gou.NewProcess("xiang.workflow.Done", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "已完成", data.Get("status")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessClose(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", -// 2, id, map[string]interface{}{"关闭原因": "测试关闭"}, -// } -// res := gou.NewProcess("xiang.workflow.Close", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "已关闭", data.Get("status")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestProcessReset(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", -// 2, id, map[string]interface{}{"驳回原因": "字段填写错误"}, -// } -// res := gou.NewProcess("xiang.workflow.Reset", args...).Run() -// data := any.Of(res).Map().MapStrAny.Dot() -// assert.Equal(t, wflow["id"], data.Get("id")) -// assert.Equal(t, "进行中", data.Get("status")) -// assert.Equal(t, "选择商务负责人", data.Get("node_name")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } diff --git a/workflow/types.go b/workflow/types.go deleted file mode 100644 index e3275a28..00000000 --- a/workflow/types.go +++ /dev/null @@ -1,53 +0,0 @@ -package workflow - -import ( - "github.com/yaoapp/yao/helper" - "github.com/yaoapp/yao/share" -) - -// WorkFlow 工作流配置结构 -type WorkFlow struct { - Name string `json:"-"` - Source []byte `json:"-"` - Version string `json:"version"` - Label string `json:"label,omitempty"` - Decription string `json:"decription,omitempty"` - Nodes []Node `json:"nodes"` - APIs map[string]API `json:"apis"` - Actions map[string]share.Render `json:"actions"` -} - -// Node 工作流节点 -type Node struct { - Name string `json:"name"` - Body share.Render `json:"body,omitempty"` - Actions []string `json:"actions,omitempty"` - User User `json:"user,omitempty"` - Next []Next `json:"next,omitempty"` -} - -// Next 下一个节点描述 -type Next struct { - Conditions []helper.Condition `json:"when,omitempty"` - Goto string `json:"goto,omitempty"` -} - -// User 工作流相关用户读取条件 -type User struct { - Process string `json:"process"` - Args []interface{} `json:"args"` -} - -// API 工作相关API -type API struct { - Label string `json:"label,omitempty"` - Description string `json:"description,omitempty"` - Process string `json:"process"` - Args []interface{} `json:"args"` -} - -// Input 用户输入数据 -type Input struct { - Data map[string]interface{} `json:"data"` // 记录数据 - Form map[string]interface{} `json:"form"` // 表单数据 -} diff --git a/workflow/workflow.go b/workflow/workflow.go deleted file mode 100644 index e54bf63a..00000000 --- a/workflow/workflow.go +++ /dev/null @@ -1,514 +0,0 @@ -package workflow - -import ( - "fmt" - "path/filepath" - "strings" - - jsoniter "github.com/json-iterator/go" - "github.com/yaoapp/gou" - gshare "github.com/yaoapp/gou/query/share" - "github.com/yaoapp/kun/any" - "github.com/yaoapp/kun/exception" - "github.com/yaoapp/kun/log" - "github.com/yaoapp/kun/maps" - "github.com/yaoapp/kun/str" - "github.com/yaoapp/yao/config" - "github.com/yaoapp/yao/helper" - "github.com/yaoapp/yao/share" -) - -// WARNING: the Workflow widget will be removed from yao engine - -// Process -// 读取工作流 xiang.workflow.Find(name, workflow_id) -// 读取工作流 xiang.workflow.Open(name, uid, data_id) -// 保存工作流 xiang.workflow.Save(name, uid, node_name, data_id, input, ...output) -// 进入下一个节点 xiang.workflow.Next(name, uid, workflow_id, output) -// 跳转到指定节点 xiang.workflow.Goto(name, uid, workflow_id, node_name, output) -// 更新工作流状态 xiang.workflow.Status(name, uid, workflow_id, status_name, output) -// 标记结束流程 xiang.workflow.Done(name, uid, workflow_id, output) -// 标记关闭流程 xiang.workflow.Close(name, uid, workflow_id, output) -// 标记重置流程 xiang.workflow.Reset(name, uid, workflow_id, output) - -// API: -// 读取工作流 GET /api/xiang/workflow/<工作流名称>/find/:id -// 读取工作流 GET /api/xiang/workflow/<工作流名称>/open -// 读取工作流配置 GET /api/xiang/workflow/<工作流名称>/setting -// 调用自定义API POST /api/xiang/workflow/<工作流名称>/<自定义API路由> - -// WorkFlows 工作流列表 -var WorkFlows = map[string]*WorkFlow{} - -// Load 加载数据表格 -func Load(cfg config.Config) { - LoadFrom(filepath.Join(cfg.Root, "workflows"), "") -} - -// LoadFrom 从特定目录加载 -func LoadFrom(dir string, prefix string) { - if share.DirNotExists(dir) { - return - } - share.Walk(dir, ".json", func(root, filename string) { - name := prefix + share.SpecName(root, filename) - content := share.ReadFile(filename) - _, err := LoadWorkFlow(content, name) - if err != nil { - log.With(log.F{"root": root, "filename": filename}).Error(err.Error()) - } - }) -} - -// LoadWorkFlow 载入工作流 -func LoadWorkFlow(source []byte, name string) (*WorkFlow, error) { - workflow := WorkFlow{Name: name, Source: source} - err := jsoniter.Unmarshal(source, &workflow) - if err != nil { - log.With(log.F{"name": name, "source": source}).Error("LoadWorkFlow: %s", err.Error()) - return nil, err - } - - workflow.SetupAPIs() - WorkFlows[workflow.Name] = &workflow - return WorkFlows[workflow.Name], nil -} - -// Select 读取已加载图表 -func Select(name string) *WorkFlow { - workflow, has := WorkFlows[name] - if !has { - exception.New( - fmt.Sprintf("工作流:%s; 尚未加载", name), - 400, - ).Throw() - } - return workflow -} - -// Reload 重新载入工作流 -func (workflow *WorkFlow) Reload() *WorkFlow { - new, err := LoadWorkFlow(workflow.Source, workflow.Name) - if err != nil { - exception.New( - fmt.Sprintf("工作流:%s; 加载失败", workflow.Name), - 400, - ).Throw() - } - WorkFlows[workflow.Name] = new - return new -} - -// Find 读取给定ID的工作流 -// uid 当前处理人ID, id 数据ID -func (workflow *WorkFlow) Find(id int) map[string]interface{} { - wflow := gou.Select("xiang.workflow") - res := wflow.MustFind(id, gou.QueryParam{ - Select: []interface{}{ - "data_id", "id", "input", "output", "name", - "user_id", "users", - "node_name", "node_status", - "status", - "updated_at", "created_at", - }}) - return res -} - -// Open 读取当前工作流(未完成的) -// uid 当前处理人ID, id 数据ID -func (workflow *WorkFlow) Open(uid int, id interface{}) map[string]interface{} { - wflow := gou.Select("xiang.workflow") - params := gou.QueryParam{ - Select: []interface{}{ - "data_id", "id", "input", "output", "name", - "user_id", "users", - "node_name", "node_status", - "status", - "updated_at", "created_at", - }, - Wheres: []gou.QueryWhere{ - {Column: "name", Value: workflow.Name}, - {Column: "data_id", Value: id}, - {Column: "user_ids", OP: "like", Value: fmt.Sprintf("%%|%d|%%", uid)}, - {Column: "status", Value: "进行中"}, - }, - Limit: 1, - } - rows := wflow.MustGet(params) - 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": users, - "status": "进行中", - "node_status": "进行中", - "input": map[string]interface{}{}, - "output": 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()) - _, idx := workflow.pickNode(string(str.Of(wflow["node_name"]))) - return map[string]interface{}{ - "nodes": nodes, - "node": nodes[idx], - "node_index": idx, - "read": true, - "write": any.Of(wflow["user_id"]).CInt() == uid, - "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{} { - wflow := gou.Select("xiang.workflow") - params := gou.QueryParam{ - Select: []interface{}{"id", "input", "output", "users"}, - Wheres: []gou.QueryWhere{ - {Column: "name", Value: workflow.Name}, - {Column: "data_id", Value: id}, - {Column: "user_ids", OP: "like", Value: fmt.Sprintf("%%|%d|%%", uid)}, - {Column: "status", Value: "进行中"}, - }, - Limit: 1, - } - - rows := wflow.MustGet(params) - data := map[string]interface{}{ - "name": workflow.Name, - "data_id": id, - "node_name": name, - "user_id": uid, - } - users := map[string]interface{}{} - users[name] = uid - output := map[string]interface{}{} - nodeInput := map[string]interface{}{} - nodeInput[name] = input - if len(outputs) > 0 { - output = outputs[0] - } - if len(rows) > 0 { - data["id"] = rows[0].Get("id") - nodeInput = workflow.MergeData(rows[0].Get("input"), nodeInput) - users = workflow.MergeUsers(rows[0].Get("users"), users) - output = workflow.MergeData(rows[0].Get("output"), output) - } else { - data["status"] = "进行中" - data["node_status"] = "进行中" - } - data["users"] = users - data["user_ids"] = workflow.UserIDs(users) - data["input"] = nodeInput - data["output"] = output - id = wflow.MustSave(data) - return wflow.MustFind(id, gou.QueryParam{}) -} - -// Done 标记完成 -// uid 当前处理人ID, id 工作流ID -func (workflow *WorkFlow) Done(uid int, id int, output map[string]interface{}) map[string]interface{} { - return workflow.Status(uid, id, "已完成", output) -} - -// Close 标记关闭 -// uid 当前处理人ID, id 工作流ID -func (workflow *WorkFlow) Close(uid int, id int, output map[string]interface{}) map[string]interface{} { - return workflow.Status(uid, id, "已关闭", output) -} - -// Status 设定状态 -// uid 当前处理人ID, id 工作流ID -func (workflow *WorkFlow) Status(uid int, id int, status string, output map[string]interface{}) map[string]interface{} { - wflow := workflow.Find(id) - mod := gou.Select("xiang.workflow") - output = workflow.MergeData(wflow["output"], output) - mod.Save(map[string]interface{}{ - "id": wflow["id"], - "output": output, - "status": status, - }) - return workflow.Find(id) -} - -// Reset 重新开始 -// uid 当前处理人ID, id 工作流ID -func (workflow *WorkFlow) Reset(uid int, id int, output map[string]interface{}) map[string]interface{} { - return workflow.Goto(uid, id, workflow.Nodes[0].Name, output) -} - -// 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{} { - wflow := workflow.Find(id) - currNode, ok := wflow["node_name"].(string) - if !ok { - exception.New("流程数据异常: 当前节点信息错误", 500).Ctx(currNode).Throw() - } - - users := map[string]interface{}{} - users[currNode] = uid - output = workflow.MergeData(wflow["output"], output) - - // 读取下一个节点 - data := map[string]interface{}{ - "$in": wflow["input"], - "$input": wflow["input"], - "$out": output, - "$outupt": output, - "$data": output, - } - nextNode := workflow.nextNode(currNode, data) - 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": output, - "node_name": nextNode.Name, - "node_status": "进行中", - "user_id": nextUID, - "users": users, - "user_ids": workflow.UserIDs(users), - }) - return workflow.Find(id) -} - -// 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() -} - -func (workflow *WorkFlow) pickNode(name string) (*Node, int) { - for i, node := range workflow.Nodes { - if node.Name == name { - return &node, i - } - } - 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() - } - - // 未声明 Next 节点, 转到下一个节点 - if curr.Next == nil { - return &workflow.Nodes[nextIndex] - } - - // 声明 Next 节点, 按条件到指定节点 - data = maps.Of(data).Dot() - for _, next := range curr.Next { - node := workflow.GetNodeWhen(next, data) - if node != nil { - return node - } - } - - exception.New("流程数据异常: 未找到符合条件的工作流节点", 500).Ctx(map[string]interface{}{"current": currentNode, "data": data}).Throw() - return nil -} - -// GetNodeWhen 读取节点 -func (workflow *WorkFlow) GetNodeWhen(next Next, data map[string]interface{}) *Node { - nextNode := "" - conditions := workflow.Conditions(next.Conditions, data) - if helper.When(conditions) { - nextNode = next.Goto - for i := 0; i < workflow.Len(); i++ { - node := workflow.Nodes[i] - if node.Name == nextNode { - return &node - } - } - } - return nil -} - -// Conditions 处理绑定参数 -func (workflow *WorkFlow) Conditions(conds []helper.Condition, data map[string]interface{}) []helper.Condition { - conditions := []helper.Condition{} - for _, cond := range conds { - if left, ok := cond.Left.(string); ok { - cond.Left = gshare.Bind(left, data) - } - if right, ok := cond.Right.(string); ok { - cond.Right = gshare.Bind(right, data) - } - conditions = append(conditions, cond) - } - return conditions -} - -// UserIDs 读取用户ID -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{}) map[string]interface{} { - res, ok := data.(map[string]interface{}) - if !ok { - return map[string]interface{}{} - } - if new, ok := new.(map[string]interface{}); ok { - for name, value := range new { - res[name] = value - } - } - 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{}{} - } - - if new, ok := new.(map[string]interface{}); ok { - for key, value := range new { - res[key] = value - } - } - return res -} - -// IsLastNode 检查是否为最后一个节点 -func (workflow *WorkFlow) IsLastNode(name string) bool { - length := workflow.Len() - 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) -} - -// InputOf 映射表转换为Input -func InputOf(in map[string]interface{}) Input { - input := Input{Data: map[string]interface{}{}, Form: map[string]interface{}{}} - if data, ok := in["data"].(map[string]interface{}); ok { - input.Data = data - } - if form, ok := in["form"].(map[string]interface{}); ok { - input.Form = form - } - return input -} diff --git a/workflow/workflow_test.go b/workflow/workflow_test.go deleted file mode 100644 index 55a0240d..00000000 --- a/workflow/workflow_test.go +++ /dev/null @@ -1,296 +0,0 @@ -package workflow - -// WARNING: the Workflow widget will be removed from yao engine - -// func init() { -// share.DBConnect(config.Conf.DB) -// share.Load(config.Conf) -// model.Load(config.Conf) -// engineModels := path.Join(os.Getenv("YAO_DEV"), "xiang", "models") -// model.LoadFrom(engineModels, "xiang.") -// query.Load(config.Conf) -// flow.Load(config.Conf) -// Load(config.Conf) -// } - -// func TestLoad(t *testing.T) { -// share.DBConnect(config.Conf.DB) -// share.Load(config.Conf) -// model.Load(config.Conf) -// query.Load(config.Conf) -// Load(config.Conf) -// LoadFrom("not a path", "404.") -// check(t) -// } - -// func TestSave(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": "张良明"}, -// }) - -// data := maps.Of(wflow).Dot() -// assert.Equal(t, int64(1), data.Get("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, float64(1), data.Get("input.选择商务负责人.data.id")) -// assert.Equal(t, "云主机", data.Get("input.选择商务负责人.data.name")) -// assert.Equal(t, float64(1), data.Get("input.选择商务负责人.form.biz_id")) -// assert.Equal(t, "张良明", data.Get("input.选择商务负责人.form.name")) -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestSaveUpdate(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": "张良明"}, -// }) - -// wflow = assignFlow.Save(1, "选择商务负责人", 1, Input{ -// Data: map[string]interface{}{"id": 1, "name": "云存储"}, -// Form: map[string]interface{}{"biz_id": 1, "name": "李明博"}, -// }) - -// data := maps.Of(wflow).Dot() -// assert.Equal(t, int64(1), data.Get("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, float64(1), data.Get("input.选择商务负责人.data.id")) -// assert.Equal(t, "云存储", data.Get("input.选择商务负责人.data.name")) -// assert.Equal(t, float64(1), data.Get("input.选择商务负责人.form.biz_id")) -// assert.Equal(t, "李明博", data.Get("input.选择商务负责人.form.name")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestOpen(t *testing.T) { -// assignFlow := Select("assign") -// assignFlow.Save(1, "选择商务负责人", 1, Input{ -// Data: map[string]interface{}{"id": 1, "name": "云主机"}, -// Form: map[string]interface{}{"biz_id": 1, "name": "张良明"}, -// }) -// wflow := assignFlow.Open(1, 1) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, int64(1), data.Get("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.选择商务负责人")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestOpenEmpty(t *testing.T) { -// assignFlow := Select("assign") -// wflow := assignFlow.Open(1, 1) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, false, 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, 1, data.Get("user_id")) -// assert.Equal(t, 1, data.Get("users.选择商务负责人")) -// } - -// func TestNext(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": "张良明"}, -// }) -// wflow = assignFlow.Next(1, any.Of(wflow["id"]).CInt(), map[string]interface{}{ -// "项目名称": "测试项目", -// "商务负责人名称": "林明波", -// }) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, int64(1), data.Get("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(2), data.Get("user_id")) -// assert.Equal(t, true, data.Has("users")) -// assert.Equal(t, "测试项目", data.Get("output.项目名称")) -// assert.Equal(t, "林明波", data.Get("output.商务负责人名称")) - -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestNextWhen(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{}{ -// "项目名称": "测试项目", -// "商务负责人名称": "林明波", -// }) - -// // Next When -// wflow = assignFlow.Next(2, id, map[string]interface{}{"审批结果": "通过"}) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, int64(1), data.Get("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, true, data.Has("users")) -// assert.Equal(t, "测试项目", data.Get("output.项目名称")) -// assert.Equal(t, "林明波", data.Get("output.商务负责人名称")) -// assert.Equal(t, "通过", data.Get("output.审批结果")) - -// // 清理数据 -// 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 TestReset(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.Reset(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 TestDone(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.Done(2, id, map[string]interface{}{"关闭原因": "测试完成"}) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, "已完成", data.Get("status")) -// assert.Equal(t, "测试完成", data.Get("output.关闭原因")) -// // 清理数据 -// capsule.Query().From("xiang_workflow").Truncate() -// } - -// func TestClose(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.Close(2, id, map[string]interface{}{"关闭原因": "测试关闭"}) -// data := maps.Of(wflow).Dot() -// assert.Equal(t, "已关闭", data.Get("status")) -// assert.Equal(t, "测试关闭", data.Get("output.关闭原因")) -// // 清理数据 -// 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": "张良明"}, -// }) - -// setting := assignFlow.Setting(1, 1) -// data := maps.Of(setting).Dot() -// assert.Equal(t, true, data.Get("read")) -// assert.Equal(t, "选择商务负责人", data.Get("node.label")) -// assert.Equal(t, true, data.Get("write")) - -// 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, true, data.Get("read")) -// assert.Equal(t, false, data.Get("write")) -// assert.Equal(t, "项目负责人审批", data.Get("node.label")) -// 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 { -// keys = append(keys, key) -// workflow.Reload() -// } -// assert.Equal(t, 1, len(keys)) -// } diff --git a/yao/models/workflow.mod.json b/yao/models/workflow.mod.json deleted file mode 100644 index 494a11cc..00000000 --- a/yao/models/workflow.mod.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "name": "工作流", - "table": { - "name": "xiang_workflow", - "comment": "工作流数据表", - "engine": "InnoDB" - }, - "columns": [ - { "label": "ID", "name": "id", "type": "ID" }, - { - "label": "名称", - "comment": "工作流名称", - "name": "name", - "type": "string", - "length": 255, - "index": true, - "validations": [ - { - "method": "typeof", - "args": ["string"], - "message": "{{input}}类型错误, {{label}}应该为字符串" - } - ] - }, - { - "label": "数据标识", - "comment": "关联数据标识, 关联数据模型表格ID", - "name": "data_id", - "type": "bigInteger", - "index": true, - "nullable": true - }, - { - "label": "节点", - "comment": "当前节点名称", - "name": "node_name", - "type": "string", - "length": 255, - "index": true, - "nullable": true - }, - { - "label": "节点状态", - "comment": "当前节点状态", - "name": "node_status", - "type": "enum", - "default": "未开始", - "option": ["未开始", "进行中", "已完成"], - "index": true, - "validations": [ - { - "method": "typeof", - "args": ["string"], - "message": "{{input}}类型错误, {{label}}应该为字符串" - }, - { - "method": "enum", - "args": ["未开始", "进行中", "已完成"], - "message": "{{input}}不在许可范围, {{label}}应该为 未开始/进行中/已完成" - } - ] - }, - { - "label": "当前处理人", - "comment": "当前处理人", - "name": "user_id", - "type": "bigInteger", - "index": true, - "nullable": true - }, - { - "label": "处理人IDs", - "comment": "相关处理人ID列表(用于检索)", - "name": "user_ids", - "type": "string", - "length": 255, - "index": true, - "nullable": true - }, - { - "label": "处理人", - "comment": "相关处理人", - "name": "users", - "type": "json", - "nullable": true - }, - { - "label": "数据", - "comment": "各节点输入数据(Key-Value)", - "name": "input", - "type": "json", - "nullable": true - }, - { - "label": "处理结果", - "comment": "各节点处理结果(Key-Value)", - "name": "output", - "type": "json", - "nullable": true - }, - { - "label": "操作记录", - "comment": "操作记录", - "name": "history", - "type": "json", - "nullable": true - }, - - { - "label": "状态", - "comment": "流程状态", - "name": "status", - "type": "enum", - "default": "未开始", - "option": ["未开始", "进行中", "已完成", "已关闭"], - "index": true, - "validations": [ - { - "method": "typeof", - "args": ["string"], - "message": "{{input}}类型错误, {{label}}应该为字符串" - }, - { - "method": "enum", - "args": ["未开始", "进行中", "已完成", "已关闭"], - "message": "{{input}}不在许可范围, {{label}}应该为 未开始/进行中/已完成/已关闭" - } - ] - } - ], - "indexes": [], - "option": { "timestamps": true, "soft_deletes": true } -}