package admin import ( "net/http" "strconv" "time" "bindbox-game/internal/pkg/core" "bindbox-game/internal/repository/mysql/model" ) type simpleRoute struct { Path string `json:"path"` Name string `json:"name"` Component string `json:"component"` Meta map[string]any `json:"meta"` Children []simpleRoute `json:"children,omitempty"` } // ListSimpleMenus 返回前端所需的简单路由结构 // @Router /api/v3/system/menus/simple [get] func (h *handler) ListSimpleMenus() core.HandlerFunc { return func(ctx core.Context) { // 读取启用的菜单,构造成前端路由结构 rows, err := h.readDB.Menus.Where(h.readDB.Menus.Status.Is(true)).Order(h.readDB.Menus.Sort).Find() if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10021, err.Error())) return } // 构建 parent_id => children nodeMap := make(map[uint64]*simpleRoute) var roots []simpleRoute for _, m := range rows { r := &simpleRoute{ Path: m.Path, Name: m.Name, Component: m.Component, Meta: map[string]any{ "title": m.Name, "keepAlive": m.KeepAlive, "isHide": m.IsHide, "isHideTab": m.IsHideTab, "icon": m.Icon, }, } nodeMap[uint64(m.ID)] = r } // 第二遍挂载到父节点 for _, m := range rows { id := uint64(m.ID) pid := uint64(m.ParentID) if pid == 0 { roots = append(roots, *nodeMap[id]) continue } parent := nodeMap[pid] if parent != nil { parent.Children = append(parent.Children, *nodeMap[id]) } else { // 无父节点,作为根返回 roots = append(roots, *nodeMap[id]) } } ctx.Payload(roots) } } type createMenuRequest struct { ParentID uint64 `json:"parent_id"` Path string `json:"path"` Name string `json:"name"` Component string `json:"component"` Icon string `json:"icon"` Sort int `json:"sort"` Status bool `json:"status"` KeepAlive bool `json:"keep_alive"` IsHide bool `json:"is_hide"` IsHideTab bool `json:"is_hide_tab"` } func (h *handler) CreateMenu() core.HandlerFunc { return func(ctx core.Context) { req := new(createMenuRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10031, err.Error())) return } err := h.writeDB.Menus.WithContext(ctx.RequestContext()).Create(&model.Menus{ParentID: int64(req.ParentID), Path: req.Path, Name: req.Name, Component: req.Component, Icon: req.Icon, Sort: int32(req.Sort), Status: req.Status, KeepAlive: req.KeepAlive, IsHide: req.IsHide, IsHideTab: req.IsHideTab}) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10032, err.Error())) return } ctx.Payload(map[string]string{"message": "ok"}) } } type modifyMenuRequest struct { ParentID *uint64 `json:"parent_id"` Path *string `json:"path"` Name *string `json:"name"` Component *string `json:"component"` Icon *string `json:"icon"` Sort *int `json:"sort"` Status *bool `json:"status"` KeepAlive *bool `json:"keep_alive"` IsHide *bool `json:"is_hide"` IsHideTab *bool `json:"is_hide_tab"` } func (h *handler) ModifyMenu() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("menu_id") id, _ := strconv.ParseInt(idStr, 10, 64) req := new(modifyMenuRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10033, err.Error())) return } set := map[string]any{} if req.ParentID != nil { set["parent_id"] = int64(*req.ParentID) } if req.Path != nil { set["path"] = *req.Path } if req.Name != nil { set["name"] = *req.Name } if req.Component != nil { set["component"] = *req.Component } if req.Icon != nil { set["icon"] = *req.Icon } if req.Sort != nil { set["sort"] = *req.Sort } if req.Status != nil { set["status"] = *req.Status } if req.KeepAlive != nil { set["keep_alive"] = *req.KeepAlive } if req.IsHide != nil { set["is_hide"] = *req.IsHide } if req.IsHideTab != nil { set["is_hide_tab"] = *req.IsHideTab } if _, err := h.writeDB.Menus.WithContext(ctx.RequestContext()).Where(h.writeDB.Menus.ID.Eq(id)).Updates(set); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10034, err.Error())) return } ctx.Payload(map[string]string{"message": "ok"}) } } func (h *handler) DeleteMenu() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("menu_id") id, _ := strconv.ParseInt(idStr, 10, 64) uid := int64(ctx.SessionUserInfo().Id) set := map[string]any{"deleted_at": time.Now(), "deleted_by": uid} if _, err := h.writeDB.Menus.WithContext(ctx.RequestContext()).Where(h.writeDB.Menus.ID.Eq(id)).Updates(set); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10035, err.Error())) return } ctx.Payload(map[string]string{"message": "ok"}) } } func (h *handler) ListMenuActions() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("menu_id") id, _ := strconv.ParseInt(idStr, 10, 64) rows, err := h.readDB.MenuActions.WithContext(ctx.RequestContext()).Where(h.readDB.MenuActions.MenuID.Eq(id)).Find() if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10036, err.Error())) return } ctx.Payload(rows) } } type createActionsRequest struct { Actions []struct { ActionMark string `json:"action_mark"` ActionName string `json:"action_name"` Status bool `json:"status"` } `json:"actions"` } func (h *handler) CreateMenuActions() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("menu_id") id, _ := strconv.ParseInt(idStr, 10, 64) req := new(createActionsRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10037, err.Error())) return } tx := h.writeDB.MenuActions.WithContext(ctx.RequestContext()) for _, a := range req.Actions { err := tx.Create(&model.MenuActions{MenuID: id, ActionMark: a.ActionMark, ActionName: a.ActionName, Status: a.Status}) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10038, err.Error())) return } } ctx.Payload(map[string]string{"message": "ok"}) } } func (h *handler) DeleteMenuAction() core.HandlerFunc { return func(ctx core.Context) { idStr := ctx.Param("menu_id") id, _ := strconv.ParseInt(idStr, 10, 64) aidStr := ctx.Param("action_id") aid, _ := strconv.ParseInt(aidStr, 10, 64) uid := int64(ctx.SessionUserInfo().Id) set := map[string]any{"deleted_at": time.Now(), "deleted_by": uid} if _, err := h.writeDB.MenuActions.WithContext(ctx.RequestContext()).Where(h.writeDB.MenuActions.ID.Eq(aid), h.writeDB.MenuActions.MenuID.Eq(id)).Updates(set); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10039, err.Error())) return } ctx.Payload(map[string]string{"message": "ok"}) } } type assignMenusRequest struct { MenuIDs []int64 `json:"menu_ids"` } type assignActionsRequest struct { ActionIDs []int64 `json:"action_ids"` } func (h *handler) AssignRoleMenus() core.HandlerFunc { return func(ctx core.Context) { ridStr := ctx.Param("role_id") rid, _ := strconv.ParseInt(ridStr, 10, 64) req := new(assignMenusRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10041, err.Error())) return } tx := h.writeDB.RoleMenus.WithContext(ctx.RequestContext()) for _, mid := range req.MenuIDs { err := tx.Create(&model.RoleMenus{RoleID: rid, MenuID: mid}) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10042, err.Error())) return } } ctx.Payload(map[string]string{"message": "ok"}) } } func (h *handler) AssignRoleActions() core.HandlerFunc { return func(ctx core.Context) { ridStr := ctx.Param("role_id") rid, _ := strconv.ParseInt(ridStr, 10, 64) req := new(assignActionsRequest) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10043, err.Error())) return } tx := h.writeDB.RoleActions.WithContext(ctx.RequestContext()) for _, aid := range req.ActionIDs { err := tx.Create(&model.RoleActions{RoleID: rid, ActionID: aid}) if err != nil { ctx.AbortWithError(core.Error(http.StatusBadRequest, 10044, err.Error())) return } } ctx.Payload(map[string]string{"message": "ok"}) } }