Files
Go-Web-Template/server/mcp/dictionary_generator.go

175 lines
4.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mcpTool
import (
"context"
"encoding/json"
"errors"
"fmt"
"git.echol.cn/loser/Go-Web-Template/server/model/system"
"github.com/mark3labs/mcp-go/mcp"
)
func init() {
RegisterTool(&DictionaryOptionsGenerator{})
}
type DictionaryOptionsGenerator struct{}
type DictionaryOption struct {
Label string `json:"label"`
Value string `json:"value"`
Sort int `json:"sort"`
}
type DictionaryGenerateRequest struct {
DictType string `json:"dictType"`
FieldDesc string `json:"fieldDesc"`
Options []DictionaryOption `json:"options"`
DictName string `json:"dictName"`
Description string `json:"description"`
}
type DictionaryGenerateResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
DictType string `json:"dictType"`
OptionsCount int `json:"optionsCount"`
}
func (d *DictionaryOptionsGenerator) New() mcp.Tool {
return mcp.NewTool("generate_dictionary_options",
mcp.WithDescription("智能生成字典选项并自动创建字典和字典详情"),
mcp.WithString("dictType",
mcp.Required(),
mcp.Description("字典类型,用于标识字典的唯一性"),
),
mcp.WithString("fieldDesc",
mcp.Required(),
mcp.Description("字段描述用于AI理解字段含义"),
),
mcp.WithString("options",
mcp.Required(),
mcp.Description("字典选项JSON字符串格式[{\"label\":\"显示名\",\"value\":\"值\",\"sort\":1}]"),
),
mcp.WithString("dictName",
mcp.Description("字典名称,如果不提供将自动生成"),
),
mcp.WithString("description",
mcp.Description("字典描述"),
),
)
}
func (d *DictionaryOptionsGenerator) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
args := request.GetArguments()
dictType, ok := args["dictType"].(string)
if !ok || dictType == "" {
return nil, errors.New("dictType 参数是必需的")
}
fieldDesc, ok := args["fieldDesc"].(string)
if !ok || fieldDesc == "" {
return nil, errors.New("fieldDesc 参数是必需的")
}
optionsStr, ok := args["options"].(string)
if !ok || optionsStr == "" {
return nil, errors.New("options 参数是必需的")
}
var options []DictionaryOption
if err := json.Unmarshal([]byte(optionsStr), &options); err != nil {
return nil, fmt.Errorf("options 参数格式错误: %v", err)
}
if len(options) == 0 {
return nil, errors.New("options 不能为空")
}
req := &DictionaryGenerateRequest{
DictType: dictType,
FieldDesc: fieldDesc,
Options: options,
DictName: stringValue(args["dictName"]),
Description: stringValue(args["description"]),
}
result, err := d.createDictionaryWithOptions(ctx, req)
if err != nil {
return nil, err
}
return textResultWithJSON("字典选项生成结果:", result)
}
func (d *DictionaryOptionsGenerator) createDictionaryWithOptions(ctx context.Context, req *DictionaryGenerateRequest) (*DictionaryGenerateResponse, error) {
existingDict, err := findDictionaryByType(ctx, req.DictType)
if err != nil {
return nil, fmt.Errorf("检查字典是否存在失败: %v", err)
}
if existingDict != nil {
return &DictionaryGenerateResponse{
Success: false,
Message: fmt.Sprintf("字典 %s 已存在,跳过创建", req.DictType),
DictType: req.DictType,
OptionsCount: 0,
}, nil
}
dictName := req.DictName
if dictName == "" {
dictName = d.generateDictionaryName(req.DictType, req.FieldDesc)
}
if err := createDictionary(ctx, system.SysDictionary{
Name: dictName,
Type: req.DictType,
Status: enabledBoolPointer(),
Desc: req.Description,
}); err != nil {
return nil, fmt.Errorf("创建字典失败: %v", err)
}
createdDict, err := findDictionaryByType(ctx, req.DictType)
if err != nil {
return nil, fmt.Errorf("获取创建的字典失败: %v", err)
}
if createdDict == nil {
return nil, fmt.Errorf("获取创建的字典失败")
}
successCount := 0
for _, option := range req.Options {
err := createDictionaryDetail(ctx, system.SysDictionaryDetail{
Label: option.Label,
Value: option.Value,
Status: enabledBoolPointer(),
Sort: option.Sort,
SysDictionaryID: int(createdDict.ID),
})
if err == nil {
successCount++
}
}
return &DictionaryGenerateResponse{
Success: true,
Message: fmt.Sprintf("成功创建字典 %s包含 %d 个选项", req.DictType, successCount),
DictType: req.DictType,
OptionsCount: successCount,
}, nil
}
func (d *DictionaryOptionsGenerator) generateDictionaryName(dictType, fieldDesc string) string {
if fieldDesc != "" {
return fmt.Sprintf("%s字典", fieldDesc)
}
return fmt.Sprintf("%s字典", dictType)
}
func stringValue(value any) string {
if str, ok := value.(string); ok {
return str
}
return ""
}