From 49d3f988c93358b7f734aae2e3fefcfb976b5479 Mon Sep 17 00:00:00 2001 From: "meilin.huang" <954537473@qq.com> Date: Sat, 2 Mar 2024 19:08:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20redis=E6=94=AF=E6=8C=81=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E6=B5=81=E7=A8=8B=E5=AE=A1=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mayfly_go_web/package.json | 2 +- .../src/components/pagetable/PageTable.vue | 2 +- mayfly_go_web/src/hooks/useRequest.ts | 7 +- .../src/views/flow/ProcinstDetail.vue | 17 +- mayfly_go_web/src/views/flow/ProcinstList.vue | 2 +- .../src/views/flow/ProcinstTaskList.vue | 2 +- mayfly_go_web/src/views/flow/enums.ts | 1 + .../flow/flowbiz/RedisRunWriteCmdBiz.vue | 80 ++++++++++ mayfly_go_web/src/views/ops/db/DbList.vue | 2 + .../ops/db/component/sqleditor/SqlExecBox.ts | 36 ++--- .../db/component/sqleditor/SqlExecDialog.vue | 70 +++----- .../ops/db/component/table/DbTableData.vue | 1 - .../ops/db/component/table/DbTableDataOp.vue | 6 +- .../src/views/ops/machine/MachineEdit.vue | 2 +- .../src/views/ops/redis/DataOperation.vue | 43 ++--- .../src/views/ops/redis/KeyDetail.vue | 15 +- .../src/views/ops/redis/KeyHeader.vue | 37 ++--- .../src/views/ops/redis/KeyValueHash.vue | 84 +++------- .../src/views/ops/redis/KeyValueList.vue | 102 ++++-------- .../src/views/ops/redis/KeyValueSet.vue | 63 ++------ .../src/views/ops/redis/KeyValueString.vue | 33 +--- .../src/views/ops/redis/KeyValueZset.vue | 87 +++------- .../src/views/ops/redis/RedisEdit.vue | 4 + .../src/views/ops/redis/RedisList.vue | 2 +- mayfly_go_web/src/views/ops/redis/api.ts | 151 ++++++++++++++---- .../views/ops/redis/components/CmdExecBox.ts | 28 ++++ .../ops/redis/components/CmdExecDialog.vue | 95 +++++++++++ mayfly_go_web/src/views/ops/redis/redis.ts | 138 ++++++++++++++++ mayfly_go_web/src/views/ops/redis/utils.ts | 2 +- .../system/account/components/AccountInfo.vue | 54 +++++++ mayfly_go_web/src/views/system/api.ts | 1 + .../src/views/system/syslog/SyslogList.vue | 9 +- server/initialize/initialize.go | 4 +- .../internal/auth/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/auth/init/init.go | 6 +- server/internal/db/api/db.go | 2 +- server/internal/db/application/application.go | 3 - server/internal/db/application/db_sql_exec.go | 15 +- .../infrastructure/persistence/persistence.go | 2 +- server/internal/db/init/init.go | 7 +- server/internal/flow/api/vo/procinst.go | 2 + .../internal/flow/application/application.go | 3 - .../internal/flow/application/biz_handler.go | 22 +-- server/internal/flow/application/param.go | 1 + server/internal/flow/application/procdef.go | 4 +- server/internal/flow/application/procinst.go | 25 +-- .../internal/flow/domain/entity/procinst.go | 21 +-- .../infrastructure/persistence/persistence.go | 2 +- server/internal/flow/init/init.go | 6 +- .../machine/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/machine/init/init.go | 6 +- server/internal/machine/mcm/client_cache.go | 6 + .../internal/mongo/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/mongo/init/init.go | 6 +- .../internal/msg/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/msg/init/init.go | 6 +- server/internal/redis/api/cmd.go | 19 +++ server/internal/redis/api/form/redis.go | 58 +------ server/internal/redis/api/hash.go | 79 --------- server/internal/redis/api/key.go | 38 ----- server/internal/redis/api/list.go | 58 ------- server/internal/redis/api/set.go | 71 -------- server/internal/redis/api/string.go | 29 ---- server/internal/redis/api/vo/redis.go | 1 + server/internal/redis/api/zset.go | 66 -------- .../internal/redis/application/application.go | 7 +- server/internal/redis/application/flow.go | 14 ++ server/internal/redis/application/redis.go | 73 ++++++++- server/internal/redis/domain/entity/query.go | 14 +- server/internal/redis/domain/entity/redis.go | 1 + .../infrastructure/persistence/persistence.go | 2 +- .../infrastructure/persistence/redis_repo.go | 1 + server/internal/redis/init/init.go | 8 +- server/internal/redis/rdm/cmd.go | 100 ++++++++++++ server/internal/redis/rdm/conn.go | 14 ++ server/internal/redis/rdm/info.go | 2 + server/internal/redis/router/redis.go | 69 +------- server/internal/sys/api/account.go | 13 ++ server/internal/sys/api/vo/account.go | 2 + .../internal/sys/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/sys/init/init.go | 6 +- server/internal/sys/router/account.go | 3 + .../internal/tag/application/application.go | 3 - .../infrastructure/persistence/persistence.go | 2 +- server/internal/tag/init/init.go | 6 +- .../resources/script/sql/mayfly-go-sqlite.sql | 2 + server/resources/script/sql/mayfly-go.sql | 4 +- server/resources/script/sql/v1.7/v1.7.4.sql | 4 +- 93 files changed, 1107 insertions(+), 1014 deletions(-) create mode 100755 mayfly_go_web/src/views/flow/flowbiz/RedisRunWriteCmdBiz.vue create mode 100644 mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts create mode 100644 mayfly_go_web/src/views/ops/redis/components/CmdExecDialog.vue create mode 100644 mayfly_go_web/src/views/ops/redis/redis.ts create mode 100644 mayfly_go_web/src/views/system/account/components/AccountInfo.vue create mode 100644 server/internal/redis/api/cmd.go delete mode 100644 server/internal/redis/api/hash.go delete mode 100644 server/internal/redis/api/list.go delete mode 100644 server/internal/redis/api/set.go delete mode 100644 server/internal/redis/api/string.go delete mode 100644 server/internal/redis/api/zset.go create mode 100644 server/internal/redis/application/flow.go create mode 100644 server/internal/redis/rdm/cmd.go diff --git a/mayfly_go_web/package.json b/mayfly_go_web/package.json index f611e873..2cde91a0 100644 --- a/mayfly_go_web/package.json +++ b/mayfly_go_web/package.json @@ -17,7 +17,7 @@ "countup.js": "^2.8.0", "cropperjs": "^1.6.1", "echarts": "^5.5.0", - "element-plus": "^2.5.6", + "element-plus": "^2.6.0", "js-base64": "^3.7.5", "jsencrypt": "^3.3.2", "lodash": "^4.17.21", diff --git a/mayfly_go_web/src/components/pagetable/PageTable.vue b/mayfly_go_web/src/components/pagetable/PageTable.vue index 679d14fa..6ed16889 100644 --- a/mayfly_go_web/src/components/pagetable/PageTable.vue +++ b/mayfly_go_web/src/components/pagetable/PageTable.vue @@ -74,7 +74,7 @@ trigger="click" >
- +
diff --git a/mayfly_go_web/src/views/ops/redis/RedisEdit.vue b/mayfly_go_web/src/views/ops/redis/RedisEdit.vue index f766e4f2..50313034 100644 --- a/mayfly_go_web/src/views/ops/redis/RedisEdit.vue +++ b/mayfly_go_web/src/views/ops/redis/RedisEdit.vue @@ -71,6 +71,8 @@ + + @@ -99,6 +101,7 @@ import { ElMessage } from 'element-plus'; import { RsaEncrypt } from '@/common/rsa'; import TagTreeSelect from '../component/TagTreeSelect.vue'; import SshTunnelSelect from '../component/SshTunnelSelect.vue'; +import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue'; const props = defineProps({ visible: { @@ -170,6 +173,7 @@ const state = reactive({ db: '', remark: '', sshTunnelMachineId: -1, + flowProcdefKey: '', }, submitForm: {} as any, dbList: [0], diff --git a/mayfly_go_web/src/views/ops/redis/RedisList.vue b/mayfly_go_web/src/views/ops/redis/RedisList.vue index 957148cc..74eddd30 100644 --- a/mayfly_go_web/src/views/ops/redis/RedisList.vue +++ b/mayfly_go_web/src/views/ops/redis/RedisList.vue @@ -127,7 +127,7 @@ {{ detailDialog.data.db }} {{ detailDialog.data.remark }} - + {{ detailDialog.data?.flowProcdefKey }} {{ detailDialog.data.sshTunnelMachineId > 0 ? '是' : '否' }} {{ dateFormat(detailDialog.data.createTime) }} diff --git a/mayfly_go_web/src/views/ops/redis/api.ts b/mayfly_go_web/src/views/ops/redis/api.ts index 2ed422dc..426f7bac 100644 --- a/mayfly_go_web/src/views/ops/redis/api.ts +++ b/mayfly_go_web/src/views/ops/redis/api.ts @@ -13,40 +13,125 @@ export const redisApi = { keyInfo: Api.newGet('/redis/{id}/{db}/key-info'), keyTtl: Api.newGet('/redis/{id}/{db}/key-ttl'), keyMemuse: Api.newGet('/redis/{id}/{db}/key-memuse'), - renameKey: Api.newPost('/redis/{id}/{db}/rename-key'), - expireKey: Api.newPost('/redis/{id}/{db}/expire-key'), - persistKey: Api.newDelete('/redis/{id}/{db}/persist-key'), - // 获取权限列表 + // 获取key列表 scan: Api.newPost('/redis/{id}/{db}/scan'), - getString: Api.newGet('/redis/{id}/{db}/string-value'), - setString: Api.newPost('/redis/{id}/{db}/string-value'), - getHashValue: Api.newGet('/redis/{id}/{db}/hash-value'), - hscan: Api.newGet('/redis/{id}/{db}/hscan'), - hget: Api.newGet('/redis/{id}/{db}/hget'), - hset: Api.newPost('/redis/{id}/{db}/hset'), - hdel: Api.newDelete('/redis/{id}/{db}/hdel'), - saveHashValue: Api.newPost('/redis/{id}/{db}/hash-value'), - getSetValue: Api.newGet('/redis/{id}/{db}/set-value'), - scard: Api.newGet('/redis/{id}/{db}/scard'), - sscan: Api.newPost('/redis/{id}/{db}/sscan'), - sadd: Api.newPost('/redis/{id}/{db}/sadd'), - srem: Api.newPost('/redis/{id}/{db}/srem'), - saveSetValue: Api.newPost('/redis/{id}/{db}/set-value'), - - del: Api.newDelete('/redis/{id}/{db}/scan/{cursor}/{count}'), - delKey: Api.newDelete('/redis/{id}/{db}/key'), - flushDb: Api.newDelete('/redis/{id}/{db}/flushdb'), - - lrem: Api.newPost('/redis/{id}/{db}/lrem'), - getListValue: Api.newGet('/redis/{id}/{db}/list-value'), - saveListValue: Api.newPost('/redis/{id}/{db}/list-value'), - setListValue: Api.newPost('/redis/{id}/{db}/list-value/lset'), - - zcard: Api.newGet('/redis/{id}/{db}/zcard'), - zscan: Api.newGet('/redis/{id}/{db}/zscan'), - zrevrange: Api.newGet('/redis/{id}/{db}/zrevrange'), - zadd: Api.newPost('/redis/{id}/{db}/zadd'), - zrem: Api.newPost('/redis/{id}/{db}/zrem'), + runCmd: Api.newPost('/redis/{id}/{db}/run-cmd'), }; + +export function splitargs(line: string) { + var ret = [] as any; + if (!line || typeof line.length !== 'number') { + return ret; + } + + var len = line.length; + var pos = 0; + while (true) { + // skip blanks + while (pos < len && isspace(line[pos])) { + pos += 1; + } + + if (pos === len) { + break; + } + + var inq = false; // if we are in "quotes" + var insq = false; // if we are in "single quotes" + var done = false; + var current = ''; + + while (!done) { + var c = line[pos]; + if (inq) { + if (c === '\\' && pos + 1 < len) { + pos += 1; + + switch (line[pos]) { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'b': + c = '\b'; + break; + case 'a': + c = 'a'; + break; + default: + c = line[pos]; + break; + } + current += c; + } else if (c === '"') { + // closing quote must be followed by a space or + // nothing at all. + if (pos + 1 < len && !isspace(line[pos + 1])) { + throw new Error("Expect '\"' followed by a space or nothing, got '" + line[pos + 1] + "'."); + } + done = true; + } else if (pos === len) { + throw new Error('Unterminated quotes.'); + } else { + current += c; + } + } else if (insq) { + if (c === '\\' && line[pos + 1] === "'") { + pos += 1; + current += "'"; + } else if (c === "'") { + // closing quote must be followed by a space or + // nothing at all. + if (pos + 1 < len && !isspace(line[pos + 1])) { + throw new Error('Expect "\'" followed by a space or nothing, got "' + line[pos + 1] + '".'); + } + done = true; + } else if (pos === len) { + throw new Error('Unterminated quotes.'); + } else { + current += c; + } + } else { + if (pos === len) { + done = true; + } else { + switch (c) { + case ' ': + case '\n': + case '\r': + case '\t': + done = true; + break; + case '"': + inq = true; + break; + case "'": + insq = true; + break; + default: + current += c; + break; + } + } + } + if (pos < len) { + pos += 1; + } + } + ret.push(current); + current = ''; + } + + return ret; +} + +function isspace(ch: string) { + return ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r' || ch === '\v' || ch === '\f'; +} diff --git a/mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts b/mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts new file mode 100644 index 00000000..8f0b9cca --- /dev/null +++ b/mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts @@ -0,0 +1,28 @@ +import { h, render } from 'vue'; +import CmdExecDialog from './CmdExecDialog.vue'; + +export type CmdExecProps = { + id: number; + db: number | string; + cmd: any[]; + flowProcdefKey?: string; + visible?: boolean; + runSuccessFn?: Function; + cancelFn?: Function; +}; + +const showCmdExecBox = (props: CmdExecProps): void => { + const propsCancelFn = props.cancelFn; + props.cancelFn = () => { + propsCancelFn && propsCancelFn(); + setTimeout(() => { + // 销毁组件 + render(null, document.body); + }, 500); + }; + + const vnode = h(CmdExecDialog, { ...props, visible: true }); + render(vnode, document.body); +}; + +export default showCmdExecBox; diff --git a/mayfly_go_web/src/views/ops/redis/components/CmdExecDialog.vue b/mayfly_go_web/src/views/ops/redis/components/CmdExecDialog.vue new file mode 100644 index 00000000..4515a7cf --- /dev/null +++ b/mayfly_go_web/src/views/ops/redis/components/CmdExecDialog.vue @@ -0,0 +1,95 @@ + + + + diff --git a/mayfly_go_web/src/views/ops/redis/redis.ts b/mayfly_go_web/src/views/ops/redis/redis.ts new file mode 100644 index 00000000..f9ec03f7 --- /dev/null +++ b/mayfly_go_web/src/views/ops/redis/redis.ts @@ -0,0 +1,138 @@ +import { redisApi } from './api'; +import showCmdExecBox from './components/CmdExecBox'; + +export class RedisInst { + /** + * 实例id + */ + id: number; + + /** + * db + */ + db: number; + + /** + * 流程定义key,若存在则需要审批执行 + */ + flowProcdefKey: string; + + /** + * 执行命令 + * @param cmd 命令列表如:['SET', 'key', 'value'] + * @returns 执行结果 + */ + async runCmd(cmd: any[]) { + // 工单流程定义存在,并且为写入命令时,弹窗输入工单相关信息并提交 + if (this.flowProcdefKey && writeCmd[cmd[0].toUpperCase()]) { + showCmdExecBox({ + id: this.id, + db: this.db, + flowProcdefKey: this.flowProcdefKey, + cmd, + }); + // 报错,阻止后续继续执行 + throw new Error('提交工单执行'); + } + + return await redisApi.runCmd.request({ + id: this.id, + db: this.db, + cmd, + }); + } +} + +const writeCmd = { + APPEND: 'APPEND key value', + BLMOVE: 'BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout', + BLPOP: 'BLPOP key [key ...] timeout', + BRPOP: 'BRPOP key [key ...] timeout', + BRPOPLPUSH: 'BRPOPLPUSH source destination timeout', + BZPOPMAX: 'BZPOPMAX key [key ...] timeout', + BZPOPMIN: 'BZPOPMIN key [key ...] timeout', + COPY: 'COPY source destination [DB destination-db] [REPLACE]', + DECR: 'DECR key', + DECRBY: 'DECRBY key decrement', + DEL: 'DEL key [key ...]', + EVAL: 'EVAL script numkeys key [key ...] arg [arg ...]', + EVALSHA: 'EVALSHA sha1 numkeys key [key ...] arg [arg ...]', + EXPIRE: 'EXPIRE key seconds', + EXPIREAT: 'EXPIREAT key timestamp', + FLUSHALL: 'FLUSHALL', + FLUSHDB: 'FLUSHDB', + GEOADD: 'GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]', + GETDEL: 'GETDEL key', + GETSET: 'GETSET key value', + HDEL: 'HDEL key field [field ...]', + HINCRBY: 'HINCRBY key field increment', + HINCRBYFLOAT: 'HINCRBYFLOAT key field increment', + HMSET: 'HMSET key field value [field value ...]', + HSET: 'HSET key field value', + HSETNX: 'HSETNX key field value', + INCR: 'INCR key', + INCRBY: 'INCRBY key increment', + INCRBYFLOAT: 'INCRBYFLOAT key increment', + LINSERT: 'LINSERT key BEFORE|AFTER pivot value', + LMOVE: 'LMOVE source destination LEFT|RIGHT LEFT|RIGHT', + LPOP: 'LPOP key', + LPUSH: 'LPUSH key value [value ...]', + LPUSHX: 'LPUSHX key value', + LREM: 'LREM key count value', + LSET: 'LSET key index value', + LTRIM: 'LTRIM key start stop', + MIGRATE: 'MIGRATE host port key destination-db timeout', + MOVE: 'MOVE key db', + MSET: 'MSET key value [key value ...]', + MSETNX: 'MSETNX key value [key value ...]', + PERSIST: 'PERSIST key', + PEXPIRE: 'PEXPIRE key milliseconds', + PEXPIREAT: 'PEXPIREAT key milliseconds-timestamp', + PSETEX: 'PSETEX key milliseconds value', + PUBLISH: 'PUBLISH channel message', + RENAME: 'RENAME key newkey', + RENAMENX: 'RENAMENX key newkey', + RESTORE: 'RESTORE key ttl serialized-value', + RPOP: 'RPOP key', + RPOPLPUSH: 'RPOPLPUSH source destination', + RPUSH: 'RPUSH key value [value ...]', + RPUSHX: 'RPUSHX key value', + SADD: 'SADD key member [member ...]', + SCRIPT: ['SCRIPT EXISTS script [script ...]', 'SCRIPT FLUSH', 'SCRIPT KILL', 'SCRIPT LOAD script'], + SDIFFSTORE: 'SDIFFSTORE destination key [key ...]', + SET: 'SET key value', + SETBIT: 'SETBIT key offset value', + SETEX: 'SETEX key seconds value', + SETNX: 'SETNX key value', + SETRANGE: 'SETRANGE key offset value', + SINTERSTORE: 'SINTERSTORE destination key [key ...]', + SMOVE: 'SMOVE source destination member', + SORT: 'SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]', + SPOP: 'SPOP key', + SREM: 'SREM key member [member ...]', + SUNIONSTORE: 'SUNIONSTORE destination key [key ...]', + SWAPDB: 'SWAPDB index1 index2', + UNLINK: 'UNLINK key [key ...]', + XADD: 'XADD key ID field string [field string ...]', + XDEL: 'XDEL key ID [ID ...]', + XGROUP: [ + 'XGROUP CREATE key groupname id|$ [MKSTREAM]', + 'XGROUP CREATECONSUMER key groupname consumername', + 'XGROUP DELCONSUMER key groupname consumername', + 'XGROUP DESTROY key groupname', + 'XGROUP SETID key groupname id|$', + ], + XTRIM: 'XTRIM key MAXLEN [~] count', + ZADD: 'ZADD key score member [score] [member]', + ZDIFFSTORE: 'ZDIFFSTORE destination numkeys key [key ...]', + ZINCRBY: 'ZINCRBY key increment member', + ZINTERSTORE: 'ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]', + ZPOPMAX: 'ZPOPMAX key [count]', + ZPOPMIN: 'ZPOPMIN key [count]', + ZRANGESTORE: 'ZRANGESTORE dst src min max [BYSCORE|BYLEX] [REV] [LIMIT offset count]', + ZREM: 'ZREM key member [member ...]', + ZREMRANGEBYLEX: 'ZREMRANGEBYLEX key min max', + ZREMRANGEBYRANK: 'ZREMRANGEBYRANK key start stop', + ZREMRANGEBYSCORE: 'ZREMRANGEBYSCORE key min max', + ZUNIONSTORE: 'ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]', +}; diff --git a/mayfly_go_web/src/views/ops/redis/utils.ts b/mayfly_go_web/src/views/ops/redis/utils.ts index 7c587cf9..d057f410 100644 --- a/mayfly_go_web/src/views/ops/redis/utils.ts +++ b/mayfly_go_web/src/views/ops/redis/utils.ts @@ -27,7 +27,7 @@ export function keysToTree(keys: any, separator: string = ':', openStatus: any = return formatTreeData(tree, '', separator, openStatus, forceCut); } -export function keysToList(keys: any, separator: string = ':', openStatus: any = null, forceCut = 20000) { +export function keysToList(keys: any) { return keys.map((x: string) => { return { key: x, diff --git a/mayfly_go_web/src/views/system/account/components/AccountInfo.vue b/mayfly_go_web/src/views/system/account/components/AccountInfo.vue new file mode 100644 index 00000000..9dae2031 --- /dev/null +++ b/mayfly_go_web/src/views/system/account/components/AccountInfo.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/mayfly_go_web/src/views/system/api.ts b/mayfly_go_web/src/views/system/api.ts index f3c28824..9e1472af 100644 --- a/mayfly_go_web/src/views/system/api.ts +++ b/mayfly_go_web/src/views/system/api.ts @@ -25,6 +25,7 @@ export const roleApi = { export const accountApi = { list: Api.newGet('/sys/accounts'), querySimple: Api.newGet('/sys/accounts/simple'), + getAccountDetail: Api.newGet('/sys/accounts/{id}'), save: Api.newPost('/sys/accounts'), update: Api.newPut('/sys/accounts/{id}'), del: Api.newDelete('/sys/accounts/{id}'), diff --git a/mayfly_go_web/src/views/system/syslog/SyslogList.vue b/mayfly_go_web/src/views/system/syslog/SyslogList.vue index 31770c17..8caf995f 100755 --- a/mayfly_go_web/src/views/system/syslog/SyslogList.vue +++ b/mayfly_go_web/src/views/system/syslog/SyslogList.vue @@ -1,6 +1,10 @@ @@ -11,6 +15,7 @@ import PageTable from '@/components/pagetable/PageTable.vue'; import { TableColumn } from '@/components/pagetable'; import { LogTypeEnum } from '../enums'; import { OptionsApi, SearchItem } from '@/components/SearchForm'; +import AccountInfo from '../account/components/AccountInfo.vue'; const searchItems = [ SearchItem.select('creatorId', '操作人') @@ -33,7 +38,7 @@ const searchItems = [ ]; const columns = [ - TableColumn.new('creator', '操作人'), + TableColumn.new('creator', '操作人').isSlot().noShowOverflowTooltip(), TableColumn.new('createTime', '操作时间').isTime(), TableColumn.new('type', '结果').typeTag(LogTypeEnum), TableColumn.new('description', '描述'), diff --git a/server/initialize/initialize.go b/server/initialize/initialize.go index 03bfec51..8ec2ad4a 100644 --- a/server/initialize/initialize.go +++ b/server/initialize/initialize.go @@ -16,7 +16,7 @@ var ( initFuncs = make([]InitFunc, 0) ) -// 添加初始化ioc函数,由各个默认自行添加 +// 添加初始化ioc函数,由各个默认自行添加(直接init方法中ioc.Register注册不会打印ioc相关日志) func AddInitIocFunc(initIocFunc InitIocFunc) { initIocFuncs = append(initIocFuncs, initIocFunc) } @@ -37,7 +37,7 @@ func InitOther() { // 为所有注册的实例注入其依赖的其他组件实例 biz.ErrIsNil(ioc.InjectComponents()) - // 调用各个默认的初始化函数 + // 调用各个模块的初始化函数 for _, initFunc := range initFuncs { go initFunc() } diff --git a/server/internal/auth/application/application.go b/server/internal/auth/application/application.go index cc8a37b5..3f121a34 100644 --- a/server/internal/auth/application/application.go +++ b/server/internal/auth/application/application.go @@ -1,12 +1,9 @@ package application import ( - "mayfly-go/internal/auth/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(oauth2AppImpl), ioc.WithComponentName("Oauth2App")) } diff --git a/server/internal/auth/infrastructure/persistence/persistence.go b/server/internal/auth/infrastructure/persistence/persistence.go index 730cc764..29d1ed70 100644 --- a/server/internal/auth/infrastructure/persistence/persistence.go +++ b/server/internal/auth/infrastructure/persistence/persistence.go @@ -4,6 +4,6 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newAuthAccountRepo(), ioc.WithComponentName("Oauth2AccountRepo")) } diff --git a/server/internal/auth/init/init.go b/server/internal/auth/init/init.go index 11855927..d4c46453 100644 --- a/server/internal/auth/init/init.go +++ b/server/internal/auth/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/auth/application" + "mayfly-go/internal/auth/infrastructure/persistence" "mayfly-go/internal/auth/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go index 40840174..a8499f76 100644 --- a/server/internal/db/api/db.go +++ b/server/internal/db/api/db.go @@ -124,7 +124,7 @@ func (d *Db) ExecSql(rc *req.Ctx) { for _, s := range sqls { s = stringx.TrimSpaceAndBr(s) // 多条执行,暂不支持查询语句 - if isMulti { + if isMulti && len(s) > 10 { biz.IsTrue(!strings.HasPrefix(strings.ToLower(s[:10]), "select"), "多条语句执行暂不不支持select语句") } diff --git a/server/internal/db/application/application.go b/server/internal/db/application/application.go index 7db4f369..a2fd020d 100644 --- a/server/internal/db/application/application.go +++ b/server/internal/db/application/application.go @@ -2,14 +2,11 @@ package application import ( "fmt" - "mayfly-go/internal/db/infrastructure/persistence" "mayfly-go/pkg/ioc" "sync" ) func InitIoc() { - persistence.Init() - ioc.Register(new(instanceAppImpl), ioc.WithComponentName("DbInstanceApp")) ioc.Register(new(dbAppImpl), ioc.WithComponentName("DbApp")) ioc.Register(new(dbSqlExecAppImpl), ioc.WithComponentName("DbSqlExecApp")) diff --git a/server/internal/db/application/db_sql_exec.go b/server/internal/db/application/db_sql_exec.go index 3d11d84c..887c3c19 100644 --- a/server/internal/db/application/db_sql_exec.go +++ b/server/internal/db/application/db_sql_exec.go @@ -97,7 +97,6 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) ( // 如果配置为0,则不校验分页参数 maxCount := config.GetDbQueryMaxCount() if maxCount != 0 { - if !strings.Contains(lowerSql, "limit") && // 兼容oracle rownum分页 !strings.Contains(lowerSql, "rownum") && @@ -118,10 +117,11 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) ( } else { execRes, execErr = d.doExec(ctx, execSqlReq, dbSqlExecRecord) } + + d.saveSqlExecLog(isSelect, dbSqlExecRecord) if execErr != nil { return nil, execErr } - d.saveSqlExecLog(isSelect, dbSqlExecRecord) return execRes, nil } @@ -152,10 +152,13 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) ( return execRes, nil } -func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, procinstStatus flowentity.ProcinstStatus, bizKey string) error { +func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *flowapp.BizHandleParam) error { + bizKey := bizHandleParam.BizKey + procinstStatus := bizHandleParam.ProcinstStatus + logx.Debugf("DbSqlExec FlowBizHandle -> bizKey: %s, procinstStatus: %s", bizKey, flowentity.ProcinstStatusEnum.GetDesc(procinstStatus)) // 流程挂起不处理 - if procinstStatus == flowentity.ProcinstSuspended { + if procinstStatus == flowentity.ProcinstStatusSuspended { return nil } dbSqlExec := &entity.DbSqlExec{FlowBizKey: bizKey} @@ -164,7 +167,7 @@ func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, procinstStatus flo return nil } - if procinstStatus != flowentity.ProcinstCompleted { + if procinstStatus != flowentity.ProcinstStatusCompleted { dbSqlExec.Status = entity.DbSqlExecStatusNo dbSqlExec.Res = fmt.Sprintf("流程%s", flowentity.ProcinstStatusEnum.GetDesc(procinstStatus)) return d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec) @@ -364,7 +367,7 @@ func (d *dbSqlExecAppImpl) doExec(ctx context.Context, execSqlReq *DbSqlExecReq, if err != nil { execRes = err.Error() dbSqlExecRecord.Status = entity.DbSqlExecStatusFail - dbSqlExecRecord.Res = err.Error() + dbSqlExecRecord.Res = execRes } else { dbSqlExecRecord.Res = fmt.Sprintf("执行成功,影响条数: %d", rowsAffected) } diff --git a/server/internal/db/infrastructure/persistence/persistence.go b/server/internal/db/infrastructure/persistence/persistence.go index abb77248..1dc8b266 100644 --- a/server/internal/db/infrastructure/persistence/persistence.go +++ b/server/internal/db/infrastructure/persistence/persistence.go @@ -4,7 +4,7 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(NewInstanceRepo(), ioc.WithComponentName("DbInstanceRepo")) ioc.Register(newDbRepo(), ioc.WithComponentName("DbRepo")) ioc.Register(newDbSqlRepo(), ioc.WithComponentName("DbSqlRepo")) diff --git a/server/internal/db/init/init.go b/server/internal/db/init/init.go index 7d50512a..058f1d9c 100644 --- a/server/internal/db/init/init.go +++ b/server/internal/db/init/init.go @@ -3,11 +3,16 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/db/application" + "mayfly-go/internal/db/infrastructure/persistence" "mayfly-go/internal/db/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) + initialize.AddInitRouterFunc(router.Init) initialize.AddInitFunc(application.Init) initialize.AddTerminateFunc(Terminate) diff --git a/server/internal/flow/api/vo/procinst.go b/server/internal/flow/api/vo/procinst.go index 05f2dd2b..a7ccba9e 100644 --- a/server/internal/flow/api/vo/procinst.go +++ b/server/internal/flow/api/vo/procinst.go @@ -12,6 +12,7 @@ type ProcinstVO struct { BizType string `json:"bizType"` // 业务类型 BizKey string `json:"bizKey"` // 业务key + BizForm string `json:"bizForm"` // 业务form BizStatus int8 `json:"bizStatus"` // 业务状态 BizHandleRes string `json:"bizHandleRes"` // 业务处理结果 TaskKey string `json:"taskKey"` // 当前任务key @@ -21,6 +22,7 @@ type ProcinstVO struct { Duration int64 `json:"duration"` // 持续时间(开始到结束) Creator string `json:"creator"` + CreatorId uint64 `json:"creatorId"` CreateTime *time.Time `json:"createTime"` UpdateTime *time.Time `json:"updateTime"` diff --git a/server/internal/flow/application/application.go b/server/internal/flow/application/application.go index 1cccedf2..96ea39a5 100644 --- a/server/internal/flow/application/application.go +++ b/server/internal/flow/application/application.go @@ -1,13 +1,10 @@ package application import ( - "mayfly-go/internal/flow/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(procdefAppImpl), ioc.WithComponentName("ProcdefApp")) ioc.Register(new(procinstAppImpl), ioc.WithComponentName("ProcinstApp")) } diff --git a/server/internal/flow/application/biz_handler.go b/server/internal/flow/application/biz_handler.go index b0952a2a..a0758530 100644 --- a/server/internal/flow/application/biz_handler.go +++ b/server/internal/flow/application/biz_handler.go @@ -7,18 +7,19 @@ import ( "mayfly-go/pkg/logx" ) -// 流程业务处理函数(流程结束后会根据流程业务类型获取该函数进行处理) -// @param procinstStatus 流程实例状态 -// @param bizKey 业务key,可为业务数据对应的主键 -// type FlowBizHandlerFunc func(ctx context.Context, procinstStatus entity.ProcinstStatus, bizKey string) error +type BizHandleParam struct { + BizType string //业务类型 + BizKey string // 业务key + BizForm string // 业务表单信息 + ProcinstStatus entity.ProcinstStatus // 业务状态 +} // 业务流程处理器(流程状态变更后会根据流程业务类型获取对应的处理器进行回调处理) type FlowBizHandler interface { // 业务流程处理函数 - // @param procinstStatus 流程实例状态 - // @param bizKey 业务key,可为业务数据对应的主键 - FlowBizHandle(ctx context.Context, procinstStatus entity.ProcinstStatus, bizKey string) error + // @param bizHandleParam 业务处理信息,可获取实例状态、关联业务key等信息 + FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) error } var ( @@ -32,11 +33,12 @@ func RegisterBizHandler(flowBizType string, handler FlowBizHandler) { } // 流程业务处理 -func FlowBizHandle(ctx context.Context, flowBizType string, bizKey string, procinstStatus entity.ProcinstStatus) error { +func FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) error { + flowBizType := bizHandleParam.BizType if handler, ok := handlers[flowBizType]; !ok { logx.Warnf("flow biz handler not found: bizType=%s", flowBizType) - return errorx.NewBiz("业务流程处理器不存在") + return errorx.NewBiz("业务处理器不存在") } else { - return handler.FlowBizHandle(ctx, procinstStatus, bizKey) + return handler.FlowBizHandle(ctx, bizHandleParam) } } diff --git a/server/internal/flow/application/param.go b/server/internal/flow/application/param.go index bd69eda9..3e159c66 100644 --- a/server/internal/flow/application/param.go +++ b/server/internal/flow/application/param.go @@ -5,6 +5,7 @@ type StarProcParam struct { BizType string // 业务类型 BizKey string // 业务key Remark string // 备注 + BizForm string // 业务表单信息 } type CompleteProcinstTaskParam struct { diff --git a/server/internal/flow/application/procdef.go b/server/internal/flow/application/procdef.go index eb9f5e97..523e39d9 100644 --- a/server/internal/flow/application/procdef.go +++ b/server/internal/flow/application/procdef.go @@ -65,10 +65,10 @@ func (p *procdefAppImpl) DeleteProcdef(ctx context.Context, defId uint64) error // 判断该流程实例是否可以执行修改操作 func (p *procdefAppImpl) canModify(prodefId uint64) error { - if activeInstCount := p.procinstApp.CountByCond(&entity.Procinst{ProcdefId: prodefId, Status: entity.ProcinstActive}); activeInstCount > 0 { + if activeInstCount := p.procinstApp.CountByCond(&entity.Procinst{ProcdefId: prodefId, Status: entity.ProcinstStatusActive}); activeInstCount > 0 { return errorx.NewBiz("存在运行中的流程实例,无法操作") } - if suspInstCount := p.procinstApp.CountByCond(&entity.Procinst{ProcdefId: prodefId, Status: entity.ProcinstSuspended}); suspInstCount > 0 { + if suspInstCount := p.procinstApp.CountByCond(&entity.Procinst{ProcdefId: prodefId, Status: entity.ProcinstStatusSuspended}); suspInstCount > 0 { return errorx.NewBiz("存在挂起中的流程实例,无法操作") } return nil diff --git a/server/internal/flow/application/procinst.go b/server/internal/flow/application/procinst.go index f92c26e9..38d5b30a 100644 --- a/server/internal/flow/application/procinst.go +++ b/server/internal/flow/application/procinst.go @@ -68,11 +68,12 @@ func (p *procinstAppImpl) StartProc(ctx context.Context, procdefKey string, reqP procinst := &entity.Procinst{ BizType: reqParam.BizType, BizKey: reqParam.BizKey, + BizForm: reqParam.BizForm, BizStatus: entity.ProcinstBizStatusWait, ProcdefId: procdef.Id, ProcdefName: procdef.Name, Remark: reqParam.Remark, - Status: entity.ProcinstActive, + Status: entity.ProcinstStatusActive, } task := p.getNextTask(procdef, "") @@ -97,7 +98,7 @@ func (p *procinstAppImpl) CancelProc(ctx context.Context, procinstId uint64) err if procinst.CreatorId != la.Id { return errorx.NewBiz("只能取消自己创建的流程") } - procinst.Status = entity.ProcinstCancelled + procinst.Status = entity.ProcinstStatusCancelled procinst.BizStatus = entity.ProcinstBizStatusNo procinst.SetEnd() @@ -130,7 +131,7 @@ func (p *procinstAppImpl) CompleteTask(ctx context.Context, instTaskId uint64, r // 获取下一实例审批任务 task := p.getNextTask(procdef, instTask.TaskKey) if task == nil { - procinst.Status = entity.ProcinstCompleted + procinst.Status = entity.ProcinstStatusCompleted procinst.SetEnd() } else { procinst.TaskKey = task.TaskKey @@ -165,7 +166,7 @@ func (p *procinstAppImpl) RejectTask(ctx context.Context, instTaskId uint64, rem procinst := new(entity.Procinst) p.GetById(procinst, instTask.ProcinstId) // 更新流程实例为终止状态,无法重新提交 - procinst.Status = entity.ProcinstTerminated + procinst.Status = entity.ProcinstStatusTerminated procinst.BizStatus = entity.ProcinstBizStatusNo procinst.SetEnd() @@ -192,7 +193,7 @@ func (p *procinstAppImpl) BackTask(ctx context.Context, instTaskId uint64, remar p.GetById(procinst, instTask.ProcinstId) // 更新流程实例为挂起状态,等待重新提交 - procinst.Status = entity.ProcinstSuspended + procinst.Status = entity.ProcinstStatusSuspended return p.Tx(ctx, func(ctx context.Context) error { return p.UpdateById(ctx, procinst) @@ -219,11 +220,17 @@ func (p *procinstAppImpl) cancelInstTasks(ctx context.Context, procinstId uint64 // 触发流程实例状态改变事件 func (p *procinstAppImpl) triggerProcinstStatusChangeEvent(ctx context.Context, procinst *entity.Procinst) error { - err := FlowBizHandle(ctx, procinst.BizType, procinst.BizKey, procinst.Status) + err := FlowBizHandle(ctx, &BizHandleParam{ + BizType: procinst.BizType, + BizKey: procinst.BizKey, + BizForm: procinst.BizForm, + ProcinstStatus: procinst.Status, + }) + if err != nil { // 业务处理错误,非完成状态则终止流程 - if procinst.Status != entity.ProcinstCompleted { - procinst.Status = entity.ProcinstTerminated + if procinst.Status != entity.ProcinstStatusCompleted { + procinst.Status = entity.ProcinstStatusTerminated procinst.SetEnd() p.cancelInstTasks(ctx, procinst.Id, "业务处理失败") } @@ -233,7 +240,7 @@ func (p *procinstAppImpl) triggerProcinstStatusChangeEvent(ctx context.Context, } // 处理成功,并且状态为完成,则更新业务状态为成功 - if procinst.Status == entity.ProcinstCompleted { + if procinst.Status == entity.ProcinstStatusCompleted { procinst.BizStatus = entity.ProcinstBizStatusSuccess procinst.BizHandleRes = "success" return p.UpdateById(ctx, procinst) diff --git a/server/internal/flow/domain/entity/procinst.go b/server/internal/flow/domain/entity/procinst.go index 8e852891..e6a79da7 100644 --- a/server/internal/flow/domain/entity/procinst.go +++ b/server/internal/flow/domain/entity/procinst.go @@ -15,6 +15,7 @@ type Procinst struct { BizType string `json:"bizType"` // 业务类型 BizKey string `json:"bizKey"` // 业务key + BizForm string `json:"bizForm"` // 业务表单 BizStatus ProcinstBizStatus `json:"bizStatus"` // 业务状态 BizHandleRes string `json:"bizHandleRes"` // 业务处理结果 TaskKey string `json:"taskKey"` // 当前任务key @@ -38,19 +39,19 @@ func (a *Procinst) SetEnd() { type ProcinstStatus int8 const ( - ProcinstActive ProcinstStatus = 1 // 流程实例正在执行中,当前有活动任务等待执行或者正在运行的流程节点 - ProcinstCompleted ProcinstStatus = 2 // 流程实例已经成功执行完成,没有剩余任务或者等待事件 - ProcinstSuspended ProcinstStatus = -1 // 流程实例被挂起,暂停执行,可能被驳回等待修改重新提交 - ProcinstTerminated ProcinstStatus = -2 // 流程实例被终止,可能是由于某种原因如被拒绝等导致流程无法正常执行 - ProcinstCancelled ProcinstStatus = -3 // 流程实例被取消,通常是用户手动操作取消了流程的执行 + ProcinstStatusActive ProcinstStatus = 1 // 流程实例正在执行中,当前有活动任务等待执行或者正在运行的流程节点 + ProcinstStatusCompleted ProcinstStatus = 2 // 流程实例已经成功执行完成,没有剩余任务或者等待事件 + ProcinstStatusSuspended ProcinstStatus = -1 // 流程实例被挂起,暂停执行,可能被驳回等待修改重新提交 + ProcinstStatusTerminated ProcinstStatus = -2 // 流程实例被终止,可能是由于某种原因如被拒绝等导致流程无法正常执行 + ProcinstStatusCancelled ProcinstStatus = -3 // 流程实例被取消,通常是用户手动操作取消了流程的执行 ) var ProcinstStatusEnum = enumx.NewEnum[ProcinstStatus]("流程状态"). - Add(ProcinstActive, "执行中"). - Add(ProcinstCompleted, "完成"). - Add(ProcinstSuspended, "挂起"). - Add(ProcinstTerminated, "终止"). - Add(ProcinstCancelled, "取消") + Add(ProcinstStatusActive, "执行中"). + Add(ProcinstStatusCompleted, "完成"). + Add(ProcinstStatusSuspended, "挂起"). + Add(ProcinstStatusTerminated, "终止"). + Add(ProcinstStatusCancelled, "取消") type ProcinstBizStatus int8 diff --git a/server/internal/flow/infrastructure/persistence/persistence.go b/server/internal/flow/infrastructure/persistence/persistence.go index f313c049..6b55cbfc 100644 --- a/server/internal/flow/infrastructure/persistence/persistence.go +++ b/server/internal/flow/infrastructure/persistence/persistence.go @@ -4,7 +4,7 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newProcdefRepo(), ioc.WithComponentName("ProcdefRepo")) ioc.Register(newProcinstRepo(), ioc.WithComponentName("ProcinstRepo")) ioc.Register(newProcinstTaskRepo(), ioc.WithComponentName("ProcinstTaskRepo")) diff --git a/server/internal/flow/init/init.go b/server/internal/flow/init/init.go index f9585d62..2e3ef3d6 100644 --- a/server/internal/flow/init/init.go +++ b/server/internal/flow/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/flow/application" + "mayfly-go/internal/flow/infrastructure/persistence" "mayfly-go/internal/flow/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/machine/application/application.go b/server/internal/machine/application/application.go index 57e8c6ea..e0ce9778 100644 --- a/server/internal/machine/application/application.go +++ b/server/internal/machine/application/application.go @@ -1,13 +1,10 @@ package application import ( - "mayfly-go/internal/machine/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(machineAppImpl), ioc.WithComponentName("MachineApp")) ioc.Register(new(machineFileAppImpl), ioc.WithComponentName("MachineFileApp")) ioc.Register(new(machineScriptAppImpl), ioc.WithComponentName("MachineScriptApp")) diff --git a/server/internal/machine/infrastructure/persistence/persistence.go b/server/internal/machine/infrastructure/persistence/persistence.go index 71e78a2a..1e1f5f99 100644 --- a/server/internal/machine/infrastructure/persistence/persistence.go +++ b/server/internal/machine/infrastructure/persistence/persistence.go @@ -4,7 +4,7 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newMachineRepo(), ioc.WithComponentName("MachineRepo")) ioc.Register(newMachineFileRepo(), ioc.WithComponentName("MachineFileRepo")) ioc.Register(newMachineScriptRepo(), ioc.WithComponentName("MachineScriptRepo")) diff --git a/server/internal/machine/init/init.go b/server/internal/machine/init/init.go index 3c971f93..7860ea88 100644 --- a/server/internal/machine/init/init.go +++ b/server/internal/machine/init/init.go @@ -6,13 +6,17 @@ import ( "mayfly-go/internal/common/consts" "mayfly-go/internal/machine/application" "mayfly-go/internal/machine/domain/entity" + "mayfly-go/internal/machine/infrastructure/persistence" "mayfly-go/internal/machine/router" "mayfly-go/pkg/eventbus" "mayfly-go/pkg/global" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) initialize.AddInitFunc(Init) } diff --git a/server/internal/machine/mcm/client_cache.go b/server/internal/machine/mcm/client_cache.go index db6cde5b..f40f1a12 100644 --- a/server/internal/machine/mcm/client_cache.go +++ b/server/internal/machine/mcm/client_cache.go @@ -70,6 +70,12 @@ func checkClientAvailability(interval time.Duration) { if cli.Info == nil { continue } + if cli.sshClient == nil { + continue + } + if cli.sshClient.Conn == nil { + continue + } if _, _, err := cli.sshClient.Conn.SendRequest("ping", true, nil); err != nil { logx.Errorf("machine[%s] cache client is not available: %s", cli.Info.Name, err.Error()) DeleteCli(cli.Info.Id) diff --git a/server/internal/mongo/application/application.go b/server/internal/mongo/application/application.go index a7839dec..cda4d239 100644 --- a/server/internal/mongo/application/application.go +++ b/server/internal/mongo/application/application.go @@ -1,12 +1,9 @@ package application import ( - "mayfly-go/internal/mongo/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(mongoAppImpl), ioc.WithComponentName("MongoApp")) } diff --git a/server/internal/mongo/infrastructure/persistence/persistence.go b/server/internal/mongo/infrastructure/persistence/persistence.go index 89580dd2..13dd3a0e 100644 --- a/server/internal/mongo/infrastructure/persistence/persistence.go +++ b/server/internal/mongo/infrastructure/persistence/persistence.go @@ -4,6 +4,6 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newMongoRepo(), ioc.WithComponentName("MongoRepo")) } diff --git a/server/internal/mongo/init/init.go b/server/internal/mongo/init/init.go index 03072e8f..29fb7fe3 100644 --- a/server/internal/mongo/init/init.go +++ b/server/internal/mongo/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/mongo/application" + "mayfly-go/internal/mongo/infrastructure/persistence" "mayfly-go/internal/mongo/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/msg/application/application.go b/server/internal/msg/application/application.go index be082150..2e0a3866 100644 --- a/server/internal/msg/application/application.go +++ b/server/internal/msg/application/application.go @@ -1,13 +1,10 @@ package application import ( - "mayfly-go/internal/msg/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(msgAppImpl), ioc.WithComponentName("MsgApp")) } diff --git a/server/internal/msg/infrastructure/persistence/persistence.go b/server/internal/msg/infrastructure/persistence/persistence.go index 4483f795..91c28722 100644 --- a/server/internal/msg/infrastructure/persistence/persistence.go +++ b/server/internal/msg/infrastructure/persistence/persistence.go @@ -4,6 +4,6 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newMsgRepo(), ioc.WithComponentName("MsgRepo")) } diff --git a/server/internal/msg/init/init.go b/server/internal/msg/init/init.go index d1e40137..69322f9f 100644 --- a/server/internal/msg/init/init.go +++ b/server/internal/msg/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/msg/application" + "mayfly-go/internal/msg/infrastructure/persistence" "mayfly-go/internal/msg/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/redis/api/cmd.go b/server/internal/redis/api/cmd.go new file mode 100644 index 00000000..b03debc6 --- /dev/null +++ b/server/internal/redis/api/cmd.go @@ -0,0 +1,19 @@ +package api + +import ( + "mayfly-go/internal/redis/api/form" + "mayfly-go/internal/redis/application" + "mayfly-go/pkg/biz" + "mayfly-go/pkg/req" +) + +func (r *Redis) RunCmd(rc *req.Ctx) { + var cmdReq form.RunCmdForm + runCmdParam := req.BindJsonAndCopyTo(rc, &cmdReq, new(application.RunCmdParam)) + biz.IsTrue(len(cmdReq.Cmd) > 0, "redis命令不能为空") + rc.ReqParam = cmdReq + + res, err := r.RedisApp.RunCmd(rc.MetaCtx, r.getRedisConn(rc), runCmdParam) + biz.ErrIsNil(err) + rc.ResData = res +} diff --git a/server/internal/redis/api/form/redis.go b/server/internal/redis/api/form/redis.go index ff1132ec..b5bb8df6 100644 --- a/server/internal/redis/api/form/redis.go +++ b/server/internal/redis/api/form/redis.go @@ -11,16 +11,7 @@ type Redis struct { SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id TagId []uint64 `binding:"required" json:"tagId"` Remark string `json:"remark"` -} - -type Rename struct { - Key string `binding:"required" json:"key"` - NewKey string `binding:"required" json:"newKey"` -} - -type Expire struct { - Key string `binding:"required" json:"key"` - Seconds int64 `binding:"required" json:"seconds"` + FlowProcdefKey string `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批) } type KeyInfo struct { @@ -28,33 +19,6 @@ type KeyInfo struct { Timed int64 `json:"timed"` } -type StringValue struct { - KeyInfo - Value any `binding:"required" json:"value"` -} - -type HashValue struct { - KeyInfo - Value []map[string]any `binding:"required" json:"value"` -} - -type SetValue struct { - KeyInfo - Value []any `binding:"required" json:"value"` -} - -type ListValue struct { - KeyInfo - Value []any `binding:"required" json:"value"` -} - -// list lset命令参数入参 -type ListSetValue struct { - Key string `binding:"required" json:"key"` - Index int64 `json:"index"` - Value any `binding:"required" json:"value"` -} - type RedisScanForm struct { Cursor map[string]uint64 `json:"cursor"` Match string `json:"match"` @@ -68,19 +32,9 @@ type ScanForm struct { Count int64 `json:"count"` } -type SmemberOption struct { - Key string `json:"key"` - Member any `json:"member"` -} - -type LRemOption struct { - Key string `json:"key"` - Count int64 `json:"count"` - Member any `json:"member"` -} - -type ZAddOption struct { - Key string `json:"key"` - Score float64 `json:"score"` - Member any `json:"member"` +type RunCmdForm struct { + Id uint64 `json:"id"` + Db int `json:"db"` + Cmd []any `json:"cmd"` + Remark string `json:"remark"` } diff --git a/server/internal/redis/api/hash.go b/server/internal/redis/api/hash.go deleted file mode 100644 index cfbb8883..00000000 --- a/server/internal/redis/api/hash.go +++ /dev/null @@ -1,79 +0,0 @@ -package api - -import ( - "context" - "mayfly-go/internal/redis/api/form" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" - "time" -) - -func (r *Redis) Hscan(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - count := rc.QueryIntDefault("count", 10) - match := rc.Query("match") - cursor := rc.QueryIntDefault("cursor", 0) - contextTodo := context.TODO() - - cmdable := ri.GetCmdable() - keys, nextCursor, err := cmdable.HScan(contextTodo, key, uint64(cursor), match, int64(count)).Result() - biz.ErrIsNilAppendErr(err, "hcan err: %s") - keySize, err := cmdable.HLen(contextTodo, key).Result() - biz.ErrIsNilAppendErr(err, "hlen err: %s") - - rc.ResData = collx.M{ - "keys": keys, - "cursor": nextCursor, - "keySize": keySize, - } -} - -func (r *Redis) Hdel(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - field := rc.Query("field") - - rc.ReqParam = collx.Kvs("redis", ri.Info, "key", key, "field", field) - delRes, err := ri.GetCmdable().HDel(context.TODO(), key, field).Result() - biz.ErrIsNilAppendErr(err, "hdel err: %s") - rc.ResData = delRes -} - -func (r *Redis) Hget(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - field := rc.Query("field") - - res, err := ri.GetCmdable().HGet(context.TODO(), key, field).Result() - biz.ErrIsNilAppendErr(err, "hget err: %s") - rc.ResData = res -} - -func (r *Redis) Hset(rc *req.Ctx) { - hashValue := req.BindJsonAndValid(rc, new(form.HashValue)) - - hv := hashValue.Value[0] - ri := r.getRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "hash", hv) - - res, err := ri.GetCmdable().HSet(context.TODO(), hashValue.Key, hv["field"].(string), hv["value"]).Result() - biz.ErrIsNilAppendErr(err, "hset失败: %s") - rc.ResData = res -} - -func (r *Redis) SaveHashValue(rc *req.Ctx) { - hashValue := req.BindJsonAndValid(rc, new(form.HashValue)) - - ri := r.getRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "hash", hashValue) - cmd := ri.GetCmdable() - - key := hashValue.Key - contextTodo := context.TODO() - for _, v := range hashValue.Value { - res := cmd.HSet(contextTodo, key, v["field"].(string), v["value"]) - biz.ErrIsNilAppendErr(res.Err(), "保存hash值失败: %s") - } - if hashValue.Timed != 0 && hashValue.Timed != -1 { - cmd.Expire(context.TODO(), key, time.Second*time.Duration(hashValue.Timed)) - } -} diff --git a/server/internal/redis/api/key.go b/server/internal/redis/api/key.go index d033f63f..21dd1d01 100644 --- a/server/internal/redis/api/key.go +++ b/server/internal/redis/api/key.go @@ -7,10 +7,8 @@ import ( "mayfly-go/internal/redis/rdm" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" "strings" "sync" - "time" "github.com/redis/go-redis/v9" ) @@ -133,39 +131,3 @@ func (r *Redis) MemoryUsage(rc *req.Ctx) { ri, key := r.checkKeyAndGetRedisConn(rc) rc.ResData = ri.GetCmdable().MemoryUsage(context.Background(), key).Val() } - -func (r *Redis) DeleteKey(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "key", key) - ri.GetCmdable().Del(context.Background(), key) -} - -func (r *Redis) RenameKey(rc *req.Ctx) { - form := req.BindJsonAndValid(rc, new(form.Rename)) - - ri := r.getRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "rename", form) - ri.GetCmdable().Rename(context.Background(), form.Key, form.NewKey) -} - -func (r *Redis) ExpireKey(rc *req.Ctx) { - form := req.BindJsonAndValid(rc, new(form.Expire)) - - ri := r.getRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "expire", form) - ri.GetCmdable().Expire(context.Background(), form.Key, time.Duration(form.Seconds)*time.Second) -} - -// 移除过期时间 -func (r *Redis) PersistKey(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - rc.ReqParam = collx.Kvs("redis", ri.Info, "key", key) - ri.GetCmdable().Persist(context.Background(), key) -} - -// 清空库 -func (r *Redis) FlushDb(rc *req.Ctx) { - ri := r.getRedisConn(rc) - rc.ReqParam = ri.Info - ri.GetCmdable().FlushDB(context.Background()) -} diff --git a/server/internal/redis/api/list.go b/server/internal/redis/api/list.go deleted file mode 100644 index 35bc8d08..00000000 --- a/server/internal/redis/api/list.go +++ /dev/null @@ -1,58 +0,0 @@ -package api - -import ( - "context" - "mayfly-go/internal/redis/api/form" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" -) - -func (r *Redis) GetListValue(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - ctx := context.TODO() - cmdable := ri.GetCmdable() - - len, err := cmdable.LLen(ctx, key).Result() - biz.ErrIsNilAppendErr(err, "获取list长度失败: %s") - - start := rc.QueryIntDefault("start", 0) - stop := rc.QueryIntDefault("stop", 10) - res, err := cmdable.LRange(ctx, key, int64(start), int64(stop)).Result() - biz.ErrIsNilAppendErr(err, "获取list值失败: %s") - - rc.ResData = collx.M{ - "len": len, - "list": res, - } -} - -func (r *Redis) Lrem(rc *req.Ctx) { - option := req.BindJsonAndValid(rc, new(form.LRemOption)) - - cmd := r.getRedisConn(rc).GetCmdable() - res, err := cmd.LRem(context.TODO(), option.Key, int64(option.Count), option.Member).Result() - biz.ErrIsNilAppendErr(err, "lrem失败: %s") - rc.ResData = res -} - -func (r *Redis) SaveListValue(rc *req.Ctx) { - listValue := req.BindJsonAndValid(rc, new(form.ListValue)) - - cmd := r.getRedisConn(rc).GetCmdable() - - key := listValue.Key - ctx := context.TODO() - for _, v := range listValue.Value { - cmd.RPush(ctx, key, v) - } -} - -func (r *Redis) Lset(rc *req.Ctx) { - listSetValue := req.BindJsonAndValid(rc, new(form.ListSetValue)) - - ri := r.getRedisConn(rc) - - _, err := ri.GetCmdable().LSet(context.TODO(), listSetValue.Key, listSetValue.Index, listSetValue.Value).Result() - biz.ErrIsNilAppendErr(err, "list set失败: %s") -} diff --git a/server/internal/redis/api/set.go b/server/internal/redis/api/set.go deleted file mode 100644 index 402285f6..00000000 --- a/server/internal/redis/api/set.go +++ /dev/null @@ -1,71 +0,0 @@ -package api - -import ( - "context" - "mayfly-go/internal/redis/api/form" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" - "time" -) - -func (r *Redis) GetSetValue(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - res, err := ri.GetCmdable().SMembers(context.TODO(), key).Result() - biz.ErrIsNilAppendErr(err, "获取set值失败: %s") - rc.ResData = res -} - -func (r *Redis) SaveSetValue(rc *req.Ctx) { - keyvalue := req.BindJsonAndValid(rc, new(form.SetValue)) - - cmd := r.getRedisConn(rc).GetCmdable() - - key := keyvalue.Key - // 简单处理->先删除,后新增 - cmd.Del(context.TODO(), key) - cmd.SAdd(context.TODO(), key, keyvalue.Value...) - - if keyvalue.Timed != -1 { - cmd.Expire(context.TODO(), key, time.Second*time.Duration(keyvalue.Timed)) - } -} - -func (r *Redis) Scard(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - - total, err := ri.GetCmdable().SCard(context.TODO(), key).Result() - biz.ErrIsNilAppendErr(err, "scard失败: %s") - rc.ResData = total -} - -func (r *Redis) Sscan(rc *req.Ctx) { - scan := req.BindJsonAndValid(rc, new(form.ScanForm)) - - cmd := r.getRedisConn(rc).GetCmdable() - keys, cursor, err := cmd.SScan(context.TODO(), scan.Key, scan.Cursor, scan.Match, scan.Count).Result() - biz.ErrIsNilAppendErr(err, "sscan失败: %s") - rc.ResData = collx.M{ - "keys": keys, - "cursor": cursor, - } -} - -func (r *Redis) Sadd(rc *req.Ctx) { - option := req.BindJsonAndValid(rc, new(form.SmemberOption)) - - cmd := r.getRedisConn(rc).GetCmdable() - - res, err := cmd.SAdd(context.TODO(), option.Key, option.Member).Result() - biz.ErrIsNilAppendErr(err, "sadd失败: %s") - rc.ResData = res -} - -func (r *Redis) Srem(rc *req.Ctx) { - option := req.BindJsonAndValid(rc, new(form.SmemberOption)) - - cmd := r.getRedisConn(rc).GetCmdable() - res, err := cmd.SRem(context.TODO(), option.Key, option.Member).Result() - biz.ErrIsNilAppendErr(err, "srem失败: %s") - rc.ResData = res -} diff --git a/server/internal/redis/api/string.go b/server/internal/redis/api/string.go deleted file mode 100644 index 4d90c436..00000000 --- a/server/internal/redis/api/string.go +++ /dev/null @@ -1,29 +0,0 @@ -package api - -import ( - "context" - "mayfly-go/internal/redis/api/form" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" - "time" -) - -func (r *Redis) GetStringValue(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - str, err := ri.GetCmdable().Get(context.TODO(), key).Result() - biz.ErrIsNilAppendErr(err, "获取字符串值失败: %s") - rc.ResData = str -} - -func (r *Redis) SaveStringValue(rc *req.Ctx) { - keyValue := req.BindJsonAndValid(rc, new(form.StringValue)) - - ri := r.getRedisConn(rc) - cmd := ri.GetCmdable() - rc.ReqParam = collx.Kvs("redis", ri.Info, "string", keyValue) - - str, err := cmd.Set(context.TODO(), keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result() - biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s") - rc.ResData = str -} diff --git a/server/internal/redis/api/vo/redis.go b/server/internal/redis/api/vo/redis.go index 09c86e01..7575afc5 100644 --- a/server/internal/redis/api/vo/redis.go +++ b/server/internal/redis/api/vo/redis.go @@ -15,6 +15,7 @@ type Redis struct { Mode *string `json:"mode"` SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id Remark *string `json:"remark"` + FlowProcdefKey string `json:"flowProcdefKey"` CreateTime *time.Time `json:"createTime"` Creator *string `json:"creator"` CreatorId *int64 `json:"creatorId"` diff --git a/server/internal/redis/api/zset.go b/server/internal/redis/api/zset.go deleted file mode 100644 index 21511a62..00000000 --- a/server/internal/redis/api/zset.go +++ /dev/null @@ -1,66 +0,0 @@ -package api - -import ( - "context" - "mayfly-go/internal/redis/api/form" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/req" - "mayfly-go/pkg/utils/collx" - - "github.com/redis/go-redis/v9" -) - -func (r *Redis) ZCard(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - - total, err := ri.GetCmdable().ZCard(context.TODO(), key).Result() - biz.ErrIsNilAppendErr(err, "zcard失败: %s") - rc.ResData = total -} - -func (r *Redis) ZScan(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - - cursor := uint64(rc.QueryIntDefault("cursor", 0)) - match := rc.QueryDefault("match", "*") - count := rc.QueryIntDefault("count", 50) - - keys, cursor, err := ri.GetCmdable().ZScan(context.TODO(), key, cursor, match, int64(count)).Result() - biz.ErrIsNilAppendErr(err, "sscan失败: %s") - rc.ResData = collx.M{ - "keys": keys, - "cursor": cursor, - } -} - -func (r *Redis) ZRevRange(rc *req.Ctx) { - ri, key := r.checkKeyAndGetRedisConn(rc) - start := rc.QueryIntDefault("start", 0) - stop := rc.QueryIntDefault("stop", 50) - - res, err := ri.GetCmdable().ZRevRangeWithScores(context.TODO(), key, int64(start), int64(stop)).Result() - biz.ErrIsNilAppendErr(err, "ZRevRange失败: %s") - rc.ResData = res -} - -func (r *Redis) ZRem(rc *req.Ctx) { - option := req.BindJsonAndValid(rc, new(form.SmemberOption)) - - cmd := r.getRedisConn(rc).GetCmdable() - res, err := cmd.ZRem(context.TODO(), option.Key, option.Member).Result() - biz.ErrIsNilAppendErr(err, "zrem失败: %s") - rc.ResData = res -} - -func (r *Redis) ZAdd(rc *req.Ctx) { - option := req.BindJsonAndValid(rc, new(form.ZAddOption)) - - cmd := r.getRedisConn(rc).GetCmdable() - zm := redis.Z{ - Score: option.Score, - Member: option.Member, - } - res, err := cmd.ZAdd(context.TODO(), option.Key, zm).Result() - biz.ErrIsNilAppendErr(err, "zadd失败: %s") - rc.ResData = res -} diff --git a/server/internal/redis/application/application.go b/server/internal/redis/application/application.go index 393eeabc..8b347043 100644 --- a/server/internal/redis/application/application.go +++ b/server/internal/redis/application/application.go @@ -1,12 +1,13 @@ package application import ( - "mayfly-go/internal/redis/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(redisAppImpl), ioc.WithComponentName("RedisApp")) } + +func Init() { + InitRedisFlowHandler() +} diff --git a/server/internal/redis/application/flow.go b/server/internal/redis/application/flow.go new file mode 100644 index 00000000..9d3b119d --- /dev/null +++ b/server/internal/redis/application/flow.go @@ -0,0 +1,14 @@ +package application + +import ( + flowapp "mayfly-go/internal/flow/application" + "mayfly-go/pkg/ioc" +) + +const ( + RedisRunWriteCmdFlowBizType = "redis_run_write_cmd_flow" // db sql exec flow biz type +) + +func InitRedisFlowHandler() { + flowapp.RegisterBizHandler(RedisRunWriteCmdFlowBizType, ioc.Get[Redis]("RedisApp")) +} diff --git a/server/internal/redis/application/redis.go b/server/internal/redis/application/redis.go index cba46c3e..56c70bc7 100644 --- a/server/internal/redis/application/redis.go +++ b/server/internal/redis/application/redis.go @@ -3,20 +3,34 @@ package application import ( "context" "mayfly-go/internal/common/consts" + flowapp "mayfly-go/internal/flow/application" + flowentity "mayfly-go/internal/flow/domain/entity" "mayfly-go/internal/redis/domain/entity" "mayfly-go/internal/redis/domain/repository" "mayfly-go/internal/redis/rdm" tagapp "mayfly-go/internal/tag/application" "mayfly-go/pkg/base" "mayfly-go/pkg/errorx" + "mayfly-go/pkg/logx" "mayfly-go/pkg/model" + "mayfly-go/pkg/utils/jsonx" "mayfly-go/pkg/utils/stringx" "strconv" "strings" + + "github.com/redis/go-redis/v9" ) +type RunCmdParam struct { + Id uint64 `json:"id"` + Db int `json:"db"` + Cmd []any `json:"cmd"` + Remark string +} + type Redis interface { base.App[*entity.Redis] + flowapp.FlowBizHandler // 分页获取机器脚本信息列表 GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) @@ -33,12 +47,16 @@ type Redis interface { // id: 数据库实例id // db: 库号 GetRedisConn(id uint64, db int) (*rdm.RedisConn, error) + + // 执行redis命令 + RunCmd(ctx context.Context, redisConn *rdm.RedisConn, cmdParam *RunCmdParam) (any, error) } type redisAppImpl struct { base.AppImpl[*entity.Redis, repository.Redis] - tagApp tagapp.TagTree `inject:"TagTreeApp"` + tagApp tagapp.TagTree `inject:"TagTreeApp"` + procinstApp flowapp.Procinst `inject:"ProcinstApp"` } // 注入RedisRepo @@ -96,7 +114,7 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds . return errorx.NewBiz("该实例已存在") } // 如果修改了redis实例的库信息,则关闭旧库的连接 - if oldRedis.Db != re.Db || oldRedis.SshTunnelMachineId != re.SshTunnelMachineId { + if oldRedis.Db != re.Db || oldRedis.SshTunnelMachineId != re.SshTunnelMachineId || oldRedis.FlowProcdefKey != re.FlowProcdefKey { for _, dbStr := range strings.Split(oldRedis.Db, ",") { db, _ := strconv.Atoi(dbStr) rdm.CloseConn(re.Id, db) @@ -151,3 +169,54 @@ func (r *redisAppImpl) GetRedisConn(id uint64, db int) (*rdm.RedisConn, error) { return re.ToRedisInfo(db, r.tagApp.ListTagPathByResource(consts.TagResourceTypeRedis, re.Code)...), nil }) } + +func (r *redisAppImpl) RunCmd(ctx context.Context, redisConn *rdm.RedisConn, cmdParam *RunCmdParam) (any, error) { + if redisConn == nil { + return nil, errorx.NewBiz("redis连接不存在") + } + + // 开启工单流程,并且为写入命令,则开启对应审批流程 + if procdefKey := redisConn.Info.FlowProcdefKey; procdefKey != "" && rdm.IsWriteCmd(cmdParam.Cmd[0]) { + _, err := r.procinstApp.StartProc(ctx, procdefKey, &flowapp.StarProcParam{ + BizType: RedisRunWriteCmdFlowBizType, + BizKey: stringx.Rand(24), + BizForm: jsonx.ToStr(cmdParam), + Remark: cmdParam.Remark, + }) + if err != nil { + return nil, err + } + return nil, nil + } + + res, err := redisConn.RunCmd(ctx, cmdParam.Cmd...) + // 获取的key不存在,不报错 + if err == redis.Nil { + return nil, nil + } + return res, err +} + +func (r *redisAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *flowapp.BizHandleParam) error { + bizKey := bizHandleParam.BizKey + procinstStatus := bizHandleParam.ProcinstStatus + + logx.Debugf("RedisRunWriteCmd FlowBizHandle -> bizKey: %s, procinstStatus: %s", bizKey, flowentity.ProcinstStatusEnum.GetDesc(procinstStatus)) + // 流程非完成状态,不处理 + if procinstStatus != flowentity.ProcinstStatusCompleted { + return nil + } + + runCmdParam, err := jsonx.To(bizHandleParam.BizForm, new(RunCmdParam)) + if err != nil { + return errorx.NewBiz("业务表单信息解析失败: %s", err.Error()) + } + + redisConn, err := r.GetRedisConn(runCmdParam.Id, runCmdParam.Db) + if err != nil { + return err + } + + _, err = redisConn.RunCmd(ctx, runCmdParam.Cmd...) + return err +} diff --git a/server/internal/redis/domain/entity/query.go b/server/internal/redis/domain/entity/query.go index 6840cab6..0aae5f9a 100644 --- a/server/internal/redis/domain/entity/query.go +++ b/server/internal/redis/domain/entity/query.go @@ -1,17 +1,11 @@ package entity -import "mayfly-go/pkg/model" - type RedisQuery struct { - model.Model + Id uint64 `form:"id"` + Name string `orm:"column(name)" json:"name" form:"name"` + Host string `orm:"column(host)" json:"host" form:"host"` - Name string `orm:"column(name)" json:"name"` - Host string `orm:"column(host)" json:"host"` - Mode string `json:"mode"` - Password string `orm:"column(password)" json:"-"` - Db string `orm:"column(database)" json:"db"` - SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id - Remark string + SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id Codes []string TagPath string `form:"tagPath"` diff --git a/server/internal/redis/domain/entity/redis.go b/server/internal/redis/domain/entity/redis.go index cedc9c22..f66c7fa5 100644 --- a/server/internal/redis/domain/entity/redis.go +++ b/server/internal/redis/domain/entity/redis.go @@ -20,6 +20,7 @@ type Redis struct { Db string `orm:"column(database)" json:"db"` SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id Remark string + FlowProcdefKey *string `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批) } func (r *Redis) PwdEncrypt() error { diff --git a/server/internal/redis/infrastructure/persistence/persistence.go b/server/internal/redis/infrastructure/persistence/persistence.go index 07e21b89..710c42a0 100644 --- a/server/internal/redis/infrastructure/persistence/persistence.go +++ b/server/internal/redis/infrastructure/persistence/persistence.go @@ -4,6 +4,6 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newRedisRepo(), ioc.WithComponentName("RedisRepo")) } diff --git a/server/internal/redis/infrastructure/persistence/redis_repo.go b/server/internal/redis/infrastructure/persistence/redis_repo.go index 3380a459..b3d46b03 100644 --- a/server/internal/redis/infrastructure/persistence/redis_repo.go +++ b/server/internal/redis/infrastructure/persistence/redis_repo.go @@ -19,6 +19,7 @@ func newRedisRepo() repository.Redis { // 分页获取机器信息列表 func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { qd := gormx.NewQuery(new(entity.Redis)). + Eq("id", condition.Id). Like("host", condition.Host). In("code", condition.Codes) return gormx.PageQuery(qd, pageParam, toEntity) diff --git a/server/internal/redis/init/init.go b/server/internal/redis/init/init.go index 55ca2aa2..3f9ef38c 100644 --- a/server/internal/redis/init/init.go +++ b/server/internal/redis/init/init.go @@ -3,10 +3,16 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/redis/application" + "mayfly-go/internal/redis/infrastructure/persistence" "mayfly-go/internal/redis/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) + initialize.AddInitRouterFunc(router.Init) + initialize.AddInitFunc(application.Init) } diff --git a/server/internal/redis/rdm/cmd.go b/server/internal/redis/rdm/cmd.go new file mode 100644 index 00000000..8b576efd --- /dev/null +++ b/server/internal/redis/rdm/cmd.go @@ -0,0 +1,100 @@ +package rdm + +import ( + "mayfly-go/pkg/utils/anyx" +) + +// write cmd +var writeCmd = map[string]string{ + "APPEND": "APPEND key value", + "BLMOVE": "BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout", + "BLPOP": "BLPOP key [key ...] timeout", + "BRPOP": "BRPOP key [key ...] timeout", + "BRPOPLPUSH": "BRPOPLPUSH source destination timeout", + "BZPOPMAX": "BZPOPMAX key [key ...] timeout", + "BZPOPMIN": "BZPOPMIN key [key ...] timeout", + "COPY": "COPY source destination [DB destination-db] [REPLACE]", + "DECR": "DECR key", + "DECRBY": "DECRBY key decrement", + "DEL": "DEL key [key ...]", + "EVAL": "EVAL script numkeys key [key ...] arg [arg ...]", + "EVALSHA": "EVALSHA sha1 numkeys key [key ...] arg [arg ...]", + "EXPIRE": "EXPIRE key seconds", + "EXPIREAT": "EXPIREAT key timestamp", + "FLUSHALL": "FLUSHALL", + "FLUSHDB": "FLUSHDB", + "GEOADD": "GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]", + "GETDEL": "GETDEL key", + "GETSET": "GETSET key value", + "HDEL": "HDEL key field [field ...]", + "HINCRBY": "HINCRBY key field increment", + "HINCRBYFLOAT": "HINCRBYFLOAT key field increment", + "HMSET": "HMSET key field value [field value ...]", + "HSET": "HSET key field value", + "HSETNX": "HSETNX key field value", + "INCR": "INCR key", + "INCRBY": "INCRBY key increment", + "INCRBYFLOAT": "INCRBYFLOAT key increment", + "LINSERT": "LINSERT key BEFORE|AFTER pivot value", + "LMOVE": "LMOVE source destination LEFT|RIGHT LEFT|RIGHT", + "LPOP": "LPOP key", + "LPUSH": "LPUSH key value [value ...]", + "LPUSHX": "LPUSHX key value", + "LREM": "LREM key count value", + "LSET": "LSET key index value", + "LTRIM": "LTRIM key start stop", + "MIGRATE": "MIGRATE host port key destination-db timeout", + "MOVE": "MOVE key db", + "MSET": "MSET key value [key value ...]", + "MSETNX": "MSETNX key value [key value ...]", + "PERSIST": "PERSIST key", + "PEXPIRE": "PEXPIRE key milliseconds", + "PEXPIREAT": "PEXPIREAT key milliseconds-timestamp", + "PSETEX": "PSETEX key milliseconds value", + "PUBLISH": "PUBLISH channel message", + "RENAME": "RENAME key newkey", + "RENAMENX": "RENAMENX key newkey", + "RESTORE": "RESTORE key ttl serialized-value", + "RPOP": "RPOP key", + "RPOPLPUSH": "RPOPLPUSH source destination", + "RPUSH": "RPUSH key value [value ...]", + "RPUSHX": "RPUSHX key value", + "SADD": "SADD key member [member ...]", + "SCRIPT": "SCRIPT EXISTS script [script ...], 'SCRIPT FLUSH', 'SCRIPT KILL', SCRIPT LOAD script", + "SDIFFSTORE": "SDIFFSTORE destination key [key ...]", + "SET": "SET key value", + "SETBIT": "SETBIT key offset value", + "SETEX": "SETEX key seconds value", + "SETNX": "SETNX key value", + "SETRANGE": "SETRANGE key offset value", + "SINTERSTORE": "SINTERSTORE destination key [key ...]", + "SMOVE": "SMOVE source destination member", + "SORT": "SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]", + "SPOP": "SPOP key", + "SREM": "SREM key member [member ...]", + "SUNIONSTORE": "SUNIONSTORE destination key [key ...]", + "SWAPDB": "SWAPDB index1 index2", + "UNLINK": "UNLINK key [key ...]", + "XADD": "XADD key ID field string [field string ...]", + "XDEL": "XDEL key ID [ID ...]", + "XGROUP": "XGROUP CREATE key groupname id|$ [MKSTREAM], XGROUP CREATECONSUMER key groupname consumername, XGROUP DELCONSUMER key groupname consumername, XGROUP DESTROY key groupname, XGROUP SETID key groupname id|$", + "XTRIM": "XTRIM key MAXLEN [~] count", + "ZADD": "ZADD key score member [score] [member]", + "ZDIFFSTORE": "ZDIFFSTORE destination numkeys key [key ...]", + "ZINCRBY": "ZINCRBY key increment member", + "ZINTERSTORE": "ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]", + "ZPOPMAX": "ZPOPMAX key [count]", + "ZPOPMIN": "ZPOPMIN key [count]", + "ZRANGESTORE": "ZRANGESTORE dst src min max [BYSCORE|BYLEX] [REV] [LIMIT offset count]", + "ZREM": "ZREM key member [member ...]", + "ZREMRANGEBYLEX": "ZREMRANGEBYLEX key min max", + "ZREMRANGEBYRANK": "ZREMRANGEBYRANK key start stop", + "ZREMRANGEBYSCORE": "ZREMRANGEBYSCORE key min max", + "ZUNIONSTORE": "ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]", +} + +// 判断命令是否写命令 +func IsWriteCmd(cmd any) bool { + _, ok := writeCmd[anyx.ConvString(cmd)] + return ok +} diff --git a/server/internal/redis/rdm/conn.go b/server/internal/redis/rdm/conn.go index cf6a99ea..c7c8de2d 100644 --- a/server/internal/redis/rdm/conn.go +++ b/server/internal/redis/rdm/conn.go @@ -2,6 +2,7 @@ package rdm import ( "context" + "mayfly-go/pkg/errorx" "mayfly-go/pkg/logx" "github.com/redis/go-redis/v9" @@ -32,6 +33,19 @@ func (r *RedisConn) Scan(cursor uint64, match string, count int64) ([]string, ui return r.GetCmdable().Scan(context.Background(), cursor, match, count).Result() } +// 执行redis命令 +// 如: SET str value命令则args为['SET', 'str', 'val'] +func (r *RedisConn) RunCmd(ctx context.Context, args ...any) (any, error) { + redisMode := r.Info.Mode + if redisMode == "" || redisMode == StandaloneMode || r.Info.Mode == SentinelMode { + return r.Cli.Do(ctx, args...).Result() + } + if redisMode == ClusterMode { + return r.ClusterCli.Do(ctx, args...).Result() + } + return nil, errorx.NewBiz("redis mode error") +} + func (r *RedisConn) Close() { mode := r.Info.Mode if mode == StandaloneMode || mode == SentinelMode { diff --git a/server/internal/redis/rdm/info.go b/server/internal/redis/rdm/info.go index 1d1dd502..66ea4758 100644 --- a/server/internal/redis/rdm/info.go +++ b/server/internal/redis/rdm/info.go @@ -34,6 +34,8 @@ type RedisInfo struct { Name string `json:"-"` TagPath []string `json:"tagPath"` SshTunnelMachineId int `json:"-"` + + FlowProcdefKey string // 工单流程定义key } func (r *RedisInfo) Conn() (*RedisConn, error) { diff --git a/server/internal/redis/router/redis.go b/server/internal/redis/router/redis.go index 308758e6..cd4267d9 100644 --- a/server/internal/redis/router/redis.go +++ b/server/internal/redis/router/redis.go @@ -18,11 +18,6 @@ func InitRedisRouter(router *gin.RouterGroup) { dashbord := new(api.Dashbord) biz.ErrIsNil(ioc.Inject(dashbord)) - // 保存数据权限 - saveDataP := req.NewPermission("redis:data:save") - // 删除数据权限 - deleteDataP := req.NewPermission("redis:data:del") - reqs := [...]*req.Conf{ req.NewGet("dashbord", dashbord.Dashbord), @@ -41,6 +36,8 @@ func InitRedisRouter(router *gin.RouterGroup) { req.NewGet(":id/cluster-info", rs.ClusterInfo), + req.NewPost(":id/:db/run-cmd", rs.RunCmd).Log(req.NewLogSave("redis-runCmd")), + // 获取指定redis keys req.NewPost(":id/:db/scan", rs.ScanKeys), @@ -49,69 +46,7 @@ func InitRedisRouter(router *gin.RouterGroup) { req.NewGet(":id/:db/key-ttl", rs.TtlKey), req.NewGet(":id/:db/key-memuse", rs.MemoryUsage), - - req.NewDelete(":id/:db/key", rs.DeleteKey).Log(req.NewLogSave("redis-删除key")).RequiredPermission(deleteDataP), - - req.NewPost(":id/:db/rename-key", rs.RenameKey).Log(req.NewLogSave("redis-重命名key")).RequiredPermission(saveDataP), - - req.NewPost(":id/:db/expire-key", rs.ExpireKey).Log(req.NewLogSave("redis-设置key过期时间")).RequiredPermission(saveDataP), - - req.NewDelete(":id/:db/persist-key", rs.PersistKey).Log(req.NewLogSave("redis-移除key过期时间")).RequiredPermission(saveDataP), - - req.NewDelete(":id/:db/flushdb", rs.FlushDb).Log(req.NewLogSave("redis-flushdb")).RequiredPermission(deleteDataP), - - // 获取string类型值 - req.NewGet(":id/:db/string-value", rs.GetStringValue), - - // 设置string类型值 - req.NewPost(":id/:db/string-value", rs.SaveStringValue).Log(req.NewLogSave("redis-setString")).RequiredPermission(saveDataP), - - // ———————————————— hash操作 ———————————————— - req.NewGet(":id/:db/hscan", rs.Hscan), - - req.NewGet(":id/:db/hget", rs.Hget), - - req.NewPost(":id/:db/hset", rs.Hset).Log(req.NewLogSave("redis-hset")).RequiredPermission(saveDataP), - - req.NewDelete(":id/:db/hdel", rs.Hdel).Log(req.NewLogSave("redis-hdel")).RequiredPermission(deleteDataP), - - // 设置hash类型值 - req.NewPost(":id/:db/hash-value", rs.SaveHashValue).Log(req.NewLogSave("redis-setHashValue")).RequiredPermission(saveDataP), - - // --------------- set操作 ---------------- - req.NewGet(":id/:db/set-value", rs.GetSetValue), - - req.NewPost(":id/:db/set-value", rs.SaveSetValue).RequiredPermission(saveDataP), - - req.NewGet(":id/:db/scard", rs.Scard), - - req.NewPost(":id/:db/sscan", rs.Sscan), - - req.NewPost(":id/:db/sadd", rs.Sadd).RequiredPermission(saveDataP), - - req.NewPost(":id/:db/srem", rs.Srem).RequiredPermission(deleteDataP), - - // --------------- list操作 ---------------- - req.NewGet(":id/:db/list-value", rs.GetListValue), - - req.NewPost(":id/:db/list-value", rs.SaveListValue).RequiredPermission(saveDataP), - - req.NewPost(":id/:db/list-value/lset", rs.Lset).RequiredPermission(saveDataP), - - req.NewPost(":id/:db/lrem", rs.Lrem).RequiredPermission(deleteDataP), - - // --------------- zset操作 ---------------- - req.NewGet(":id/:db/zcard", rs.ZCard), - - req.NewGet(":id/:db/zscan", rs.ZScan), - - req.NewGet(":id/:db/zrevrange", rs.ZRevRange), - - req.NewPost(":id/:db/zrem", rs.ZRem).Log(req.NewLogSave("redis-zrem")).RequiredPermission(deleteDataP), - - req.NewPost(":id/:db/zadd", rs.ZAdd).RequiredPermission(saveDataP), } req.BatchSetGroup(redis, reqs[:]) - } diff --git a/server/internal/sys/api/account.go b/server/internal/sys/api/account.go index f6e0e879..09875f8e 100644 --- a/server/internal/sys/api/account.go +++ b/server/internal/sys/api/account.go @@ -15,6 +15,7 @@ import ( "mayfly-go/pkg/utils/collx" "mayfly-go/pkg/utils/conv" "mayfly-go/pkg/utils/cryptox" + "mayfly-go/pkg/utils/structx" "strconv" "strings" "time" @@ -143,6 +144,18 @@ func (a *Account) SimpleAccounts(rc *req.Ctx) { rc.ResData = res } +// 获取账号详情 +func (a *Account) AccountDetail(rc *req.Ctx) { + accountId := uint64(rc.PathParamInt("id")) + account, err := a.AccountApp.GetById(new(entity.Account), accountId) + biz.ErrIsNil(err, "账号不存在") + accountvo := new(vo.SimpleAccountVO) + structx.Copy(accountvo, account) + + accountvo.Roles = a.getAccountRoles(accountId) + rc.ResData = accountvo +} + // @router /accounts func (a *Account) SaveAccount(rc *req.Ctx) { form := &form.AccountCreateForm{} diff --git a/server/internal/sys/api/vo/account.go b/server/internal/sys/api/vo/account.go index 091b0020..84ce8b4e 100644 --- a/server/internal/sys/api/vo/account.go +++ b/server/internal/sys/api/vo/account.go @@ -19,6 +19,8 @@ type SimpleAccountVO struct { Id uint64 `json:"id"` Name string `json:"name"` Username string `json:"username"` + + Roles []*AccountRoleVO `json:"roles" gorm:"-"` } // 账号角色信息 diff --git a/server/internal/sys/application/application.go b/server/internal/sys/application/application.go index fd5d9ba9..d3c5eee3 100644 --- a/server/internal/sys/application/application.go +++ b/server/internal/sys/application/application.go @@ -1,13 +1,10 @@ package application import ( - "mayfly-go/internal/sys/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(accountAppImpl), ioc.WithComponentName("AccountApp")) ioc.Register(new(roleAppImpl), ioc.WithComponentName("RoleApp")) ioc.Register(new(configAppImpl), ioc.WithComponentName("ConfigApp")) diff --git a/server/internal/sys/infrastructure/persistence/persistence.go b/server/internal/sys/infrastructure/persistence/persistence.go index 3a7947cb..418f22f8 100644 --- a/server/internal/sys/infrastructure/persistence/persistence.go +++ b/server/internal/sys/infrastructure/persistence/persistence.go @@ -4,7 +4,7 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newAccountRepo(), ioc.WithComponentName("AccountRepo")) ioc.Register(newRoleRepo(), ioc.WithComponentName("RoleRepo")) ioc.Register(newAccountRoleRepo(), ioc.WithComponentName("AccountRoleRepo")) diff --git a/server/internal/sys/init/init.go b/server/internal/sys/init/init.go index 30e27c89..49012f67 100644 --- a/server/internal/sys/init/init.go +++ b/server/internal/sys/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/sys/application" + "mayfly-go/internal/sys/infrastructure/persistence" "mayfly-go/internal/sys/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/sys/router/account.go b/server/internal/sys/router/account.go index 0cfa860b..414f4169 100644 --- a/server/internal/sys/router/account.go +++ b/server/internal/sys/router/account.go @@ -37,6 +37,9 @@ func InitAccountRouter(router *gin.RouterGroup) { // 获取用户列表信息(只包含最基础信息) req.NewGet("/simple", a.SimpleAccounts), + // 根据账号id获取账号基础信息 + req.NewGet("/:id", a.AccountDetail), + req.NewPost("", a.SaveAccount).Log(req.NewLogSave("保存账号信息")).RequiredPermission(addAccountPermission), req.NewPut("change-status/:id/:status", a.ChangeStatus).Log(req.NewLogSave("修改账号状态")).RequiredPermission(addAccountPermission), diff --git a/server/internal/tag/application/application.go b/server/internal/tag/application/application.go index a400bd5e..9f9c9c81 100644 --- a/server/internal/tag/application/application.go +++ b/server/internal/tag/application/application.go @@ -1,13 +1,10 @@ package application import ( - "mayfly-go/internal/tag/infrastructure/persistence" "mayfly-go/pkg/ioc" ) func InitIoc() { - persistence.Init() - ioc.Register(new(tagTreeAppImpl), ioc.WithComponentName("TagTreeApp")) ioc.Register(new(teamAppImpl), ioc.WithComponentName("TeamApp")) ioc.Register(new(tagResourceAppImpl), ioc.WithComponentName("TagResourceApp")) diff --git a/server/internal/tag/infrastructure/persistence/persistence.go b/server/internal/tag/infrastructure/persistence/persistence.go index f9e865f3..3c3b6448 100644 --- a/server/internal/tag/infrastructure/persistence/persistence.go +++ b/server/internal/tag/infrastructure/persistence/persistence.go @@ -4,7 +4,7 @@ import ( "mayfly-go/pkg/ioc" ) -func Init() { +func InitIoc() { ioc.Register(newTagTreeRepo(), ioc.WithComponentName("TagTreeRepo")) ioc.Register(newTagTreeTeamRepo(), ioc.WithComponentName("TagTreeTeamRepo")) ioc.Register(newTagResourceRepo(), ioc.WithComponentName("TagResourceRepo")) diff --git a/server/internal/tag/init/init.go b/server/internal/tag/init/init.go index c62b95a5..e71e887a 100644 --- a/server/internal/tag/init/init.go +++ b/server/internal/tag/init/init.go @@ -3,10 +3,14 @@ package init import ( "mayfly-go/initialize" "mayfly-go/internal/tag/application" + "mayfly-go/internal/tag/infrastructure/persistence" "mayfly-go/internal/tag/router" ) func init() { - initialize.AddInitIocFunc(application.InitIoc) + initialize.AddInitIocFunc(func() { + persistence.InitIoc() + application.InitIoc() + }) initialize.AddInitRouterFunc(router.Init) } diff --git a/server/resources/script/sql/mayfly-go-sqlite.sql b/server/resources/script/sql/mayfly-go-sqlite.sql index e4919b5c..c65f4225 100644 --- a/server/resources/script/sql/mayfly-go-sqlite.sql +++ b/server/resources/script/sql/mayfly-go-sqlite.sql @@ -617,6 +617,7 @@ CREATE TABLE IF NOT EXISTS "t_redis" ( "mode" text(32), "ssh_tunnel_machine_id" integer(20), "remark" text(125), + "flow_procdef_key" text(64), "creator" text(32), "creator_id" integer(32), "create_time" datetime, @@ -1024,6 +1025,7 @@ CREATE TABLE "t_flow_procinst" ( "status" tinyint DEFAULT NULL , "biz_type" text(64) NOT NULL , "biz_key" text(64) NOT NULL , + "biz_form" text(5000) DEFAULT NULL , "biz_status" tinyint DEFAULT NULL , "biz_handle_res" text(100) DEFAULT NULL , "remark" text(191) DEFAULT NULL, diff --git a/server/resources/script/sql/mayfly-go.sql b/server/resources/script/sql/mayfly-go.sql index 095481a9..d5d3200f 100644 --- a/server/resources/script/sql/mayfly-go.sql +++ b/server/resources/script/sql/mayfly-go.sql @@ -531,6 +531,7 @@ CREATE TABLE `t_redis` ( `mode` varchar(32) DEFAULT NULL, `ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id', `remark` varchar(125) DEFAULT NULL, + `flow_procdef_key` varchar(100) DEFAULT NULL COMMENT '工单流程定义key', `creator` varchar(32) DEFAULT NULL, `creator_id` bigint(32) DEFAULT NULL, `create_time` datetime DEFAULT NULL, @@ -1045,8 +1046,9 @@ CREATE TABLE `t_flow_procinst` ( `status` tinyint DEFAULT NULL COMMENT '状态', `biz_type` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '关联业务类型', `biz_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '关联业务key', + `biz_form` text DEFAULT NULL COMMENT '业务form', `biz_status` tinyint DEFAULT NULL COMMENT '业务状态', - `biz_handle_res` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '关联的业务处理结果', + `biz_handle_res` varchar(1000) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '关联的业务处理结果', `remark` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `end_time` datetime DEFAULT NULL COMMENT '结束时间', `duration` bigint DEFAULT NULL COMMENT '流程持续时间(开始到结束)', diff --git a/server/resources/script/sql/v1.7/v1.7.4.sql b/server/resources/script/sql/v1.7/v1.7.4.sql index 31756994..2cdb1f65 100644 --- a/server/resources/script/sql/v1.7/v1.7.4.sql +++ b/server/resources/script/sql/v1.7/v1.7.4.sql @@ -35,8 +35,9 @@ CREATE TABLE `t_flow_procinst` ( `status` tinyint DEFAULT NULL COMMENT '状态', `biz_type` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '关联业务类型', `biz_key` varchar(64) NOT NULL COMMENT '关联业务key', + `biz_form` text DEFAULT NULL COMMENT '业务form', `biz_status` tinyint DEFAULT NULL COMMENT '业务状态', - `biz_handle_res` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '关联的业务处理结果', + `biz_handle_res` varchar(1000) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '关联的业务处理结果', `remark` varchar(191) DEFAULT NULL, `end_time` datetime DEFAULT NULL COMMENT '结束时间', `duration` bigint DEFAULT NULL COMMENT '流程持续时间(开始到结束)', @@ -80,6 +81,7 @@ ALTER TABLE t_db_sql_exec ADD flow_biz_key varchar(64) NULL COMMENT '工单流 ALTER TABLE t_db_sql_exec ADD res varchar(1000) NULL COMMENT '执行结果'; ALTER TABLE t_db ADD flow_procdef_key varchar(64) NULL COMMENT '审批流-流程定义key(有值则说明关键操作需要进行审批执行)'; +ALTER TABLE t_redis ADD flow_procdef_key varchar(64) NULL COMMENT '审批流-流程定义key(有值则说明关键操作需要进行审批执行)'; -- 历史执行记录调整为成功状态 UPDATE t_db_sql_exec SET status = 2;