All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m39s
- 新增店铺角色管理 API 和数据模型 - 实现角色继承和权限检查逻辑 - 添加流程测试框架和集成测试 - 更新权限服务和账号管理逻辑 - 添加数据库迁移脚本 - 归档 OpenSpec 变更文档 Ultraworked with Sisyphus
146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
package shop
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
|
)
|
|
|
|
func (s *Service) AssignRolesToShop(ctx context.Context, shopID uint, roleIDs []uint) ([]*model.ShopRole, error) {
|
|
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
shop, err := s.shopStore.GetByID(ctx, shopID)
|
|
if err != nil {
|
|
return nil, errors.New(errors.CodeNotFound, "店铺不存在")
|
|
}
|
|
|
|
currentUserID := middleware.GetUserIDFromContext(ctx)
|
|
|
|
if len(roleIDs) == 0 {
|
|
if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "清空店铺角色失败")
|
|
}
|
|
return []*model.ShopRole{}, nil
|
|
}
|
|
|
|
roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
|
|
if err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色失败")
|
|
}
|
|
if len(roles) != len(roleIDs) {
|
|
return nil, errors.New(errors.CodeNotFound, "部分角色不存在")
|
|
}
|
|
|
|
for _, role := range roles {
|
|
if role.RoleType != constants.RoleTypeCustomer {
|
|
return nil, errors.New(errors.CodeInvalidParam, "店铺只能分配客户角色")
|
|
}
|
|
if role.Status != constants.StatusEnabled {
|
|
return nil, errors.New(errors.CodeInvalidParam, "角色已禁用")
|
|
}
|
|
}
|
|
|
|
if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "删除现有店铺角色失败")
|
|
}
|
|
|
|
shopRoles := make([]*model.ShopRole, 0, len(roleIDs))
|
|
for _, roleID := range roleIDs {
|
|
shopRole := &model.ShopRole{
|
|
ShopID: shop.ID,
|
|
RoleID: roleID,
|
|
Status: constants.StatusEnabled,
|
|
Creator: currentUserID,
|
|
Updater: currentUserID,
|
|
}
|
|
shopRoles = append(shopRoles, shopRole)
|
|
}
|
|
|
|
if err := s.shopRoleStore.BatchCreate(ctx, shopRoles); err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "批量创建店铺角色失败")
|
|
}
|
|
|
|
return shopRoles, nil
|
|
}
|
|
|
|
func (s *Service) GetShopRoles(ctx context.Context, shopID uint) (*dto.ShopRolesResponse, error) {
|
|
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_, err := s.shopStore.GetByID(ctx, shopID)
|
|
if err != nil {
|
|
return nil, errors.New(errors.CodeNotFound, "店铺不存在")
|
|
}
|
|
|
|
shopRoles, err := s.shopRoleStore.GetByShopID(ctx, shopID)
|
|
if err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺角色失败")
|
|
}
|
|
|
|
if len(shopRoles) == 0 {
|
|
return &dto.ShopRolesResponse{
|
|
ShopID: shopID,
|
|
Roles: []*dto.ShopRoleResponse{},
|
|
}, nil
|
|
}
|
|
|
|
roleIDs := make([]uint, 0, len(shopRoles))
|
|
for _, sr := range shopRoles {
|
|
roleIDs = append(roleIDs, sr.RoleID)
|
|
}
|
|
|
|
roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
|
|
if err != nil {
|
|
return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色详情失败")
|
|
}
|
|
|
|
roleMap := make(map[uint]*model.Role)
|
|
for _, role := range roles {
|
|
roleMap[role.ID] = role
|
|
}
|
|
|
|
responses := make([]*dto.ShopRoleResponse, 0, len(shopRoles))
|
|
for _, sr := range shopRoles {
|
|
role, exists := roleMap[sr.RoleID]
|
|
if !exists {
|
|
continue
|
|
}
|
|
responses = append(responses, &dto.ShopRoleResponse{
|
|
ShopID: sr.ShopID,
|
|
RoleID: sr.RoleID,
|
|
RoleName: role.RoleName,
|
|
RoleDesc: role.RoleDesc,
|
|
Status: sr.Status,
|
|
})
|
|
}
|
|
|
|
return &dto.ShopRolesResponse{
|
|
ShopID: shopID,
|
|
Roles: responses,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) DeleteShopRole(ctx context.Context, shopID, roleID uint) error {
|
|
if err := middleware.CanManageShop(ctx, shopID, s.shopStore); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err := s.shopStore.GetByID(ctx, shopID)
|
|
if err != nil {
|
|
return errors.New(errors.CodeNotFound, "店铺不存在")
|
|
}
|
|
|
|
if err := s.shopRoleStore.Delete(ctx, shopID, roleID); err != nil {
|
|
return errors.Wrap(errors.CodeInternalError, err, "删除店铺角色失败")
|
|
}
|
|
|
|
return nil
|
|
}
|