package system import ( "encoding/json" "net/http" "strconv" "strings" "time" "management/internal/db/model/dto" db "management/internal/db/sqlc" "management/internal/erpserver/biz" "management/internal/global/know" "management/internal/pkg/convertor" "management/internal/pkg/session" "management/internal/pkg/tpl" "github.com/google/uuid" ) const style = "layui-btn-primary layui-btn-sm" type MenuHandler interface { MenuExpansion } type MenuExpansion interface { Menus(w http.ResponseWriter, r *http.Request) List(w http.ResponseWriter, r *http.Request) Add(w http.ResponseWriter, r *http.Request) AddChildren(w http.ResponseWriter, r *http.Request) Edit(w http.ResponseWriter, r *http.Request) Save(w http.ResponseWriter, r *http.Request) Data(w http.ResponseWriter, r *http.Request) Refresh(w http.ResponseWriter, r *http.Request) } type menuHandler struct { render tpl.Renderer session session.ISession biz biz.IBiz } var _ MenuHandler = (*menuHandler)(nil) func NewMenuHandler(render tpl.Renderer, session session.ISession, biz biz.IBiz) *menuHandler { return &menuHandler{ render: render, session: session, biz: biz, } } func (h *menuHandler) Menus(w http.ResponseWriter, r *http.Request) { ctx := r.Context() b := h.session.GetBytes(ctx, know.StoreName) var u dto.AuthorizeUser if err := json.Unmarshal(b, &u); err != nil { h.render.JSONERR(w, err.Error()) return } menus, err := h.biz.SystemV1().MenuBiz().RecursiveSysMenus(ctx, u.RoleID) if err != nil { h.render.JSONERR(w, err.Error()) return } h.render.JSON(w, menus) } func (h *menuHandler) List(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: h.render.HTML(w, r, "menu/list.tmpl", nil) case http.MethodPost: res, err := h.biz.SystemV1().MenuBiz().ListMenuTree(r.Context()) if err != nil { h.render.JSONERR(w, err.Error()) return } data := tpl.ResponseList{ Code: 0, Message: "ok", Count: 0, Data: res, } h.render.JSON(w, data) default: h.render.JSONERR(w, "method not allowed") } } func (h *menuHandler) Add(w http.ResponseWriter, r *http.Request) { h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{ "Item": &db.SysMenu{Style: style, Visible: true, Sort: 6666}, }) } func (h *menuHandler) AddChildren(w http.ResponseWriter, r *http.Request) { vars := r.URL.Query() parentID := convertor.QueryInt[int32](vars, "parentID", 0) vm := &db.SysMenu{ParentID: int32(parentID), Style: style, Visible: true, Sort: 6666} parent, err := h.biz.SystemV1().MenuBiz().Get(r.Context(), parentID) if err == nil { if parent.Type == "node" { vm.Type = "menu" } else if parent.Type == "menu" { vm.Type = "btn" } } h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{ "Item": vm, }) } func (h *menuHandler) Edit(w http.ResponseWriter, r *http.Request) { vars := r.URL.Query() id := convertor.QueryInt[int32](vars, "id", 0) vm := &db.SysMenu{Style: style, Sort: 6666} if id > 0 { vm, _ = h.biz.SystemV1().MenuBiz().Get(r.Context(), id) } h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{ "Item": vm, }) } func (h *menuHandler) Save(w http.ResponseWriter, r *http.Request) { id := convertor.ConvertInt[int32](r.PostFormValue("ID"), 0) name := r.PostFormValue("Name") dispalyName := r.PostFormValue("DisplayName") t := r.PostFormValue("Type") url := r.PostFormValue("Url") if len(url) == 0 { url = uuid.Must(uuid.NewRandom()).String() } avatar := r.PostFormValue("Avatar") style := r.PostFormValue("Style") parentID := convertor.ConvertInt[int32](r.PostFormValue("ParentID"), 0) visible := convertor.ConvertBool(r.PostFormValue("Visible"), false) isList := convertor.ConvertBool(r.PostFormValue("IsList"), false) sort := convertor.ConvertInt[int32](r.PostFormValue("Sort"), 6666) status := convertor.ConvertInt[int32](r.PostFormValue("Status"), 0) ctx := r.Context() if len(avatar) > 0 && !strings.Contains(avatar, "layui-icon ") { avatar = "layui-icon " + avatar } parentPath := "" if parentID > 0 { parent, err := h.biz.SystemV1().MenuBiz().Get(ctx, parentID) if err != nil { h.render.JSONERR(w, err.Error()) return } parentPath = parent.ParentPath + "," + strconv.Itoa(int(parentID)) + "," parentPath = strings.ReplaceAll(parentPath, ",,", ",") } if id == 0 { arg := &db.CreateSysMenuParams{ Name: name, DisplayName: dispalyName, Url: url, Type: t, ParentID: int32(parentID), ParentPath: parentPath, Avatar: avatar, Style: style, Visible: visible, IsList: isList, Status: status, Sort: sort, CreatedAt: time.Now(), UpdatedAt: time.Now(), } _, err := h.biz.SystemV1().MenuBiz().Create(ctx, arg) if err != nil { if db.IsUniqueViolation(err) { h.render.JSONERR(w, "菜单已存在") return } h.render.JSONERR(w, err.Error()) return } h.render.JSONOK(w, "添加成功") } else { res, err := h.biz.SystemV1().MenuBiz().Get(ctx, id) if err != nil { h.render.JSONERR(w, err.Error()) return } arg := &db.UpdateSysMenuParams{ ID: res.ID, Name: name, DisplayName: dispalyName, Url: url, Type: t, ParentID: parentID, ParentPath: parentPath, Avatar: avatar, Style: style, Visible: visible, IsList: isList, Status: status, Sort: sort, UpdatedAt: time.Now(), } _, err = h.biz.SystemV1().MenuBiz().Update(ctx, arg) if err != nil { h.render.JSONERR(w, err.Error()) return } h.render.JSONOK(w, "更新成功") } } func (h *menuHandler) Data(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := r.URL.Query() t := vars.Get("type") if t == "tree" { res, err := h.biz.SystemV1().MenuBiz().Tree(ctx, 0) if err != nil { h.render.JSONERR(w, err.Error()) return } h.render.JSON(w, res) return } else if t == "xmselect_tree" { res, err := h.biz.SystemV1().MenuBiz().XmSelectTree(ctx, 0) if err != nil { h.render.JSONERR(w, err.Error()) return } h.render.JSON(w, res) return } } func (h *menuHandler) Refresh(w http.ResponseWriter, r *http.Request) { err := h.biz.SystemV1().MenuBiz().RefreshMenus(r.Context()) if err != nil { h.render.JSONERR(w, err.Error()) return } h.render.JSONOK(w, "刷新成功") }