package role import ( "bytes" "context" "fmt" "time" "management/internal/erpserver/model/dto" "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.RoleRepository { return &store{ db: db, log: log, } } func (s *store) Initialize(ctx context.Context) (*system.Role, error) { count, err := s.Count(ctx, dto.SearchDto{}) if err != nil { return nil, err } if count == 0 { obj := system.Role{ Name: "Company", DisplayName: "公司", Vip: false, ParentID: 0, ParentPath: ",0,", Status: 0, CreatedAt: time.Now(), UpdatedAt: time.Now(), } if err := s.Create(ctx, &obj); err != nil { return nil, err } obj1 := system.Role{ Name: "SuperAdmin", DisplayName: "超级管理员", Vip: true, ParentID: obj.ID, ParentPath: fmt.Sprintf(",0,%d,", obj.ID), Status: 0, CreatedAt: time.Now(), UpdatedAt: time.Now(), } if err := s.Create(ctx, &obj1); err != nil { return nil, err } return &obj1, nil } return s.GetByVip(ctx, true) } func (s *store) Create(ctx context.Context, obj *system.Role) error { //goland:noinspection ALL const q = ` INSERT INTO sys_role ( name, display_name, parent_id, parent_path, vip, status, sort ) VALUES ( :name, :display_name, :parent_id, :parent_path, :vip, :status, :sort )` return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj) } func (s *store) Update(ctx context.Context, obj *system.Role) error { const q = ` UPDATE sys_role SET name = :name, display_name = :display_name, parent_id = :parent_id, parent_path = :parent_path, 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) GetByVip(ctx context.Context, vip bool) (*system.Role, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, parent_id, parent_path, vip, status, sort, created_at, updated_at FROM sys_role WHERE vip = :vip;` data := map[string]any{ "vip": vip, } var role system.Role if err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &role); err != nil { return nil, fmt.Errorf("select vip role: %w", err) } return &role, nil } func (s *store) Get(ctx context.Context, id int32) (*system.Role, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, parent_id, parent_path, vip, status, sort, created_at, updated_at FROM sys_role WHERE id = :id;` data := map[string]any{ "id": id, } var role system.Role err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &role) if err != nil { return nil, fmt.Errorf("select id role: %w", err) } return &role, nil } func (s *store) All(ctx context.Context) ([]*system.Role, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, parent_id, parent_path, vip, status, sort, created_at, updated_at FROM sys_role;` data := map[string]any{} var roles []system.Role err := sqldb.NamedQuerySlice(ctx, s.log, s.db.DB(ctx), q, data, &roles) if err != nil { return nil, fmt.Errorf("select all role: %w", err) } return toPointer(roles), nil } func (s *store) Count(ctx context.Context, filter dto.SearchDto) (int64, error) { //goland:noinspection ALL const q = ` SELECT COUNT(1) FROM sys_role` data := map[string]any{} buf := bytes.NewBufferString(q) applyFilter(filter, data, buf) var count struct { Count int64 `db:"count"` } err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), buf.String(), data, &count) if err != nil { return 0, fmt.Errorf("select count role: %w", err) } return count.Count, nil } func (s *store) List(ctx context.Context, filter dto.SearchDto) ([]*system.Role, error) { //goland:noinspection ALL const q = ` SELECT id, name, display_name, parent_id, parent_path, vip, status, sort, created_at, updated_at FROM sys_role` data := map[string]any{ "offset": (filter.Page - 1) * filter.Rows, "rows_per_page": filter.Rows, } buf := bytes.NewBufferString(q) applyFilter(filter, data, buf) buf.WriteString(" ORDER BY id DESC") buf.WriteString(" LIMIT :rows_per_page OFFSET :offset") var roles []system.Role err := sqldb.NamedQuerySlice(ctx, s.log, s.db.DB(ctx), buf.String(), data, &roles) if err != nil { return nil, err } return toPointer(roles), nil } func (s *store) RebuildParentPath(ctx context.Context) error { query := `UPDATE sys_role 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_role WHERE id = tm.id UNION ALL SELECT sys_role.id, sys_role.parent_id FROM sys_role, temp WHERE sys_role.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.Role) []*system.Role { var res []*system.Role for _, v := range data { res = append(res, &v) } return res }