dictionary_generator.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package mcpTool
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "github.com/flipped-aurora/gin-vue-admin/server/global"
  8. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  9. "github.com/flipped-aurora/gin-vue-admin/server/service"
  10. "github.com/mark3labs/mcp-go/mcp"
  11. "go.uber.org/zap"
  12. "gorm.io/gorm"
  13. )
  14. func init() {
  15. RegisterTool(&DictionaryOptionsGenerator{})
  16. }
  17. // DictionaryOptionsGenerator 字典选项生成器
  18. type DictionaryOptionsGenerator struct{}
  19. // DictionaryGenerateRequest 字典生成请求
  20. type DictionaryGenerateRequest struct {
  21. DictType string `json:"dictType"` // 字典类型
  22. FieldDesc string `json:"fieldDesc"` // 字段描述
  23. Options []DictionaryOption `json:"options"` // AI生成的字典选项
  24. DictName string `json:"dictName"` // 字典名称(可选)
  25. Description string `json:"description"` // 字典描述(可选)
  26. }
  27. // DictionaryGenerateResponse 字典生成响应
  28. type DictionaryGenerateResponse struct {
  29. Success bool `json:"success"`
  30. Message string `json:"message"`
  31. DictType string `json:"dictType"`
  32. OptionsCount int `json:"optionsCount"`
  33. }
  34. // New 返回工具注册信息
  35. func (d *DictionaryOptionsGenerator) New() mcp.Tool {
  36. return mcp.NewTool("generate_dictionary_options",
  37. mcp.WithDescription("智能生成字典选项并自动创建字典和字典详情"),
  38. mcp.WithString("dictType",
  39. mcp.Required(),
  40. mcp.Description("字典类型,用于标识字典的唯一性"),
  41. ),
  42. mcp.WithString("fieldDesc",
  43. mcp.Required(),
  44. mcp.Description("字段描述,用于AI理解字段含义"),
  45. ),
  46. mcp.WithString("options",
  47. mcp.Required(),
  48. mcp.Description("字典选项JSON字符串,格式:[{\"label\":\"显示名\",\"value\":\"值\",\"sort\":1}]"),
  49. ),
  50. mcp.WithString("dictName",
  51. mcp.Description("字典名称,如果不提供将自动生成"),
  52. ),
  53. mcp.WithString("description",
  54. mcp.Description("字典描述"),
  55. ),
  56. )
  57. }
  58. // Name 返回工具名称
  59. func (d *DictionaryOptionsGenerator) Name() string {
  60. return "generate_dictionary_options"
  61. }
  62. // Description 返回工具描述
  63. func (d *DictionaryOptionsGenerator) Description() string {
  64. return `字典选项生成工具 - 让AI生成并创建字典选项
  65. 此工具允许AI根据字典类型和字段描述生成合适的字典选项,并自动创建字典和字典详情。
  66. 参数说明:
  67. - dictType: 字典类型(必填)
  68. - fieldDesc: 字段描述(必填)
  69. - options: AI生成的字典选项数组(必填)
  70. - label: 选项标签
  71. - value: 选项值
  72. - sort: 排序号
  73. - dictName: 字典名称(可选,默认根据fieldDesc生成)
  74. - description: 字典描述(可选)
  75. 使用场景:
  76. 1. 在创建模块时,如果字段需要字典类型,AI可以根据字段描述智能生成合适的选项
  77. 2. 支持各种业务场景的字典选项生成,如状态、类型、等级等
  78. 3. 自动创建字典和字典详情,无需手动配置
  79. 示例调用:
  80. {
  81. "dictType": "user_status",
  82. "fieldDesc": "用户状态",
  83. "options": [
  84. {"label": "正常", "value": "1", "sort": 1},
  85. {"label": "禁用", "value": "0", "sort": 2}
  86. ],
  87. "dictName": "用户状态字典",
  88. "description": "用于管理用户账户状态的字典"
  89. }`
  90. }
  91. // InputSchema 返回输入参数的JSON Schema
  92. func (d *DictionaryOptionsGenerator) InputSchema() map[string]interface{} {
  93. return map[string]interface{}{
  94. "type": "object",
  95. "properties": map[string]interface{}{
  96. "dictType": map[string]interface{}{
  97. "type": "string",
  98. "description": "字典类型,用于标识字典的唯一性",
  99. },
  100. "fieldDesc": map[string]interface{}{
  101. "type": "string",
  102. "description": "字段描述,用于生成字典名称和理解字典用途",
  103. },
  104. "options": map[string]interface{}{
  105. "type": "array",
  106. "description": "AI生成的字典选项数组",
  107. "items": map[string]interface{}{
  108. "type": "object",
  109. "properties": map[string]interface{}{
  110. "label": map[string]interface{}{
  111. "type": "string",
  112. "description": "选项标签,显示给用户的文本",
  113. },
  114. "value": map[string]interface{}{
  115. "type": "string",
  116. "description": "选项值,存储在数据库中的值",
  117. },
  118. "sort": map[string]interface{}{
  119. "type": "integer",
  120. "description": "排序号,用于控制选项显示顺序",
  121. },
  122. },
  123. "required": []string{"label", "value", "sort"},
  124. },
  125. },
  126. "dictName": map[string]interface{}{
  127. "type": "string",
  128. "description": "字典名称,可选,默认根据fieldDesc生成",
  129. },
  130. "description": map[string]interface{}{
  131. "type": "string",
  132. "description": "字典描述,可选",
  133. },
  134. },
  135. "required": []string{"dictType", "fieldDesc", "options"},
  136. }
  137. }
  138. // Handle 处理工具调用
  139. func (d *DictionaryOptionsGenerator) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
  140. // 解析请求参数
  141. args := request.GetArguments()
  142. dictType, ok := args["dictType"].(string)
  143. if !ok || dictType == "" {
  144. return nil, errors.New("dictType 参数是必需的")
  145. }
  146. fieldDesc, ok := args["fieldDesc"].(string)
  147. if !ok || fieldDesc == "" {
  148. return nil, errors.New("fieldDesc 参数是必需的")
  149. }
  150. optionsStr, ok := args["options"].(string)
  151. if !ok || optionsStr == "" {
  152. return nil, errors.New("options 参数是必需的")
  153. }
  154. // 解析options JSON字符串
  155. var options []DictionaryOption
  156. if err := json.Unmarshal([]byte(optionsStr), &options); err != nil {
  157. return nil, fmt.Errorf("options 参数格式错误: %v", err)
  158. }
  159. if len(options) == 0 {
  160. return nil, errors.New("options 不能为空")
  161. }
  162. // 可选参数
  163. dictName, _ := args["dictName"].(string)
  164. description, _ := args["description"].(string)
  165. // 构建请求对象
  166. req := &DictionaryGenerateRequest{
  167. DictType: dictType,
  168. FieldDesc: fieldDesc,
  169. Options: options,
  170. DictName: dictName,
  171. Description: description,
  172. }
  173. // 创建字典
  174. response, err := d.createDictionaryWithOptions(ctx, req)
  175. if err != nil {
  176. return nil, err
  177. }
  178. // 构建响应
  179. resultJSON, err := json.MarshalIndent(response, "", " ")
  180. if err != nil {
  181. return nil, fmt.Errorf("序列化结果失败: %v", err)
  182. }
  183. return &mcp.CallToolResult{
  184. Content: []mcp.Content{
  185. mcp.TextContent{
  186. Type: "text",
  187. Text: fmt.Sprintf("字典选项生成结果:\n\n%s", string(resultJSON)),
  188. },
  189. },
  190. }, nil
  191. }
  192. // createDictionaryWithOptions 创建字典和字典选项
  193. func (d *DictionaryOptionsGenerator) createDictionaryWithOptions(ctx context.Context, req *DictionaryGenerateRequest) (*DictionaryGenerateResponse, error) {
  194. // 检查字典是否已存在
  195. exists, err := d.checkDictionaryExists(req.DictType)
  196. if err != nil {
  197. return nil, fmt.Errorf("检查字典是否存在失败: %v", err)
  198. }
  199. if exists {
  200. return &DictionaryGenerateResponse{
  201. Success: false,
  202. Message: fmt.Sprintf("字典 %s 已存在,跳过创建", req.DictType),
  203. DictType: req.DictType,
  204. OptionsCount: 0,
  205. }, nil
  206. }
  207. // 生成字典名称
  208. dictName := req.DictName
  209. if dictName == "" {
  210. dictName = d.generateDictionaryName(req.DictType, req.FieldDesc)
  211. }
  212. // 创建字典
  213. dictionaryService := service.ServiceGroupApp.SystemServiceGroup.DictionaryService
  214. dictionary := system.SysDictionary{
  215. Name: dictName,
  216. Type: req.DictType,
  217. Status: &[]bool{true}[0], // 默认启用
  218. Desc: req.Description,
  219. }
  220. err = dictionaryService.CreateSysDictionary(dictionary)
  221. if err != nil {
  222. return nil, fmt.Errorf("创建字典失败: %v", err)
  223. }
  224. // 获取刚创建的字典ID
  225. var createdDict system.SysDictionary
  226. err = global.GVA_DB.Where("type = ?", req.DictType).First(&createdDict).Error
  227. if err != nil {
  228. return nil, fmt.Errorf("获取创建的字典失败: %v", err)
  229. }
  230. // 创建字典详情项
  231. dictionaryDetailService := service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
  232. successCount := 0
  233. for _, option := range req.Options {
  234. dictionaryDetail := system.SysDictionaryDetail{
  235. Label: option.Label,
  236. Value: option.Value,
  237. Status: &[]bool{true}[0], // 默认启用
  238. Sort: option.Sort,
  239. SysDictionaryID: int(createdDict.ID),
  240. }
  241. err = dictionaryDetailService.CreateSysDictionaryDetail(dictionaryDetail)
  242. if err != nil {
  243. global.GVA_LOG.Warn("创建字典详情项失败", zap.Error(err))
  244. } else {
  245. successCount++
  246. }
  247. }
  248. return &DictionaryGenerateResponse{
  249. Success: true,
  250. Message: fmt.Sprintf("成功创建字典 %s,包含 %d 个选项", req.DictType, successCount),
  251. DictType: req.DictType,
  252. OptionsCount: successCount,
  253. }, nil
  254. }
  255. // checkDictionaryExists 检查字典是否存在
  256. func (d *DictionaryOptionsGenerator) checkDictionaryExists(dictType string) (bool, error) {
  257. var dictionary system.SysDictionary
  258. err := global.GVA_DB.Where("type = ?", dictType).First(&dictionary).Error
  259. if err != nil {
  260. if errors.Is(err, gorm.ErrRecordNotFound) {
  261. return false, nil // 字典不存在
  262. }
  263. return false, err // 其他错误
  264. }
  265. return true, nil // 字典存在
  266. }
  267. // generateDictionaryName 生成字典名称
  268. func (d *DictionaryOptionsGenerator) generateDictionaryName(dictType, fieldDesc string) string {
  269. if fieldDesc != "" {
  270. return fmt.Sprintf("%s字典", fieldDesc)
  271. }
  272. return fmt.Sprintf("%s字典", dictType)
  273. }