From c86f2ad412f198d60f48650d3c838d55e37dc420 Mon Sep 17 00:00:00 2001
From: "meilin.huang" <954537473@qq.com>
Date: Tue, 19 Aug 2025 19:44:14 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=A0=B7=E5=BC=8F=E4=BC=98?=
 =?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 frontend/package.json                         |  10 +-
 frontend/src/layout/component/main.vue        |  25 ++-
 frontend/src/layout/main/transverse.vue       |   2 +-
 frontend/src/layout/navMenu/horizontal.vue    |  58 +++---
 frontend/src/theme/element.scss               |  45 +----
 frontend/src/views/msg/tmpl/TmplList.vue      |   2 +-
 frontend/src/views/ops/component/TagTree.vue  |  35 +++-
 .../ops/db/component/table/DbTableData.vue    | 179 +++++++++++++-----
 frontend/src/views/ops/db/db.ts               |   4 +-
 server/go.mod                                 |  10 +-
 server/internal/machine/api/machine_file.go   |   6 +-
 11 files changed, 216 insertions(+), 160 deletions(-)
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 @@
 
-    
-        
+    
+        
             
         
 
@@ -13,7 +13,7 @@
 
 
 
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/layout/navMenu/horizontal.vue b/frontend/src/layout/navMenu/horizontal.vue
index 12467492..0b92c6b7 100644
--- a/frontend/src/layout/navMenu/horizontal.vue
+++ b/frontend/src/layout/navMenu/horizontal.vue
@@ -34,13 +34,12 @@
 
 
 
 
-
+
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 @@
 
                                     
                                     
-                                        
-                                            
-                                        
+                                        
+                                            
+                                                
+                                                
+                                                
+                                                
+                                            
+                                            
+                                                
+                                                    
+                                                        
+                                                        {{ $t('db.asc') }}
+                                                    
+                                                    
+                                                        
+                                                        {{ $t('db.desc') }}
+                                                    
+                                                    
+                                                        
+                                                        {{ $t('db.fixed') }}
+                                                    
+                                                    
+                                                        
+                                                        {{ $t('db.cancelFiexd') }}
+                                                    
+                                                
+                                            
+                                        
                                     
                                  
                              
@@ -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)
+		})
 	}
 
 	// 等待所有协程执行完成