package menu import ( "fmt" "hyapp-admin-server/internal/modules/shared" "hyapp-admin-server/internal/repository" "hyapp-admin-server/internal/response" "github.com/gin-gonic/gin" ) type Handler struct { service *MenuService audit shared.OperationLogger } func New(store *repository.Store, audit shared.OperationLogger) *Handler { return &Handler{service: NewService(store), audit: audit} } func (h *Handler) NavigationMenus(c *gin.Context) { menus, err := h.service.NavigationMenus(shared.ActorFromContext(c)) if err != nil { response.ServerError(c, "获取菜单失败") return } response.OK(c, pruneEmptyMenuGroups(buildMenuTree(menus))) } func (h *Handler) ListSystemMenus(c *gin.Context) { // navigation/menus 是当前用户菜单;system/menus 是维护页全量菜单,二者权限边界不同。 menus, err := h.service.ListSystemMenus() if err != nil { response.ServerError(c, "获取菜单失败") return } response.OK(c, buildMenuTree(menus)) } func (h *Handler) CreateMenu(c *gin.Context) { var req menuRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "菜单名称和编码不能为空") return } menu, err := h.service.CreateMenu(menuInput(req)) if err != nil { response.BadRequest(c, err.Error()) return } shared.OperationLog(c, h.audit, "create-menu", "admin_menus", "success", menu.Code) response.Created(c, menuNodeFromModel(*menu)) } func (h *Handler) UpdateMenu(c *gin.Context) { id, ok := shared.ParseID(c, "id") if !ok { return } var req menuRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "菜单名称和编码不能为空") return } menu, err := h.service.UpdateMenu(id, menuInput(req)) if err != nil { response.BadRequest(c, err.Error()) return } shared.OperationLog(c, h.audit, "update-menu", "admin_menus", "success", menu.Code) response.OK(c, menuNodeFromModel(*menu)) } func (h *Handler) DeleteMenu(c *gin.Context) { id, ok := shared.ParseID(c, "id") if !ok { return } if err := h.service.DeleteMenu(id); err != nil { response.BadRequest(c, err.Error()) return } shared.OperationLog(c, h.audit, "delete-menu", "admin_menus", "success", fmt.Sprintf("menu_id=%d", id)) response.OK(c, gin.H{"deleted": true}) } func (h *Handler) UpdateMenuVisible(c *gin.Context) { id, ok := shared.ParseID(c, "id") if !ok { return } var req visibleRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "菜单显隐参数不正确") return } menu, err := h.service.UpdateMenuVisible(id, req.Visible) if err != nil { response.BadRequest(c, err.Error()) return } shared.OperationLog(c, h.audit, "update-menu-visible", "admin_menus", "success", fmt.Sprintf("%s -> %t", menu.Code, req.Visible)) response.OK(c, menuNodeFromModel(*menu)) } func (h *Handler) SortMenus(c *gin.Context) { var req menuSortRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "菜单排序参数不正确") return } if err := h.service.SortMenus(req.Items); err != nil { response.BadRequest(c, err.Error()) return } shared.OperationLog(c, h.audit, "sort-menus", "admin_menus", "success", fmt.Sprintf("%d items", len(req.Items))) response.OK(c, gin.H{"sorted": len(req.Items)}) } func menuInput(req menuRequest) MenuInput { return MenuInput{ ParentID: req.ParentID, Label: req.Label, Code: req.Code, Path: req.Path, Icon: req.Icon, PermissionCode: req.PermissionCode, Sort: req.Sort, Visible: req.Visible, } }