🎨 更新项目版本

This commit is contained in:
2025-09-03 01:45:01 +08:00
parent f928348284
commit 5496bdaa94
130 changed files with 9397 additions and 1816 deletions

287
mcp/menu_creator.go Normal file
View File

@@ -0,0 +1,287 @@
package mcpTool
import (
"context"
"encoding/json"
"errors"
"fmt"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/model/system"
"git.echol.cn/loser/lckt/service"
"github.com/mark3labs/mcp-go/mcp"
"go.uber.org/zap"
)
// 注册工具
func init() {
RegisterTool(&MenuCreator{})
}
// MenuCreateRequest 菜单创建请求结构
type MenuCreateRequest struct {
ParentId uint `json:"parentId"` // 父菜单ID0表示根菜单
Path string `json:"path"` // 路由path
Name string `json:"name"` // 路由name
Hidden bool `json:"hidden"` // 是否在列表隐藏
Component string `json:"component"` // 对应前端文件路径
Sort int `json:"sort"` // 排序标记
Title string `json:"title"` // 菜单名
Icon string `json:"icon"` // 菜单图标
KeepAlive bool `json:"keepAlive"` // 是否缓存
DefaultMenu bool `json:"defaultMenu"` // 是否是基础路由
CloseTab bool `json:"closeTab"` // 自动关闭tab
ActiveName string `json:"activeName"` // 高亮菜单
Parameters []MenuParameterRequest `json:"parameters"` // 路由参数
MenuBtn []MenuButtonRequest `json:"menuBtn"` // 菜单按钮
}
// MenuParameterRequest 菜单参数请求结构
type MenuParameterRequest struct {
Type string `json:"type"` // 参数类型params或query
Key string `json:"key"` // 参数key
Value string `json:"value"` // 参数值
}
// MenuButtonRequest 菜单按钮请求结构
type MenuButtonRequest struct {
Name string `json:"name"` // 按钮名称
Desc string `json:"desc"` // 按钮描述
}
// MenuCreateResponse 菜单创建响应结构
type MenuCreateResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
MenuID uint `json:"menuId"`
Name string `json:"name"`
Path string `json:"path"`
}
// MenuCreator 菜单创建工具
type MenuCreator struct{}
// New 创建菜单创建工具
func (m *MenuCreator) New() mcp.Tool {
return mcp.NewTool("create_menu",
mcp.WithDescription(`创建前端菜单记录用于AI编辑器自动添加前端页面时自动创建对应的菜单项。
**重要限制:**
- 当使用gva_auto_generate工具且needCreatedModules=true时模块创建会自动生成菜单项不应调用此工具
- 仅在以下情况使用1) 单独创建菜单不涉及模块创建2) AI编辑器自动添加前端页面时`),
mcp.WithNumber("parentId",
mcp.Description("父菜单ID0表示根菜单"),
mcp.DefaultNumber(0),
),
mcp.WithString("path",
mcp.Required(),
mcp.Description("路由pathuserList"),
),
mcp.WithString("name",
mcp.Required(),
mcp.Description("路由name用于Vue RouteruserList"),
),
mcp.WithBoolean("hidden",
mcp.Description("是否在菜单列表中隐藏"),
),
mcp.WithString("component",
mcp.Required(),
mcp.Description("对应的前端Vue组件路径view/user/list.vue"),
),
mcp.WithNumber("sort",
mcp.Description("菜单排序号,数字越小越靠前"),
mcp.DefaultNumber(1),
),
mcp.WithString("title",
mcp.Required(),
mcp.Description("菜单显示标题"),
),
mcp.WithString("icon",
mcp.Description("菜单图标名称"),
mcp.DefaultString("menu"),
),
mcp.WithBoolean("keepAlive",
mcp.Description("是否缓存页面"),
),
mcp.WithBoolean("defaultMenu",
mcp.Description("是否是基础路由"),
),
mcp.WithBoolean("closeTab",
mcp.Description("是否自动关闭tab"),
),
mcp.WithString("activeName",
mcp.Description("高亮菜单名称"),
),
mcp.WithString("parameters",
mcp.Description("路由参数JSON字符串格式[{\"type\":\"params\",\"key\":\"id\",\"value\":\"1\"}]"),
),
mcp.WithString("menuBtn",
mcp.Description("菜单按钮JSON字符串格式[{\"name\":\"add\",\"desc\":\"新增\"}]"),
),
)
}
// Handle 处理菜单创建请求
func (m *MenuCreator) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 解析请求参数
args := request.GetArguments()
// 必需参数
path, ok := args["path"].(string)
if !ok || path == "" {
return nil, errors.New("path 参数是必需的")
}
name, ok := args["name"].(string)
if !ok || name == "" {
return nil, errors.New("name 参数是必需的")
}
component, ok := args["component"].(string)
if !ok || component == "" {
return nil, errors.New("component 参数是必需的")
}
title, ok := args["title"].(string)
if !ok || title == "" {
return nil, errors.New("title 参数是必需的")
}
// 可选参数
parentId := uint(0)
if val, ok := args["parentId"].(float64); ok {
parentId = uint(val)
}
hidden := false
if val, ok := args["hidden"].(bool); ok {
hidden = val
}
sort := 1
if val, ok := args["sort"].(float64); ok {
sort = int(val)
}
icon := "menu"
if val, ok := args["icon"].(string); ok && val != "" {
icon = val
}
keepAlive := false
if val, ok := args["keepAlive"].(bool); ok {
keepAlive = val
}
defaultMenu := false
if val, ok := args["defaultMenu"].(bool); ok {
defaultMenu = val
}
closeTab := false
if val, ok := args["closeTab"].(bool); ok {
closeTab = val
}
activeName := ""
if val, ok := args["activeName"].(string); ok {
activeName = val
}
// 解析参数和按钮
var parameters []system.SysBaseMenuParameter
if parametersStr, ok := args["parameters"].(string); ok && parametersStr != "" {
var paramReqs []MenuParameterRequest
if err := json.Unmarshal([]byte(parametersStr), &paramReqs); err != nil {
return nil, fmt.Errorf("parameters 参数格式错误: %v", err)
}
for _, param := range paramReqs {
parameters = append(parameters, system.SysBaseMenuParameter{
Type: param.Type,
Key: param.Key,
Value: param.Value,
})
}
}
var menuBtn []system.SysBaseMenuBtn
if menuBtnStr, ok := args["menuBtn"].(string); ok && menuBtnStr != "" {
var btnReqs []MenuButtonRequest
if err := json.Unmarshal([]byte(menuBtnStr), &btnReqs); err != nil {
return nil, fmt.Errorf("menuBtn 参数格式错误: %v", err)
}
for _, btn := range btnReqs {
menuBtn = append(menuBtn, system.SysBaseMenuBtn{
Name: btn.Name,
Desc: btn.Desc,
})
}
}
// 构建菜单对象
menu := system.SysBaseMenu{
ParentId: parentId,
Path: path,
Name: name,
Hidden: hidden,
Component: component,
Sort: sort,
Meta: system.Meta{
Title: title,
Icon: icon,
KeepAlive: keepAlive,
DefaultMenu: defaultMenu,
CloseTab: closeTab,
ActiveName: activeName,
},
Parameters: parameters,
MenuBtn: menuBtn,
}
// 创建菜单
menuService := service.ServiceGroupApp.SystemServiceGroup.MenuService
err := menuService.AddBaseMenu(menu)
if err != nil {
return nil, fmt.Errorf("创建菜单失败: %v", err)
}
// 获取创建的菜单ID
var createdMenu system.SysBaseMenu
err = global.GVA_DB.Where("name = ? AND path = ?", name, path).First(&createdMenu).Error
if err != nil {
global.GVA_LOG.Warn("获取创建的菜单ID失败", zap.Error(err))
}
// 构建响应
response := &MenuCreateResponse{
Success: true,
Message: fmt.Sprintf("成功创建菜单 %s", title),
MenuID: createdMenu.ID,
Name: name,
Path: path,
}
resultJSON, err := json.MarshalIndent(response, "", " ")
if err != nil {
return nil, fmt.Errorf("序列化结果失败: %v", err)
}
// 添加权限分配提醒
permissionReminder := "\n\n⚠ 重要提醒:\n" +
"菜单创建完成后,请前往【系统管理】->【角色管理】中为相关角色分配新创建的菜单权限," +
"以确保用户能够正常访问新菜单。\n" +
"具体步骤:\n" +
"1. 进入角色管理页面\n" +
"2. 选择需要授权的角色\n" +
"3. 在菜单权限中勾选新创建的菜单项\n" +
"4. 保存权限配置"
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.TextContent{
Type: "text",
Text: fmt.Sprintf("菜单创建结果:\n\n%s%s", string(resultJSON), permissionReminder),
},
},
}, nil
}