{"record":{"id":"f480bba786db6312","repo":"flipped-aurora/gin-vue-admin","slug":"name-name","errorCode":null,"errorMessage":"存在重复name，请修改name","messagePattern":"存在重复name，请修改name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_menu.go","lineNumber":141,"sourceCode":"func (menuService *MenuService) getBaseChildrenList(menu *system.SysBaseMenu, treeMap map[uint][]system.SysBaseMenu) (err error) {\n\tmenu.Children = treeMap[menu.ID]\n\tfor i := 0; i < len(menu.Children); i++ {\n\t\terr = menuService.getBaseChildrenList(&menu.Children[i], treeMap)\n\t}\n\treturn err\n}\n\n//@author: [piexlmax](https://github.com/piexlmax)\n//@function: AddBaseMenu\n//@description: 添加基础路由\n//@param: menu model.SysBaseMenu\n//@return: error\n\nfunc (menuService *MenuService) AddBaseMenu(ctx context.Context, menu system.SysBaseMenu) error {\n\treturn global.GVA_DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {\n\t\t// 检查name是否重复\n\t\tif !errors.Is(tx.Where(\"name = ?\", menu.Name).First(&system.SysBaseMenu{}).Error, gorm.ErrRecordNotFound) {\n\t\t\treturn errors.New(\"存在重复name，请修改name\")\n\t\t}\n\n\t\tif menu.ParentId != 0 {\n\t\t\t// 检查父菜单是否存在\n\t\t\tvar parentMenu system.SysBaseMenu\n\t\t\tif err := tx.First(&parentMenu, menu.ParentId).Error; err != nil {\n\t\t\t\tif errors.Is(err, gorm.ErrRecordNotFound) {\n\t\t\t\t\treturn errors.New(\"父菜单不存在\")\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// 检查父菜单下现有子菜单数量\n\t\t\tvar existingChildrenCount int64\n\t\t\terr := tx.Model(&system.SysBaseMenu{}).Where(\"parent_id = ?\", menu.ParentId).Count(&existingChildrenCount).Error\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_menu.go#L123-L159","documentation":"Raised inside AddBaseMenu's transaction: before inserting a new base menu, the service checks whether another SysBaseMenu row already has the same route name. Because menu Name is used as the route identifier, duplicates are rejected with this ad-hoc error and the transaction rolls back.","triggerScenarios":"POST /menu/addMenu (or any caller of MenuService.AddBaseMenu) with a menu whose Name matches an existing menu row in sys_base_menu.","commonSituations":"Re-submitting a form twice; importing seed data that already created menus; copying a menu and forgetting to change the name; syncing menus from another environment with the same route names.","solutions":["Pick a unique Name for the new menu (query SELECT name FROM sys_base_menu to see taken names).","If the menu already exists, use the update API instead of adding a new one.","Remove duplicate rows from import/seed data before re-running."],"exampleFix":"// before\nmenuApi.addMenu({ name: 'user', ... })  // 'user' already exists\n// after\nmenuApi.addMenu({ name: 'userProfile', ... })","handlingStrategy":"validation","validationCode":"const names = (await menuApi.getMenuList()).data.list.map(m => m.name)\nif (names.includes(newMenu.name)) {\n  alert(`菜单 name \"${newMenu.name}\" 已存在，请修改后再提交`)\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await menuApi.addMenu(newMenu)\n} catch (e) {\n  if (String(e.msg).includes('存在重复name')) {\n    formRef.value.validateField('name') // highlight the name field for editing\n  } else throw e\n}","preventionTips":["Adopt a naming convention (module.page, e.g. user.profile) to reduce collisions.","Add client-side duplicate-name checking against the loaded menu list before submit.","Keep import/seed data idempotent (skip existing names)."],"tags":["go","gin-vue-admin","menu","duplicate-key","validation"],"backgroundTag":"duplicate-name","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}