mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: redis支持工单流程审批
This commit is contained in:
		@@ -17,7 +17,7 @@
 | 
				
			|||||||
    "countup.js": "^2.8.0",
 | 
					    "countup.js": "^2.8.0",
 | 
				
			||||||
    "cropperjs": "^1.6.1",
 | 
					    "cropperjs": "^1.6.1",
 | 
				
			||||||
    "echarts": "^5.5.0",
 | 
					    "echarts": "^5.5.0",
 | 
				
			||||||
    "element-plus": "^2.5.6",
 | 
					    "element-plus": "^2.6.0",
 | 
				
			||||||
    "js-base64": "^3.7.5",
 | 
					    "js-base64": "^3.7.5",
 | 
				
			||||||
    "jsencrypt": "^3.3.2",
 | 
					    "jsencrypt": "^3.3.2",
 | 
				
			||||||
    "lodash": "^4.17.21",
 | 
					    "lodash": "^4.17.21",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,7 @@
 | 
				
			|||||||
                                        trigger="click"
 | 
					                                        trigger="click"
 | 
				
			||||||
                                    >
 | 
					                                    >
 | 
				
			||||||
                                        <div v-for="(item, index) in tableColumns" :key="index">
 | 
					                                        <div v-for="(item, index) in tableColumns" :key="index">
 | 
				
			||||||
                                            <el-checkbox v-model="item.show" :label="item.label" :true-label="true" :false-label="false" />
 | 
					                                            <el-checkbox v-model="item.show" :label="item.label" :true-value="true" :false-value="false" />
 | 
				
			||||||
                                        </div>
 | 
					                                        </div>
 | 
				
			||||||
                                        <template #reference>
 | 
					                                        <template #reference>
 | 
				
			||||||
                                            <el-button icon="Operation" circle :size="props.size"></el-button>
 | 
					                                            <el-button icon="Operation" circle :size="props.size"></el-button>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,9 +48,6 @@ export function useApiFetch<T>(api: Api, params: any = null, reqOptions: Request
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let paramsValue = unref(params);
 | 
					            let paramsValue = unref(params);
 | 
				
			||||||
            if (api.beforeHandler) {
 | 
					 | 
				
			||||||
                paramsValue = api.beforeHandler(paramsValue);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let apiUrl = url;
 | 
					            let apiUrl = url;
 | 
				
			||||||
            // 简单判断该url是否是restful风格
 | 
					            // 简单判断该url是否是restful风格
 | 
				
			||||||
@@ -58,6 +55,10 @@ export function useApiFetch<T>(api: Api, params: any = null, reqOptions: Request
 | 
				
			|||||||
                apiUrl = templateResolve(apiUrl, paramsValue);
 | 
					                apiUrl = templateResolve(apiUrl, paramsValue);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (api.beforeHandler) {
 | 
				
			||||||
 | 
					                paramsValue = api.beforeHandler(paramsValue);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (paramsValue) {
 | 
					            if (paramsValue) {
 | 
				
			||||||
                const method = options.method?.toLowerCase();
 | 
					                const method = options.method?.toLowerCase();
 | 
				
			||||||
                // post和put使用json格式传参
 | 
					                // post和put使用json格式传参
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,10 @@
 | 
				
			|||||||
                        <enum-tag :enums="FlowBizType" :value="procinst.bizType"></enum-tag>
 | 
					                        <enum-tag :enums="FlowBizType" :value="procinst.bizType"></enum-tag>
 | 
				
			||||||
                    </el-descriptions-item>
 | 
					                    </el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <el-descriptions-item label="发起人">{{ procinst.creator }}</el-descriptions-item>
 | 
					                    <el-descriptions-item label="发起人">
 | 
				
			||||||
 | 
					                        <AccountInfo :account-id="procinst.creatorId" :username="procinst.creator" />
 | 
				
			||||||
 | 
					                        <!-- {{ procinst.creator }} -->
 | 
				
			||||||
 | 
					                    </el-descriptions-item>
 | 
				
			||||||
                    <el-descriptions-item label="发起时间">{{ dateFormat(procinst.createTime) }}</el-descriptions-item>
 | 
					                    <el-descriptions-item label="发起时间">{{ dateFormat(procinst.createTime) }}</el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <div v-if="procinst.duration">
 | 
					                    <div v-if="procinst.duration">
 | 
				
			||||||
@@ -41,7 +44,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <el-divider content-position="left">业务信息</el-divider>
 | 
					                <el-divider content-position="left">业务信息</el-divider>
 | 
				
			||||||
                <component v-if="procinst.bizType" ref="keyValueRef" :is="bizComponents[procinst.bizType]" :biz-key="procinst.bizKey"> </component>
 | 
					                <component
 | 
				
			||||||
 | 
					                    v-if="procinst.bizType"
 | 
				
			||||||
 | 
					                    ref="keyValueRef"
 | 
				
			||||||
 | 
					                    :is="bizComponents[procinst.bizType]"
 | 
				
			||||||
 | 
					                    :biz-key="procinst.bizKey"
 | 
				
			||||||
 | 
					                    :biz-form="procinst.bizForm"
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                </component>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div v-if="props.instTaskId">
 | 
					            <div v-if="props.instTaskId">
 | 
				
			||||||
@@ -80,8 +90,10 @@ import { dateFormat } from '@/common/utils/date';
 | 
				
			|||||||
import ProcdefTasks from './components/ProcdefTasks.vue';
 | 
					import ProcdefTasks from './components/ProcdefTasks.vue';
 | 
				
			||||||
import { formatTime } from '@/common/utils/format';
 | 
					import { formatTime } from '@/common/utils/format';
 | 
				
			||||||
import EnumTag from '@/components/enumtag/EnumTag.vue';
 | 
					import EnumTag from '@/components/enumtag/EnumTag.vue';
 | 
				
			||||||
 | 
					import AccountInfo from '@/views/system/account/components/AccountInfo.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DbSqlExecBiz = defineAsyncComponent(() => import('./flowbiz/DbSqlExecBiz.vue'));
 | 
					const DbSqlExecBiz = defineAsyncComponent(() => import('./flowbiz/DbSqlExecBiz.vue'));
 | 
				
			||||||
 | 
					const RedisRunWriteCmdBiz = defineAsyncComponent(() => import('./flowbiz/RedisRunWriteCmdBiz.vue'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    procinstId: {
 | 
					    procinstId: {
 | 
				
			||||||
@@ -104,6 +116,7 @@ const emit = defineEmits(['cancel', 'val-change']);
 | 
				
			|||||||
// 业务组件
 | 
					// 业务组件
 | 
				
			||||||
const bizComponents = shallowReactive({
 | 
					const bizComponents = shallowReactive({
 | 
				
			||||||
    db_sql_exec_flow: DbSqlExecBiz,
 | 
					    db_sql_exec_flow: DbSqlExecBiz,
 | 
				
			||||||
 | 
					    redis_run_write_cmd_flow: RedisRunWriteCmdBiz,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,10 +52,10 @@ import { formatTime } from '@/common/utils/format';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const searchItems = [SearchItem.select('status', '流程状态').withEnum(ProcinstStatus), SearchItem.select('bizType', '业务类型').withEnum(FlowBizType)];
 | 
					const searchItems = [SearchItem.select('status', '流程状态').withEnum(ProcinstStatus), SearchItem.select('bizType', '业务类型').withEnum(FlowBizType)];
 | 
				
			||||||
const columns = [
 | 
					const columns = [
 | 
				
			||||||
    TableColumn.new('procdefName', '流程名'),
 | 
					 | 
				
			||||||
    TableColumn.new('bizType', '业务').typeTag(FlowBizType),
 | 
					    TableColumn.new('bizType', '业务').typeTag(FlowBizType),
 | 
				
			||||||
    TableColumn.new('remark', '备注'),
 | 
					    TableColumn.new('remark', '备注'),
 | 
				
			||||||
    TableColumn.new('creator', '发起人'),
 | 
					    TableColumn.new('creator', '发起人'),
 | 
				
			||||||
 | 
					    TableColumn.new('procdefName', '流程名'),
 | 
				
			||||||
    TableColumn.new('status', '流程状态').typeTag(ProcinstStatus),
 | 
					    TableColumn.new('status', '流程状态').typeTag(ProcinstStatus),
 | 
				
			||||||
    TableColumn.new('bizStatus', '业务状态').typeTag(ProcinstBizStatus),
 | 
					    TableColumn.new('bizStatus', '业务状态').typeTag(ProcinstBizStatus),
 | 
				
			||||||
    TableColumn.new('createTime', '发起时间').isTime(),
 | 
					    TableColumn.new('createTime', '发起时间').isTime(),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,12 +41,12 @@ import { formatTime } from '@/common/utils/format';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const searchItems = [SearchItem.select('status', '任务状态').withEnum(ProcinstTaskStatus), SearchItem.select('bizType', '业务类型').withEnum(FlowBizType)];
 | 
					const searchItems = [SearchItem.select('status', '任务状态').withEnum(ProcinstTaskStatus), SearchItem.select('bizType', '业务类型').withEnum(FlowBizType)];
 | 
				
			||||||
const columns = [
 | 
					const columns = [
 | 
				
			||||||
    TableColumn.new('procinst.procdefName', '流程名'),
 | 
					 | 
				
			||||||
    TableColumn.new('procinst.bizType', '业务').typeTag(FlowBizType),
 | 
					    TableColumn.new('procinst.bizType', '业务').typeTag(FlowBizType),
 | 
				
			||||||
    TableColumn.new('procinst.remark', '备注'),
 | 
					    TableColumn.new('procinst.remark', '备注'),
 | 
				
			||||||
    TableColumn.new('procinst.creator', '发起人'),
 | 
					    TableColumn.new('procinst.creator', '发起人'),
 | 
				
			||||||
    TableColumn.new('procinst.status', '流程状态').typeTag(ProcinstStatus),
 | 
					    TableColumn.new('procinst.status', '流程状态').typeTag(ProcinstStatus),
 | 
				
			||||||
    TableColumn.new('status', '任务状态').typeTag(ProcinstTaskStatus),
 | 
					    TableColumn.new('status', '任务状态').typeTag(ProcinstTaskStatus),
 | 
				
			||||||
 | 
					    TableColumn.new('procinst.procdefName', '流程名'),
 | 
				
			||||||
    TableColumn.new('taskName', '当前节点'),
 | 
					    TableColumn.new('taskName', '当前节点'),
 | 
				
			||||||
    TableColumn.new('procinst.createTime', '发起时间').isTime(),
 | 
					    TableColumn.new('procinst.createTime', '发起时间').isTime(),
 | 
				
			||||||
    TableColumn.new('createTime', '开始时间').isTime(),
 | 
					    TableColumn.new('createTime', '开始时间').isTime(),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,4 +30,5 @@ export const ProcinstTaskStatus = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const FlowBizType = {
 | 
					export const FlowBizType = {
 | 
				
			||||||
    DbSqlExec: EnumValue.of('db_sql_exec_flow', 'DBMS-执行SQL'),
 | 
					    DbSqlExec: EnumValue.of('db_sql_exec_flow', 'DBMS-执行SQL'),
 | 
				
			||||||
 | 
					    RedisRunWriteCmd: EnumValue.of('redis_run_write_cmd_flow', 'Redis-执行write命令'),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										80
									
								
								mayfly_go_web/src/views/flow/flowbiz/RedisRunWriteCmdBiz.vue
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										80
									
								
								mayfly_go_web/src/views/flow/flowbiz/RedisRunWriteCmdBiz.vue
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <el-descriptions :column="3" border>
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="名称">{{ redis?.name }}</el-descriptions-item>
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="id">{{ redis?.id }}</el-descriptions-item>
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="用户名">{{ redis?.username }}</el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="3" label="关联标签"><ResourceTags :tags="redis.tags" /></el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="主机">{{ `${redis?.host}` }}</el-descriptions-item>
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="库">{{ state.db }}</el-descriptions-item>
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="1" label="mode">
 | 
				
			||||||
 | 
					                {{ redis.mode }}
 | 
				
			||||||
 | 
					            </el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <el-descriptions-item :span="3" label="执行Cmd">
 | 
				
			||||||
 | 
					                <el-input type="textarea" disabled v-model="cmd" rows="5" />
 | 
				
			||||||
 | 
					            </el-descriptions-item>
 | 
				
			||||||
 | 
					        </el-descriptions>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import { toRefs, reactive, watch, onMounted } from 'vue';
 | 
				
			||||||
 | 
					import ResourceTags from '@/views/ops/component/ResourceTags.vue';
 | 
				
			||||||
 | 
					import { redisApi } from '@/views/ops/redis/api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					    // 业务表单
 | 
				
			||||||
 | 
					    bizForm: {
 | 
				
			||||||
 | 
					        type: [String],
 | 
				
			||||||
 | 
					        default: '',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const state = reactive({
 | 
				
			||||||
 | 
					    cmd: '',
 | 
				
			||||||
 | 
					    db: 0,
 | 
				
			||||||
 | 
					    redis: {} as any,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { cmd, redis } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					    parseRunCmdForm(props.bizForm);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					    () => props.bizForm,
 | 
				
			||||||
 | 
					    (newValue: any) => {
 | 
				
			||||||
 | 
					        parseRunCmdForm(newValue);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const parseRunCmdForm = async (bizForm: string) => {
 | 
				
			||||||
 | 
					    if (!bizForm) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const form = JSON.parse(bizForm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const cmds = form.cmd.map((item: any, index: number) => {
 | 
				
			||||||
 | 
					        if (index === 0) {
 | 
				
			||||||
 | 
					            return item; // 第一个元素直接返回原值
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof item === 'string') {
 | 
				
			||||||
 | 
					            return `'${item}'`; // 字符串加单引号
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return item; // 其他类型直接返回
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    state.cmd = cmds.join('  ');
 | 
				
			||||||
 | 
					    state.db = form.db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const res = await redisApi.redisList.request({ id: form.id });
 | 
				
			||||||
 | 
					    if (!res.list) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    state.redis = res.list?.[0];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style lang="scss"></style>
 | 
				
			||||||
@@ -183,6 +183,8 @@
 | 
				
			|||||||
                <el-descriptions-item :span="3" label="数据库">{{ infoDialog.data?.database }}</el-descriptions-item>
 | 
					                <el-descriptions-item :span="3" label="数据库">{{ infoDialog.data?.database }}</el-descriptions-item>
 | 
				
			||||||
                <el-descriptions-item :span="3" label="备注">{{ infoDialog.data?.remark }}</el-descriptions-item>
 | 
					                <el-descriptions-item :span="3" label="备注">{{ infoDialog.data?.remark }}</el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <el-descriptions-item :span="3" label="工单流程key">{{ infoDialog.data?.flowProcdefKey }}</el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <el-descriptions-item :span="2" label="创建时间">{{ dateFormat(infoDialog.data?.createTime) }} </el-descriptions-item>
 | 
					                <el-descriptions-item :span="2" label="创建时间">{{ dateFormat(infoDialog.data?.createTime) }} </el-descriptions-item>
 | 
				
			||||||
                <el-descriptions-item :span="1" label="创建者">{{ infoDialog.data?.creator }}</el-descriptions-item>
 | 
					                <el-descriptions-item :span="1" label="创建者">{{ infoDialog.data?.creator }}</el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { h, render, VNode } from 'vue';
 | 
					import { h, render } from 'vue';
 | 
				
			||||||
import SqlExecDialog from './SqlExecDialog.vue';
 | 
					import SqlExecDialog from './SqlExecDialog.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type SqlExecProps = {
 | 
					export type SqlExecProps = {
 | 
				
			||||||
@@ -11,27 +11,21 @@ export type SqlExecProps = {
 | 
				
			|||||||
    cancelCallback?: Function;
 | 
					    cancelCallback?: Function;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const boxId = 'sql-exec-dialog-id';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let boxInstance: VNode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const SqlExecBox = (props: SqlExecProps): void => {
 | 
					const SqlExecBox = (props: SqlExecProps): void => {
 | 
				
			||||||
    if (!boxInstance) {
 | 
					    const propsCancelFn = props.cancelCallback;
 | 
				
			||||||
        const container = document.createElement('div');
 | 
					    //  包装取消回调函数,新增销毁组件代码
 | 
				
			||||||
        container.id = boxId;
 | 
					    props.cancelCallback = () => {
 | 
				
			||||||
        // 创建 虚拟dom
 | 
					        propsCancelFn && propsCancelFn();
 | 
				
			||||||
        boxInstance = h(SqlExecDialog);
 | 
					        setTimeout(() => {
 | 
				
			||||||
        // 将虚拟dom渲染到 container dom 上
 | 
					            // 销毁组件
 | 
				
			||||||
        render(boxInstance, container);
 | 
					            render(null, document.body);
 | 
				
			||||||
        // 最后将 container 追加到 body 上
 | 
					        }, 500);
 | 
				
			||||||
        document.body.appendChild(container);
 | 
					    };
 | 
				
			||||||
    }
 | 
					    const vnode = h(SqlExecDialog, {
 | 
				
			||||||
 | 
					        ...props,
 | 
				
			||||||
    const boxVue = boxInstance.component;
 | 
					        visible: true,
 | 
				
			||||||
    if (boxVue) {
 | 
					    });
 | 
				
			||||||
        // 调用open方法显示弹框,注意不能使用boxVue.ctx来调用组件函数(build打包后ctx会获取不到)
 | 
					    render(vnode, document.body);
 | 
				
			||||||
        boxVue.exposed?.open(props);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default SqlExecBox;
 | 
					export default SqlExecBox;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
        <el-dialog title="待执行SQL" v-model="dialogVisible" :show-close="false" width="600px" @close="cancel">
 | 
					        <el-dialog title="待执行SQL" v-model="dialogVisible" :show-close="false" width="600px">
 | 
				
			||||||
            <monaco-editor height="300px" class="codesql" language="sql" v-model="sqlValue" />
 | 
					            <monaco-editor height="300px" class="codesql" language="sql" v-model="sqlValue" />
 | 
				
			||||||
            <el-input @keyup.enter="runSql" ref="remarkInputRef" v-model="remark" placeholder="请输入执行备注" class="mt5" />
 | 
					            <el-input @keyup.enter="runSql" ref="remarkInputRef" v-model="remark" placeholder="请输入执行备注" class="mt5" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div v-if="state.flowProcdefKey">
 | 
					            <div v-if="props.flowProcdefKey">
 | 
				
			||||||
                <el-divider content-position="left">审批节点</el-divider>
 | 
					                <el-divider content-position="left">审批节点</el-divider>
 | 
				
			||||||
                <procdef-tasks :procdef-key="state.flowProcdefKey" />
 | 
					                <procdef-tasks :procdef-key="props.flowProcdefKey" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <template #footer>
 | 
					            <template #footer>
 | 
				
			||||||
@@ -20,7 +20,7 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { toRefs, ref, nextTick, reactive } from 'vue';
 | 
					import { toRefs, ref, reactive, onMounted } from 'vue';
 | 
				
			||||||
import { dbApi } from '@/views/ops/db/api';
 | 
					import { dbApi } from '@/views/ops/db/api';
 | 
				
			||||||
import { ElDialog, ElButton, ElInput, ElMessage, InputInstance, ElDivider } from 'element-plus';
 | 
					import { ElDialog, ElButton, ElInput, ElMessage, InputInstance, ElDivider } from 'element-plus';
 | 
				
			||||||
// import base style
 | 
					// import base style
 | 
				
			||||||
@@ -30,39 +30,24 @@ import { format as sqlFormatter } from 'sql-formatter';
 | 
				
			|||||||
import { SqlExecProps } from './SqlExecBox';
 | 
					import { SqlExecProps } from './SqlExecBox';
 | 
				
			||||||
import ProcdefTasks from '@/views/flow/components/ProcdefTasks.vue';
 | 
					import ProcdefTasks from '@/views/flow/components/ProcdefTasks.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = withDefaults(defineProps<SqlExecProps>(), {});
 | 
				
			||||||
    visible: {
 | 
					 | 
				
			||||||
        type: Boolean,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    dbId: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: String,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    sql: {
 | 
					 | 
				
			||||||
        type: String,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const remarkInputRef = ref<InputInstance>();
 | 
					const remarkInputRef = ref<InputInstance>();
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    dialogVisible: false,
 | 
					    dialogVisible: false,
 | 
				
			||||||
    sqlValue: '',
 | 
					    sqlValue: '',
 | 
				
			||||||
    dbId: 0,
 | 
					 | 
				
			||||||
    db: '',
 | 
					 | 
				
			||||||
    flowProcdefKey: '' as any,
 | 
					 | 
				
			||||||
    remark: '',
 | 
					    remark: '',
 | 
				
			||||||
    btnLoading: false,
 | 
					    btnLoading: false,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { dialogVisible, sqlValue, remark, btnLoading } = toRefs(state);
 | 
					const { dialogVisible, sqlValue, remark, btnLoading } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
state.sqlValue = props.sql as any;
 | 
					 | 
				
			||||||
let runSuccessCallback: any;
 | 
					 | 
				
			||||||
let cancelCallback: any;
 | 
					 | 
				
			||||||
let runSuccess: boolean = false;
 | 
					let runSuccess: boolean = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					    open();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 执行sql
 | 
					 * 执行sql
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -75,14 +60,14 @@ const runSql = async () => {
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
        state.btnLoading = true;
 | 
					        state.btnLoading = true;
 | 
				
			||||||
        const res = await dbApi.sqlExec.request({
 | 
					        const res = await dbApi.sqlExec.request({
 | 
				
			||||||
            id: state.dbId,
 | 
					            id: props.dbId,
 | 
				
			||||||
            db: state.db,
 | 
					            db: props.db,
 | 
				
			||||||
            remark: state.remark,
 | 
					            remark: state.remark,
 | 
				
			||||||
            sql: state.sqlValue.trim(),
 | 
					            sql: state.sqlValue.trim(),
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 存在流程审批
 | 
					        // 存在流程审批
 | 
				
			||||||
        if (state.flowProcdefKey) {
 | 
					        if (props.flowProcdefKey) {
 | 
				
			||||||
            runSuccess = false;
 | 
					            runSuccess = false;
 | 
				
			||||||
            ElMessage.success('工单提交成功');
 | 
					            ElMessage.success('工单提交成功');
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
@@ -101,10 +86,9 @@ const runSql = async () => {
 | 
				
			|||||||
        runSuccess = false;
 | 
					        runSuccess = false;
 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
        if (runSuccess) {
 | 
					        if (runSuccess) {
 | 
				
			||||||
            if (runSuccessCallback) {
 | 
					            if (props.runSuccessCallback) {
 | 
				
			||||||
                runSuccessCallback();
 | 
					                props.runSuccessCallback();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // cancel();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        state.btnLoading = false;
 | 
					        state.btnLoading = false;
 | 
				
			||||||
        cancel();
 | 
					        cancel();
 | 
				
			||||||
@@ -113,34 +97,20 @@ const runSql = async () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const cancel = () => {
 | 
					const cancel = () => {
 | 
				
			||||||
    state.dialogVisible = false;
 | 
					    state.dialogVisible = false;
 | 
				
			||||||
    // 没有执行成功,并且取消回调函数存在,则执行
 | 
					    props.cancelCallback && props.cancelCallback();
 | 
				
			||||||
    if (!runSuccess && cancelCallback) {
 | 
					 | 
				
			||||||
        cancelCallback();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    setTimeout(() => {
 | 
					    setTimeout(() => {
 | 
				
			||||||
        state.dbId = 0;
 | 
					 | 
				
			||||||
        state.sqlValue = '';
 | 
					        state.sqlValue = '';
 | 
				
			||||||
        state.remark = '';
 | 
					        state.remark = '';
 | 
				
			||||||
        runSuccessCallback = null;
 | 
					 | 
				
			||||||
        cancelCallback = null;
 | 
					 | 
				
			||||||
        runSuccess = false;
 | 
					        runSuccess = false;
 | 
				
			||||||
    }, 200);
 | 
					    }, 200);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const open = (props: SqlExecProps) => {
 | 
					const open = () => {
 | 
				
			||||||
    runSuccessCallback = props.runSuccessCallback;
 | 
					    state.sqlValue = sqlFormatter(props.sql, { language: props.dbType || 'mysql' });
 | 
				
			||||||
    cancelCallback = props.cancelCallback;
 | 
					 | 
				
			||||||
    props.dbType = props.dbType || 'mysql';
 | 
					 | 
				
			||||||
    state.sqlValue = sqlFormatter(props.sql, { language: props.dbType });
 | 
					 | 
				
			||||||
    state.dbId = props.dbId;
 | 
					 | 
				
			||||||
    state.db = props.db;
 | 
					 | 
				
			||||||
    state.flowProcdefKey = props.flowProcdefKey;
 | 
					 | 
				
			||||||
    state.dialogVisible = true;
 | 
					    state.dialogVisible = true;
 | 
				
			||||||
    nextTick(() => {
 | 
					    setTimeout(() => {
 | 
				
			||||||
        setTimeout(() => {
 | 
					        remarkInputRef.value?.focus();
 | 
				
			||||||
            remarkInputRef.value?.focus();
 | 
					    }, 200);
 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineExpose({ open });
 | 
					defineExpose({ open });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -742,7 +742,6 @@ const onExitEditMode = (rowData: any, column: any, rowIndex = 0) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const submitUpdateFields = async () => {
 | 
					const submitUpdateFields = async () => {
 | 
				
			||||||
    debugger;
 | 
					 | 
				
			||||||
    const dbInst = getNowDbInst();
 | 
					    const dbInst = getNowDbInst();
 | 
				
			||||||
    if (cellUpdateMap.size == 0) {
 | 
					    if (cellUpdateMap.size == 0) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,8 @@
 | 
				
			|||||||
                            <el-checkbox
 | 
					                            <el-checkbox
 | 
				
			||||||
                                v-model="item.show"
 | 
					                                v-model="item.show"
 | 
				
			||||||
                                :label="`${!item.columnComment ? item.columnName : item.columnName + ' [' + item.columnComment + ']'}`"
 | 
					                                :label="`${!item.columnComment ? item.columnName : item.columnName + ' [' + item.columnComment + ']'}`"
 | 
				
			||||||
                                :true-label="true"
 | 
					                                :true-value="true"
 | 
				
			||||||
                                :false-label="false"
 | 
					                                :false-value="false"
 | 
				
			||||||
                                size="small"
 | 
					                                size="small"
 | 
				
			||||||
                            />
 | 
					                            />
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
@@ -55,7 +55,7 @@
 | 
				
			|||||||
                        title="展示配置"
 | 
					                        title="展示配置"
 | 
				
			||||||
                        trigger="click"
 | 
					                        trigger="click"
 | 
				
			||||||
                    >
 | 
					                    >
 | 
				
			||||||
                        <el-checkbox v-model="dbConfig.showColumnComment" label="显示字段备注" :true-label="true" :false-label="false" size="small" />
 | 
					                        <el-checkbox v-model="dbConfig.showColumnComment" label="显示字段备注" :true-value="true" :false-value="false" size="small" />
 | 
				
			||||||
                        <template #reference>
 | 
					                        <template #reference>
 | 
				
			||||||
                            <el-link type="primary" icon="setting" :underline="false"></el-link>
 | 
					                            <el-link type="primary" icon="setting" :underline="false"></el-link>
 | 
				
			||||||
                        </template>
 | 
					                        </template>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <el-tab-pane label="其他配置" name="other">
 | 
					                    <el-tab-pane label="其他配置" name="other">
 | 
				
			||||||
                        <el-form-item prop="enableRecorder" label="终端回放">
 | 
					                        <el-form-item prop="enableRecorder" label="终端回放">
 | 
				
			||||||
                            <el-checkbox v-model="form.enableRecorder" :true-label="1" :false-label="-1"></el-checkbox>
 | 
					                            <el-checkbox v-model="form.enableRecorder" :true-value="1" :false-value="-1"></el-checkbox>
 | 
				
			||||||
                        </el-form-item>
 | 
					                        </el-form-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <el-form-item prop="sshTunnelMachineId" label="SSH隧道">
 | 
					                        <el-form-item prop="sshTunnelMachineId" label="SSH隧道">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,7 +141,7 @@
 | 
				
			|||||||
                <div class="key-detail card pd5">
 | 
					                <div class="key-detail card pd5">
 | 
				
			||||||
                    <el-tabs @tab-remove="removeDataTab" v-model="state.activeName">
 | 
					                    <el-tabs @tab-remove="removeDataTab" v-model="state.activeName">
 | 
				
			||||||
                        <el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
 | 
					                        <el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
 | 
				
			||||||
                            <key-detail :redisId="scanParam.id" :db="scanParam.db" :key-info="dt.keyInfo" @change-key="searchKey()" @del-key="delKey" />
 | 
					                            <key-detail :redis="redisInst" :key-info="dt.keyInfo" @change-key="searchKey()" @del-key="delKey" />
 | 
				
			||||||
                        </el-tab-pane>
 | 
					                        </el-tab-pane>
 | 
				
			||||||
                    </el-tabs>
 | 
					                    </el-tabs>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -178,7 +178,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { redisApi } from './api';
 | 
					import { redisApi } from './api';
 | 
				
			||||||
import { ref, defineAsyncComponent, toRefs, reactive, onMounted, nextTick } from 'vue';
 | 
					import { ref, defineAsyncComponent, toRefs, reactive, onMounted, nextTick, Ref } from 'vue';
 | 
				
			||||||
import { ElMessage, ElMessageBox } from 'element-plus';
 | 
					import { ElMessage, ElMessageBox } from 'element-plus';
 | 
				
			||||||
import { isTrue, notBlank, notNull } from '@/common/assert';
 | 
					import { isTrue, notBlank, notNull } from '@/common/assert';
 | 
				
			||||||
import { copyToClipboard } from '@/common/utils/string';
 | 
					import { copyToClipboard } from '@/common/utils/string';
 | 
				
			||||||
@@ -189,6 +189,7 @@ import { Contextmenu, ContextmenuItem } from '@/components/contextmenu';
 | 
				
			|||||||
import { sleep } from '@/common/utils/loading';
 | 
					import { sleep } from '@/common/utils/loading';
 | 
				
			||||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
 | 
					import { TagResourceTypeEnum } from '@/common/commonEnum';
 | 
				
			||||||
import { Splitpanes, Pane } from 'splitpanes';
 | 
					import { Splitpanes, Pane } from 'splitpanes';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));
 | 
					const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -240,6 +241,7 @@ const NodeTypeRedis = new NodeType(RedisNodeType.Redis).withLoadNodesFunc(async
 | 
				
			|||||||
        return new TagTreeNode(x, `db${x}`, NodeTypeDb).withIsLeaf(true).withParams({
 | 
					        return new TagTreeNode(x, `db${x}`, NodeTypeDb).withIsLeaf(true).withParams({
 | 
				
			||||||
            id: redisInfo.id,
 | 
					            id: redisInfo.id,
 | 
				
			||||||
            db: x,
 | 
					            db: x,
 | 
				
			||||||
 | 
					            flowProcdefKey: redisInfo.flowProcdefKey,
 | 
				
			||||||
            name: `db${x}`,
 | 
					            name: `db${x}`,
 | 
				
			||||||
            keys: 0,
 | 
					            keys: 0,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@@ -269,6 +271,11 @@ const NodeTypeDb = new NodeType(RedisNodeType.Db).withNodeClickFunc((nodeData: T
 | 
				
			|||||||
    resetScanParam();
 | 
					    resetScanParam();
 | 
				
			||||||
    state.scanParam.id = nodeData.params.id;
 | 
					    state.scanParam.id = nodeData.params.id;
 | 
				
			||||||
    state.scanParam.db = nodeData.params.db;
 | 
					    state.scanParam.db = nodeData.params.db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    redisInst.value.id = nodeData.params.id;
 | 
				
			||||||
 | 
					    redisInst.value.db = Number.parseInt(nodeData.params.db);
 | 
				
			||||||
 | 
					    redisInst.value.flowProcdefKey = nodeData.params.flowProcdefKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    scan();
 | 
					    scan();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -281,6 +288,7 @@ const treeProps = {
 | 
				
			|||||||
const defaultCount = 250;
 | 
					const defaultCount = 250;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const keyTreeRef: any = ref(null);
 | 
					const keyTreeRef: any = ref(null);
 | 
				
			||||||
 | 
					const redisInst: Ref<RedisInst> = ref(new RedisInst());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    tags: [],
 | 
					    tags: [],
 | 
				
			||||||
@@ -506,15 +514,11 @@ const flushDb = () => {
 | 
				
			|||||||
        type: 'warning',
 | 
					        type: 'warning',
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
        .then(() => {
 | 
					        .then(() => {
 | 
				
			||||||
            redisApi.flushDb
 | 
					            // FLUSHDB [ASYNC | SYNC]
 | 
				
			||||||
                .request({
 | 
					            redisInst.value.runCmd(['FLUSHDB']).then(() => {
 | 
				
			||||||
                    id: state.scanParam.id,
 | 
					                ElMessage.success('清除成功!');
 | 
				
			||||||
                    db: state.scanParam.db,
 | 
					                searchKey();
 | 
				
			||||||
                })
 | 
					            });
 | 
				
			||||||
                .then(() => {
 | 
					 | 
				
			||||||
                    ElMessage.success('清除成功!');
 | 
					 | 
				
			||||||
                    searchKey();
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch(() => {});
 | 
					        .catch(() => {});
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -526,19 +530,9 @@ const cancelNewKey = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const newKey = async () => {
 | 
					const newKey = async () => {
 | 
				
			||||||
    const keyInfo = state.newKeyDialog.keyInfo;
 | 
					    const keyInfo = state.newKeyDialog.keyInfo;
 | 
				
			||||||
    const keyType = keyInfo.type;
 | 
					 | 
				
			||||||
    const key = keyInfo.key;
 | 
					    const key = keyInfo.key;
 | 
				
			||||||
    notBlank(key, '键名不能为空');
 | 
					    notBlank(key, '键名不能为空');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (keyType == 'string') {
 | 
					 | 
				
			||||||
        await redisApi.setString.request({
 | 
					 | 
				
			||||||
            id: state.scanParam.id,
 | 
					 | 
				
			||||||
            db: state.scanParam.db,
 | 
					 | 
				
			||||||
            key: key,
 | 
					 | 
				
			||||||
            value: '',
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showKeyDetail(
 | 
					    showKeyDetail(
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ...keyInfo,
 | 
					            ...keyInfo,
 | 
				
			||||||
@@ -565,11 +559,8 @@ const delKey = (key: string) => {
 | 
				
			|||||||
        type: 'warning',
 | 
					        type: 'warning',
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
        .then(async () => {
 | 
					        .then(async () => {
 | 
				
			||||||
            await redisApi.delKey.request({
 | 
					            // DEL key [key ...]
 | 
				
			||||||
                key,
 | 
					            await redisInst.value.runCmd(['DEL', key]);
 | 
				
			||||||
                id: state.scanParam.id,
 | 
					 | 
				
			||||||
                db: state.scanParam.db,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            ElMessage.success('删除成功!');
 | 
					            ElMessage.success('删除成功!');
 | 
				
			||||||
            searchKey();
 | 
					            searchKey();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,7 @@
 | 
				
			|||||||
            <!-- key info -->
 | 
					            <!-- key info -->
 | 
				
			||||||
            <key-header
 | 
					            <key-header
 | 
				
			||||||
                ref="keyHeader"
 | 
					                ref="keyHeader"
 | 
				
			||||||
                :redis-id="redisId"
 | 
					                :redis="props.redis"
 | 
				
			||||||
                :db="db"
 | 
					 | 
				
			||||||
                :key-info="state.keyInfo"
 | 
					                :key-info="state.keyInfo"
 | 
				
			||||||
                @refresh-content="refreshContent"
 | 
					                @refresh-content="refreshContent"
 | 
				
			||||||
                @del-key="delKey"
 | 
					                @del-key="delKey"
 | 
				
			||||||
@@ -15,7 +14,7 @@
 | 
				
			|||||||
            </key-header>
 | 
					            </key-header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- key content -->
 | 
					            <!-- key content -->
 | 
				
			||||||
            <component ref="keyValueRef" :is="components[componentName]" :redis-id="redisId" :db="db" :key-info="keyInfo"> </component>
 | 
					            <component ref="keyValueRef" :is="components[componentName]" :redis="props.redis" :key-info="keyInfo"> </component>
 | 
				
			||||||
        </el-container>
 | 
					        </el-container>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
@@ -23,6 +22,7 @@
 | 
				
			|||||||
import { defineAsyncComponent, watch, ref, shallowReactive, reactive, computed, onMounted } from 'vue';
 | 
					import { defineAsyncComponent, watch, ref, shallowReactive, reactive, computed, onMounted } from 'vue';
 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import KeyHeader from './KeyHeader.vue';
 | 
					import KeyHeader from './KeyHeader.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const KeyValueString = defineAsyncComponent(() => import('./KeyValueString.vue'));
 | 
					const KeyValueString = defineAsyncComponent(() => import('./KeyValueString.vue'));
 | 
				
			||||||
const KeyValueHash = defineAsyncComponent(() => import('./KeyValueHash.vue'));
 | 
					const KeyValueHash = defineAsyncComponent(() => import('./KeyValueHash.vue'));
 | 
				
			||||||
@@ -41,11 +41,9 @@ const components = shallowReactive({
 | 
				
			|||||||
const keyValueRef = ref(null) as any;
 | 
					const keyValueRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: Number,
 | 
					        type: RedisInst,
 | 
				
			||||||
    },
 | 
					        required: true,
 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: Number,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -55,7 +53,6 @@ const props = defineProps({
 | 
				
			|||||||
const emit = defineEmits(['update:visible', 'changeKey', 'delKey']);
 | 
					const emit = defineEmits(['update:visible', 'changeKey', 'delKey']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    keyInfo: {} as any,
 | 
					    keyInfo: {} as any,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,13 +47,12 @@ import { reactive, watch, toRefs, onMounted } from 'vue';
 | 
				
			|||||||
import { redisApi } from './api';
 | 
					import { redisApi } from './api';
 | 
				
			||||||
import { ElMessage, ElMessageBox } from 'element-plus';
 | 
					import { ElMessage, ElMessageBox } from 'element-plus';
 | 
				
			||||||
import { formatTime } from '@/common/utils/format';
 | 
					import { formatTime } from '@/common/utils/format';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: Number,
 | 
					        type: RedisInst,
 | 
				
			||||||
    },
 | 
					        required: true,
 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: Number,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -63,7 +62,6 @@ const props = defineProps({
 | 
				
			|||||||
const emit = defineEmits(['refreshContent', 'delKey', 'changeKey']);
 | 
					const emit = defineEmits(['refreshContent', 'delKey', 'changeKey']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        key: '',
 | 
					        key: '',
 | 
				
			||||||
        type: '',
 | 
					        type: '',
 | 
				
			||||||
@@ -85,8 +83,8 @@ onMounted(() => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const refreshKey = async () => {
 | 
					const refreshKey = async () => {
 | 
				
			||||||
    const ttl = await redisApi.keyTtl.request({
 | 
					    const ttl = await redisApi.keyTtl.request({
 | 
				
			||||||
        id: props.redisId,
 | 
					        id: props.redis.id,
 | 
				
			||||||
        db: props.db,
 | 
					        db: props.redis.db,
 | 
				
			||||||
        key: state.oldKey,
 | 
					        key: state.oldKey,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    state.keyInfo.timed = ttl;
 | 
					    state.keyInfo.timed = ttl;
 | 
				
			||||||
@@ -101,12 +99,8 @@ const renameKey = async () => {
 | 
				
			|||||||
    if (!state.oldKey || state.ki.key == state.oldKey) {
 | 
					    if (!state.oldKey || state.ki.key == state.oldKey) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    await redisApi.renameKey.request({
 | 
					    // RENAME key newkey
 | 
				
			||||||
        id: props.redisId,
 | 
					    await props.redis.runCmd(['RENAME', state.oldKey, state.ki.key]);
 | 
				
			||||||
        db: props.db,
 | 
					 | 
				
			||||||
        newKey: state.ki.key,
 | 
					 | 
				
			||||||
        key: state.oldKey,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('设置成功');
 | 
					    ElMessage.success('设置成功');
 | 
				
			||||||
    emit('changeKey');
 | 
					    emit('changeKey');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -131,22 +125,15 @@ const ttlKey = async () => {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await redisApi.expireKey.request({
 | 
					    // EXPIRE key seconds [NX | XX | GT | LT]
 | 
				
			||||||
        id: props.redisId,
 | 
					    await props.redis.runCmd(['EXPIRE', state.ki.key, state.ki.timed]);
 | 
				
			||||||
        db: props.db,
 | 
					 | 
				
			||||||
        key: state.ki.key,
 | 
					 | 
				
			||||||
        seconds: state.ki.timed,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('设置成功');
 | 
					    ElMessage.success('设置成功');
 | 
				
			||||||
    emit('changeKey');
 | 
					    emit('changeKey');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const persistKey = async () => {
 | 
					const persistKey = async () => {
 | 
				
			||||||
    await redisApi.persistKey.request({
 | 
					    // PERSIST key
 | 
				
			||||||
        id: props.redisId,
 | 
					    await props.redis.runCmd(['PERSIST', state.keyInfo.key]);
 | 
				
			||||||
        db: props.db,
 | 
					 | 
				
			||||||
        key: state.keyInfo.key,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('设置成功');
 | 
					    ElMessage.success('设置成功');
 | 
				
			||||||
    emit('changeKey');
 | 
					    emit('changeKey');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,21 +52,15 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { ref, onMounted, reactive, toRefs } from 'vue';
 | 
					import { ref, onMounted, reactive, toRefs } from 'vue';
 | 
				
			||||||
import { redisApi } from './api';
 | 
					 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import { notBlank } from '@/common/assert';
 | 
					import { notBlank } from '@/common/assert';
 | 
				
			||||||
import FormatViewer from './FormatViewer.vue';
 | 
					import FormatViewer from './FormatViewer.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: [Number],
 | 
					        type: RedisInst,
 | 
				
			||||||
        require: true,
 | 
					        required: true,
 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
        require: true,
 | 
					 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -76,8 +70,6 @@ const props = defineProps({
 | 
				
			|||||||
const formatViewerRef = ref(null) as any;
 | 
					const formatViewerRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    db: 0,
 | 
					 | 
				
			||||||
    key: '',
 | 
					    key: '',
 | 
				
			||||||
    scanParam: {
 | 
					    scanParam: {
 | 
				
			||||||
        cursor: 0,
 | 
					        cursor: 0,
 | 
				
			||||||
@@ -98,8 +90,6 @@ const state = reactive({
 | 
				
			|||||||
const { hashValues, total, loadMoreDisable, editDialog } = toRefs(state);
 | 
					const { hashValues, total, loadMoreDisable, editDialog } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
    state.redisId = props.redisId;
 | 
					 | 
				
			||||||
    state.db = props.db;
 | 
					 | 
				
			||||||
    state.key = props.keyInfo?.key;
 | 
					    state.key = props.keyInfo?.key;
 | 
				
			||||||
    initData();
 | 
					    initData();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -118,16 +108,15 @@ const hscan = async (resetTableData = false, resetCursor = false) => {
 | 
				
			|||||||
        state.scanParam.cursor = 0;
 | 
					        state.scanParam.cursor = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const scanRes = await redisApi.hscan.request({
 | 
					    props.redis.runCmd(['HLEN', state.key]).then((res) => (state.total = res));
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					
 | 
				
			||||||
        match: getScanMatch(),
 | 
					    // HSCAN key cursor [MATCH pattern] [COUNT count]
 | 
				
			||||||
        ...state.scanParam,
 | 
					    // 返回值 [coursor, keys:[]]
 | 
				
			||||||
    });
 | 
					    let scanRes = await props.redis.runCmd(['HSCAN', state.key, state.scanParam.cursor, 'MATCH', getScanMatch(), 'COUNT', state.scanParam.count]);
 | 
				
			||||||
    state.scanParam.cursor = scanRes.cursor;
 | 
					    state.scanParam.cursor = scanRes[0];
 | 
				
			||||||
    state.loadMoreDisable = scanRes.cursor == 0;
 | 
					    state.loadMoreDisable = state.scanParam.cursor == 0;
 | 
				
			||||||
    state.total = scanRes.keySize;
 | 
					    const keys = scanRes[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const keys = scanRes.keys;
 | 
					 | 
				
			||||||
    const hashValue = [];
 | 
					    const hashValue = [];
 | 
				
			||||||
    const fieldCount = keys.length / 2;
 | 
					    const fieldCount = keys.length / 2;
 | 
				
			||||||
    let nextFieldIndex = 0;
 | 
					    let nextFieldIndex = 0;
 | 
				
			||||||
@@ -143,10 +132,7 @@ const hscan = async (resetTableData = false, resetCursor = false) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const hdel = async (field: any, index: any) => {
 | 
					const hdel = async (field: any, index: any) => {
 | 
				
			||||||
    await redisApi.hdel.request({
 | 
					    await props.redis.runCmd(['HDEL', state.key, field]);
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					 | 
				
			||||||
        field,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ElMessage.success('删除成功');
 | 
					    ElMessage.success('删除成功');
 | 
				
			||||||
    state.hashValues.splice(index, 1);
 | 
					    state.hashValues.splice(index, 1);
 | 
				
			||||||
@@ -161,57 +147,25 @@ const showEditDialog = (row: any) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const confirmEditData = async () => {
 | 
					const confirmEditData = async () => {
 | 
				
			||||||
    const param = getBaseReqParam();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const field = state.editDialog.field;
 | 
					    const field = state.editDialog.field;
 | 
				
			||||||
    notBlank(field, 'field不能为空');
 | 
					    notBlank(field, 'field不能为空');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
					 | 
				
			||||||
    const dataRow = state.editDialog.dataRow;
 | 
					 | 
				
			||||||
    if (dataRow) {
 | 
					 | 
				
			||||||
        await redisApi.hdel.request({
 | 
					 | 
				
			||||||
            ...param,
 | 
					 | 
				
			||||||
            field: dataRow.field,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 获取hash value内容并新增
 | 
					    // 获取hash value内容并新增
 | 
				
			||||||
    const value = formatViewerRef.value.getContent();
 | 
					    const value = formatViewerRef.value.getContent();
 | 
				
			||||||
    const res = await redisApi.hset.request({
 | 
					 | 
				
			||||||
        ...param,
 | 
					 | 
				
			||||||
        value: [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                field,
 | 
					 | 
				
			||||||
                value: value,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const res = await props.redis.runCmd(['HSET', state.key, field, value]);
 | 
				
			||||||
    ElMessage.success('保存成功');
 | 
					    ElMessage.success('保存成功');
 | 
				
			||||||
    if (dataRow) {
 | 
					    // 响应0则为被覆盖,则重新scan
 | 
				
			||||||
        state.editDialog.dataRow.value = value;
 | 
					    if (res == 0) {
 | 
				
			||||||
        state.editDialog.dataRow.field = field;
 | 
					        hscan(true, true);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // 响应0则为被覆盖,则重新scan
 | 
					        state.hashValues.unshift({ value, field });
 | 
				
			||||||
        if (res == 0) {
 | 
					        state.total++;
 | 
				
			||||||
            hscan(true, true);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            state.hashValues.unshift({ value, field });
 | 
					 | 
				
			||||||
            state.total++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    state.editDialog.visible = false;
 | 
					    state.editDialog.visible = false;
 | 
				
			||||||
    state.editDialog.dataRow = null;
 | 
					    state.editDialog.dataRow = null;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getBaseReqParam = () => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        id: state.redisId,
 | 
					 | 
				
			||||||
        db: state.db,
 | 
					 | 
				
			||||||
        key: state.key,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineExpose({ initData });
 | 
					defineExpose({ initData });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss">
 | 
					<style lang="scss">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
        <el-button @click="showEditDialog(null)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
 | 
					        <el-button @click="showEditDialog(null, -1)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
 | 
				
			||||||
        <el-table size="small" border :data="values" height="450" min-height="300" stripe>
 | 
					        <el-table size="small" border :data="values" height="450" min-height="300" stripe>
 | 
				
			||||||
            <el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100"> </el-table-column>
 | 
					            <el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100"> </el-table-column>
 | 
				
			||||||
            <el-table-column resizable sortable prop="value" label="value" show-overflow-tooltip min-width="200"> </el-table-column>
 | 
					            <el-table-column resizable sortable prop="value" label="value" show-overflow-tooltip min-width="200"> </el-table-column>
 | 
				
			||||||
            <el-table-column label="操作">
 | 
					            <el-table-column label="操作">
 | 
				
			||||||
                <template #default="scope">
 | 
					                <template #default="scope">
 | 
				
			||||||
                    <el-link @click="showEditDialog(scope.row)" :underline="false" type="primary" icon="edit" plain></el-link>
 | 
					                    <el-link @click="showEditDialog(scope.row, scope.$index)" :underline="false" type="primary" icon="edit" plain></el-link>
 | 
				
			||||||
                    <el-popconfirm title="确定删除?" @confirm="lrem(scope.row, scope.$index)">
 | 
					                    <el-popconfirm title="确定删除?" @confirm="lrem(scope.row, scope.$index)">
 | 
				
			||||||
                        <template #reference>
 | 
					                        <template #reference>
 | 
				
			||||||
                            <el-link v-auth="'redis:data:del'" :underline="false" type="danger" icon="delete" size="small" plain class="ml5"></el-link>
 | 
					                            <el-link v-auth="'redis:data:del'" :underline="false" type="danger" icon="delete" size="small" plain class="ml5"></el-link>
 | 
				
			||||||
@@ -38,20 +38,14 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
					import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
				
			||||||
import { redisApi } from './api';
 | 
					 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import FormatViewer from './FormatViewer.vue';
 | 
					import FormatViewer from './FormatViewer.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: [Number],
 | 
					        type: RedisInst,
 | 
				
			||||||
        require: true,
 | 
					        required: true,
 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
        require: true,
 | 
					 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -61,8 +55,6 @@ const props = defineProps({
 | 
				
			|||||||
const formatViewerRef = ref(null) as any;
 | 
					const formatViewerRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    db: 0,
 | 
					 | 
				
			||||||
    key: '',
 | 
					    key: '',
 | 
				
			||||||
    pageNum: 1,
 | 
					    pageNum: 1,
 | 
				
			||||||
    pageSize: 50,
 | 
					    pageSize: 50,
 | 
				
			||||||
@@ -70,17 +62,15 @@ const state = reactive({
 | 
				
			|||||||
    values: [] as any,
 | 
					    values: [] as any,
 | 
				
			||||||
    loadMoreDisable: false,
 | 
					    loadMoreDisable: false,
 | 
				
			||||||
    editDialog: {
 | 
					    editDialog: {
 | 
				
			||||||
 | 
					        index: -1,
 | 
				
			||||||
        visible: false,
 | 
					        visible: false,
 | 
				
			||||||
        content: '',
 | 
					        content: '',
 | 
				
			||||||
        dataRow: null as any,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { total, values, loadMoreDisable, editDialog } = toRefs(state);
 | 
					const { total, values, loadMoreDisable, editDialog } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
    state.redisId = props.redisId;
 | 
					 | 
				
			||||||
    state.db = props.db;
 | 
					 | 
				
			||||||
    state.key = props.keyInfo?.key;
 | 
					    state.key = props.keyInfo?.key;
 | 
				
			||||||
    initData();
 | 
					    initData();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -93,14 +83,12 @@ const initData = () => {
 | 
				
			|||||||
const getListValue = async (resetTableData = false) => {
 | 
					const getListValue = async (resetTableData = false) => {
 | 
				
			||||||
    const pageNum = state.pageNum;
 | 
					    const pageNum = state.pageNum;
 | 
				
			||||||
    const pageSize = state.pageSize;
 | 
					    const pageSize = state.pageSize;
 | 
				
			||||||
    const res = await redisApi.getListValue.request({
 | 
					 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					 | 
				
			||||||
        start: (pageNum - 1) * pageSize,
 | 
					 | 
				
			||||||
        stop: pageNum * pageSize - 1,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    state.total = res.len;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const datas = res.list.map((x: any) => {
 | 
					    props.redis.runCmd(['LLEN', state.key]).then((res) => (state.total = res));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // LRANGE key start stop
 | 
				
			||||||
 | 
					    const res = await props.redis.runCmd(['LRANGE', state.key, (pageNum - 1) * pageSize, pageNum * pageSize - 1]);
 | 
				
			||||||
 | 
					    const datas = res.map((x: any) => {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            value: x,
 | 
					            value: x,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
@@ -114,71 +102,41 @@ const getListValue = async (resetTableData = false) => {
 | 
				
			|||||||
    state.loadMoreDisable = state.values.length === state.total;
 | 
					    state.loadMoreDisable = state.values.length === state.total;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// const lset = async (row: any, rowIndex: number) => {
 | 
					const showEditDialog = (row: any, index = -1) => {
 | 
				
			||||||
//     await redisApi.setListValue.request({
 | 
					    state.editDialog.index = index;
 | 
				
			||||||
//         ...getBaseReqParam(),
 | 
					 | 
				
			||||||
//         index: (state.pageNum - 1) * state.pageSize + rowIndex,
 | 
					 | 
				
			||||||
//         value: row.value,
 | 
					 | 
				
			||||||
//     });
 | 
					 | 
				
			||||||
//     ElMessage.success('数据保存成功');
 | 
					 | 
				
			||||||
// };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const showEditDialog = (row: any) => {
 | 
					 | 
				
			||||||
    state.editDialog.dataRow = row;
 | 
					 | 
				
			||||||
    state.editDialog.content = row ? row.value : '';
 | 
					    state.editDialog.content = row ? row.value : '';
 | 
				
			||||||
    state.editDialog.visible = true;
 | 
					    state.editDialog.visible = true;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const confirmEditData = async () => {
 | 
					const confirmEditData = async () => {
 | 
				
			||||||
    const param = getBaseReqParam();
 | 
					    const index = state.editDialog.index;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
					 | 
				
			||||||
    const dataRow = state.editDialog.dataRow;
 | 
					 | 
				
			||||||
    if (dataRow) {
 | 
					 | 
				
			||||||
        await redisApi.lrem.request({
 | 
					 | 
				
			||||||
            member: state.editDialog.dataRow.value,
 | 
					 | 
				
			||||||
            count: 1,
 | 
					 | 
				
			||||||
            ...param,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 获取list member内容并新增
 | 
					    // 获取list member内容并新增
 | 
				
			||||||
    const member = formatViewerRef.value.getContent();
 | 
					    const member = formatViewerRef.value.getContent();
 | 
				
			||||||
    await redisApi.saveListValue.request({
 | 
					    try {
 | 
				
			||||||
        value: [member],
 | 
					        // 索引=-1 说明是新增
 | 
				
			||||||
        ...param,
 | 
					        if (index == -1) {
 | 
				
			||||||
    });
 | 
					            // RPUSH key element [element ...]
 | 
				
			||||||
 | 
					            await props.redis.runCmd(['RPUSH', state.key, member]);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // LSET key index element
 | 
				
			||||||
 | 
					            await props.redis.runCmd(['LSET', state.key, index, member]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ElMessage.success('保存成功');
 | 
					        ElMessage.success('保存成功');
 | 
				
			||||||
    if (dataRow) {
 | 
					        initData();
 | 
				
			||||||
        state.editDialog.dataRow.value = member;
 | 
					    } finally {
 | 
				
			||||||
    } else {
 | 
					        state.editDialog.visible = false;
 | 
				
			||||||
        state.values.push({ value: member });
 | 
					 | 
				
			||||||
        state.total++;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    state.editDialog.visible = false;
 | 
					 | 
				
			||||||
    state.editDialog.dataRow = null;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const lrem = async (row: any, index: any) => {
 | 
					const lrem = async (row: any, index: any) => {
 | 
				
			||||||
    await redisApi.lrem.request({
 | 
					    // LREM key count element
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					    await props.redis.runCmd(['LREM', state.key, 1, row.value]);
 | 
				
			||||||
        member: row.value,
 | 
					 | 
				
			||||||
        count: 1,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('删除成功');
 | 
					    ElMessage.success('删除成功');
 | 
				
			||||||
    state.values.splice(index, 1);
 | 
					    state.values.splice(index, 1);
 | 
				
			||||||
    state.total--;
 | 
					    state.total--;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getBaseReqParam = () => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        id: state.redisId,
 | 
					 | 
				
			||||||
        db: state.db,
 | 
					 | 
				
			||||||
        key: state.key,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineExpose({ initData });
 | 
					defineExpose({ initData });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss"></style>
 | 
					<style lang="scss"></style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,20 +48,14 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
					import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
				
			||||||
import { redisApi } from './api';
 | 
					 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import FormatViewer from './FormatViewer.vue';
 | 
					import FormatViewer from './FormatViewer.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: [Number],
 | 
					        type: RedisInst,
 | 
				
			||||||
        require: true,
 | 
					        required: true,
 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
        require: true,
 | 
					 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -71,8 +65,6 @@ const props = defineProps({
 | 
				
			|||||||
const formatViewerRef = ref(null) as any;
 | 
					const formatViewerRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    db: 0,
 | 
					 | 
				
			||||||
    key: '',
 | 
					    key: '',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    filterValue: '',
 | 
					    filterValue: '',
 | 
				
			||||||
@@ -94,8 +86,6 @@ const state = reactive({
 | 
				
			|||||||
const { total, setDatas, loadMoreDisable, editDialog } = toRefs(state);
 | 
					const { total, setDatas, loadMoreDisable, editDialog } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
    state.redisId = props.redisId;
 | 
					 | 
				
			||||||
    state.db = props.db;
 | 
					 | 
				
			||||||
    state.key = props.keyInfo?.key;
 | 
					    state.key = props.keyInfo?.key;
 | 
				
			||||||
    initData();
 | 
					    initData();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -114,26 +104,24 @@ const sscanData = async (resetDatas = true, resetCursor = false) => {
 | 
				
			|||||||
    if (resetCursor) {
 | 
					    if (resetCursor) {
 | 
				
			||||||
        state.scanParam.cursor = 0;
 | 
					        state.scanParam.cursor = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const res = await redisApi.sscan.request({
 | 
					    // SSCAN key cursor [MATCH pattern] [COUNT count]
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					    // 响应[cursor, vals[]]
 | 
				
			||||||
        match: getScanMatch(),
 | 
					    const res = await props.redis.runCmd(['SSCAN', state.key, state.scanParam.cursor, 'MATCH', getScanMatch(), 'COUNT', state.scanParam.count]);
 | 
				
			||||||
        ...state.scanParam,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (resetDatas) {
 | 
					    if (resetDatas) {
 | 
				
			||||||
        state.setDatas = [];
 | 
					        state.setDatas = [];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    res.keys.forEach((x: any) => {
 | 
					    res[1].forEach((x: any) => {
 | 
				
			||||||
        state.setDatas.push({
 | 
					        state.setDatas.push({
 | 
				
			||||||
            value: x,
 | 
					            value: x,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    state.scanParam.cursor = res.cursor;
 | 
					    state.scanParam.cursor = res[0];
 | 
				
			||||||
    state.loadMoreDisable = res.cursor == 0;
 | 
					    state.loadMoreDisable = state.scanParam.cursor == 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getTotal = () => {
 | 
					const getTotal = () => {
 | 
				
			||||||
    redisApi.scard.request(getBaseReqParam()).then((res) => {
 | 
					    // SCARD key
 | 
				
			||||||
 | 
					    props.redis.runCmd(['SCARD', state.key]).then((res) => {
 | 
				
			||||||
        state.total = res;
 | 
					        state.total = res;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -145,23 +133,16 @@ const showEditDialog = (row: any) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const confirmEditData = async () => {
 | 
					const confirmEditData = async () => {
 | 
				
			||||||
    const param = getBaseReqParam();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
					    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
				
			||||||
    const dataRow = state.editDialog.dataRow;
 | 
					    const dataRow = state.editDialog.dataRow;
 | 
				
			||||||
    if (dataRow) {
 | 
					    if (dataRow) {
 | 
				
			||||||
        await redisApi.srem.request({
 | 
					        await props.redis.runCmd(['SREM', state.key, state.editDialog.dataRow.value]);
 | 
				
			||||||
            member: state.editDialog.dataRow.value,
 | 
					 | 
				
			||||||
            ...param,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 获取set member内容并新增
 | 
					    // 获取set member内容并新增
 | 
				
			||||||
    const member = formatViewerRef.value.getContent();
 | 
					    const member = formatViewerRef.value.getContent();
 | 
				
			||||||
    await redisApi.sadd.request({
 | 
					    // SADD key member [member ...]
 | 
				
			||||||
        member,
 | 
					    await props.redis.runCmd(['SADD', state.key, member]);
 | 
				
			||||||
        ...param,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ElMessage.success('保存成功');
 | 
					    ElMessage.success('保存成功');
 | 
				
			||||||
    if (dataRow) {
 | 
					    if (dataRow) {
 | 
				
			||||||
@@ -175,23 +156,13 @@ const confirmEditData = async () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const srem = async (row: any, index: any) => {
 | 
					const srem = async (row: any, index: any) => {
 | 
				
			||||||
    await redisApi.srem.request({
 | 
					    // SREM key member [member ...]
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					    await props.redis.runCmd(['SREM', state.key, row.value]);
 | 
				
			||||||
        member: row.value,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('删除成功');
 | 
					    ElMessage.success('删除成功');
 | 
				
			||||||
    state.setDatas.splice(index, 1);
 | 
					    state.setDatas.splice(index, 1);
 | 
				
			||||||
    state.total--;
 | 
					    state.total--;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getBaseReqParam = () => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        id: state.redisId,
 | 
					 | 
				
			||||||
        db: state.db,
 | 
					 | 
				
			||||||
        key: state.key,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineExpose({ initData });
 | 
					defineExpose({ initData });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss"></style>
 | 
					<style lang="scss"></style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,21 +12,15 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { ref, watch, reactive, toRefs, onMounted } from 'vue';
 | 
					import { ref, watch, reactive, toRefs, onMounted } from 'vue';
 | 
				
			||||||
import { redisApi } from './api';
 | 
					 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import { notEmpty } from '@/common/assert';
 | 
					import { notEmpty } from '@/common/assert';
 | 
				
			||||||
import FormatViewer from './FormatViewer.vue';
 | 
					import FormatViewer from './FormatViewer.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: [Number],
 | 
					        type: RedisInst,
 | 
				
			||||||
        require: true,
 | 
					        required: true,
 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
        require: true,
 | 
					 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -36,8 +30,6 @@ const props = defineProps({
 | 
				
			|||||||
const formatViewerRef = ref(null) as any;
 | 
					const formatViewerRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    db: 0,
 | 
					 | 
				
			||||||
    key: '',
 | 
					    key: '',
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        key: '',
 | 
					        key: '',
 | 
				
			||||||
@@ -61,8 +53,6 @@ watch(props, (newVal) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const setProps = (val: any) => {
 | 
					const setProps = (val: any) => {
 | 
				
			||||||
    state.redisId = val.redisId;
 | 
					 | 
				
			||||||
    state.db = val.db;
 | 
					 | 
				
			||||||
    state.key = val.keyInfo?.key;
 | 
					    state.key = val.keyInfo?.key;
 | 
				
			||||||
    initData();
 | 
					    initData();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -73,7 +63,7 @@ const initData = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const getStringValue = async () => {
 | 
					const getStringValue = async () => {
 | 
				
			||||||
    if (state.key) {
 | 
					    if (state.key) {
 | 
				
			||||||
        state.string.value = await redisApi.getString.request(getBaseReqParam());
 | 
					        state.string.value = await props.redis.runCmd(['GET', state.key]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,21 +71,10 @@ const saveValue = async () => {
 | 
				
			|||||||
    state.string.value = formatViewerRef.value.getContent();
 | 
					    state.string.value = formatViewerRef.value.getContent();
 | 
				
			||||||
    notEmpty(state.string.value, 'value不能为空');
 | 
					    notEmpty(state.string.value, 'value不能为空');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await redisApi.setString.request({
 | 
					    await props.redis.runCmd(['SET', state.key, state.string.value]);
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					 | 
				
			||||||
        value: state.string.value,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('数据保存成功');
 | 
					    ElMessage.success('数据保存成功');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getBaseReqParam = () => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        id: state.redisId,
 | 
					 | 
				
			||||||
        db: state.db,
 | 
					 | 
				
			||||||
        key: state.key,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineExpose({ initData });
 | 
					defineExpose({ initData });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss">
 | 
					<style lang="scss">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,20 +52,14 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
					import { ref, reactive, toRefs, onMounted } from 'vue';
 | 
				
			||||||
import { redisApi } from './api';
 | 
					 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import FormatViewer from './FormatViewer.vue';
 | 
					import FormatViewer from './FormatViewer.vue';
 | 
				
			||||||
 | 
					import { RedisInst } from './redis';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    redisId: {
 | 
					    redis: {
 | 
				
			||||||
        type: [Number],
 | 
					        type: RedisInst,
 | 
				
			||||||
        require: true,
 | 
					        required: true,
 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    db: {
 | 
					 | 
				
			||||||
        type: [Number],
 | 
					 | 
				
			||||||
        require: true,
 | 
					 | 
				
			||||||
        default: 0,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    keyInfo: {
 | 
					    keyInfo: {
 | 
				
			||||||
        type: [Object],
 | 
					        type: [Object],
 | 
				
			||||||
@@ -75,8 +69,6 @@ const props = defineProps({
 | 
				
			|||||||
const formatViewerRef = ref(null) as any;
 | 
					const formatViewerRef = ref(null) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const state = reactive({
 | 
					const state = reactive({
 | 
				
			||||||
    redisId: 0,
 | 
					 | 
				
			||||||
    db: 0,
 | 
					 | 
				
			||||||
    key: '',
 | 
					    key: '',
 | 
				
			||||||
    filterValue: '',
 | 
					    filterValue: '',
 | 
				
			||||||
    scanCursor: 0,
 | 
					    scanCursor: 0,
 | 
				
			||||||
@@ -96,8 +88,6 @@ const state = reactive({
 | 
				
			|||||||
const { total, values, loadMoreDisable, editDialog } = toRefs(state);
 | 
					const { total, values, loadMoreDisable, editDialog } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
    state.redisId = props.redisId;
 | 
					 | 
				
			||||||
    state.db = props.db;
 | 
					 | 
				
			||||||
    state.key = props.keyInfo?.key;
 | 
					    state.key = props.keyInfo?.key;
 | 
				
			||||||
    initData();
 | 
					    initData();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -105,7 +95,7 @@ onMounted(() => {
 | 
				
			|||||||
const initData = async () => {
 | 
					const initData = async () => {
 | 
				
			||||||
    state.pageNum = 1;
 | 
					    state.pageNum = 1;
 | 
				
			||||||
    state.filterValue = '';
 | 
					    state.filterValue = '';
 | 
				
			||||||
    await getTotal();
 | 
					    getTotal();
 | 
				
			||||||
    await zrevrange(true);
 | 
					    await zrevrange(true);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,17 +110,14 @@ const loadDatas = (resetTableData = false) => {
 | 
				
			|||||||
const zrevrange = async (resetTableData = false) => {
 | 
					const zrevrange = async (resetTableData = false) => {
 | 
				
			||||||
    const pageNum = state.pageNum;
 | 
					    const pageNum = state.pageNum;
 | 
				
			||||||
    const pageSize = state.pageSize;
 | 
					    const pageSize = state.pageSize;
 | 
				
			||||||
    const res = await redisApi.zrevrange.request({
 | 
					    // ZREVRANGE key start stop [WITHSCORES]
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					    const res = await props.redis.runCmd(['ZREVRANGE', state.key, (pageNum - 1) * pageSize, pageNum * pageSize - 1, 'WITHSCORES']);
 | 
				
			||||||
        start: (pageNum - 1) * pageSize,
 | 
					 | 
				
			||||||
        stop: pageNum * pageSize - 1,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const vs = [];
 | 
					    const vs = [];
 | 
				
			||||||
    for (let member of res) {
 | 
					    for (let member of res) {
 | 
				
			||||||
        vs.push({
 | 
					        vs.push({
 | 
				
			||||||
            score: member.Score,
 | 
					            value: member[0],
 | 
				
			||||||
            value: member.Member,
 | 
					            score: member[1],
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (resetTableData) {
 | 
					    if (resetTableData) {
 | 
				
			||||||
@@ -150,14 +137,11 @@ const zscanData = async (resetTableData = true, resetCursor = false) => {
 | 
				
			|||||||
    if (resetCursor) {
 | 
					    if (resetCursor) {
 | 
				
			||||||
        state.scanCursor = 0;
 | 
					        state.scanCursor = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const res = await redisApi.zscan.request({
 | 
					    // ZSCAN key cursor [MATCH pattern] [COUNT count]
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					    // 响应[coursor, vals[]]
 | 
				
			||||||
        match: getScanMatch(),
 | 
					    const res = await props.redis.runCmd(['ZSCAN', state.key, state.scanCursor, 'MATCH', getScanMatch(), 'COUNT', state.pageSize]);
 | 
				
			||||||
        cursor: state.scanCursor,
 | 
					 | 
				
			||||||
        count: state.pageSize,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const keys = res.keys;
 | 
					    const keys = res[1];
 | 
				
			||||||
    const vs = [];
 | 
					    const vs = [];
 | 
				
			||||||
    const memCount = keys.length / 2;
 | 
					    const memCount = keys.length / 2;
 | 
				
			||||||
    let nextMemndex = 0;
 | 
					    let nextMemndex = 0;
 | 
				
			||||||
@@ -171,20 +155,15 @@ const zscanData = async (resetTableData = true, resetCursor = false) => {
 | 
				
			|||||||
        state.values.push(...vs);
 | 
					        state.values.push(...vs);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state.scanCursor = res.cursor;
 | 
					    state.scanCursor = res[0];
 | 
				
			||||||
    state.loadMoreDisable = res.cursor == 0;
 | 
					    state.loadMoreDisable = state.scanCursor == 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getTotal = () => {
 | 
					const getTotal = () => {
 | 
				
			||||||
    redisApi.zcard
 | 
					    // ZCARD key
 | 
				
			||||||
        .request({
 | 
					    props.redis.runCmd(['ZCARD', state.key]).then((res) => {
 | 
				
			||||||
            id: state.redisId,
 | 
					        state.total = res;
 | 
				
			||||||
            db: state.db,
 | 
					    });
 | 
				
			||||||
            key: state.key,
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .then((res) => {
 | 
					 | 
				
			||||||
            state.total = res;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const showEditDialog = (row: any) => {
 | 
					const showEditDialog = (row: any) => {
 | 
				
			||||||
@@ -195,25 +174,18 @@ const showEditDialog = (row: any) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const confirmEditData = async () => {
 | 
					const confirmEditData = async () => {
 | 
				
			||||||
    const param = getBaseReqParam();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
					    // 存在数据行,则说明为修改,则要先删除旧数据后新增
 | 
				
			||||||
    const dataRow = state.editDialog.dataRow;
 | 
					    const dataRow = state.editDialog.dataRow;
 | 
				
			||||||
    if (dataRow) {
 | 
					    if (dataRow) {
 | 
				
			||||||
        await redisApi.zrem.request({
 | 
					        // ZREM key member [member ...]
 | 
				
			||||||
            member: state.editDialog.dataRow.value,
 | 
					        await props.redis.runCmd(['ZREM', state.key, state.editDialog.dataRow.value]);
 | 
				
			||||||
            ...param,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const score = state.editDialog.score;
 | 
					    const score = state.editDialog.score;
 | 
				
			||||||
    // 获取zset member内容并新增
 | 
					    // 获取zset member内容并新增
 | 
				
			||||||
    const member = formatViewerRef.value.getContent();
 | 
					    const member = formatViewerRef.value.getContent();
 | 
				
			||||||
    await redisApi.zadd.request({
 | 
					    // ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]
 | 
				
			||||||
        score,
 | 
					    await props.redis.runCmd(['ZADD', state.key, score, member]);
 | 
				
			||||||
        member,
 | 
					 | 
				
			||||||
        ...param,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ElMessage.success('保存成功');
 | 
					    ElMessage.success('保存成功');
 | 
				
			||||||
    if (dataRow) {
 | 
					    if (dataRow) {
 | 
				
			||||||
@@ -228,23 +200,12 @@ const confirmEditData = async () => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const zrem = async (row: any, index: any) => {
 | 
					const zrem = async (row: any, index: any) => {
 | 
				
			||||||
    await redisApi.zrem.request({
 | 
					    await props.redis.runCmd(['ZREM', state.key, row.value]);
 | 
				
			||||||
        ...getBaseReqParam(),
 | 
					 | 
				
			||||||
        member: row.value,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    ElMessage.success('删除成功');
 | 
					    ElMessage.success('删除成功');
 | 
				
			||||||
    state.values.splice(index, 1);
 | 
					    state.values.splice(index, 1);
 | 
				
			||||||
    state.total--;
 | 
					    state.total--;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getBaseReqParam = () => {
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        id: state.redisId,
 | 
					 | 
				
			||||||
        db: state.db,
 | 
					 | 
				
			||||||
        key: state.key,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineExpose({ initData });
 | 
					defineExpose({ initData });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss"></style>
 | 
					<style lang="scss"></style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,6 +71,8 @@
 | 
				
			|||||||
                        <el-form-item prop="remark" label="备注">
 | 
					                        <el-form-item prop="remark" label="备注">
 | 
				
			||||||
                            <el-input v-model.trim="form.remark" auto-complete="off" type="textarea"></el-input>
 | 
					                            <el-input v-model.trim="form.remark" auto-complete="off" type="textarea"></el-input>
 | 
				
			||||||
                        </el-form-item>
 | 
					                        </el-form-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <procdef-select-form-item v-model="form.flowProcdefKey" />
 | 
				
			||||||
                    </el-tab-pane>
 | 
					                    </el-tab-pane>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <el-tab-pane label="其他配置" name="other">
 | 
					                    <el-tab-pane label="其他配置" name="other">
 | 
				
			||||||
@@ -99,6 +101,7 @@ import { ElMessage } from 'element-plus';
 | 
				
			|||||||
import { RsaEncrypt } from '@/common/rsa';
 | 
					import { RsaEncrypt } from '@/common/rsa';
 | 
				
			||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
 | 
					import TagTreeSelect from '../component/TagTreeSelect.vue';
 | 
				
			||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
 | 
					import SshTunnelSelect from '../component/SshTunnelSelect.vue';
 | 
				
			||||||
 | 
					import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
    visible: {
 | 
					    visible: {
 | 
				
			||||||
@@ -170,6 +173,7 @@ const state = reactive({
 | 
				
			|||||||
        db: '',
 | 
					        db: '',
 | 
				
			||||||
        remark: '',
 | 
					        remark: '',
 | 
				
			||||||
        sshTunnelMachineId: -1,
 | 
					        sshTunnelMachineId: -1,
 | 
				
			||||||
 | 
					        flowProcdefKey: '',
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    submitForm: {} as any,
 | 
					    submitForm: {} as any,
 | 
				
			||||||
    dbList: [0],
 | 
					    dbList: [0],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,7 +127,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <el-descriptions-item :span="3" label="库">{{ detailDialog.data.db }}</el-descriptions-item>
 | 
					                <el-descriptions-item :span="3" label="库">{{ detailDialog.data.db }}</el-descriptions-item>
 | 
				
			||||||
                <el-descriptions-item :span="3" label="备注">{{ detailDialog.data.remark }}</el-descriptions-item>
 | 
					                <el-descriptions-item :span="3" label="备注">{{ detailDialog.data.remark }}</el-descriptions-item>
 | 
				
			||||||
 | 
					                <el-descriptions-item :span="3" label="工单流程key">{{ detailDialog.data?.flowProcdefKey }}</el-descriptions-item>
 | 
				
			||||||
                <el-descriptions-item :span="3" label="SSH隧道">{{ detailDialog.data.sshTunnelMachineId > 0 ? '是' : '否' }} </el-descriptions-item>
 | 
					                <el-descriptions-item :span="3" label="SSH隧道">{{ detailDialog.data.sshTunnelMachineId > 0 ? '是' : '否' }} </el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <el-descriptions-item :span="2" label="创建时间">{{ dateFormat(detailDialog.data.createTime) }} </el-descriptions-item>
 | 
					                <el-descriptions-item :span="2" label="创建时间">{{ dateFormat(detailDialog.data.createTime) }} </el-descriptions-item>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,40 +13,125 @@ export const redisApi = {
 | 
				
			|||||||
    keyInfo: Api.newGet('/redis/{id}/{db}/key-info'),
 | 
					    keyInfo: Api.newGet('/redis/{id}/{db}/key-info'),
 | 
				
			||||||
    keyTtl: Api.newGet('/redis/{id}/{db}/key-ttl'),
 | 
					    keyTtl: Api.newGet('/redis/{id}/{db}/key-ttl'),
 | 
				
			||||||
    keyMemuse: Api.newGet('/redis/{id}/{db}/key-memuse'),
 | 
					    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'),
 | 
					    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'),
 | 
					    runCmd: Api.newPost('/redis/{id}/{db}/run-cmd'),
 | 
				
			||||||
    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'),
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								mayfly_go_web/src/views/ops/redis/components/CmdExecBox.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
				
			||||||
@@ -0,0 +1,95 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <el-dialog title="待执行cmd" v-model="dialogVisible" :show-close="false" width="600px" @close="cancel">
 | 
				
			||||||
 | 
					            <el-input type="textarea" disabled v-model="state.cmdStr" class="mt5" rows="5" />
 | 
				
			||||||
 | 
					            <el-input @keyup.enter="runCmd" ref="remarkInputRef" v-model="remark" placeholder="请输入执行备注" class="mt5" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div v-if="props.flowProcdefKey">
 | 
				
			||||||
 | 
					                <el-divider content-position="left">审批节点</el-divider>
 | 
				
			||||||
 | 
					                <procdef-tasks :procdef-key="props.flowProcdefKey" />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <template #footer>
 | 
				
			||||||
 | 
					                <span class="dialog-footer">
 | 
				
			||||||
 | 
					                    <el-button @click="cancel">取 消</el-button>
 | 
				
			||||||
 | 
					                    <el-button @click="runCmd" type="primary" :loading="btnLoading">执 行</el-button>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					        </el-dialog>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import { toRefs, ref, reactive, onMounted } from 'vue';
 | 
				
			||||||
 | 
					import { ElDialog, ElButton, ElInput, ElMessage, InputInstance, ElDivider } from 'element-plus';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ProcdefTasks from '@/views/flow/components/ProcdefTasks.vue';
 | 
				
			||||||
 | 
					import { redisApi } from '../api';
 | 
				
			||||||
 | 
					import { CmdExecProps } from './CmdExecBox';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<CmdExecProps>(), {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const remarkInputRef = ref<InputInstance>();
 | 
				
			||||||
 | 
					const state = reactive({
 | 
				
			||||||
 | 
					    dialogVisible: false,
 | 
				
			||||||
 | 
					    flowProcdefKey: '' as any,
 | 
				
			||||||
 | 
					    cmdStr: '',
 | 
				
			||||||
 | 
					    remark: '',
 | 
				
			||||||
 | 
					    btnLoading: false,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { dialogVisible, remark, btnLoading } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					    show(props);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const show = (props: CmdExecProps) => {
 | 
				
			||||||
 | 
					    const cmdArr = props.cmd.map((item: any, index: number) => {
 | 
				
			||||||
 | 
					        if (index === 0) {
 | 
				
			||||||
 | 
					            return item; // 第一个元素直接返回原值
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof item === 'string') {
 | 
				
			||||||
 | 
					            return `'${item}'`; // 字符串加单引号
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return item; // 其他类型直接返回
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    state.cmdStr = cmdArr.join('  ');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state.dialogVisible = props.visible || true;
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					        remarkInputRef.value?.focus();
 | 
				
			||||||
 | 
					    }, 200);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 执行cmd
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const runCmd = async () => {
 | 
				
			||||||
 | 
					    if (!state.remark) {
 | 
				
			||||||
 | 
					        ElMessage.error('请输入执行备注信息');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        state.btnLoading = true;
 | 
				
			||||||
 | 
					        await redisApi.runCmd.request({
 | 
				
			||||||
 | 
					            id: props.id,
 | 
				
			||||||
 | 
					            db: props.db,
 | 
				
			||||||
 | 
					            cmd: props.cmd,
 | 
				
			||||||
 | 
					            remark: state.remark,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        props.runSuccessFn && props.runSuccessFn();
 | 
				
			||||||
 | 
					        ElMessage.success('工单提交成功');
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					        state.btnLoading = false;
 | 
				
			||||||
 | 
					        cancel();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cancel = () => {
 | 
				
			||||||
 | 
					    state.dialogVisible = false;
 | 
				
			||||||
 | 
					    props.cancelFn && props.cancelFn();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<style lang="scss"></style>
 | 
				
			||||||
							
								
								
									
										138
									
								
								mayfly_go_web/src/views/ops/redis/redis.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								mayfly_go_web/src/views/ops/redis/redis.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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]',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -27,7 +27,7 @@ export function keysToTree(keys: any, separator: string = ':', openStatus: any =
 | 
				
			|||||||
    return formatTreeData(tree, '', separator, openStatus, forceCut);
 | 
					    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 keys.map((x: string) => {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            key: x,
 | 
					            key: x,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <el-popover v-if="props.accountId" @show="getAccountInfo(props.accountId)" placement="top-start" title="账号信息" :width="400" trigger="click">
 | 
				
			||||||
 | 
					            <template #reference>
 | 
				
			||||||
 | 
					                <el-link type="primary">{{ props.username }}</el-link>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					            <el-descriptions v-loading="loading" :column="2" border>
 | 
				
			||||||
 | 
					                <el-descriptions-item label="username">{{ account.username }}</el-descriptions-item>
 | 
				
			||||||
 | 
					                <el-descriptions-item label="姓名">
 | 
				
			||||||
 | 
					                    {{ account.name }}
 | 
				
			||||||
 | 
					                </el-descriptions-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <el-descriptions-item :span="2" label="角色">
 | 
				
			||||||
 | 
					                    <el-tag v-for="role in account.roles" :key="role.code" class="ml5">
 | 
				
			||||||
 | 
					                        {{ role.roleName }}
 | 
				
			||||||
 | 
					                    </el-tag>
 | 
				
			||||||
 | 
					                </el-descriptions-item>
 | 
				
			||||||
 | 
					            </el-descriptions>
 | 
				
			||||||
 | 
					        </el-popover>
 | 
				
			||||||
 | 
					        <span v-else>{{ props.username }}</span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import { reactive, toRefs } from 'vue';
 | 
				
			||||||
 | 
					import { accountApi } from '../../api';
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					    accountId: {
 | 
				
			||||||
 | 
					        type: [Number],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    username: {
 | 
				
			||||||
 | 
					        type: [String],
 | 
				
			||||||
 | 
					        required: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const state = reactive({
 | 
				
			||||||
 | 
					    account: {} as any,
 | 
				
			||||||
 | 
					    loading: false,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { account, loading } = toRefs(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getAccountInfo = async (id: number) => {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        state.loading = true;
 | 
				
			||||||
 | 
					        state.account = await accountApi.getAccountDetail.request({ id });
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					        state.loading = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss"></style>
 | 
				
			||||||
@@ -25,6 +25,7 @@ export const roleApi = {
 | 
				
			|||||||
export const accountApi = {
 | 
					export const accountApi = {
 | 
				
			||||||
    list: Api.newGet('/sys/accounts'),
 | 
					    list: Api.newGet('/sys/accounts'),
 | 
				
			||||||
    querySimple: Api.newGet('/sys/accounts/simple'),
 | 
					    querySimple: Api.newGet('/sys/accounts/simple'),
 | 
				
			||||||
 | 
					    getAccountDetail: Api.newGet('/sys/accounts/{id}'),
 | 
				
			||||||
    save: Api.newPost('/sys/accounts'),
 | 
					    save: Api.newPost('/sys/accounts'),
 | 
				
			||||||
    update: Api.newPut('/sys/accounts/{id}'),
 | 
					    update: Api.newPut('/sys/accounts/{id}'),
 | 
				
			||||||
    del: Api.newDelete('/sys/accounts/{id}'),
 | 
					    del: Api.newDelete('/sys/accounts/{id}'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,10 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
        <page-table :page-api="logApi.list" :search-items="searchItems" v-model:query-form="query" :columns="columns"> </page-table>
 | 
					        <page-table :page-api="logApi.list" :search-items="searchItems" v-model:query-form="query" :columns="columns">
 | 
				
			||||||
 | 
					            <template #creator="{ data }">
 | 
				
			||||||
 | 
					                <account-info :account-id="data.creatorId" :username="data.creator" />
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					        </page-table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,6 +15,7 @@ import PageTable from '@/components/pagetable/PageTable.vue';
 | 
				
			|||||||
import { TableColumn } from '@/components/pagetable';
 | 
					import { TableColumn } from '@/components/pagetable';
 | 
				
			||||||
import { LogTypeEnum } from '../enums';
 | 
					import { LogTypeEnum } from '../enums';
 | 
				
			||||||
import { OptionsApi, SearchItem } from '@/components/SearchForm';
 | 
					import { OptionsApi, SearchItem } from '@/components/SearchForm';
 | 
				
			||||||
 | 
					import AccountInfo from '../account/components/AccountInfo.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const searchItems = [
 | 
					const searchItems = [
 | 
				
			||||||
    SearchItem.select('creatorId', '操作人')
 | 
					    SearchItem.select('creatorId', '操作人')
 | 
				
			||||||
@@ -33,7 +38,7 @@ const searchItems = [
 | 
				
			|||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const columns = [
 | 
					const columns = [
 | 
				
			||||||
    TableColumn.new('creator', '操作人'),
 | 
					    TableColumn.new('creator', '操作人').isSlot().noShowOverflowTooltip(),
 | 
				
			||||||
    TableColumn.new('createTime', '操作时间').isTime(),
 | 
					    TableColumn.new('createTime', '操作时间').isTime(),
 | 
				
			||||||
    TableColumn.new('type', '结果').typeTag(LogTypeEnum),
 | 
					    TableColumn.new('type', '结果').typeTag(LogTypeEnum),
 | 
				
			||||||
    TableColumn.new('description', '描述'),
 | 
					    TableColumn.new('description', '描述'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ var (
 | 
				
			|||||||
	initFuncs    = make([]InitFunc, 0)
 | 
						initFuncs    = make([]InitFunc, 0)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 添加初始化ioc函数,由各个默认自行添加
 | 
					// 添加初始化ioc函数,由各个默认自行添加(直接init方法中ioc.Register注册不会打印ioc相关日志)
 | 
				
			||||||
func AddInitIocFunc(initIocFunc InitIocFunc) {
 | 
					func AddInitIocFunc(initIocFunc InitIocFunc) {
 | 
				
			||||||
	initIocFuncs = append(initIocFuncs, initIocFunc)
 | 
						initIocFuncs = append(initIocFuncs, initIocFunc)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -37,7 +37,7 @@ func InitOther() {
 | 
				
			|||||||
	// 为所有注册的实例注入其依赖的其他组件实例
 | 
						// 为所有注册的实例注入其依赖的其他组件实例
 | 
				
			||||||
	biz.ErrIsNil(ioc.InjectComponents())
 | 
						biz.ErrIsNil(ioc.InjectComponents())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 调用各个默认的初始化函数
 | 
						// 调用各个模块的初始化函数
 | 
				
			||||||
	for _, initFunc := range initFuncs {
 | 
						for _, initFunc := range initFuncs {
 | 
				
			||||||
		go initFunc()
 | 
							go initFunc()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,9 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/auth/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(oauth2AppImpl), ioc.WithComponentName("Oauth2App"))
 | 
						ioc.Register(new(oauth2AppImpl), ioc.WithComponentName("Oauth2App"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,6 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newAuthAccountRepo(), ioc.WithComponentName("Oauth2AccountRepo"))
 | 
						ioc.Register(newAuthAccountRepo(), ioc.WithComponentName("Oauth2AccountRepo"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/auth/application"
 | 
						"mayfly-go/internal/auth/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/auth/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/auth/router"
 | 
						"mayfly-go/internal/auth/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -124,7 +124,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
 | 
				
			|||||||
	for _, s := range sqls {
 | 
						for _, s := range sqls {
 | 
				
			||||||
		s = stringx.TrimSpaceAndBr(s)
 | 
							s = stringx.TrimSpaceAndBr(s)
 | 
				
			||||||
		// 多条执行,暂不支持查询语句
 | 
							// 多条执行,暂不支持查询语句
 | 
				
			||||||
		if isMulti {
 | 
							if isMulti && len(s) > 10 {
 | 
				
			||||||
			biz.IsTrue(!strings.HasPrefix(strings.ToLower(s[:10]), "select"), "多条语句执行暂不不支持select语句")
 | 
								biz.IsTrue(!strings.HasPrefix(strings.ToLower(s[:10]), "select"), "多条语句执行暂不不支持select语句")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,11 @@ package application
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/internal/db/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(instanceAppImpl), ioc.WithComponentName("DbInstanceApp"))
 | 
						ioc.Register(new(instanceAppImpl), ioc.WithComponentName("DbInstanceApp"))
 | 
				
			||||||
	ioc.Register(new(dbAppImpl), ioc.WithComponentName("DbApp"))
 | 
						ioc.Register(new(dbAppImpl), ioc.WithComponentName("DbApp"))
 | 
				
			||||||
	ioc.Register(new(dbSqlExecAppImpl), ioc.WithComponentName("DbSqlExecApp"))
 | 
						ioc.Register(new(dbSqlExecAppImpl), ioc.WithComponentName("DbSqlExecApp"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,7 +97,6 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
 | 
				
			|||||||
			// 如果配置为0,则不校验分页参数
 | 
								// 如果配置为0,则不校验分页参数
 | 
				
			||||||
			maxCount := config.GetDbQueryMaxCount()
 | 
								maxCount := config.GetDbQueryMaxCount()
 | 
				
			||||||
			if maxCount != 0 {
 | 
								if maxCount != 0 {
 | 
				
			||||||
 | 
					 | 
				
			||||||
				if !strings.Contains(lowerSql, "limit") &&
 | 
									if !strings.Contains(lowerSql, "limit") &&
 | 
				
			||||||
					// 兼容oracle rownum分页
 | 
										// 兼容oracle rownum分页
 | 
				
			||||||
					!strings.Contains(lowerSql, "rownum") &&
 | 
										!strings.Contains(lowerSql, "rownum") &&
 | 
				
			||||||
@@ -118,10 +117,11 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			execRes, execErr = d.doExec(ctx, execSqlReq, dbSqlExecRecord)
 | 
								execRes, execErr = d.doExec(ctx, execSqlReq, dbSqlExecRecord)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							d.saveSqlExecLog(isSelect, dbSqlExecRecord)
 | 
				
			||||||
		if execErr != nil {
 | 
							if execErr != nil {
 | 
				
			||||||
			return nil, execErr
 | 
								return nil, execErr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		d.saveSqlExecLog(isSelect, dbSqlExecRecord)
 | 
					 | 
				
			||||||
		return execRes, nil
 | 
							return execRes, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,10 +152,13 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
 | 
				
			|||||||
	return execRes, nil
 | 
						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))
 | 
						logx.Debugf("DbSqlExec FlowBizHandle -> bizKey: %s, procinstStatus: %s", bizKey, flowentity.ProcinstStatusEnum.GetDesc(procinstStatus))
 | 
				
			||||||
	// 流程挂起不处理
 | 
						// 流程挂起不处理
 | 
				
			||||||
	if procinstStatus == flowentity.ProcinstSuspended {
 | 
						if procinstStatus == flowentity.ProcinstStatusSuspended {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dbSqlExec := &entity.DbSqlExec{FlowBizKey: bizKey}
 | 
						dbSqlExec := &entity.DbSqlExec{FlowBizKey: bizKey}
 | 
				
			||||||
@@ -164,7 +167,7 @@ func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, procinstStatus flo
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if procinstStatus != flowentity.ProcinstCompleted {
 | 
						if procinstStatus != flowentity.ProcinstStatusCompleted {
 | 
				
			||||||
		dbSqlExec.Status = entity.DbSqlExecStatusNo
 | 
							dbSqlExec.Status = entity.DbSqlExecStatusNo
 | 
				
			||||||
		dbSqlExec.Res = fmt.Sprintf("流程%s", flowentity.ProcinstStatusEnum.GetDesc(procinstStatus))
 | 
							dbSqlExec.Res = fmt.Sprintf("流程%s", flowentity.ProcinstStatusEnum.GetDesc(procinstStatus))
 | 
				
			||||||
		return d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
 | 
							return d.dbSqlExecRepo.UpdateById(ctx, dbSqlExec)
 | 
				
			||||||
@@ -364,7 +367,7 @@ func (d *dbSqlExecAppImpl) doExec(ctx context.Context, execSqlReq *DbSqlExecReq,
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		execRes = err.Error()
 | 
							execRes = err.Error()
 | 
				
			||||||
		dbSqlExecRecord.Status = entity.DbSqlExecStatusFail
 | 
							dbSqlExecRecord.Status = entity.DbSqlExecStatusFail
 | 
				
			||||||
		dbSqlExecRecord.Res = err.Error()
 | 
							dbSqlExecRecord.Res = execRes
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dbSqlExecRecord.Res = fmt.Sprintf("执行成功,影响条数: %d", rowsAffected)
 | 
							dbSqlExecRecord.Res = fmt.Sprintf("执行成功,影响条数: %d", rowsAffected)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(NewInstanceRepo(), ioc.WithComponentName("DbInstanceRepo"))
 | 
						ioc.Register(NewInstanceRepo(), ioc.WithComponentName("DbInstanceRepo"))
 | 
				
			||||||
	ioc.Register(newDbRepo(), ioc.WithComponentName("DbRepo"))
 | 
						ioc.Register(newDbRepo(), ioc.WithComponentName("DbRepo"))
 | 
				
			||||||
	ioc.Register(newDbSqlRepo(), ioc.WithComponentName("DbSqlRepo"))
 | 
						ioc.Register(newDbSqlRepo(), ioc.WithComponentName("DbSqlRepo"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,11 +3,16 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/db/application"
 | 
						"mayfly-go/internal/db/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/db/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/db/router"
 | 
						"mayfly-go/internal/db/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
	initialize.AddInitFunc(application.Init)
 | 
						initialize.AddInitFunc(application.Init)
 | 
				
			||||||
	initialize.AddTerminateFunc(Terminate)
 | 
						initialize.AddTerminateFunc(Terminate)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ type ProcinstVO struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	BizType      string     `json:"bizType"`      // 业务类型
 | 
						BizType      string     `json:"bizType"`      // 业务类型
 | 
				
			||||||
	BizKey       string     `json:"bizKey"`       // 业务key
 | 
						BizKey       string     `json:"bizKey"`       // 业务key
 | 
				
			||||||
 | 
						BizForm      string     `json:"bizForm"`      // 业务form
 | 
				
			||||||
	BizStatus    int8       `json:"bizStatus"`    // 业务状态
 | 
						BizStatus    int8       `json:"bizStatus"`    // 业务状态
 | 
				
			||||||
	BizHandleRes string     `json:"bizHandleRes"` // 业务处理结果
 | 
						BizHandleRes string     `json:"bizHandleRes"` // 业务处理结果
 | 
				
			||||||
	TaskKey      string     `json:"taskKey"`      // 当前任务key
 | 
						TaskKey      string     `json:"taskKey"`      // 当前任务key
 | 
				
			||||||
@@ -21,6 +22,7 @@ type ProcinstVO struct {
 | 
				
			|||||||
	Duration     int64      `json:"duration"` // 持续时间(开始到结束)
 | 
						Duration     int64      `json:"duration"` // 持续时间(开始到结束)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Creator    string     `json:"creator"`
 | 
						Creator    string     `json:"creator"`
 | 
				
			||||||
 | 
						CreatorId  uint64     `json:"creatorId"`
 | 
				
			||||||
	CreateTime *time.Time `json:"createTime"`
 | 
						CreateTime *time.Time `json:"createTime"`
 | 
				
			||||||
	UpdateTime *time.Time `json:"updateTime"`
 | 
						UpdateTime *time.Time `json:"updateTime"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,10 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/flow/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(procdefAppImpl), ioc.WithComponentName("ProcdefApp"))
 | 
						ioc.Register(new(procdefAppImpl), ioc.WithComponentName("ProcdefApp"))
 | 
				
			||||||
	ioc.Register(new(procinstAppImpl), ioc.WithComponentName("ProcinstApp"))
 | 
						ioc.Register(new(procinstAppImpl), ioc.WithComponentName("ProcinstApp"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,18 +7,19 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/logx"
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 流程业务处理函数(流程结束后会根据流程业务类型获取该函数进行处理)
 | 
					type BizHandleParam struct {
 | 
				
			||||||
// @param procinstStatus 流程实例状态
 | 
						BizType        string                //业务类型
 | 
				
			||||||
// @param bizKey 业务key,可为业务数据对应的主键
 | 
						BizKey         string                // 业务key
 | 
				
			||||||
// type FlowBizHandlerFunc func(ctx context.Context, procinstStatus entity.ProcinstStatus, bizKey string) error
 | 
						BizForm        string                // 业务表单信息
 | 
				
			||||||
 | 
						ProcinstStatus entity.ProcinstStatus // 业务状态
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 业务流程处理器(流程状态变更后会根据流程业务类型获取对应的处理器进行回调处理)
 | 
					// 业务流程处理器(流程状态变更后会根据流程业务类型获取对应的处理器进行回调处理)
 | 
				
			||||||
type FlowBizHandler interface {
 | 
					type FlowBizHandler interface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 业务流程处理函数
 | 
						// 业务流程处理函数
 | 
				
			||||||
	// @param procinstStatus 流程实例状态
 | 
						// @param bizHandleParam 业务处理信息,可获取实例状态、关联业务key等信息
 | 
				
			||||||
	// @param bizKey 业务key,可为业务数据对应的主键
 | 
						FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) error
 | 
				
			||||||
	FlowBizHandle(ctx context.Context, procinstStatus entity.ProcinstStatus, bizKey string) error
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					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 {
 | 
						if handler, ok := handlers[flowBizType]; !ok {
 | 
				
			||||||
		logx.Warnf("flow biz handler not found: bizType=%s", flowBizType)
 | 
							logx.Warnf("flow biz handler not found: bizType=%s", flowBizType)
 | 
				
			||||||
		return errorx.NewBiz("业务流程处理器不存在")
 | 
							return errorx.NewBiz("业务处理器不存在")
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return handler.FlowBizHandle(ctx, procinstStatus, bizKey)
 | 
							return handler.FlowBizHandle(ctx, bizHandleParam)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ type StarProcParam struct {
 | 
				
			|||||||
	BizType string // 业务类型
 | 
						BizType string // 业务类型
 | 
				
			||||||
	BizKey  string // 业务key
 | 
						BizKey  string // 业务key
 | 
				
			||||||
	Remark  string // 备注
 | 
						Remark  string // 备注
 | 
				
			||||||
 | 
						BizForm string // 业务表单信息
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CompleteProcinstTaskParam struct {
 | 
					type CompleteProcinstTaskParam struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,10 +65,10 @@ func (p *procdefAppImpl) DeleteProcdef(ctx context.Context, defId uint64) error
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 判断该流程实例是否可以执行修改操作
 | 
					// 判断该流程实例是否可以执行修改操作
 | 
				
			||||||
func (p *procdefAppImpl) canModify(prodefId 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("存在运行中的流程实例,无法操作")
 | 
							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 errorx.NewBiz("存在挂起中的流程实例,无法操作")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,11 +68,12 @@ func (p *procinstAppImpl) StartProc(ctx context.Context, procdefKey string, reqP
 | 
				
			|||||||
	procinst := &entity.Procinst{
 | 
						procinst := &entity.Procinst{
 | 
				
			||||||
		BizType:     reqParam.BizType,
 | 
							BizType:     reqParam.BizType,
 | 
				
			||||||
		BizKey:      reqParam.BizKey,
 | 
							BizKey:      reqParam.BizKey,
 | 
				
			||||||
 | 
							BizForm:     reqParam.BizForm,
 | 
				
			||||||
		BizStatus:   entity.ProcinstBizStatusWait,
 | 
							BizStatus:   entity.ProcinstBizStatusWait,
 | 
				
			||||||
		ProcdefId:   procdef.Id,
 | 
							ProcdefId:   procdef.Id,
 | 
				
			||||||
		ProcdefName: procdef.Name,
 | 
							ProcdefName: procdef.Name,
 | 
				
			||||||
		Remark:      reqParam.Remark,
 | 
							Remark:      reqParam.Remark,
 | 
				
			||||||
		Status:      entity.ProcinstActive,
 | 
							Status:      entity.ProcinstStatusActive,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	task := p.getNextTask(procdef, "")
 | 
						task := p.getNextTask(procdef, "")
 | 
				
			||||||
@@ -97,7 +98,7 @@ func (p *procinstAppImpl) CancelProc(ctx context.Context, procinstId uint64) err
 | 
				
			|||||||
	if procinst.CreatorId != la.Id {
 | 
						if procinst.CreatorId != la.Id {
 | 
				
			||||||
		return errorx.NewBiz("只能取消自己创建的流程")
 | 
							return errorx.NewBiz("只能取消自己创建的流程")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	procinst.Status = entity.ProcinstCancelled
 | 
						procinst.Status = entity.ProcinstStatusCancelled
 | 
				
			||||||
	procinst.BizStatus = entity.ProcinstBizStatusNo
 | 
						procinst.BizStatus = entity.ProcinstBizStatusNo
 | 
				
			||||||
	procinst.SetEnd()
 | 
						procinst.SetEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,7 +131,7 @@ func (p *procinstAppImpl) CompleteTask(ctx context.Context, instTaskId uint64, r
 | 
				
			|||||||
	// 获取下一实例审批任务
 | 
						// 获取下一实例审批任务
 | 
				
			||||||
	task := p.getNextTask(procdef, instTask.TaskKey)
 | 
						task := p.getNextTask(procdef, instTask.TaskKey)
 | 
				
			||||||
	if task == nil {
 | 
						if task == nil {
 | 
				
			||||||
		procinst.Status = entity.ProcinstCompleted
 | 
							procinst.Status = entity.ProcinstStatusCompleted
 | 
				
			||||||
		procinst.SetEnd()
 | 
							procinst.SetEnd()
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		procinst.TaskKey = task.TaskKey
 | 
							procinst.TaskKey = task.TaskKey
 | 
				
			||||||
@@ -165,7 +166,7 @@ func (p *procinstAppImpl) RejectTask(ctx context.Context, instTaskId uint64, rem
 | 
				
			|||||||
	procinst := new(entity.Procinst)
 | 
						procinst := new(entity.Procinst)
 | 
				
			||||||
	p.GetById(procinst, instTask.ProcinstId)
 | 
						p.GetById(procinst, instTask.ProcinstId)
 | 
				
			||||||
	// 更新流程实例为终止状态,无法重新提交
 | 
						// 更新流程实例为终止状态,无法重新提交
 | 
				
			||||||
	procinst.Status = entity.ProcinstTerminated
 | 
						procinst.Status = entity.ProcinstStatusTerminated
 | 
				
			||||||
	procinst.BizStatus = entity.ProcinstBizStatusNo
 | 
						procinst.BizStatus = entity.ProcinstBizStatusNo
 | 
				
			||||||
	procinst.SetEnd()
 | 
						procinst.SetEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -192,7 +193,7 @@ func (p *procinstAppImpl) BackTask(ctx context.Context, instTaskId uint64, remar
 | 
				
			|||||||
	p.GetById(procinst, instTask.ProcinstId)
 | 
						p.GetById(procinst, instTask.ProcinstId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 更新流程实例为挂起状态,等待重新提交
 | 
						// 更新流程实例为挂起状态,等待重新提交
 | 
				
			||||||
	procinst.Status = entity.ProcinstSuspended
 | 
						procinst.Status = entity.ProcinstStatusSuspended
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return p.Tx(ctx, func(ctx context.Context) error {
 | 
						return p.Tx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		return p.UpdateById(ctx, procinst)
 | 
							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 {
 | 
					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 err != nil {
 | 
				
			||||||
		// 业务处理错误,非完成状态则终止流程
 | 
							// 业务处理错误,非完成状态则终止流程
 | 
				
			||||||
		if procinst.Status != entity.ProcinstCompleted {
 | 
							if procinst.Status != entity.ProcinstStatusCompleted {
 | 
				
			||||||
			procinst.Status = entity.ProcinstTerminated
 | 
								procinst.Status = entity.ProcinstStatusTerminated
 | 
				
			||||||
			procinst.SetEnd()
 | 
								procinst.SetEnd()
 | 
				
			||||||
			p.cancelInstTasks(ctx, procinst.Id, "业务处理失败")
 | 
								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.BizStatus = entity.ProcinstBizStatusSuccess
 | 
				
			||||||
		procinst.BizHandleRes = "success"
 | 
							procinst.BizHandleRes = "success"
 | 
				
			||||||
		return p.UpdateById(ctx, procinst)
 | 
							return p.UpdateById(ctx, procinst)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ type Procinst struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	BizType      string            `json:"bizType"`      // 业务类型
 | 
						BizType      string            `json:"bizType"`      // 业务类型
 | 
				
			||||||
	BizKey       string            `json:"bizKey"`       // 业务key
 | 
						BizKey       string            `json:"bizKey"`       // 业务key
 | 
				
			||||||
 | 
						BizForm      string            `json:"bizForm"`      // 业务表单
 | 
				
			||||||
	BizStatus    ProcinstBizStatus `json:"bizStatus"`    // 业务状态
 | 
						BizStatus    ProcinstBizStatus `json:"bizStatus"`    // 业务状态
 | 
				
			||||||
	BizHandleRes string            `json:"bizHandleRes"` // 业务处理结果
 | 
						BizHandleRes string            `json:"bizHandleRes"` // 业务处理结果
 | 
				
			||||||
	TaskKey      string            `json:"taskKey"`      // 当前任务key
 | 
						TaskKey      string            `json:"taskKey"`      // 当前任务key
 | 
				
			||||||
@@ -38,19 +39,19 @@ func (a *Procinst) SetEnd() {
 | 
				
			|||||||
type ProcinstStatus int8
 | 
					type ProcinstStatus int8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	ProcinstActive     ProcinstStatus = 1  // 流程实例正在执行中,当前有活动任务等待执行或者正在运行的流程节点
 | 
						ProcinstStatusActive     ProcinstStatus = 1  // 流程实例正在执行中,当前有活动任务等待执行或者正在运行的流程节点
 | 
				
			||||||
	ProcinstCompleted  ProcinstStatus = 2  // 流程实例已经成功执行完成,没有剩余任务或者等待事件
 | 
						ProcinstStatusCompleted  ProcinstStatus = 2  // 流程实例已经成功执行完成,没有剩余任务或者等待事件
 | 
				
			||||||
	ProcinstSuspended  ProcinstStatus = -1 // 流程实例被挂起,暂停执行,可能被驳回等待修改重新提交
 | 
						ProcinstStatusSuspended  ProcinstStatus = -1 // 流程实例被挂起,暂停执行,可能被驳回等待修改重新提交
 | 
				
			||||||
	ProcinstTerminated ProcinstStatus = -2 // 流程实例被终止,可能是由于某种原因如被拒绝等导致流程无法正常执行
 | 
						ProcinstStatusTerminated ProcinstStatus = -2 // 流程实例被终止,可能是由于某种原因如被拒绝等导致流程无法正常执行
 | 
				
			||||||
	ProcinstCancelled  ProcinstStatus = -3 // 流程实例被取消,通常是用户手动操作取消了流程的执行
 | 
						ProcinstStatusCancelled  ProcinstStatus = -3 // 流程实例被取消,通常是用户手动操作取消了流程的执行
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var ProcinstStatusEnum = enumx.NewEnum[ProcinstStatus]("流程状态").
 | 
					var ProcinstStatusEnum = enumx.NewEnum[ProcinstStatus]("流程状态").
 | 
				
			||||||
	Add(ProcinstActive, "执行中").
 | 
						Add(ProcinstStatusActive, "执行中").
 | 
				
			||||||
	Add(ProcinstCompleted, "完成").
 | 
						Add(ProcinstStatusCompleted, "完成").
 | 
				
			||||||
	Add(ProcinstSuspended, "挂起").
 | 
						Add(ProcinstStatusSuspended, "挂起").
 | 
				
			||||||
	Add(ProcinstTerminated, "终止").
 | 
						Add(ProcinstStatusTerminated, "终止").
 | 
				
			||||||
	Add(ProcinstCancelled, "取消")
 | 
						Add(ProcinstStatusCancelled, "取消")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ProcinstBizStatus int8
 | 
					type ProcinstBizStatus int8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newProcdefRepo(), ioc.WithComponentName("ProcdefRepo"))
 | 
						ioc.Register(newProcdefRepo(), ioc.WithComponentName("ProcdefRepo"))
 | 
				
			||||||
	ioc.Register(newProcinstRepo(), ioc.WithComponentName("ProcinstRepo"))
 | 
						ioc.Register(newProcinstRepo(), ioc.WithComponentName("ProcinstRepo"))
 | 
				
			||||||
	ioc.Register(newProcinstTaskRepo(), ioc.WithComponentName("ProcinstTaskRepo"))
 | 
						ioc.Register(newProcinstTaskRepo(), ioc.WithComponentName("ProcinstTaskRepo"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/flow/application"
 | 
						"mayfly-go/internal/flow/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/flow/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/flow/router"
 | 
						"mayfly-go/internal/flow/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,10 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/machine/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(machineAppImpl), ioc.WithComponentName("MachineApp"))
 | 
						ioc.Register(new(machineAppImpl), ioc.WithComponentName("MachineApp"))
 | 
				
			||||||
	ioc.Register(new(machineFileAppImpl), ioc.WithComponentName("MachineFileApp"))
 | 
						ioc.Register(new(machineFileAppImpl), ioc.WithComponentName("MachineFileApp"))
 | 
				
			||||||
	ioc.Register(new(machineScriptAppImpl), ioc.WithComponentName("MachineScriptApp"))
 | 
						ioc.Register(new(machineScriptAppImpl), ioc.WithComponentName("MachineScriptApp"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newMachineRepo(), ioc.WithComponentName("MachineRepo"))
 | 
						ioc.Register(newMachineRepo(), ioc.WithComponentName("MachineRepo"))
 | 
				
			||||||
	ioc.Register(newMachineFileRepo(), ioc.WithComponentName("MachineFileRepo"))
 | 
						ioc.Register(newMachineFileRepo(), ioc.WithComponentName("MachineFileRepo"))
 | 
				
			||||||
	ioc.Register(newMachineScriptRepo(), ioc.WithComponentName("MachineScriptRepo"))
 | 
						ioc.Register(newMachineScriptRepo(), ioc.WithComponentName("MachineScriptRepo"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,13 +6,17 @@ import (
 | 
				
			|||||||
	"mayfly-go/internal/common/consts"
 | 
						"mayfly-go/internal/common/consts"
 | 
				
			||||||
	"mayfly-go/internal/machine/application"
 | 
						"mayfly-go/internal/machine/application"
 | 
				
			||||||
	"mayfly-go/internal/machine/domain/entity"
 | 
						"mayfly-go/internal/machine/domain/entity"
 | 
				
			||||||
 | 
						"mayfly-go/internal/machine/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/machine/router"
 | 
						"mayfly-go/internal/machine/router"
 | 
				
			||||||
	"mayfly-go/pkg/eventbus"
 | 
						"mayfly-go/pkg/eventbus"
 | 
				
			||||||
	"mayfly-go/pkg/global"
 | 
						"mayfly-go/pkg/global"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
	initialize.AddInitFunc(Init)
 | 
						initialize.AddInitFunc(Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,12 @@ func checkClientAvailability(interval time.Duration) {
 | 
				
			|||||||
			if cli.Info == nil {
 | 
								if cli.Info == nil {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if cli.sshClient == nil {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if cli.sshClient.Conn == nil {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if _, _, err := cli.sshClient.Conn.SendRequest("ping", true, nil); err != nil {
 | 
								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())
 | 
									logx.Errorf("machine[%s] cache client is not available: %s", cli.Info.Name, err.Error())
 | 
				
			||||||
				DeleteCli(cli.Info.Id)
 | 
									DeleteCli(cli.Info.Id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,9 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/mongo/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(mongoAppImpl), ioc.WithComponentName("MongoApp"))
 | 
						ioc.Register(new(mongoAppImpl), ioc.WithComponentName("MongoApp"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,6 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newMongoRepo(), ioc.WithComponentName("MongoRepo"))
 | 
						ioc.Register(newMongoRepo(), ioc.WithComponentName("MongoRepo"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/mongo/application"
 | 
						"mayfly-go/internal/mongo/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/mongo/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/mongo/router"
 | 
						"mayfly-go/internal/mongo/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,10 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/msg/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(msgAppImpl), ioc.WithComponentName("MsgApp"))
 | 
						ioc.Register(new(msgAppImpl), ioc.WithComponentName("MsgApp"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,6 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newMsgRepo(), ioc.WithComponentName("MsgRepo"))
 | 
						ioc.Register(newMsgRepo(), ioc.WithComponentName("MsgRepo"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/msg/application"
 | 
						"mayfly-go/internal/msg/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/msg/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/msg/router"
 | 
						"mayfly-go/internal/msg/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								server/internal/redis/api/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								server/internal/redis/api/cmd.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -11,16 +11,7 @@ type Redis struct {
 | 
				
			|||||||
	SshTunnelMachineId int      `json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
						SshTunnelMachineId int      `json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
				
			||||||
	TagId              []uint64 `binding:"required" json:"tagId"`
 | 
						TagId              []uint64 `binding:"required" json:"tagId"`
 | 
				
			||||||
	Remark             string   `json:"remark"`
 | 
						Remark             string   `json:"remark"`
 | 
				
			||||||
}
 | 
						FlowProcdefKey     string   `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批)
 | 
				
			||||||
 | 
					 | 
				
			||||||
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"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type KeyInfo struct {
 | 
					type KeyInfo struct {
 | 
				
			||||||
@@ -28,33 +19,6 @@ type KeyInfo struct {
 | 
				
			|||||||
	Timed int64  `json:"timed"`
 | 
						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 {
 | 
					type RedisScanForm struct {
 | 
				
			||||||
	Cursor map[string]uint64 `json:"cursor"`
 | 
						Cursor map[string]uint64 `json:"cursor"`
 | 
				
			||||||
	Match  string            `json:"match"`
 | 
						Match  string            `json:"match"`
 | 
				
			||||||
@@ -68,19 +32,9 @@ type ScanForm struct {
 | 
				
			|||||||
	Count  int64  `json:"count"`
 | 
						Count  int64  `json:"count"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SmemberOption struct {
 | 
					type RunCmdForm struct {
 | 
				
			||||||
	Key    string `json:"key"`
 | 
						Id     uint64 `json:"id"`
 | 
				
			||||||
	Member any    `json:"member"`
 | 
						Db     int    `json:"db"`
 | 
				
			||||||
}
 | 
						Cmd    []any  `json:"cmd"`
 | 
				
			||||||
 | 
						Remark string `json:"remark"`
 | 
				
			||||||
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"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -7,10 +7,8 @@ import (
 | 
				
			|||||||
	"mayfly-go/internal/redis/rdm"
 | 
						"mayfly-go/internal/redis/rdm"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
	"mayfly-go/pkg/req"
 | 
						"mayfly-go/pkg/req"
 | 
				
			||||||
	"mayfly-go/pkg/utils/collx"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/redis/go-redis/v9"
 | 
						"github.com/redis/go-redis/v9"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -133,39 +131,3 @@ func (r *Redis) MemoryUsage(rc *req.Ctx) {
 | 
				
			|||||||
	ri, key := r.checkKeyAndGetRedisConn(rc)
 | 
						ri, key := r.checkKeyAndGetRedisConn(rc)
 | 
				
			||||||
	rc.ResData = ri.GetCmdable().MemoryUsage(context.Background(), key).Val()
 | 
						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())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -15,6 +15,7 @@ type Redis struct {
 | 
				
			|||||||
	Mode               *string    `json:"mode"`
 | 
						Mode               *string    `json:"mode"`
 | 
				
			||||||
	SshTunnelMachineId int        `json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
						SshTunnelMachineId int        `json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
				
			||||||
	Remark             *string    `json:"remark"`
 | 
						Remark             *string    `json:"remark"`
 | 
				
			||||||
 | 
						FlowProcdefKey     string     `json:"flowProcdefKey"`
 | 
				
			||||||
	CreateTime         *time.Time `json:"createTime"`
 | 
						CreateTime         *time.Time `json:"createTime"`
 | 
				
			||||||
	Creator            *string    `json:"creator"`
 | 
						Creator            *string    `json:"creator"`
 | 
				
			||||||
	CreatorId          *int64     `json:"creatorId"`
 | 
						CreatorId          *int64     `json:"creatorId"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,12 +1,13 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/redis/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(redisAppImpl), ioc.WithComponentName("RedisApp"))
 | 
						ioc.Register(new(redisAppImpl), ioc.WithComponentName("RedisApp"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Init() {
 | 
				
			||||||
 | 
						InitRedisFlowHandler()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								server/internal/redis/application/flow.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								server/internal/redis/application/flow.go
									
									
									
									
									
										Normal file
									
								
							@@ -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"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,20 +3,34 @@ package application
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"mayfly-go/internal/common/consts"
 | 
						"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/entity"
 | 
				
			||||||
	"mayfly-go/internal/redis/domain/repository"
 | 
						"mayfly-go/internal/redis/domain/repository"
 | 
				
			||||||
	"mayfly-go/internal/redis/rdm"
 | 
						"mayfly-go/internal/redis/rdm"
 | 
				
			||||||
	tagapp "mayfly-go/internal/tag/application"
 | 
						tagapp "mayfly-go/internal/tag/application"
 | 
				
			||||||
	"mayfly-go/pkg/base"
 | 
						"mayfly-go/pkg/base"
 | 
				
			||||||
	"mayfly-go/pkg/errorx"
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
	"mayfly-go/pkg/model"
 | 
						"mayfly-go/pkg/model"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/utils/jsonx"
 | 
				
			||||||
	"mayfly-go/pkg/utils/stringx"
 | 
						"mayfly-go/pkg/utils/stringx"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"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 {
 | 
					type Redis interface {
 | 
				
			||||||
	base.App[*entity.Redis]
 | 
						base.App[*entity.Redis]
 | 
				
			||||||
 | 
						flowapp.FlowBizHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 分页获取机器脚本信息列表
 | 
						// 分页获取机器脚本信息列表
 | 
				
			||||||
	GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
						GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
				
			||||||
@@ -33,12 +47,16 @@ type Redis interface {
 | 
				
			|||||||
	// id: 数据库实例id
 | 
						// id: 数据库实例id
 | 
				
			||||||
	// db: 库号
 | 
						// db: 库号
 | 
				
			||||||
	GetRedisConn(id uint64, db int) (*rdm.RedisConn, error)
 | 
						GetRedisConn(id uint64, db int) (*rdm.RedisConn, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 执行redis命令
 | 
				
			||||||
 | 
						RunCmd(ctx context.Context, redisConn *rdm.RedisConn, cmdParam *RunCmdParam) (any, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type redisAppImpl struct {
 | 
					type redisAppImpl struct {
 | 
				
			||||||
	base.AppImpl[*entity.Redis, repository.Redis]
 | 
						base.AppImpl[*entity.Redis, repository.Redis]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tagApp tagapp.TagTree `inject:"TagTreeApp"`
 | 
						tagApp      tagapp.TagTree   `inject:"TagTreeApp"`
 | 
				
			||||||
 | 
						procinstApp flowapp.Procinst `inject:"ProcinstApp"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 注入RedisRepo
 | 
					// 注入RedisRepo
 | 
				
			||||||
@@ -96,7 +114,7 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds .
 | 
				
			|||||||
		return errorx.NewBiz("该实例已存在")
 | 
							return errorx.NewBiz("该实例已存在")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// 如果修改了redis实例的库信息,则关闭旧库的连接
 | 
						// 如果修改了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, ",") {
 | 
							for _, dbStr := range strings.Split(oldRedis.Db, ",") {
 | 
				
			||||||
			db, _ := strconv.Atoi(dbStr)
 | 
								db, _ := strconv.Atoi(dbStr)
 | 
				
			||||||
			rdm.CloseConn(re.Id, db)
 | 
								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
 | 
							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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,11 @@
 | 
				
			|||||||
package entity
 | 
					package entity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "mayfly-go/pkg/model"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type RedisQuery struct {
 | 
					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"`
 | 
						SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Codes   []string
 | 
						Codes   []string
 | 
				
			||||||
	TagPath string `form:"tagPath"`
 | 
						TagPath string `form:"tagPath"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ type Redis struct {
 | 
				
			|||||||
	Db                 string `orm:"column(database)" json:"db"`
 | 
						Db                 string `orm:"column(database)" json:"db"`
 | 
				
			||||||
	SshTunnelMachineId int    `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
						SshTunnelMachineId int    `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id
 | 
				
			||||||
	Remark             string
 | 
						Remark             string
 | 
				
			||||||
 | 
						FlowProcdefKey     *string `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Redis) PwdEncrypt() error {
 | 
					func (r *Redis) PwdEncrypt() error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,6 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newRedisRepo(), ioc.WithComponentName("RedisRepo"))
 | 
						ioc.Register(newRedisRepo(), ioc.WithComponentName("RedisRepo"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
					func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
				
			||||||
	qd := gormx.NewQuery(new(entity.Redis)).
 | 
						qd := gormx.NewQuery(new(entity.Redis)).
 | 
				
			||||||
 | 
							Eq("id", condition.Id).
 | 
				
			||||||
		Like("host", condition.Host).
 | 
							Like("host", condition.Host).
 | 
				
			||||||
		In("code", condition.Codes)
 | 
							In("code", condition.Codes)
 | 
				
			||||||
	return gormx.PageQuery(qd, pageParam, toEntity)
 | 
						return gormx.PageQuery(qd, pageParam, toEntity)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,16 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/redis/application"
 | 
						"mayfly-go/internal/redis/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/redis/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/redis/router"
 | 
						"mayfly-go/internal/redis/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
 | 
						initialize.AddInitFunc(application.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								server/internal/redis/rdm/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								server/internal/redis/rdm/cmd.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,7 @@ package rdm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/errorx"
 | 
				
			||||||
	"mayfly-go/pkg/logx"
 | 
						"mayfly-go/pkg/logx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/redis/go-redis/v9"
 | 
						"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()
 | 
						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() {
 | 
					func (r *RedisConn) Close() {
 | 
				
			||||||
	mode := r.Info.Mode
 | 
						mode := r.Info.Mode
 | 
				
			||||||
	if mode == StandaloneMode || mode == SentinelMode {
 | 
						if mode == StandaloneMode || mode == SentinelMode {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,8 @@ type RedisInfo struct {
 | 
				
			|||||||
	Name               string   `json:"-"`
 | 
						Name               string   `json:"-"`
 | 
				
			||||||
	TagPath            []string `json:"tagPath"`
 | 
						TagPath            []string `json:"tagPath"`
 | 
				
			||||||
	SshTunnelMachineId int      `json:"-"`
 | 
						SshTunnelMachineId int      `json:"-"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FlowProcdefKey string // 工单流程定义key
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *RedisInfo) Conn() (*RedisConn, error) {
 | 
					func (r *RedisInfo) Conn() (*RedisConn, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,11 +18,6 @@ func InitRedisRouter(router *gin.RouterGroup) {
 | 
				
			|||||||
	dashbord := new(api.Dashbord)
 | 
						dashbord := new(api.Dashbord)
 | 
				
			||||||
	biz.ErrIsNil(ioc.Inject(dashbord))
 | 
						biz.ErrIsNil(ioc.Inject(dashbord))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 保存数据权限
 | 
					 | 
				
			||||||
	saveDataP := req.NewPermission("redis:data:save")
 | 
					 | 
				
			||||||
	// 删除数据权限
 | 
					 | 
				
			||||||
	deleteDataP := req.NewPermission("redis:data:del")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	reqs := [...]*req.Conf{
 | 
						reqs := [...]*req.Conf{
 | 
				
			||||||
		req.NewGet("dashbord", dashbord.Dashbord),
 | 
							req.NewGet("dashbord", dashbord.Dashbord),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,6 +36,8 @@ func InitRedisRouter(router *gin.RouterGroup) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		req.NewGet(":id/cluster-info", rs.ClusterInfo),
 | 
							req.NewGet(":id/cluster-info", rs.ClusterInfo),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							req.NewPost(":id/:db/run-cmd", rs.RunCmd).Log(req.NewLogSave("redis-runCmd")),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 获取指定redis keys
 | 
							// 获取指定redis keys
 | 
				
			||||||
		req.NewPost(":id/:db/scan", rs.ScanKeys),
 | 
							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-ttl", rs.TtlKey),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		req.NewGet(":id/:db/key-memuse", rs.MemoryUsage),
 | 
							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[:])
 | 
						req.BatchSetGroup(redis, reqs[:])
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/utils/collx"
 | 
						"mayfly-go/pkg/utils/collx"
 | 
				
			||||||
	"mayfly-go/pkg/utils/conv"
 | 
						"mayfly-go/pkg/utils/conv"
 | 
				
			||||||
	"mayfly-go/pkg/utils/cryptox"
 | 
						"mayfly-go/pkg/utils/cryptox"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/utils/structx"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -143,6 +144,18 @@ func (a *Account) SimpleAccounts(rc *req.Ctx) {
 | 
				
			|||||||
	rc.ResData = res
 | 
						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
 | 
					// @router /accounts
 | 
				
			||||||
func (a *Account) SaveAccount(rc *req.Ctx) {
 | 
					func (a *Account) SaveAccount(rc *req.Ctx) {
 | 
				
			||||||
	form := &form.AccountCreateForm{}
 | 
						form := &form.AccountCreateForm{}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,8 @@ type SimpleAccountVO struct {
 | 
				
			|||||||
	Id       uint64 `json:"id"`
 | 
						Id       uint64 `json:"id"`
 | 
				
			||||||
	Name     string `json:"name"`
 | 
						Name     string `json:"name"`
 | 
				
			||||||
	Username string `json:"username"`
 | 
						Username string `json:"username"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Roles []*AccountRoleVO `json:"roles" gorm:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 账号角色信息
 | 
					// 账号角色信息
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,10 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/sys/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(accountAppImpl), ioc.WithComponentName("AccountApp"))
 | 
						ioc.Register(new(accountAppImpl), ioc.WithComponentName("AccountApp"))
 | 
				
			||||||
	ioc.Register(new(roleAppImpl), ioc.WithComponentName("RoleApp"))
 | 
						ioc.Register(new(roleAppImpl), ioc.WithComponentName("RoleApp"))
 | 
				
			||||||
	ioc.Register(new(configAppImpl), ioc.WithComponentName("ConfigApp"))
 | 
						ioc.Register(new(configAppImpl), ioc.WithComponentName("ConfigApp"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newAccountRepo(), ioc.WithComponentName("AccountRepo"))
 | 
						ioc.Register(newAccountRepo(), ioc.WithComponentName("AccountRepo"))
 | 
				
			||||||
	ioc.Register(newRoleRepo(), ioc.WithComponentName("RoleRepo"))
 | 
						ioc.Register(newRoleRepo(), ioc.WithComponentName("RoleRepo"))
 | 
				
			||||||
	ioc.Register(newAccountRoleRepo(), ioc.WithComponentName("AccountRoleRepo"))
 | 
						ioc.Register(newAccountRoleRepo(), ioc.WithComponentName("AccountRoleRepo"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/sys/application"
 | 
						"mayfly-go/internal/sys/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/sys/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/sys/router"
 | 
						"mayfly-go/internal/sys/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,9 @@ func InitAccountRouter(router *gin.RouterGroup) {
 | 
				
			|||||||
		// 获取用户列表信息(只包含最基础信息)
 | 
							// 获取用户列表信息(只包含最基础信息)
 | 
				
			||||||
		req.NewGet("/simple", a.SimpleAccounts),
 | 
							req.NewGet("/simple", a.SimpleAccounts),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 根据账号id获取账号基础信息
 | 
				
			||||||
 | 
							req.NewGet("/:id", a.AccountDetail),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		req.NewPost("", a.SaveAccount).Log(req.NewLogSave("保存账号信息")).RequiredPermission(addAccountPermission),
 | 
							req.NewPost("", a.SaveAccount).Log(req.NewLogSave("保存账号信息")).RequiredPermission(addAccountPermission),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		req.NewPut("change-status/:id/:status", a.ChangeStatus).Log(req.NewLogSave("修改账号状态")).RequiredPermission(addAccountPermission),
 | 
							req.NewPut("change-status/:id/:status", a.ChangeStatus).Log(req.NewLogSave("修改账号状态")).RequiredPermission(addAccountPermission),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,10 @@
 | 
				
			|||||||
package application
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/internal/tag/infrastructure/persistence"
 | 
					 | 
				
			||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitIoc() {
 | 
					func InitIoc() {
 | 
				
			||||||
	persistence.Init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ioc.Register(new(tagTreeAppImpl), ioc.WithComponentName("TagTreeApp"))
 | 
						ioc.Register(new(tagTreeAppImpl), ioc.WithComponentName("TagTreeApp"))
 | 
				
			||||||
	ioc.Register(new(teamAppImpl), ioc.WithComponentName("TeamApp"))
 | 
						ioc.Register(new(teamAppImpl), ioc.WithComponentName("TeamApp"))
 | 
				
			||||||
	ioc.Register(new(tagResourceAppImpl), ioc.WithComponentName("TagResourceApp"))
 | 
						ioc.Register(new(tagResourceAppImpl), ioc.WithComponentName("TagResourceApp"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"mayfly-go/pkg/ioc"
 | 
						"mayfly-go/pkg/ioc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func InitIoc() {
 | 
				
			||||||
	ioc.Register(newTagTreeRepo(), ioc.WithComponentName("TagTreeRepo"))
 | 
						ioc.Register(newTagTreeRepo(), ioc.WithComponentName("TagTreeRepo"))
 | 
				
			||||||
	ioc.Register(newTagTreeTeamRepo(), ioc.WithComponentName("TagTreeTeamRepo"))
 | 
						ioc.Register(newTagTreeTeamRepo(), ioc.WithComponentName("TagTreeTeamRepo"))
 | 
				
			||||||
	ioc.Register(newTagResourceRepo(), ioc.WithComponentName("TagResourceRepo"))
 | 
						ioc.Register(newTagResourceRepo(), ioc.WithComponentName("TagResourceRepo"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,14 @@ package init
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/initialize"
 | 
						"mayfly-go/initialize"
 | 
				
			||||||
	"mayfly-go/internal/tag/application"
 | 
						"mayfly-go/internal/tag/application"
 | 
				
			||||||
 | 
						"mayfly-go/internal/tag/infrastructure/persistence"
 | 
				
			||||||
	"mayfly-go/internal/tag/router"
 | 
						"mayfly-go/internal/tag/router"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	initialize.AddInitIocFunc(application.InitIoc)
 | 
						initialize.AddInitIocFunc(func() {
 | 
				
			||||||
 | 
							persistence.InitIoc()
 | 
				
			||||||
 | 
							application.InitIoc()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	initialize.AddInitRouterFunc(router.Init)
 | 
						initialize.AddInitRouterFunc(router.Init)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -617,6 +617,7 @@ CREATE TABLE IF NOT EXISTS "t_redis" (
 | 
				
			|||||||
  "mode" text(32),
 | 
					  "mode" text(32),
 | 
				
			||||||
  "ssh_tunnel_machine_id" integer(20),
 | 
					  "ssh_tunnel_machine_id" integer(20),
 | 
				
			||||||
  "remark" text(125),
 | 
					  "remark" text(125),
 | 
				
			||||||
 | 
					  "flow_procdef_key" text(64),
 | 
				
			||||||
  "creator" text(32),
 | 
					  "creator" text(32),
 | 
				
			||||||
  "creator_id" integer(32),
 | 
					  "creator_id" integer(32),
 | 
				
			||||||
  "create_time"  datetime,
 | 
					  "create_time"  datetime,
 | 
				
			||||||
@@ -1024,6 +1025,7 @@ CREATE TABLE "t_flow_procinst" (
 | 
				
			|||||||
  "status" tinyint DEFAULT NULL ,
 | 
					  "status" tinyint DEFAULT NULL ,
 | 
				
			||||||
  "biz_type" text(64) NOT NULL ,
 | 
					  "biz_type" text(64) NOT NULL ,
 | 
				
			||||||
  "biz_key" text(64)  NOT NULL ,
 | 
					  "biz_key" text(64)  NOT NULL ,
 | 
				
			||||||
 | 
					  "biz_form" text(5000) DEFAULT NULL ,
 | 
				
			||||||
  "biz_status" tinyint DEFAULT NULL ,
 | 
					  "biz_status" tinyint DEFAULT NULL ,
 | 
				
			||||||
  "biz_handle_res" text(100) DEFAULT NULL ,
 | 
					  "biz_handle_res" text(100) DEFAULT NULL ,
 | 
				
			||||||
  "remark" text(191)  DEFAULT NULL,
 | 
					  "remark" text(191)  DEFAULT NULL,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -531,6 +531,7 @@ CREATE TABLE `t_redis` (
 | 
				
			|||||||
  `mode` varchar(32) DEFAULT NULL,
 | 
					  `mode` varchar(32) DEFAULT NULL,
 | 
				
			||||||
  `ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
 | 
					  `ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
 | 
				
			||||||
  `remark` varchar(125) DEFAULT NULL,
 | 
					  `remark` varchar(125) DEFAULT NULL,
 | 
				
			||||||
 | 
					  `flow_procdef_key` varchar(100) DEFAULT NULL COMMENT '工单流程定义key',
 | 
				
			||||||
  `creator` varchar(32) DEFAULT NULL,
 | 
					  `creator` varchar(32) DEFAULT NULL,
 | 
				
			||||||
  `creator_id` bigint(32) DEFAULT NULL,
 | 
					  `creator_id` bigint(32) DEFAULT NULL,
 | 
				
			||||||
  `create_time` datetime DEFAULT NULL,
 | 
					  `create_time` datetime DEFAULT NULL,
 | 
				
			||||||
@@ -1045,8 +1046,9 @@ CREATE TABLE `t_flow_procinst` (
 | 
				
			|||||||
  `status` tinyint DEFAULT NULL COMMENT '状态',
 | 
					  `status` tinyint DEFAULT NULL COMMENT '状态',
 | 
				
			||||||
  `biz_type` varchar(64) COLLATE utf8mb4_bin NOT 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_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_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,
 | 
					  `remark` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
 | 
				
			||||||
  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
 | 
					  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
 | 
				
			||||||
  `duration` bigint DEFAULT NULL COMMENT '流程持续时间(开始到结束)',
 | 
					  `duration` bigint DEFAULT NULL COMMENT '流程持续时间(开始到结束)',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,8 +35,9 @@ CREATE TABLE `t_flow_procinst` (
 | 
				
			|||||||
  `status` tinyint DEFAULT NULL COMMENT '状态',
 | 
					  `status` tinyint DEFAULT NULL COMMENT '状态',
 | 
				
			||||||
  `biz_type` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '关联业务类型',
 | 
					  `biz_type` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '关联业务类型',
 | 
				
			||||||
  `biz_key` varchar(64)  NOT NULL COMMENT '关联业务key',
 | 
					  `biz_key` varchar(64)  NOT NULL COMMENT '关联业务key',
 | 
				
			||||||
 | 
					  `biz_form` text  DEFAULT NULL COMMENT '业务form',
 | 
				
			||||||
  `biz_status` tinyint DEFAULT NULL COMMENT '业务状态',
 | 
					  `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,
 | 
					  `remark` varchar(191)  DEFAULT NULL,
 | 
				
			||||||
  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
 | 
					  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
 | 
				
			||||||
  `duration` bigint 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_sql_exec ADD res varchar(1000) NULL COMMENT '执行结果';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALTER TABLE t_db ADD flow_procdef_key varchar(64) NULL COMMENT '审批流-流程定义key(有值则说明关键操作需要进行审批执行)';
 | 
					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;
 | 
					UPDATE t_db_sql_exec SET status = 2;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user