package menu import ( "errors" "net/http" "strconv" "strings" "time" systemmodel "management/internal/erpserver/model/system" v1 "management/internal/erpserver/service/v1" "management/internal/erpserver/templ/system/menu" "management/internal/pkg/convertor" "management/internal/pkg/mid" "management/internal/pkg/render" "management/internal/pkg/sqldb" "github.com/google/uuid" ) const style = "layui-btn-primary layui-btn-sm" type app struct { render render.Renderer menuService v1.MenuService } func newApp(render render.Renderer, menuService v1.MenuService) *app { return &app{ render: render, menuService: menuService, } } func (a *app) menus(w http.ResponseWriter, r *http.Request) { ctx := r.Context() user := mid.GetUser(ctx) menus, err := a.menuService.OwerMenus(ctx, user.RoleID) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSON(w, menus) } func (a *app) list(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: ctx := r.Context() a.render.Render(ctx, w, menu.List(ctx)) case http.MethodPost: res, err := a.menuService.ListMenuTree(r.Context()) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSON(w, render.NewResponseList(0, res)) default: a.render.JSONErr(w, "method not allowed") } } func (a *app) add(w http.ResponseWriter, r *http.Request) { ctx := r.Context() a.render.Render(ctx, w, menu.Edit(ctx, &systemmodel.Menu{Style: style, Visible: true, Sort: 6666})) } func (a *app) addChildren(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := r.URL.Query() parentID := convertor.QueryInt[int32](vars, "parentID", 0) vm := &systemmodel.Menu{ParentID: parentID, Style: style, Visible: true, Sort: 6666} parent, err := a.menuService.Get(ctx, parentID) if err == nil { if parent.Type == "node" { vm.Type = "menu" } else if parent.Type == "menu" { vm.Type = "btn" } } a.render.Render(ctx, w, menu.Edit(ctx, vm)) } func (a *app) edit(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := r.URL.Query() id := convertor.QueryInt[int32](vars, "id", 0) vm := &systemmodel.Menu{Style: style, Sort: 6666} if id > 0 { vm, _ = a.menuService.Get(r.Context(), id) } a.render.Render(ctx, w, menu.Edit(ctx, vm)) } func (a *app) save(w http.ResponseWriter, r *http.Request) { id := convertor.Int[int32](r.PostFormValue("ID"), 0) name := r.PostFormValue("Name") displayName := 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.Int[int32](r.PostFormValue("ParentID"), 0) visible := convertor.Bool(r.PostFormValue("Visible"), false) isList := convertor.Bool(r.PostFormValue("IsList"), false) sort := convertor.Int[int32](r.PostFormValue("Sort"), 6666) status := convertor.Int[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 := a.menuService.Get(ctx, parentID) if err != nil { a.render.JSONErr(w, err.Error()) return } parentPath = parent.ParentPath + "," + strconv.Itoa(int(parentID)) + "," parentPath = strings.ReplaceAll(parentPath, ",,", ",") } if id == 0 { arg := &systemmodel.Menu{ Name: name, DisplayName: displayName, Url: url, Type: t, ParentID: parentID, ParentPath: parentPath, Avatar: avatar, Style: style, Visible: visible, IsList: isList, Status: status, Sort: sort, CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := a.menuService.Create(ctx, arg) if err != nil { if errors.Is(err, sqldb.ErrDBDuplicatedEntry) { a.render.JSONErr(w, "菜单已存在") return } a.render.JSONErr(w, err.Error()) return } a.render.JSONOk(w, "添加成功") } else { res, err := a.menuService.Get(ctx, id) if err != nil { a.render.JSONErr(w, err.Error()) return } res.Name = name res.DisplayName = displayName res.Url = url res.Type = t res.ParentID = parentID res.ParentPath = parentPath res.Avatar = avatar res.Style = style res.Visible = visible res.IsList = isList res.Status = status res.Sort = sort res.UpdatedAt = time.Now() err = a.menuService.Update(ctx, res) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSONOk(w, "更新成功") } } func (a *app) data(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := r.URL.Query() t := vars.Get("type") if t == "tree" { res, err := a.menuService.Tree(ctx, 0) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSON(w, res) return } else if t == "xm_select_tree" { res, err := a.menuService.XmSelectTree(ctx, 0) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSON(w, res) return } a.render.JSON(w, nil) } func (a *app) refreshCache(w http.ResponseWriter, r *http.Request) { err := a.menuService.RefreshCache(r.Context()) if err != nil { a.render.JSONErr(w, err.Error()) return } a.render.JSONOk(w, "缓存刷新成功") }