package controllers import ( "encoding/json" "server/models" "strconv" "strings" beego "github.com/beego/beego/v2/server/web" ) type BackendMenuController struct { beego.Controller } type AdminMenuController = BackendMenuController type menuPayload struct { Pid *int64 `json:"pid"` Title *string `json:"title"` Path *string `json:"path"` ComponentPath *string `json:"component_path"` Icon *string `json:"icon"` Sort *int64 `json:"sort"` Status *int8 `json:"status"` IsVisible *int8 `json:"is_visible"` Views []int `json:"views"` Type *int8 `json:"type"` Permission *string `json:"permission"` } func parseViews(raw *string) []int { if raw == nil || strings.TrimSpace(*raw) == "" { return nil } var arr []int if err := json.Unmarshal([]byte(*raw), &arr); err != nil { return nil } return arr } func hasView(arr []int, v int) bool { for _, n := range arr { if n == v { return true } } return false } func filterMenusByView(menus []models.SystemMenu, v int) []models.SystemMenu { out := make([]models.SystemMenu, 0, len(menus)) for _, m := range menus { views := parseViews(m.Views) if v == 1 && len(views) == 0 { out = append(out, m) continue } if hasView(views, v) { out = append(out, m) } } return out } func (c *BackendMenuController) GetMenu() { var menus []models.SystemMenu _, err := models.Orm.QueryTable(new(models.SystemMenu)).Filter("status", 1).All(&menus) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取菜单失败: " + err.Error(), "data": nil} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": buildMenuTree(filterMenusByView(menus, 1), 0)} _ = c.ServeJSON() } func (c *BackendMenuController) GetBackendMenu() { var menus []models.SystemMenu _, err := models.Orm.QueryTable(new(models.SystemMenu)).Filter("status", 1).All(&menus) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取菜单失败: " + err.Error(), "data": nil} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": buildMenuTree(filterMenusByView(menus, 2), 0)} _ = c.ServeJSON() } func (c *BackendMenuController) GetTenantList() { var tid uint64 if jwtTid := c.Ctx.Input.GetData("tid"); jwtTid != nil { tid = jwtTid.(uint64) } if tid == 0 { c.Data["json"] = map[string]interface{}{"code": 401, "msg": "未登录或非法请求"} _ = c.ServeJSON() return } var menus []models.SystemMenu if _, err := models.Orm.QueryTable(new(models.SystemMenu)).Filter("status", 1).All(&menus); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取失败:" + err.Error()} _ = c.ServeJSON() return } tree := buildMenuTree(filterMenusByView(menus, 2), 0) c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "获取成功", "data": map[string]interface{}{"list": tree, "total": len(tree)}, } _ = c.ServeJSON() } func (c *BackendMenuController) GetAllMenus() { var menus []models.SystemMenu cid, _ := c.GetInt("cid") if _, err := models.Orm.QueryTable(new(models.SystemMenu)).All(&menus); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取菜单失败: " + err.Error(), "data": nil} _ = c.ServeJSON() return } if cid == 1 { menus = filterMenusByView(menus, 1) } else if cid == 2 { menus = filterMenusByView(menus, 2) } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": buildMenuTree(menus, 0)} _ = c.ServeJSON() } func (c *BackendMenuController) GetAllBackendMenus() { var menus []models.SystemMenu if _, err := models.Orm.QueryTable(new(models.SystemMenu)).All(&menus); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取菜单失败: " + err.Error(), "data": nil} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": buildMenuTree(filterMenusByView(menus, 2), 0)} _ = c.ServeJSON() } type menuNode struct { ID uint64 `json:"id"` Pid int64 `json:"pid"` Title string `json:"title"` Path string `json:"path,omitempty"` ComponentPath string `json:"component_path,omitempty"` Icon string `json:"icon,omitempty"` Sort int64 `json:"sort"` Status int8 `json:"status"` IsVisible *int8 `json:"is_visible,omitempty"` Views []int `json:"views,omitempty"` Type int8 `json:"type"` Permission string `json:"permission,omitempty"` Children []*menuNode `json:"children,omitempty"` } func buildMenuTree(menus []models.SystemMenu, pid int64) []*menuNode { var tree []*menuNode for _, m := range menus { if m.Pid == pid { node := &menuNode{ ID: m.ID, Pid: m.Pid, Title: m.Title, Sort: m.Sort, Status: m.Status, IsVisible: m.IsVisible, Views: parseViews(m.Views), Type: m.Type, } if m.Path != nil { node.Path = *m.Path } if m.ComponentPath != nil { node.ComponentPath = *m.ComponentPath } if m.Icon != nil { node.Icon = *m.Icon } if m.Permission != nil { node.Permission = *m.Permission } if children := buildMenuTree(menus, int64(m.ID)); len(children) > 0 { node.Children = children } tree = append(tree, node) } } return tree } func (c *BackendMenuController) UpdateMenuStatus() { id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64) if err != nil || id == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"} _ = c.ServeJSON() return } var body struct { Status *int8 `json:"status"` } if err := json.Unmarshal(c.Ctx.Input.RequestBody, &body); err != nil || body.Status == nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"} _ = c.ServeJSON() return } if _, err = models.Orm.QueryTable(new(models.SystemMenu)).Filter("id", id).Update(map[string]interface{}{"status": *body.Status}); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "更新失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "success": true} _ = c.ServeJSON() } func (c *BackendMenuController) CreateMenu() { payload, ok := c.parseMenuPayload(true) if !ok { return } var viewsStr string views := payload.Views if len(views) == 0 { views = []int{1} } if b, err := json.Marshal(views); err == nil { viewsStr = string(b) } menu := models.SystemMenu{ Pid: valueInt64(payload.Pid, 0), Title: strings.TrimSpace(valueString(payload.Title, "")), Sort: valueInt64(payload.Sort, 0), Status: valueInt8(payload.Status, 1), IsVisible: ptrInt8(valueInt8(payload.IsVisible, 1)), Views: &viewsStr, Type: valueInt8(payload.Type, 1), Path: ptrString(valueString(payload.Path, "")), ComponentPath: ptrString(valueString(payload.ComponentPath, "")), Icon: ptrString(valueString(payload.Icon, "")), Permission: ptrString(valueString(payload.Permission, "")), } id, err := models.Orm.Insert(&menu) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "创建成功", "data": map[string]interface{}{"id": id}} _ = c.ServeJSON() } func (c *BackendMenuController) UpdateMenu() { id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64) if err != nil || id == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"} _ = c.ServeJSON() return } payload, ok := c.parseMenuPayload(false) if !ok { return } views := payload.Views if len(views) == 0 { views = []int{1} } viewsBytes, _ := json.Marshal(views) update := map[string]interface{}{ "pid": valueInt64(payload.Pid, 0), "title": strings.TrimSpace(valueString(payload.Title, "")), "path": valueString(payload.Path, ""), "component_path": valueString(payload.ComponentPath, ""), "icon": valueString(payload.Icon, ""), "sort": valueInt64(payload.Sort, 0), "status": valueInt8(payload.Status, 1), "is_visible": valueInt8(payload.IsVisible, 1), "views": string(viewsBytes), "type": valueInt8(payload.Type, 1), "permission": valueString(payload.Permission, ""), } if _, err = models.Orm.QueryTable(new(models.SystemMenu)).Filter("id", id).Update(update); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "更新失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "更新成功"} _ = c.ServeJSON() } func (c *BackendMenuController) DeleteMenu() { id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64) if err != nil || id == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"} _ = c.ServeJSON() return } if _, err = models.Orm.QueryTable(new(models.SystemMenu)).Filter("id", id).Delete(); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "删除失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功", "success": true} _ = c.ServeJSON() } func (c *BackendMenuController) parseMenuPayload(needTitle bool) (*menuPayload, bool) { var payload menuPayload if err := json.Unmarshal(c.Ctx.Input.RequestBody, &payload); err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"} _ = c.ServeJSON() return nil, false } if needTitle && strings.TrimSpace(valueString(payload.Title, "")) == "" { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "菜单名称不能为空"} _ = c.ServeJSON() return nil, false } return &payload, true } func valueString(v *string, def string) string { if v == nil { return def } return *v } func valueInt8(v *int8, def int8) int8 { if v == nil { return def } return *v } func valueInt64(v *int64, def int64) int64 { if v == nil { return def } return *v } func ptrString(v string) *string { return &v } func ptrInt8(v int8) *int8 { return &v }