2025-06-18 17:50:02 +08:00

235 lines
5.4 KiB
Go

package user
import (
"bytes"
"context"
"fmt"
"time"
"management/internal/erpserver/model/dto"
"management/internal/erpserver/model/system"
"management/internal/erpserver/repository"
"management/internal/pkg/crypto"
"management/internal/pkg/rand"
"management/internal/pkg/sqldb"
"github.com/drhin/logger"
"github.com/google/uuid"
)
type store struct {
db *repository.Store
log *logger.Logger
}
func NewStore(db *repository.Store, log *logger.Logger) system.UserRepository {
return &store{
db: db,
log: log,
}
}
func (s *store) Initialize(ctx context.Context, departId, roleId int32) error {
count, err := s.Count(ctx, dto.SearchDto{})
if err != nil {
return err
}
if count == 0 {
salt, err := rand.String(10)
if err != nil {
return err
}
password := "secret"
hashedPassword, err := crypto.BcryptHashPassword(password + salt)
if err != nil {
return err
}
initTime, err := time.ParseInLocation(time.DateTime, "0001-01-01 00:00:00", time.Local)
if err != nil {
return err
}
user := system.User{
Uuid: uuid.Must(uuid.NewV7()),
Email: "1185230223@qq.com",
Username: "kenneth",
HashedPassword: hashedPassword,
Salt: salt,
Avatar: "/assets/admin/images/avatar.jpg",
Gender: 1,
DepartmentID: departId,
RoleID: roleId,
Status: 0,
ChangePasswordAt: initTime,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
return s.Create(ctx, &user)
}
return nil
}
func (s *store) Create(ctx context.Context, obj *system.User) error {
//goland:noinspection ALL
const q = `
INSERT INTO sys_user (
uuid, email, username, hashed_password, salt, avatar, gender, department_id, role_id, status
) VALUES (
:uuid, :email, :username, :hashed_password, :salt, :avatar, :gender, :department_id, :role_id, :status
);`
return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
}
func (s *store) Update(ctx context.Context, obj *system.User) error {
//goland:noinspection ALL
const q = `
UPDATE sys_user
SET email = :email,
username = :username,
hashed_password = :hashed_password,
avatar = :avatar,
gender = :gender,
department_id = :department_id,
role_id = :role_id,
status = :status,
change_password_at = :change_password_at,
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.User, error) {
//goland:noinspection ALL
const q = `
SELECT
id, uuid, email, username, hashed_password, salt, avatar, gender, department_id,
role_id, status, change_password_at, created_at, updated_at
FROM
sys_user
WHERE
id = :id;`
data := map[string]any{
"id": id,
}
var user system.User
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &user)
if err != nil {
return nil, fmt.Errorf("select id user: %w", err)
}
return &user, nil
}
func (s *store) GetByEmail(ctx context.Context, email string) (*system.User, error) {
//goland:noinspection ALL
const q = `
SELECT
id, uuid, email, username, hashed_password, salt, avatar, gender, department_id,
role_id, status, change_password_at, created_at, updated_at
FROM
sys_user
WHERE
email = :email;`
data := map[string]any{
"email": email,
}
var user system.User
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &user)
if err != nil {
return nil, fmt.Errorf("select email user: %w", err)
}
return &user, nil
}
func (s *store) All(ctx context.Context) ([]*system.User, error) {
//goland:noinspection ALL
const q = `
SELECT
id, uuid, email, username, hashed_password, salt, avatar, gender, department_id,
role_id, status, change_password_at, created_at, updated_at
FROM
sys_user;`
data := map[string]any{}
var users []system.User
err := sqldb.NamedQuerySlice(ctx, s.log, s.db.DB(ctx), q, data, &users)
if err != nil {
return nil, fmt.Errorf("select all role: %w", err)
}
return toPointer(users), nil
}
func (s *store) Count(ctx context.Context, filter dto.SearchDto) (int64, error) {
//goland:noinspection ALL
const q = `
SELECT
COUNT(1)
FROM
sys_user`
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 user: %w", err)
}
return count.Count, nil
}
func (s *store) List(ctx context.Context, filter dto.SearchDto) ([]*system.User, error) {
//goland:noinspection ALL
const q = `
SELECT
id, uuid, email, username, hashed_password, salt, avatar, gender, department_id,
role_id, status, change_password_at, created_at, updated_at
FROM
sys_user`
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 users []system.User
err := sqldb.NamedQuerySlice(ctx, s.log, s.db.DB(ctx), buf.String(), data, &users)
if err != nil {
return nil, err
}
return toPointer(users), nil
}
func toPointer(data []system.User) []*system.User {
var res []*system.User
for _, v := range data {
res = append(res, &v)
}
return res
}