From dd34d6e3beefbe3a63cac645f49480b2fc47786d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?piexlMax=28=E5=A5=87=E6=B7=BC?= Date: Tue, 26 Aug 2025 18:43:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20mcp=E5=AD=97=E6=AE=B5=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/go.mod | 4 +++ server/mcp/gva_auto_generate.go | 58 ++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/server/go.mod b/server/go.mod index 8a313c48..a83d2196 100644 --- a/server/go.mod +++ b/server/go.mod @@ -74,6 +74,8 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dzwvip/gorm-oracle v0.1.2 // indirect + github.com/emirpasic/gods v1.12.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gammazero/toposort v0.1.1 // indirect github.com/gin-contrib/sse v1.0.0 // indirect @@ -137,6 +139,7 @@ require ( github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sijms/go-ora/v2 v2.7.17 // indirect github.com/sorairolake/lzip-go v0.3.5 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.12.0 // indirect @@ -144,6 +147,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/therootcompany/xz v1.0.1 // indirect + github.com/thoas/go-funk v0.7.0 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.9.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect diff --git a/server/mcp/gva_auto_generate.go b/server/mcp/gva_auto_generate.go index cb9ae0c3..8fe4ef85 100644 --- a/server/mcp/gva_auto_generate.go +++ b/server/mcp/gva_auto_generate.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" "time" + "unicode" "github.com/flipped-aurora/gin-vue-admin/server/global" common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" @@ -176,7 +177,7 @@ func (t *AutomationModuleAnalyzer) New() mcp.Tool { "fieldName": "字段名(string)必须大写开头", "fieldDesc": "字段描述(string)", "fieldType": "字段类型支持:string(字符串),richtext(富文本),int(整型),bool(布尔值),float64(浮点型),time.Time(时间),enum(枚举),picture(单图片,字符串),pictures(多图片,json字符串),video(视频,字符串),file(文件,json字符串),json(JSON),array(数组)", - "fieldJson": "JSON标签(string)", + "fieldJson": "JSON标签(string 必须是小驼峰命名,例:userName)", "dataTypeLong": "数据长度(string)", "comment": "注释(string)", "columnName": "数据库列名(string)", @@ -808,7 +809,7 @@ func (t *AutomationModuleAnalyzer) handleAnalyze(ctx context.Context, request mc "fieldName": "字段名(必须大写开头)", "fieldDesc": "字段描述", "fieldType": "字段类型支持:string(字符串),richtext(富文本),int(整型),bool(布尔值),float64(浮点型),time.Time(时间),enum(枚举),picture(单图片,字符串),pictures(多图片,json字符串),video(视频,字符串),file(文件,json字符串),json(JSON),array(数组)", - "fieldJson": "json标签", + "fieldJson": "json标签(string 必须是小驼峰命名,例:userName)", "dataTypeLong": "长度", "comment": "注释", "columnName": "数据库列名", @@ -1243,14 +1244,7 @@ func (t *AutomationModuleAnalyzer) validateExecutionPlan(plan *ExecutionPlan) er if field.FieldName == "" { return fmt.Errorf("模块 %d 字段 %d 的 fieldName 不能为空", moduleIndex+1, i+1) } - - // 确保字段名首字母大写 - if len(field.FieldName) > 0 { - firstChar := string(field.FieldName[0]) - if firstChar >= "a" && firstChar <= "z" { - moduleInfo.Fields[i].FieldName = strings.ToUpper(firstChar) + field.FieldName[1:] - } - } + if field.FieldDesc == "" { return fmt.Errorf("模块 %d 字段 %d 的 fieldDesc 不能为空", moduleIndex+1, i+1) } @@ -1264,6 +1258,48 @@ func (t *AutomationModuleAnalyzer) validateExecutionPlan(plan *ExecutionPlan) er return fmt.Errorf("模块 %d 字段 %d 的 columnName 不能为空", moduleIndex+1, i+1) } + // 确保字段名首字母大写 + if len(field.FieldName) > 0 { + firstChar := string(field.FieldName[0]) + if firstChar >= "a" && firstChar <= "z" { + moduleInfo.Fields[i].FieldName = strings.ToUpper(firstChar) + field.FieldName[1:] + } + } + + // 确保FieldJson使用小驼峰命名 + if len(field.FieldJson) > 0 { + // 处理下划线命名转小驼峰 + if strings.Contains(field.FieldJson, "_") { + parts := strings.Split(field.FieldJson, "_") + camelCase := strings.ToLower(parts[0]) + for j := 1; j < len(parts); j++ { + if len(parts[j]) > 0 { + camelCase += strings.ToUpper(string(parts[j][0])) + strings.ToLower(parts[j][1:]) + } + } + moduleInfo.Fields[i].FieldJson = camelCase + } else { + // 处理首字母大写转小写 + firstChar := string(field.FieldJson[0]) + if firstChar >= "A" && firstChar <= "Z" { + moduleInfo.Fields[i].FieldJson = strings.ToLower(firstChar) + field.FieldJson[1:] + } + } + } + + // 确保ColumnName使用下划线命名 + if len(field.ColumnName) > 0 { + // 将驼峰命名转换为下划线命名 + var result strings.Builder + for i, r := range field.ColumnName { + if i > 0 && r >= 'A' && r <= 'Z' { + result.WriteRune('_') + } + result.WriteRune(unicode.ToLower(r)) + } + moduleInfo.Fields[i].ColumnName = result.String() + } + // 验证字段类型 validFieldTypes := []string{"string", "int", "int64", "float64", "bool", "time.Time", "enum", "picture", "video", "file", "pictures", "array", "richtext", "json"} validType := false @@ -1377,7 +1413,7 @@ func (t *AutomationModuleAnalyzer) executeCreation(ctx context.Context, plan *Ex } result.Message += fmt.Sprintf("批量创建完成,共处理 %d 个模块; ", len(plan.ModulesInfo)) - + // 添加重要提醒:不要使用其他MCP工具 result.Message += "\n\n⚠️ 重要提醒:\n" result.Message += "模块创建已完成,API和菜单已自动生成。请不要再调用以下MCP工具:\n"