Skip to content

Commit 6860395

Browse files
author
piexlMax(奇淼
committed
feat: 调整初始化menu的逻辑
1 parent 9df778f commit 6860395

File tree

6 files changed

+112
-40
lines changed

6 files changed

+112
-40
lines changed

server/service/system/auto_code_package.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ func (s *autoCodePackage) Templates(ctx context.Context) ([]string, error) {
233233
if entries[i].Name() == "preview" {
234234
continue
235235
} // preview 为预览代码生成器的代码
236+
if entries[i].Name() == "mcp" {
237+
continue
238+
} // preview 为mcp生成器的代码
236239
templates = append(templates, entries[i].Name())
237240
}
238241
}

server/source/system/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func (i *initApi) InitializeData(ctx context.Context) (context.Context, error) {
117117
{ApiGroup: "代码生成器", Method: "GET", Path: "/autoCode/getColumn", Description: "获取所选table的所有字段"},
118118
{ApiGroup: "代码生成器", Method: "POST", Path: "/autoCode/installPlugin", Description: "安装插件"},
119119
{ApiGroup: "代码生成器", Method: "POST", Path: "/autoCode/pubPlug", Description: "打包插件"},
120+
{ApiGroup: "代码生成器", Method: "POST", Path: "/autoCode/mcp", Description: "自动生成 MCP Tool 模板"},
120121

121122
{ApiGroup: "模板配置", Method: "POST", Path: "/autoCode/createPackage", Description: "配置模板"},
122123
{ApiGroup: "模板配置", Method: "GET", Path: "/autoCode/getTemplates", Description: "获取模板文件"},

server/source/system/authorities_menus.go

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,35 +35,72 @@ func (i *initMenuAuthority) InitializeData(ctx context.Context) (next context.Co
3535
if !ok {
3636
return ctx, system.ErrMissingDBContext
3737
}
38+
3839
initAuth := &initAuthority{}
3940
authorities, ok := ctx.Value(initAuth.InitializerName()).([]sysModel.SysAuthority)
4041
if !ok {
4142
return ctx, errors.Wrap(system.ErrMissingDependentContext, "创建 [菜单-权限] 关联失败, 未找到权限表初始化数据")
4243
}
43-
menus, ok := ctx.Value(new(initMenu).InitializerName()).([]sysModel.SysBaseMenu)
44+
45+
allMenus, ok := ctx.Value(new(initMenu).InitializerName()).([]sysModel.SysBaseMenu)
4446
if !ok {
4547
return next, errors.Wrap(errors.New(""), "创建 [菜单-权限] 关联失败, 未找到菜单表初始化数据")
4648
}
4749
next = ctx
48-
// 888
49-
if err = db.Model(&authorities[0]).Association("SysBaseMenus").Replace(menus); err != nil {
50-
return next, err
50+
51+
// 构建菜单ID映射,方便快速查找
52+
menuMap := make(map[uint]sysModel.SysBaseMenu)
53+
for _, menu := range allMenus {
54+
menuMap[menu.ID] = menu
55+
}
56+
57+
// 为不同角色分配不同权限
58+
// 1. 超级管理员角色(888) - 拥有所有菜单权限
59+
if err = db.Model(&authorities[0]).Association("SysBaseMenus").Replace(allMenus); err != nil {
60+
return next, errors.Wrap(err, "为超级管理员分配菜单失败")
61+
}
62+
63+
// 2. 普通用户角色(8881) - 仅拥有基础功能菜单
64+
// 仅选择部分父级菜单及其子菜单
65+
var menu8881 []sysModel.SysBaseMenu
66+
67+
// 添加仪表盘、关于我们和个人信息菜单
68+
for _, menu := range allMenus {
69+
if menu.ParentId == 0 && (menu.Name == "dashboard" || menu.Name == "about" || menu.Name == "person" || menu.Name == "state") {
70+
menu8881 = append(menu8881, menu)
71+
}
5172
}
5273

53-
// 8881
54-
menu8881 := menus[:2]
55-
menu8881 = append(menu8881, menus[7])
5674
if err = db.Model(&authorities[1]).Association("SysBaseMenus").Replace(menu8881); err != nil {
57-
return next, err
75+
return next, errors.Wrap(err, "为普通用户分配菜单失败")
5876
}
5977

60-
// 9528
61-
if err = db.Model(&authorities[2]).Association("SysBaseMenus").Replace(menus[:11]); err != nil {
62-
return next, err
78+
// 3. 测试角色(9528) - 拥有部分菜单权限
79+
var menu9528 []sysModel.SysBaseMenu
80+
81+
// 添加所有父级菜单
82+
for _, menu := range allMenus {
83+
if menu.ParentId == 0 {
84+
menu9528 = append(menu9528, menu)
85+
}
6386
}
64-
if err = db.Model(&authorities[2]).Association("SysBaseMenus").Append(menus[12:17]); err != nil {
65-
return next, err
87+
88+
// 添加部分子菜单 - 系统工具、示例文件等模块的子菜单
89+
for _, menu := range allMenus {
90+
parentName := ""
91+
if menu.ParentId > 0 && menuMap[menu.ParentId].Name != "" {
92+
parentName = menuMap[menu.ParentId].Name
93+
}
94+
95+
if menu.ParentId > 0 && (parentName == "systemTools" || parentName == "example") {
96+
menu9528 = append(menu9528, menu)
97+
}
98+
}
99+
100+
if err = db.Model(&authorities[2]).Association("SysBaseMenus").Replace(menu9528); err != nil {
101+
return next, errors.Wrap(err, "为测试角色分配菜单失败")
66102
}
103+
67104
return next, nil
68105
}
69106

server/source/system/casbin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ func (i *initCasbin) InitializeData(ctx context.Context) (context.Context, error
130130
{Ptype: "p", V0: "888", V1: "/autoCode/installPlugin", V2: "POST"},
131131
{Ptype: "p", V0: "888", V1: "/autoCode/pubPlug", V2: "POST"},
132132
{Ptype: "p", V0: "888", V1: "/autoCode/addFunc", V2: "POST"},
133+
{Ptype: "p", V0: "888", V1: "/autoCode/mcp", V2: "POST"},
133134

134135
{Ptype: "p", V0: "888", V1: "/sysDictionaryDetail/findSysDictionaryDetail", V2: "GET"},
135136
{Ptype: "p", V0: "888", V1: "/sysDictionaryDetail/updateSysDictionaryDetail", V2: "PUT"},

server/source/system/menu.go

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,44 +50,73 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er
5050
if !ok {
5151
return ctx, system.ErrMissingDBContext
5252
}
53-
entities := []SysBaseMenu{
53+
54+
// 定义所有菜单
55+
allMenus := []SysBaseMenu{
5456
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "dashboard", Name: "dashboard", Component: "view/dashboard/index.vue", Sort: 1, Meta: Meta{Title: "仪表盘", Icon: "odometer"}},
5557
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 9, Meta: Meta{Title: "关于我们", Icon: "info-filled"}},
5658
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "admin", Name: "superAdmin", Component: "view/superAdmin/index.vue", Sort: 3, Meta: Meta{Title: "超级管理员", Icon: "user"}},
57-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "authority", Name: "authority", Component: "view/superAdmin/authority/authority.vue", Sort: 1, Meta: Meta{Title: "角色管理", Icon: "avatar"}},
58-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "menu", Name: "menu", Component: "view/superAdmin/menu/menu.vue", Sort: 2, Meta: Meta{Title: "菜单管理", Icon: "tickets", KeepAlive: true}},
59-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "api", Name: "api", Component: "view/superAdmin/api/api.vue", Sort: 3, Meta: Meta{Title: "api管理", Icon: "platform", KeepAlive: true}},
60-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: Meta{Title: "用户管理", Icon: "coordinate"}},
61-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: Meta{Title: "字典管理", Icon: "notebook"}},
62-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: Meta{Title: "操作历史", Icon: "pie-chart"}},
6359
{MenuLevel: 0, Hidden: true, ParentId: 0, Path: "person", Name: "person", Component: "view/person/person.vue", Sort: 4, Meta: Meta{Title: "个人信息", Icon: "message"}},
6460
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 7, Meta: Meta{Title: "示例文件", Icon: "management"}},
65-
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: Meta{Title: "媒体库(上传下载)", Icon: "upload"}},
66-
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: Meta{Title: "断点续传", Icon: "upload-filled"}},
67-
{MenuLevel: 0, Hidden: false, ParentId: 11, Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: Meta{Title: "客户列表(资源示例)", Icon: "avatar"}},
6861
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "systemTools", Name: "systemTools", Component: "view/systemTools/index.vue", Sort: 5, Meta: Meta{Title: "系统工具", Icon: "tools"}},
69-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
70-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 3, Meta: Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
71-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 4, Meta: Meta{Title: "系统配置", Icon: "operation"}},
72-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoCodeAdmin", Name: "autoCodeAdmin", Component: "view/systemTools/autoCodeAdmin/index.vue", Sort: 2, Meta: Meta{Title: "自动化代码管理", Icon: "magic-stick"}},
73-
{MenuLevel: 0, Hidden: true, ParentId: 15, Path: "autoCodeEdit/:id", Name: "autoCodeEdit", Component: "view/systemTools/autoCode/index.vue", Sort: 0, Meta: Meta{Title: "自动化代码-${id}", Icon: "magic-stick"}},
74-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "autoPkg", Name: "autoPkg", Component: "view/systemTools/autoPkg/autoPkg.vue", Sort: 0, Meta: Meta{Title: "模板配置", Icon: "folder"}},
7562
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Component: "/", Sort: 0, Meta: Meta{Title: "官方网站", Icon: "customer-gva"}},
7663
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "state", Name: "state", Component: "view/system/state.vue", Sort: 8, Meta: Meta{Title: "服务器状态", Icon: "cloudy"}},
7764
{MenuLevel: 0, Hidden: false, ParentId: 0, Path: "plugin", Name: "plugin", Component: "view/routerHolder.vue", Sort: 6, Meta: Meta{Title: "插件系统", Icon: "cherry"}},
78-
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "https://plugin.gin-vue-admin.com/", Name: "https://plugin.gin-vue-admin.com/", Component: "https://plugin.gin-vue-admin.com/", Sort: 0, Meta: Meta{Title: "插件市场", Icon: "shop"}},
79-
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "installPlugin", Name: "installPlugin", Component: "view/systemTools/installPlugin/index.vue", Sort: 1, Meta: Meta{Title: "插件安装", Icon: "box"}},
80-
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "pubPlug", Name: "pubPlug", Component: "view/systemTools/pubPlug/pubPlug.vue", Sort: 3, Meta: Meta{Title: "打包插件", Icon: "files"}},
81-
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 4, Meta: Meta{Title: "邮件插件", Icon: "message"}},
82-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 5, Meta: Meta{Title: "导出模板", Icon: "reading"}},
83-
{MenuLevel: 0, Hidden: false, ParentId: 24, Path: "anInfo", Name: "anInfo", Component: "plugin/announcement/view/info.vue", Sort: 5, Meta: Meta{Title: "公告管理[示例]", Icon: "scaleToOriginal"}},
84-
{MenuLevel: 0, Hidden: false, ParentId: 3, Path: "sysParams", Name: "sysParams", Component: "view/superAdmin/params/sysParams.vue", Sort: 7, Meta: Meta{Title: "参数管理", Icon: "compass"}},
85-
{MenuLevel: 0, Hidden: false, ParentId: 15, Path: "picture", Name: "picture", Component: "view/systemTools/autoCode/picture.vue", Sort: 6, Meta: Meta{Title: "AI页面绘制", Icon: "picture-filled"}},
8665
}
87-
if err = db.Create(&entities).Error; err != nil {
88-
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"表数据初始化失败!")
66+
67+
// 先创建父级菜单(ParentId = 0 的菜单)
68+
if err = db.Create(&allMenus).Error; err != nil {
69+
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"父级菜单初始化失败!")
70+
}
71+
72+
// 建立菜单映射 - 通过Name查找已创建的菜单及其ID
73+
menuNameMap := make(map[string]uint)
74+
for _, menu := range allMenus {
75+
menuNameMap[menu.Name] = menu.ID
76+
}
77+
78+
// 定义子菜单,并设置正确的ParentId
79+
childMenus := []SysBaseMenu{
80+
// superAdmin子菜单
81+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "authority", Name: "authority", Component: "view/superAdmin/authority/authority.vue", Sort: 1, Meta: Meta{Title: "角色管理", Icon: "avatar"}},
82+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "menu", Name: "menu", Component: "view/superAdmin/menu/menu.vue", Sort: 2, Meta: Meta{Title: "菜单管理", Icon: "tickets", KeepAlive: true}},
83+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "api", Name: "api", Component: "view/superAdmin/api/api.vue", Sort: 3, Meta: Meta{Title: "api管理", Icon: "platform", KeepAlive: true}},
84+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: Meta{Title: "用户管理", Icon: "coordinate"}},
85+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: Meta{Title: "字典管理", Icon: "notebook"}},
86+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: Meta{Title: "操作历史", Icon: "pie-chart"}},
87+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["superAdmin"], Path: "sysParams", Name: "sysParams", Component: "view/superAdmin/params/sysParams.vue", Sort: 7, Meta: Meta{Title: "参数管理", Icon: "compass"}},
88+
89+
// example子菜单
90+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["example"], Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: Meta{Title: "媒体库(上传下载)", Icon: "upload"}},
91+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["example"], Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: Meta{Title: "断点续传", Icon: "upload-filled"}},
92+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["example"], Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: Meta{Title: "客户列表(资源示例)", Icon: "avatar"}},
93+
94+
// systemTools子菜单
95+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
96+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 3, Meta: Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
97+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 4, Meta: Meta{Title: "系统配置", Icon: "operation"}},
98+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "autoCodeAdmin", Name: "autoCodeAdmin", Component: "view/systemTools/autoCodeAdmin/index.vue", Sort: 2, Meta: Meta{Title: "自动化代码管理", Icon: "magic-stick"}},
99+
{MenuLevel: 1, Hidden: true, ParentId: menuNameMap["systemTools"], Path: "autoCodeEdit/:id", Name: "autoCodeEdit", Component: "view/systemTools/autoCode/index.vue", Sort: 0, Meta: Meta{Title: "自动化代码-${id}", Icon: "magic-stick"}},
100+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "autoPkg", Name: "autoPkg", Component: "view/systemTools/autoPkg/autoPkg.vue", Sort: 0, Meta: Meta{Title: "模板配置", Icon: "folder"}},
101+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 5, Meta: Meta{Title: "导出模板", Icon: "reading"}},
102+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["systemTools"], Path: "picture", Name: "picture", Component: "view/systemTools/autoCode/picture.vue", Sort: 6, Meta: Meta{Title: "AI页面绘制", Icon: "picture-filled"}},
103+
104+
// plugin子菜单
105+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["plugin"], Path: "https://plugin.gin-vue-admin.com/", Name: "https://plugin.gin-vue-admin.com/", Component: "https://plugin.gin-vue-admin.com/", Sort: 0, Meta: Meta{Title: "插件市场", Icon: "shop"}},
106+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["plugin"], Path: "installPlugin", Name: "installPlugin", Component: "view/systemTools/installPlugin/index.vue", Sort: 1, Meta: Meta{Title: "插件安装", Icon: "box"}},
107+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["plugin"], Path: "pubPlug", Name: "pubPlug", Component: "view/systemTools/pubPlug/pubPlug.vue", Sort: 3, Meta: Meta{Title: "打包插件", Icon: "files"}},
108+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["plugin"], Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 4, Meta: Meta{Title: "邮件插件", Icon: "message"}},
109+
{MenuLevel: 1, Hidden: false, ParentId: menuNameMap["plugin"], Path: "anInfo", Name: "anInfo", Component: "plugin/announcement/view/info.vue", Sort: 5, Meta: Meta{Title: "公告管理[示例]", Icon: "scaleToOriginal"}},
110+
}
111+
112+
// 创建子菜单
113+
if err = db.Create(&childMenus).Error; err != nil {
114+
return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+"子菜单初始化失败!")
89115
}
90-
next = context.WithValue(ctx, i.InitializerName(), entities)
116+
117+
// 组合所有菜单作为返回结果
118+
allEntities := append(allMenus, childMenus...)
119+
next = context.WithValue(ctx, i.InitializerName(), allEntities)
91120
return next, nil
92121
}
93122

web/src/pathInfo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"/src/view/systemTools/autoCode/component/fieldDialog.vue": "FieldDialog",
5858
"/src/view/systemTools/autoCode/component/previewCodeDialog.vue": "PreviewCodeDialog",
5959
"/src/view/systemTools/autoCode/index.vue": "AutoCode",
60+
"/src/view/systemTools/autoCode/mcp.vue": "Mcp",
6061
"/src/view/systemTools/autoCode/picture.vue": "Picture",
6162
"/src/view/systemTools/autoCodeAdmin/index.vue": "AutoCodeAdmin",
6263
"/src/view/systemTools/autoPkg/autoPkg.vue": "AutoPkg",

0 commit comments

Comments
 (0)