diff --git a/frontend/package.json b/frontend/package.json
index f6659094..d05fedcd 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,8 +11,8 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
- "@logicflow/core": "^2.0.15",
- "@logicflow/extension": "^2.0.20",
+ "@logicflow/core": "^2.0.16",
+ "@logicflow/extension": "^2.0.21",
"@vueuse/core": "^13.3.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-search": "^0.15.0",
@@ -24,7 +24,7 @@
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"echarts": "^5.6.0",
- "element-plus": "^2.10.1",
+ "element-plus": "^2.10.2",
"js-base64": "^3.7.7",
"jsencrypt": "^3.3.2",
"mitt": "^3.0.1",
@@ -45,7 +45,7 @@
"vuedraggable": "^4.1.0"
},
"devDependencies": {
- "@tailwindcss/vite": "^4.1.6",
+ "@tailwindcss/vite": "^4.1.9",
"@types/crypto-js": "^4.2.2",
"@types/node": "^18.14.0",
"@types/nprogress": "^0.2.0",
@@ -58,13 +58,13 @@
"code-inspector-plugin": "^0.20.9",
"dotenv": "^16.3.1",
"eslint": "^9.27.0",
- "eslint-plugin-vue": "^10.1.0",
+ "eslint-plugin-vue": "^10.2.0",
"postcss": "^8.5.4",
"prettier": "^3.5.3",
- "sass": "^1.89.1",
- "tailwindcss": "^4.1.8",
+ "sass": "^1.89.2",
+ "tailwindcss": "^4.1.9",
"typescript": "^5.8.2",
- "vite": "^6.3.5",
+ "vite": "npm:rolldown-vite@latest",
"vite-plugin-progress": "0.0.7",
"vue-eslint-parser": "^10.1.3"
},
diff --git a/frontend/src/common/config.ts b/frontend/src/common/config.ts
index 80155add..7af327e3 100644
--- a/frontend/src/common/config.ts
+++ b/frontend/src/common/config.ts
@@ -15,7 +15,7 @@ const config = {
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
// 系统版本
- version: 'v1.10.0',
+ version: 'v1.10.1',
};
export default config;
diff --git a/frontend/src/common/utils/export.ts b/frontend/src/common/utils/export.ts
index c1a87d27..9a4332fc 100644
--- a/frontend/src/common/utils/export.ts
+++ b/frontend/src/common/utils/export.ts
@@ -42,4 +42,5 @@ export function exportFile(filename: string, content: string) {
link.setAttribute('download', `${filename}`);
document.body.appendChild(link);
link.click();
+ document.body.removeChild(link); // 下载完成后移除元素
}
diff --git a/frontend/src/components/enumtag/EnumTag.vue b/frontend/src/components/enumtag/EnumTag.vue
index 677d0385..5b65e06a 100644
--- a/frontend/src/components/enumtag/EnumTag.vue
+++ b/frontend/src/components/enumtag/EnumTag.vue
@@ -12,8 +12,9 @@ const props = defineProps({
required: true,
},
value: {
- type: [Object, String, Number],
+ type: [Object, String, Number, null],
required: true,
+ default: () => null,
},
});
@@ -40,7 +41,7 @@ onMounted(() => {
});
const convert = (value: any) => {
- const enumValue = EnumValue.getEnumByValue(props.enums, value) as any;
+ const enumValue = EnumValue.getEnumByValue(props.enums, value);
if (!enumValue) {
state.enumLabel = '-';
state.type = 'danger';
@@ -50,8 +51,8 @@ const convert = (value: any) => {
state.enumLabel = enumValue?.label || '';
if (enumValue.tag) {
- state.color = enumValue.tag.color;
- state.type = enumValue.tag.type;
+ state.color = enumValue.tag.color || '';
+ state.type = enumValue.tag.type || defaultType;
} else {
state.type = defaultType;
}
diff --git a/frontend/src/components/pagetable/PageTable.vue b/frontend/src/components/pagetable/PageTable.vue
index 3c50ffa2..d4cc660b 100644
--- a/frontend/src/components/pagetable/PageTable.vue
+++ b/frontend/src/components/pagetable/PageTable.vue
@@ -68,7 +68,7 @@
trigger="click"
>
-
+
diff --git a/frontend/src/components/pagetable/index.ts b/frontend/src/components/pagetable/index.ts
index e5c4ce65..ab213b84 100644
--- a/frontend/src/components/pagetable/index.ts
+++ b/frontend/src/components/pagetable/index.ts
@@ -71,9 +71,9 @@ export class TableColumn {
formatFunc: Function;
/**
- * 是否显示该列
+ * 是否显示该列,1显示 0不显示
*/
- show: boolean = true;
+ show: number = 1;
/**
* 是否展示美化按钮(主要用于美化json文本等)
diff --git a/frontend/src/i18n/en/machine.ts b/frontend/src/i18n/en/machine.ts
index 5542b30c..9c8f9d1d 100644
--- a/frontend/src/i18n/en/machine.ts
+++ b/frontend/src/i18n/en/machine.ts
@@ -87,6 +87,8 @@ export default {
scriptResultEnumRealTime: 'Real-time',
scriptTypeEnumPrivate: 'Private',
scriptTypeEnumPublic: 'Public',
+ category: 'Category',
+ categoryTips: 'support input new category and selection',
// security
cmdConfig: 'Command Config',
diff --git a/frontend/src/i18n/en/system.ts b/frontend/src/i18n/en/system.ts
index 4ce63d77..188f2a38 100644
--- a/frontend/src/i18n/en/system.ts
+++ b/frontend/src/i18n/en/system.ts
@@ -27,7 +27,6 @@ export default {
menuCodePlaceholder: `A menu that does not begin with '/' will automatically concatenate the parent menu path`,
routerNameTips:
'For component caching to work, the key for route.ts in the frontend module should match the vue component name, such as ResourceList',
- componentPathTips: 'Access path components, such as: ` system/resource/ResourceList `, default in ` views ` directory',
isCacheTips: `If yes is selected, it will be 'keepalive' cached (reentering the page without refreshing the page and requesting data again), and needs the route name to match the vue component name`,
isHideTips:
'Select Hide and the route will not appear in the menu bar, but it will still be accessible. Disabled will not be able to access and operate',
diff --git a/frontend/src/i18n/zh-cn/machine.ts b/frontend/src/i18n/zh-cn/machine.ts
index 0b698ddb..eedb8daf 100644
--- a/frontend/src/i18n/zh-cn/machine.ts
+++ b/frontend/src/i18n/zh-cn/machine.ts
@@ -88,6 +88,8 @@ export default {
scriptResultEnumRealTime: '实时交互',
scriptTypeEnumPrivate: '私有',
scriptTypeEnumPublic: '公共',
+ category: '分类',
+ categoryTips: '支持输入新分类并选择',
// security
cmdConfig: '命令配置',
diff --git a/frontend/src/i18n/zh-cn/system.ts b/frontend/src/i18n/zh-cn/system.ts
index 66575fa9..0f33ca4f 100644
--- a/frontend/src/i18n/zh-cn/system.ts
+++ b/frontend/src/i18n/zh-cn/system.ts
@@ -26,7 +26,6 @@ export default {
menuCodeTips: `菜单类型则为访问路径(若菜单路径不以'/'开头则访问地址会自动拼接父菜单路径)、否则为资源唯一编码`,
menuCodePlaceholder: `菜单不以'/'开头则自动拼接父菜单路径`,
routerNameTips: '前端模块下route.ts中对应的key,与vue的组件名一致才可使组件缓存生效,如ResourceList',
- componentPathTips: '访问的组件路径,如:`system/resource/ResourceList`,默认在`views`目录下',
isCacheTips: '选择是则会被`keep-alive`缓存(重新进入页面不会刷新页面及重新请求数据),需要路由名与vue的组件名一致',
isHideTips: '选择隐藏则路由将不会出现在菜单栏中,但仍然可以访问。禁用则不可访问与操作',
externalLinkTips: '内嵌: 以iframe展示、外链: 新标签打开',
diff --git a/frontend/src/layout/navBars/breadcrumb/breadcrumb.vue b/frontend/src/layout/navBars/breadcrumb/breadcrumb.vue
index 7129eb12..2674758c 100644
--- a/frontend/src/layout/navBars/breadcrumb/breadcrumb.vue
+++ b/frontend/src/layout/navBars/breadcrumb/breadcrumb.vue
@@ -2,7 +2,7 @@
-
+
diff --git a/frontend/src/router/dynamicRouter.ts b/frontend/src/router/dynamicRouter.ts
index 6f356783..d1ead1d0 100644
--- a/frontend/src/router/dynamicRouter.ts
+++ b/frontend/src/router/dynamicRouter.ts
@@ -83,9 +83,8 @@ type RouterConvCallbackFunc = (router: any) => void;
* @param name ==> title,路由标题 相当于route.meta.title
*
* @param meta ==> 路由菜单元信息
- * @param meta.routeName ==> route.name -> 路由 name (对应页面组件 name, 可用作 KeepAlive 缓存标识 && 按钮权限筛选)
+ * @param meta.routeName ==> route.name -> 路由 name (对应页面组件 name, 可用作 KeepAlive 缓存标识 && 按钮权限筛选) -> 对应模块下route.ts字段key
* @param meta.redirect ==> route.redirect -> 路由重定向地址
- * @param meta.component ==> 文件路径
* @param meta.icon ==> 菜单和面包屑对应的图标
* @param meta.isHide ==> 是否在菜单中隐藏 (通常列表详情页需要隐藏)
* @param meta.isFull ==> 菜单是否全屏 (示例:数据大屏页面)
diff --git a/frontend/src/views/flow/ProcinstDetail.vue b/frontend/src/views/flow/ProcinstDetail.vue
index bb285e49..6818dcb2 100755
--- a/frontend/src/views/flow/ProcinstDetail.vue
+++ b/frontend/src/views/flow/ProcinstDetail.vue
@@ -21,7 +21,7 @@
-
+
diff --git a/frontend/src/views/flow/components/flowdesign/node/usertask/PropSetting.vue b/frontend/src/views/flow/components/flowdesign/node/usertask/PropSetting.vue
index 4e1efcc4..a29cc401 100644
--- a/frontend/src/views/flow/components/flowdesign/node/usertask/PropSetting.vue
+++ b/frontend/src/views/flow/components/flowdesign/node/usertask/PropSetting.vue
@@ -10,7 +10,7 @@
-
+
diff --git a/frontend/src/views/ops/component/ResourceAuthCert.vue b/frontend/src/views/ops/component/ResourceAuthCert.vue
index 88f13d79..c3b9d6dd 100644
--- a/frontend/src/views/ops/component/ResourceAuthCert.vue
+++ b/frontend/src/views/ops/component/ResourceAuthCert.vue
@@ -19,6 +19,7 @@ const props = defineProps({
authCerts: {
type: [Array],
required: true,
+ default: () => [],
},
});
diff --git a/frontend/src/views/ops/component/ResourceTags.vue b/frontend/src/views/ops/component/ResourceTags.vue
index 2cf8d879..6455cb5b 100644
--- a/frontend/src/views/ops/component/ResourceTags.vue
+++ b/frontend/src/views/ops/component/ResourceTags.vue
@@ -26,6 +26,7 @@ const props = defineProps({
tags: {
type: [Array],
required: true,
+ default: () => [],
},
});
diff --git a/frontend/src/views/ops/component/TagTree.vue b/frontend/src/views/ops/component/TagTree.vue
index eae88641..bb7a4eb6 100644
--- a/frontend/src/views/ops/component/TagTree.vue
+++ b/frontend/src/views/ops/component/TagTree.vue
@@ -19,10 +19,9 @@
:default-expanded-keys="props.defaultExpandedKeys"
>
-
@@ -44,7 +43,7 @@
-
+
@@ -153,7 +152,16 @@ const loadNode = async (node: any, resolve: (data: any) => void, reject: () => v
return resolve(nodes);
};
-const treeNodeClick = async (data: any) => {
+let lastNodeClickTime = 0;
+
+const treeNodeClick = async (data: any, node: any) => {
+ const currentClickNodeTime = Date.now();
+ if (currentClickNodeTime - lastNodeClickTime < 300) {
+ treeNodeDblclick(data, node);
+ return;
+ }
+ lastNodeClickTime = currentClickNodeTime;
+
if (!data.disabled && !data.type.nodeDblclickFunc && data.type.nodeClickFunc) {
emit('nodeClick', data);
await data.type.nodeClickFunc(data);
@@ -170,7 +178,6 @@ const treeNodeDblclick = (data: any, node: any) => {
node.expand();
}
- // emit('nodeDblick', data);
if (!data.disabled && data.type.nodeDblclickFunc) {
data.type.nodeDblclickFunc(data);
}
diff --git a/frontend/src/views/ops/db/DbEdit.vue b/frontend/src/views/ops/db/DbEdit.vue
index bb79e18a..4a2235e4 100644
--- a/frontend/src/views/ops/db/DbEdit.vue
+++ b/frontend/src/views/ops/db/DbEdit.vue
@@ -89,7 +89,7 @@ import { Rules } from '@/common/rule';
const props = defineProps({
instance: {
- type: [Boolean, Object],
+ type: [Boolean, Object, null],
},
db: {
type: [Boolean, Object],
diff --git a/frontend/src/views/ops/db/DbList.vue b/frontend/src/views/ops/db/DbList.vue
index ccad0fa0..f51e2d4b 100644
--- a/frontend/src/views/ops/db/DbList.vue
+++ b/frontend/src/views/ops/db/DbList.vue
@@ -365,7 +365,7 @@ const editDb = (data: any) => {
state.dbEditDialog.data = { ...data };
} else {
state.dbEditDialog.data = {
- instanceId: props.instance.id,
+ instanceId: props.instance?.id,
};
}
state.dbEditDialog.title = data ? useI18nEditTitle('db.db') : useI18nCreateTitle('db.db');
@@ -373,7 +373,7 @@ const editDb = (data: any) => {
};
const confirmEditDb = async (db: any) => {
- db.instanceId = props.instance.id;
+ db.instanceId = props.instance?.id;
await dbApi.saveDb.request(db);
useI18nSaveSuccessMsg();
search();
diff --git a/frontend/src/views/ops/db/InstanceList.vue b/frontend/src/views/ops/db/InstanceList.vue
index 3d6fff79..f9158898 100644
--- a/frontend/src/views/ops/db/InstanceList.vue
+++ b/frontend/src/views/ops/db/InstanceList.vue
@@ -155,7 +155,7 @@ const state = reactive({
},
dbEditDialog: {
visible: false,
- instance: null as any,
+ instance: {},
title: '',
},
});
diff --git a/frontend/src/views/ops/machine/MachineEdit.vue b/frontend/src/views/ops/machine/MachineEdit.vue
index f13acab6..28ba09c7 100644
--- a/frontend/src/views/ops/machine/MachineEdit.vue
+++ b/frontend/src/views/ops/machine/MachineEdit.vue
@@ -61,10 +61,8 @@
-
- {{ $t('common.cancel') }}
- {{ $t('common.confirm') }}
-
+ {{ $t('common.cancel') }}
+ {{ $t('common.confirm') }}
diff --git a/frontend/src/views/ops/machine/ScriptEdit.vue b/frontend/src/views/ops/machine/ScriptEdit.vue
index 1ec8ed80..5f6969f3 100644
--- a/frontend/src/views/ops/machine/ScriptEdit.vue
+++ b/frontend/src/views/ops/machine/ScriptEdit.vue
@@ -1,15 +1,20 @@
-
-
+
+
+
+
+
@@ -22,6 +27,12 @@
+
+
+
+
+
+
@@ -43,14 +54,12 @@
-
+ {{ $t('common.cancel') }}
+
+ {{ $t('common.save') }}
+
-
+
@@ -64,6 +73,7 @@ import SvgIcon from '@/components/svgIcon/index.vue';
import EnumSelect from '@/components/enumselect/EnumSelect.vue';
import { useI18nFormValidate, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
+import DrawerHeader from '@/components/drawer-header/DrawerHeader.vue';
const props = defineProps({
data: {
@@ -93,6 +103,7 @@ const rules = {
const { isCommon, machineId } = toRefs(props);
const scriptForm: any = ref(null);
+const categorys = ref([]);
const state = reactive({
params: [] as any,
@@ -104,6 +115,7 @@ const state = reactive({
script: '',
params: '',
type: null,
+ category: '',
},
btnLoading: false,
});
@@ -114,6 +126,9 @@ watch(props, (newValue: any) => {
if (!dialogVisible.value) {
return;
}
+ machineApi.scriptCategorys.request().then((res: any) => {
+ categorys.value = res;
+ });
if (newValue.data) {
state.form = { ...newValue.data };
if (state.form.params) {
@@ -125,7 +140,7 @@ watch(props, (newValue: any) => {
}
});
-const btnOk = async () => {
+const onConfirm = async () => {
state.form.machineId = isCommon.value ? 9999999 : (machineId?.value as any);
await useI18nFormValidate(scriptForm);
if (state.params) {
@@ -134,11 +149,11 @@ const btnOk = async () => {
machineApi.saveScript.request(state.form).then(() => {
useI18nSaveSuccessMsg();
emit('submitSuccess');
- cancel();
+ onCancel();
});
};
-const cancel = () => {
+const onCancel = () => {
dialogVisible.value = false;
emit('cancel');
state.params = [];
diff --git a/frontend/src/views/ops/machine/ScriptManage.vue b/frontend/src/views/ops/machine/ScriptManage.vue
index 0f11fc84..d09f6c20 100644
--- a/frontend/src/views/ops/machine/ScriptManage.vue
+++ b/frontend/src/views/ops/machine/ScriptManage.vue
@@ -99,6 +99,7 @@ import { DynamicFormDialog } from '@/components/dynamic-form';
import { SearchItem } from '@/components/SearchForm';
import { useI18n } from 'vue-i18n';
import { useI18nCreateTitle, useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nEditTitle } from '@/hooks/useI18n';
+import { OptionsApi } from '@/components/SearchForm/index';
const { t } = useI18n();
@@ -117,11 +118,24 @@ const pageTableRef: Ref = ref(null);
const state = reactive({
selectionData: [],
- searchItems: [SearchItem.select('type', 'common.type').withEnum(ScriptTypeEnum)],
+ searchItems: [
+ SearchItem.select('type', 'common.type').withEnum(ScriptTypeEnum),
+ SearchItem.select('category', 'machine.category').withOptionsApi(
+ OptionsApi.new(machineApi.scriptCategorys, {}).withConvertFn((res) => {
+ return res.map((x: any) => {
+ return {
+ label: x,
+ value: x,
+ };
+ });
+ })
+ ),
+ ],
columns: [
TableColumn.new('name', 'common.name'),
TableColumn.new('description', 'common.remark'),
TableColumn.new('type', 'common.type').typeTag(ScriptResultEnum),
+ TableColumn.new('category', 'machine.category'),
TableColumn.new('action', 'common.operation').isSlot().setMinWidth(140).alignCenter(),
],
query: {
diff --git a/frontend/src/views/ops/machine/api.ts b/frontend/src/views/ops/machine/api.ts
index 4fd7e626..cc51f146 100644
--- a/frontend/src/views/ops/machine/api.ts
+++ b/frontend/src/views/ops/machine/api.ts
@@ -23,6 +23,7 @@ export const machineApi = {
// 删除机器
del: Api.newDelete('/machines/{id}'),
scripts: Api.newGet('/machines/{machineId}/scripts'),
+ scriptCategorys: Api.newGet('/machines/scripts/categorys'),
runScript: Api.newGet('/machines/scripts/{scriptId}/{ac}/run'),
saveScript: Api.newPost('/machines/{machineId}/scripts'),
deleteScript: Api.newDelete('/machines/{machineId}/scripts/{scriptId}'),
diff --git a/frontend/src/views/ops/tag/TagTreeList.vue b/frontend/src/views/ops/tag/TagTreeList.vue
index 1e9aa4d5..c7d76891 100644
--- a/frontend/src/views/ops/tag/TagTreeList.vue
+++ b/frontend/src/views/ops/tag/TagTreeList.vue
@@ -117,6 +117,7 @@
-
+
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 8abed7b4..d6accbf1 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -58,11 +58,21 @@ const viteConfig: UserConfig = {
entryFileNames: `assets/[name]-[hash].js`,
chunkFileNames: `assets/[name]-[hash].js`,
assetFileNames: `assets/[name]-[hash].[ext]`,
- compact: true,
- manualChunks: {
- vue: ['vue', 'vue-router', 'pinia'],
- echarts: ['echarts'],
- monaco: ['monaco-editor'],
+ advancedChunks: {
+ groups: [
+ {
+ name: 'vue',
+ test: /(vue|vue-router|pinia)/i,
+ },
+ {
+ name: 'echarts',
+ test: /(echarts)/i,
+ },
+ {
+ name: 'monaco',
+ test: /(monaco-editor)/i,
+ },
+ ],
},
},
},
diff --git a/server/internal/db/application/db.go b/server/internal/db/application/db.go
index 8df76dd4..6f020da0 100644
--- a/server/internal/db/application/db.go
+++ b/server/internal/db/application/db.go
@@ -68,7 +68,7 @@ func (d *dbAppImpl) GetPageList(condition *entity.DbQuery, orderBy ...string) (*
func (d *dbAppImpl) SaveDb(ctx context.Context, dbEntity *entity.Db) error {
// 查找是否存在
- oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId}
+ oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId, AuthCertName: dbEntity.AuthCertName}
authCert, err := d.resourceAuthCertApp.GetAuthCert(dbEntity.AuthCertName)
if err != nil {
diff --git a/server/internal/machine/api/form/form.go b/server/internal/machine/api/form/form.go
index 688b6b32..a194ec2e 100644
--- a/server/internal/machine/api/form/form.go
+++ b/server/internal/machine/api/form/form.go
@@ -32,6 +32,7 @@ type MachineScriptForm struct {
Name string `json:"name" binding:"required"`
MachineId uint64 `json:"machineId" binding:"required"`
Type int `json:"type" binding:"required"`
+ Category string `json:"category"`
Description string `json:"description" binding:"required"`
Params string `json:"params"`
Script string `json:"script" binding:"required"`
diff --git a/server/internal/machine/api/machine_script.go b/server/internal/machine/api/machine_script.go
index aad72589..2a328559 100644
--- a/server/internal/machine/api/machine_script.go
+++ b/server/internal/machine/api/machine_script.go
@@ -28,6 +28,8 @@ func (ms *MachineScript) ReqConfs() *req.Confs {
// 获取指定机器脚本列表
req.NewGet(":machineId/scripts", ms.MachineScripts),
+ req.NewGet("/scripts/categorys", ms.MachineScriptCategorys),
+
req.NewPost(":machineId/scripts", ms.SaveMachineScript).Log(req.NewLogSave("机器-保存脚本")).RequiredPermissionCode("machine:script:save"),
req.NewDelete(":machineId/scripts/:scriptId", ms.DeleteMachineScript).Log(req.NewLogSave("机器-删除脚本")).RequiredPermissionCode("machine:script:del"),
@@ -39,12 +41,18 @@ func (ms *MachineScript) ReqConfs() *req.Confs {
}
func (m *MachineScript) MachineScripts(rc *req.Ctx) {
- condition := &entity.MachineScript{MachineId: GetMachineId(rc)}
+ condition := &entity.MachineScript{MachineId: GetMachineId(rc), Category: rc.Query("category")}
res, err := m.machineScriptApp.GetPageList(condition, rc.GetPageParam())
biz.ErrIsNil(err)
rc.ResData = model.PageResultConv[*entity.MachineScript, *vo.MachineScriptVO](res)
}
+func (m *MachineScript) MachineScriptCategorys(rc *req.Ctx) {
+ res, err := m.machineScriptApp.GetScriptCategorys(rc.MetaCtx)
+ biz.ErrIsNil(err)
+ rc.ResData = res
+}
+
func (m *MachineScript) SaveMachineScript(rc *req.Ctx) {
form, machineScript := req.BindJsonAndCopyTo[*form.MachineScriptForm, *entity.MachineScript](rc)
diff --git a/server/internal/machine/api/vo/vo.go b/server/internal/machine/api/vo/vo.go
index e989325b..f0084a4d 100644
--- a/server/internal/machine/api/vo/vo.go
+++ b/server/internal/machine/api/vo/vo.go
@@ -49,6 +49,7 @@ type MachineScriptVO struct {
Name *string `json:"name"`
Script *string `json:"script"`
Type *int `json:"type"`
+ Category string `json:"category"`
Description *string `json:"description"`
Params *string `json:"params"`
MachineId *uint64 `json:"machineId"`
diff --git a/server/internal/machine/application/machine_script.go b/server/internal/machine/application/machine_script.go
index 9d64198d..32a4eabe 100644
--- a/server/internal/machine/application/machine_script.go
+++ b/server/internal/machine/application/machine_script.go
@@ -7,6 +7,7 @@ import (
"mayfly-go/pkg/base"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/model"
+ "mayfly-go/pkg/utils/collx"
)
type MachineScript interface {
@@ -15,11 +16,16 @@ type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam model.PageParam, orderBy ...string) (*model.PageResult[*entity.MachineScript], error)
+ // GetScriptCategorys 获取脚本分类
+ GetScriptCategorys(ctx context.Context) ([]string, error)
+
Save(ctx context.Context, entity *entity.MachineScript) error
Delete(ctx context.Context, id uint64)
}
+var _ (MachineScript) = (*machineScriptAppImpl)(nil)
+
type machineScriptAppImpl struct {
base.AppImpl[*entity.MachineScript, repository.MachineScript]
@@ -33,6 +39,15 @@ func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, page
return m.GetRepo().GetPageList(condition, pageParam, orderBy...)
}
+func (m *machineScriptAppImpl) GetScriptCategorys(ctx context.Context) ([]string, error) {
+ scripts, err := m.ListByCond(new(entity.MachineScript), "category")
+ if err != nil {
+ return nil, err
+ }
+
+ return collx.ArrayRemoveBlank(collx.ArrayDeduplicate(collx.ArrayMap(scripts, func(script *entity.MachineScript) string { return script.Category }))), nil
+}
+
// 保存机器脚本
func (m *machineScriptAppImpl) Save(ctx context.Context, ms *entity.MachineScript) error {
// 如果机器id不为公共脚本id,则校验机器是否存在
diff --git a/server/internal/machine/domain/entity/machine_script.go b/server/internal/machine/domain/entity/machine_script.go
index 7e4a678f..0a93ca91 100644
--- a/server/internal/machine/domain/entity/machine_script.go
+++ b/server/internal/machine/domain/entity/machine_script.go
@@ -8,7 +8,8 @@ type MachineScript struct {
Name string `json:"name" gorm:"not null;size:255;comment:脚本名"` // 脚本名
MachineId uint64 `json:"machineId" gorm:"not null;comment:机器id[0:公共]"` // 机器id
Type int `json:"type" gorm:"comment:脚本类型[1: 有结果;2:无结果;3:实时交互]"` // 脚本类型[1: 有结果;2:无结果;3:实时交互]
- Description string `json:"description" gorm:"size:255;comment:脚本描述"` // 脚本描述
- Params string `json:"params" gorm:"size:500;comment:脚本入参"` // 参数列表json
- Script string `json:"script" gorm:"type:text;comment:脚本内容"` // 脚本内容
+ Category string `json:"category" gorm:"size:20;comment:分类"`
+ Description string `json:"description" gorm:"size:255;comment:脚本描述"` // 脚本描述
+ Params string `json:"params" gorm:"size:500;comment:脚本入参"` // 参数列表json
+ Script string `json:"script" gorm:"type:text;comment:脚本内容"` // 脚本内容
}
diff --git a/server/internal/pkg/config/app.go b/server/internal/pkg/config/app.go
index daf4a95a..f00e8abe 100644
--- a/server/internal/pkg/config/app.go
+++ b/server/internal/pkg/config/app.go
@@ -4,7 +4,7 @@ import "fmt"
const (
AppName = "mayfly-go"
- Version = "v1.10.0"
+ Version = "v1.10.1"
)
func GetAppInfo() string {
diff --git a/server/migration/migrations/v1_10.go b/server/migration/migrations/v1_10.go
index 71a6f176..302da918 100644
--- a/server/migration/migrations/v1_10.go
+++ b/server/migration/migrations/v1_10.go
@@ -3,6 +3,7 @@ package migrations
import (
esentity "mayfly-go/internal/es/domain/entity"
flowentity "mayfly-go/internal/flow/domain/entity"
+ machineentity "mayfly-go/internal/machine/domain/entity"
sysentity "mayfly-go/internal/sys/domain/entity"
"mayfly-go/pkg/model"
"time"
@@ -14,6 +15,7 @@ import (
func V1_10() []*gormigrate.Migration {
var migrations []*gormigrate.Migration
migrations = append(migrations, V1_10_0()...)
+ migrations = append(migrations, V1_10_1()...)
return migrations
}
@@ -132,3 +134,22 @@ func V1_10_0() []*gormigrate.Migration {
},
}
}
+
+func V1_10_1() []*gormigrate.Migration {
+ return []*gormigrate.Migration{
+ {
+ ID: "20250610-v1.10.1",
+ Migrate: func(tx *gorm.DB) error {
+ if !tx.Migrator().HasColumn(&machineentity.MachineScript{}, "category") {
+ if err := tx.Migrator().AddColumn(&machineentity.MachineScript{}, "category"); err != nil {
+ return err
+ }
+ }
+ return nil
+ },
+ Rollback: func(tx *gorm.DB) error {
+ return nil
+ },
+ },
+ }
+}