137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
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,
|
||
}
|
||
}
|