361 lines
10 KiB
Go
361 lines
10 KiB
Go
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 }
|