255 lines
5.7 KiB
Go
255 lines
5.7 KiB
Go
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 {
|
|
var err error
|
|
obj := &system.Role{
|
|
Name: "Company",
|
|
DisplayName: "公司",
|
|
Vip: false,
|
|
ParentID: 0,
|
|
ParentPath: ",0,",
|
|
Status: 0,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
obj, err = s.Create(ctx, obj)
|
|
if 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(),
|
|
}
|
|
obj1, err = s.Create(ctx, obj1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return obj1, nil
|
|
}
|
|
|
|
return s.GetByVip(ctx, true)
|
|
|
|
}
|
|
|
|
func (s *store) Create(ctx context.Context, obj *system.Role) (*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
|
|
) RETURNING *`
|
|
|
|
data := map[string]any{
|
|
"name": obj.Name,
|
|
"display_name": obj.DisplayName,
|
|
"parent_id": obj.ParentID,
|
|
"parent_path": obj.ParentPath,
|
|
"vip": obj.Vip,
|
|
"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.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
|
|
}
|