diff --git a/frontend/package.json b/frontend/package.json index d9722b56..336ad120 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,9 +10,9 @@ "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/" }, "dependencies": { - "@element-plus/icons-vue": "^2.3.1", - "@logicflow/core": "^2.0.16", - "@logicflow/extension": "^2.0.21", + "@element-plus/icons-vue": "^2.3.2", + "@logicflow/core": "^2.1.1", + "@logicflow/extension": "^2.1.2", "@vueuse/core": "^13.6.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": "^6.0.0", - "element-plus": "^2.10.5", + "element-plus": "^2.10.7", "js-base64": "^3.7.7", "jsencrypt": "^3.3.2", "monaco-editor": "^0.52.2", @@ -59,7 +59,7 @@ "eslint-plugin-vue": "^10.4.0", "postcss": "^8.5.6", "prettier": "^3.6.1", - "sass": "^1.89.2", + "sass": "^1.90.0", "tailwindcss": "^4.1.11", "typescript": "^5.9.2", "vite": "npm:rolldown-vite@latest", diff --git a/frontend/src/layout/component/main.vue b/frontend/src/layout/component/main.vue index d5228012..f166faae 100644 --- a/frontend/src/layout/component/main.vue +++ b/frontend/src/layout/component/main.vue @@ -1,6 +1,6 @@ diff --git a/frontend/src/layout/main/transverse.vue b/frontend/src/layout/main/transverse.vue index d8561900..5fa41e62 100644 --- a/frontend/src/layout/main/transverse.vue +++ b/frontend/src/layout/main/transverse.vue @@ -1,5 +1,5 @@ - + diff --git a/frontend/src/views/ops/db/component/table/DbTableData.vue b/frontend/src/views/ops/db/component/table/DbTableData.vue index 42bdf73e..3d64a3f7 100644 --- a/frontend/src/views/ops/db/component/table/DbTableData.vue +++ b/frontend/src/views/ops/db/component/table/DbTableData.vue @@ -33,7 +33,7 @@ -
+
@@ -65,9 +65,56 @@
- - - + + + + + + + + +
@@ -214,43 +261,9 @@ const props = defineProps({ const contextmenuRef = ref(); const tableRef = ref(); -/** 表头 menu items **/ - -const cmHeaderAsc = new ContextmenuItem('asc', 'db.asc') - .withIcon('top') - .withOnClick((data: any) => { - onTableSortChange({ columnName: data.dataKey, order: 'asc' }); - }) - .withHideFunc(() => !props.showColumnTip); - -const cmHeaderDesc = new ContextmenuItem('desc', 'db.desc') - .withIcon('bottom') - .withOnClick((data: any) => { - onTableSortChange({ columnName: data.dataKey, order: 'desc' }); - }) - .withHideFunc(() => !props.showColumnTip); - -const cmHeaderFixed = new ContextmenuItem('fixed', 'db.fixed') - .withIcon('Paperclip') - .withOnClick((data: any) => { - state.columns.forEach((column: any) => { - if (column.dataKey == data.dataKey) { - column.fixed = true; - } - }); - }) - .withHideFunc((data: any) => data.fixed); - -const cmHeaderCancelFixed = new ContextmenuItem('cancelFixed', 'db.cancelFiexd') - .withIcon('Minus') - .withOnClick((data: any) => { - state.columns.forEach((column: any) => { - if (column.dataKey == data.dataKey) { - column.fixed = false; - } - }); - }) - .withHideFunc((data: any) => !data.fixed); +// 用于控制列操作按钮的显示 +const showColumnActions = ref({} as any); +const columnActionVisible = ref({} as any); /** 表数据 contextmenu items **/ @@ -508,6 +521,55 @@ const cancelLoading = async () => { endLoading(); }; +/** + * 显示列操作按钮 + */ +const showColumnAction = (column: any) => { + showColumnActions.value[column.key] = true; +}; + +/** + * 隐藏列操作按钮 + */ +const hideColumnAction = () => { + showColumnActions.value = {}; +}; + +/** + * 处理列操作命令 + */ +const handleColumnCommand = (column: any, command: string) => { + switch (command) { + case 'sort-asc': + onTableSortChange({ columnName: column.dataKey, order: 'asc' }); + break; + case 'sort-desc': + onTableSortChange({ columnName: column.dataKey, order: 'desc' }); + break; + case 'fix': + state.columns.forEach((col: any) => { + if (col.dataKey == column.dataKey) { + col.fixed = true; + } + }); + break; + case 'unfix': + state.columns.forEach((col: any) => { + if (col.dataKey == column.dataKey) { + col.fixed = false; + } + }); + break; + } + // 点击了取消固定等操作后,可能更多的icon还是显示在列上,所以需要重新置为空对象。暂时不懂是组件bug还是啥 + columnActionVisible.value = {}; +}; + +const onColumnActionVisibleChange = (column: any, visible: boolean) => { + columnActionVisible.value = {}; // 只显示一个列的更多icon + columnActionVisible.value[column.key] = visible; +}; + /** * 当前单元格是否允许编辑 * @param rowIndex ri @@ -570,16 +632,6 @@ const rowEventHandlers = { }, }; -const headerContextmenuClick = (event: any, data: any) => { - event.preventDefault(); // 阻止默认的右击菜单行为 - - const { clientX, clientY } = event; - state.contextmenu.dropdown.x = clientX; - state.contextmenu.dropdown.y = clientY; - state.contextmenu.items = [cmHeaderAsc, cmHeaderDesc, cmHeaderFixed, cmHeaderCancelFixed]; - contextmenuRef.value.openContextmenu(data); -}; - const dataContextmenuClick = (event: any, rowIndex: number, column: any, data: any) => { event.preventDefault(); // 阻止默认的右击菜单行为 @@ -851,6 +903,31 @@ defineExpose({ top: 2px; right: 0; padding: 2px; + display: flex; + align-items: center; + } + + .column-actions-trigger { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + border-radius: 50%; + cursor: pointer; + + &:hover { + background-color: var(--el-fill-color-light); + } + } + + .column-more-icon { + opacity: 0; + transition: opacity 0.2s; + } + + .column-more-icon-visible { + opacity: 1 !important; } } diff --git a/frontend/src/views/ops/db/db.ts b/frontend/src/views/ops/db/db.ts index 21d75648..a1e6d031 100644 --- a/frontend/src/views/ops/db/db.ts +++ b/frontend/src/views/ops/db/db.ts @@ -497,8 +497,8 @@ export class DbInst { return; } - // 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、排序图标等 - const columnWidth: number = getTextWidth(prop + 'abc') + 10; + // 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、更多/排序图标等 + const columnWidth: number = getTextWidth(prop + 'abc') + 25; // prop为该列的字段名(传字符串);tableData为该表格的数据源(传变量); if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) { return columnWidth; diff --git a/server/go.mod b/server/go.mod index 87b70c6b..b57c8c86 100644 --- a/server/go.mod +++ b/server/go.mod @@ -1,6 +1,6 @@ module mayfly-go -go 1.24 +go 1.25 require ( gitee.com/chunanyong/dm v1.8.20 @@ -23,7 +23,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.13.9 github.com/pquerna/otp v1.5.0 - github.com/redis/go-redis/v9 v9.11.0 + github.com/redis/go-redis/v9 v9.12.1 github.com/robfig/cron/v3 v3.0.1 // 定时任务 github.com/sijms/go-ora/v2 v2.9.0 github.com/spf13/cast v1.9.2 @@ -31,7 +31,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/veops/go-ansiterm v0.0.5 go.mongodb.org/mongo-driver/v2 v2.2.2 // mongo - golang.org/x/crypto v0.40.0 // ssh + golang.org/x/crypto v0.41.0 // ssh golang.org/x/oauth2 v0.30.0 golang.org/x/sync v0.16.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -91,8 +91,8 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect golang.org/x/image v0.29.0 // indirect golang.org/x/net v0.42.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect google.golang.org/protobuf v1.36.6 // indirect modernc.org/libc v1.66.4 // indirect modernc.org/mathutil v1.7.1 // indirect diff --git a/server/internal/machine/api/machine_file.go b/server/internal/machine/api/machine_file.go index f508b570..ce41e3dc 100644 --- a/server/internal/machine/api/machine_file.go +++ b/server/internal/machine/api/machine_file.go @@ -379,7 +379,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { isSuccess := true for _, chunk := range chunks { - go func(files []FolderFile, wg *sync.WaitGroup) { + wg.Go(func() { defer func() { // 协程执行完成后调用Done方法 wg.Done() @@ -397,7 +397,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { } }() - for _, file := range files { + for _, file := range chunk { fileHeader := file.Fileheader dir := file.Dir file, _ := fileHeader.Open() @@ -410,7 +410,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { defer createfile.Close() io.Copy(createfile, file) } - }(chunk, &wg) + }) } // 等待所有协程执行完成