package menu import ( "context" "fmt" "management/internal/erpserver/model/system" "management/internal/erpserver/repository" "management/internal/pkg/sqldb" "github.com/drhin/logger" ) type store struct { db *repository.Store log *logger.Logger } func NewStore(db *repository.Store, log *logger.Logger) system.MenuRepository { return &store{ db: db, log: log, } } func (s *store) Create(ctx context.Context, obj *system.Menu) (*system.Menu, error) { //goland:noinspection ALL const q = ` INSERT INTO sys_menu ( name, display_name, url, type, parent_id, parent_path, avatar, style, visible, is_list, status, sort ) VALUES ( :name, :display_name, :url, :type, :parent_id, :parent_path, :avatar, :style, :visible, :is_list, :status, :sort ) RETURNING *;` data := map[string]any{ "name": obj.Name, "display_name": obj.DisplayName, "url": obj.Url, "type": obj.Type, "parent_id": obj.ParentID, "parent_path": obj.ParentPath, "avatar": obj.Avatar, "style": obj.Style, "visible": obj.Visible, "is_list": obj.IsList, "status": obj.Status, "sort": obj.Sort, } err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj) if err != nil { return nil, err } return obj, nil } func (s *store) Update(ctx context.Context, obj *system.Menu) error { const q = ` UPDATE sys_menu SET name = :name, display_name = :display_name, url = :url, type = :type, parent_id = :parent_id, parent_path = :parent_path, avatar = :avatar, style = :style, visible = :visible, is_list = :is_list, status = :status, sort = :sort, updated_at = :updated_at WHERE id = :id;` return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj) } func (s *store) Get(ctx context.Context, id int32) (*system.Menu, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, url, type, parent_id, parent_path, avatar, style, visible, is_list, status, sort, created_at, updated_at FROM sys_menu WHERE id = :id;` data := map[string]any{ "id": id, } var menu system.Menu err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &menu) if err != nil { return nil, fmt.Errorf("select id menu: %w", err) } return &menu, nil } func (s *store) GetByUrl(ctx context.Context, url string) (*system.Menu, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, url, type, parent_id, parent_path, avatar, style, visible, is_list, status, sort, created_at, updated_at FROM sys_menu WHERE url = :url;` data := map[string]any{ "url": url, } var menu system.Menu err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &menu) if err != nil { return nil, fmt.Errorf("select id menu: %w", err) } return &menu, nil } func (s *store) All(ctx context.Context) ([]*system.Menu, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, url, type, parent_id, parent_path, avatar, style, visible, is_list, status, sort, created_at, updated_at FROM sys_menu;` data := map[string]any{} var menus []system.Menu err := sqldb.NamedQuerySlice(ctx, s.log, s.db.DB(ctx), q, data, &menus) if err != nil { return nil, fmt.Errorf("select all menu: %w", err) } return toPointer(menus), nil } func (s *store) Count(ctx context.Context) (int64, error) { //goland:noinspection ALL const q = ` SELECT COUNT(1) FROM sys_menu` data := map[string]any{} var count struct { Count int64 `db:"count"` } err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &count) if err != nil { return 0, fmt.Errorf("select count menu: %w", err) } return count.Count, nil } func (s *store) RebuildParentPath(ctx context.Context) error { query := ` UPDATE sys_menu AS tm SET parent_path = (SELECT ',' || string_agg(cast(t.parent_id AS VARCHAR), ',') || ',' FROM (WITH RECURSIVE temp (id, parent_id) AS (SELECT id, tm.parent_id FROM sys_menu WHERE id = tm.id UNION ALL SELECT sys_menu.id, sys_menu.parent_id FROM sys_menu, temp WHERE sys_menu.id = temp.parent_id) SELECT id, parent_id FROM temp ORDER BY id) AS t) WHERE tm.status = 0;` return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), query, nil) } func toPointer(data []system.Menu) []*system.Menu { var res []*system.Menu for _, v := range data { res = append(res, &v) } return res }