backend/tmp/reborn/repository/role_repository.go

206 lines
5.1 KiB
Go

package repository
import (
"context"
"permission/reborn/domain/entity"
"permission/reborn/domain/errors"
"permission/reborn/domain/repository"
"gorm.io/gorm"
)
type roleRepository struct {
db *gorm.DB
}
// NewRoleRepository 建立角色 Repository
func NewRoleRepository(db *gorm.DB) repository.RoleRepository {
return &roleRepository{db: db}
}
func (r *roleRepository) Create(ctx context.Context, role *entity.Role) error {
if err := role.Validate(); err != nil {
return errors.Wrap(errors.ErrCodeInvalidInput, "invalid role data", err)
}
if err := r.db.WithContext(ctx).Create(role).Error; err != nil {
return errors.Wrap(errors.ErrCodeDBQuery, "failed to create role", err)
}
return nil
}
func (r *roleRepository) Update(ctx context.Context, role *entity.Role) error {
if err := role.Validate(); err != nil {
return errors.Wrap(errors.ErrCodeInvalidInput, "invalid role data", err)
}
result := r.db.WithContext(ctx).
Model(&entity.Role{}).
Where("uid = ? AND status != ?", role.UID, entity.StatusDeleted).
Updates(map[string]interface{}{
"name": role.Name,
"status": role.Status,
})
if result.Error != nil {
return errors.Wrap(errors.ErrCodeDBQuery, "failed to update role", result.Error)
}
if result.RowsAffected == 0 {
return errors.ErrRoleNotFound
}
return nil
}
func (r *roleRepository) Delete(ctx context.Context, uid string) error {
result := r.db.WithContext(ctx).
Model(&entity.Role{}).
Where("uid = ?", uid).
Update("status", entity.StatusDeleted)
if result.Error != nil {
return errors.Wrap(errors.ErrCodeDBQuery, "failed to delete role", result.Error)
}
if result.RowsAffected == 0 {
return errors.ErrRoleNotFound
}
return nil
}
func (r *roleRepository) Get(ctx context.Context, id int64) (*entity.Role, error) {
var role entity.Role
err := r.db.WithContext(ctx).
Where("id = ? AND status != ?", id, entity.StatusDeleted).
First(&role).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.ErrRoleNotFound
}
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get role", err)
}
return &role, nil
}
func (r *roleRepository) GetByUID(ctx context.Context, uid string) (*entity.Role, error) {
var role entity.Role
err := r.db.WithContext(ctx).
Where("uid = ? AND status != ?", uid, entity.StatusDeleted).
First(&role).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.ErrRoleNotFound
}
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get role by uid", err)
}
return &role, nil
}
func (r *roleRepository) GetByUIDs(ctx context.Context, uids []string) ([]*entity.Role, error) {
if len(uids) == 0 {
return []*entity.Role{}, nil
}
var roles []*entity.Role
err := r.db.WithContext(ctx).
Where("uid IN ? AND status != ?", uids, entity.StatusDeleted).
Find(&roles).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get roles by uids", err)
}
return roles, nil
}
func (r *roleRepository) List(ctx context.Context, filter repository.RoleFilter) ([]*entity.Role, error) {
query := r.buildQuery(ctx, filter)
var roles []*entity.Role
if err := query.Find(&roles).Error; err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to list roles", err)
}
return roles, nil
}
func (r *roleRepository) Page(ctx context.Context, filter repository.RoleFilter, page, size int) ([]*entity.Role, int64, error) {
query := r.buildQuery(ctx, filter)
// 計算總數
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, errors.Wrap(errors.ErrCodeDBQuery, "failed to count roles", err)
}
// 分頁查詢
var roles []*entity.Role
offset := (page - 1) * size
if err := query.Offset(offset).Limit(size).Find(&roles).Error; err != nil {
return nil, 0, errors.Wrap(errors.ErrCodeDBQuery, "failed to page roles", err)
}
return roles, total, nil
}
func (r *roleRepository) Exists(ctx context.Context, uid string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).
Model(&entity.Role{}).
Where("uid = ? AND status != ?", uid, entity.StatusDeleted).
Count(&count).Error
if err != nil {
return false, errors.Wrap(errors.ErrCodeDBQuery, "failed to check role exists", err)
}
return count > 0, nil
}
func (r *roleRepository) NextID(ctx context.Context) (int64, error) {
var role entity.Role
err := r.db.WithContext(ctx).
Order("id DESC").
Limit(1).
First(&role).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return 1, nil
}
return 0, errors.Wrap(errors.ErrCodeDBQuery, "failed to get next id", err)
}
return role.ID + 1, nil
}
func (r *roleRepository) buildQuery(ctx context.Context, filter repository.RoleFilter) *gorm.DB {
query := r.db.WithContext(ctx).
Model(&entity.Role{}).
Where("status != ?", entity.StatusDeleted)
if filter.ClientID > 0 {
query = query.Where("client_id = ?", filter.ClientID)
}
if filter.UID != "" {
query = query.Where("uid = ?", filter.UID)
}
if filter.Name != "" {
query = query.Where("name LIKE ?", "%"+filter.Name+"%")
}
if filter.Status != nil {
query = query.Where("status = ?", *filter.Status)
}
return query
}