feat: OpenAPI 契约对齐与框架优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
主要变更: 1. OpenAPI 文档契约对齐 - 统一错误响应字段名为 msg(非 message) - 规范 envelope 响应结构(code, msg, data, timestamp) - 个人客户路由纳入文档体系(使用 Register 机制) - 新增 BuildDocHandlers() 统一管理 handler 构造 - 确保文档生成的幂等性 2. Service 层错误处理统一 - 全面替换 fmt.Errorf 为 errors.New/Wrap - 统一错误码使用规范 - Handler 层参数校验不泄露底层细节 - 新增错误码验证集成测试 3. 代码质量提升 - 删除未使用的 Task handler 和路由 - 新增代码规范检查脚本(check-service-errors.sh) - 新增注释路径一致性检查(check-comment-paths.sh) - 更新 API 文档生成指南 4. OpenSpec 归档 - 归档 openapi-contract-alignment 变更(63 tasks) - 归档 service-error-unify-core 变更 - 归档 service-error-unify-support 变更 - 归档 code-cleanup-docs-update 变更 - 归档 handler-validation-security 变更 - 同步 delta specs 到主规范文件 影响范围: - pkg/openapi: 新增 handlers.go,优化 generator.go - internal/service/*: 48 个 service 文件错误处理统一 - internal/handler/admin: 优化参数校验错误提示 - internal/routes: 个人客户路由改造,删除 task 路由 - scripts: 新增 3 个代码检查脚本 - docs: 更新 OpenAPI 文档(15750+ 行) - openspec/specs: 同步 3 个主规范文件 破坏性变更:无 向后兼容:是
This commit is contained in:
@@ -66,7 +66,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateAccountRequest) (*m
|
||||
// bcrypt 哈希密码
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码哈希失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
|
||||
// 创建账号
|
||||
@@ -81,7 +81,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateAccountRequest) (*m
|
||||
}
|
||||
|
||||
if err := s.accountStore.Create(ctx, account); err != nil {
|
||||
return nil, fmt.Errorf("创建账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建账号失败")
|
||||
}
|
||||
|
||||
// TODO: 清除店铺的下级 ID 缓存(需要在 Service 层处理)
|
||||
@@ -97,7 +97,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*model.Account, error) {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
return account, nil
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateAccountReq
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
@@ -141,7 +141,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateAccountReq
|
||||
if req.Password != nil {
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码哈希失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
account.Password = string(hashedPassword)
|
||||
}
|
||||
@@ -153,7 +153,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateAccountReq
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.accountStore.Update(ctx, account); err != nil {
|
||||
return nil, fmt.Errorf("更新账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新账号失败")
|
||||
}
|
||||
|
||||
return account, nil
|
||||
@@ -167,11 +167,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
if err := s.accountStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除账号失败")
|
||||
}
|
||||
|
||||
// 账号删除后不需要清理缓存
|
||||
@@ -223,7 +223,7 @@ func (s *Service) AssignRoles(ctx context.Context, accountID uint, roleIDs []uin
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
// 超级管理员禁止分配角色
|
||||
@@ -234,7 +234,7 @@ func (s *Service) AssignRoles(ctx context.Context, accountID uint, roleIDs []uin
|
||||
// 空数组:清空所有角色
|
||||
if len(roleIDs) == 0 {
|
||||
if err := s.accountRoleStore.DeleteByAccountID(ctx, accountID); err != nil {
|
||||
return nil, fmt.Errorf("清空账号角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "清空账号角色失败")
|
||||
}
|
||||
return []*model.AccountRole{}, nil
|
||||
}
|
||||
@@ -246,7 +246,7 @@ func (s *Service) AssignRoles(ctx context.Context, accountID uint, roleIDs []uin
|
||||
|
||||
existingCount, err := s.accountRoleStore.CountByAccountID(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("统计现有角色数量失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "统计现有角色数量失败")
|
||||
}
|
||||
|
||||
newRoleCount := 0
|
||||
@@ -267,7 +267,7 @@ func (s *Service) AssignRoles(ctx context.Context, accountID uint, roleIDs []uin
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeRoleNotFound, fmt.Sprintf("角色 %d 不存在", roleID))
|
||||
}
|
||||
return nil, fmt.Errorf("获取角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
if !constants.IsRoleTypeMatchUserType(role.RoleType, account.UserType) {
|
||||
@@ -290,7 +290,7 @@ func (s *Service) AssignRoles(ctx context.Context, accountID uint, roleIDs []uin
|
||||
Updater: currentUserID,
|
||||
}
|
||||
if err := s.accountRoleStore.Create(ctx, ar); err != nil {
|
||||
return nil, fmt.Errorf("创建账号-角色关联失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建账号-角色关联失败")
|
||||
}
|
||||
ars = append(ars, ar)
|
||||
}
|
||||
@@ -306,13 +306,13 @@ func (s *Service) GetRoles(ctx context.Context, accountID uint) ([]*model.Role,
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
// 获取角色 ID 列表
|
||||
roleIDs, err := s.accountRoleStore.GetRoleIDsByAccountID(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取账号角色 ID 失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号角色 ID 失败")
|
||||
}
|
||||
|
||||
if len(roleIDs) == 0 {
|
||||
@@ -331,12 +331,12 @@ func (s *Service) RemoveRole(ctx context.Context, accountID, roleID uint) error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
// 删除关联
|
||||
if err := s.accountRoleStore.Delete(ctx, accountID, roleID); err != nil {
|
||||
return fmt.Errorf("删除账号-角色关联失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除账号-角色关联失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -360,16 +360,16 @@ func (s *Service) UpdatePassword(ctx context.Context, accountID uint, newPasswor
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码哈希失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
|
||||
if err := s.accountStore.UpdatePassword(ctx, accountID, string(hashedPassword), currentUserID); err != nil {
|
||||
return fmt.Errorf("更新密码失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新密码失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -387,11 +387,11 @@ func (s *Service) UpdateStatus(ctx context.Context, accountID uint, status int)
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
if err := s.accountStore.UpdateStatus(ctx, accountID, status, currentUserID); err != nil {
|
||||
return fmt.Errorf("更新状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -449,12 +449,12 @@ func (s *Service) CreateSystemAccount(ctx context.Context, account *model.Accoun
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(account.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码哈希失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
account.Password = string(hashedPassword)
|
||||
|
||||
if err := s.accountStore.Create(ctx, account); err != nil {
|
||||
return fmt.Errorf("创建账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建账号失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -52,7 +51,7 @@ func (s *Service) Login(ctx context.Context, req *dto.LoginRequest, clientIP str
|
||||
s.logger.Warn("登录失败:用户名不存在", zap.String("username", req.Username), zap.String("ip", clientIP))
|
||||
return nil, errors.New(errors.CodeInvalidCredentials, "用户名或密码错误")
|
||||
}
|
||||
return nil, errors.New(errors.CodeDatabaseError, fmt.Sprintf("查询账号失败: %v", err))
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询账号失败")
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(account.Password), []byte(req.Password)); err != nil {
|
||||
@@ -141,7 +140,7 @@ func (s *Service) GetCurrentUser(ctx context.Context, userID uint) (*dto.UserInf
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, nil, errors.New(errors.CodeDatabaseError, fmt.Sprintf("查询账号失败: %v", err))
|
||||
return nil, nil, errors.Wrap(errors.CodeInternalError, err, "查询账号失败")
|
||||
}
|
||||
|
||||
permissions, err := s.getUserPermissions(ctx, userID)
|
||||
@@ -161,7 +160,7 @@ func (s *Service) ChangePassword(ctx context.Context, userID uint, oldPassword,
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return errors.New(errors.CodeDatabaseError, fmt.Sprintf("查询账号失败: %v", err))
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询账号失败")
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(account.Password), []byte(oldPassword)); err != nil {
|
||||
@@ -170,11 +169,11 @@ func (s *Service) ChangePassword(ctx context.Context, userID uint, oldPassword,
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to hash password: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码加密失败")
|
||||
}
|
||||
|
||||
if err := s.accountStore.UpdatePassword(ctx, userID, string(hashedPassword), userID); err != nil {
|
||||
return errors.New(errors.CodeDatabaseError, fmt.Sprintf("更新密码失败: %v", err))
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新密码失败")
|
||||
}
|
||||
|
||||
if err := s.tokenManager.RevokeAllUserTokens(ctx, userID); err != nil {
|
||||
@@ -189,7 +188,7 @@ func (s *Service) ChangePassword(ctx context.Context, userID uint, oldPassword,
|
||||
func (s *Service) getUserPermissions(ctx context.Context, userID uint) ([]string, error) {
|
||||
accountRoles, err := s.accountRoleStore.GetByAccountID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get account roles: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询用户角色失败")
|
||||
}
|
||||
|
||||
if len(accountRoles) == 0 {
|
||||
@@ -203,7 +202,7 @@ func (s *Service) getUserPermissions(ctx context.Context, userID uint) ([]string
|
||||
|
||||
permIDs, err := s.rolePermStore.GetPermIDsByRoleIDs(ctx, roleIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get permission IDs: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色权限失败")
|
||||
}
|
||||
|
||||
if len(permIDs) == 0 {
|
||||
@@ -212,7 +211,7 @@ func (s *Service) getUserPermissions(ctx context.Context, userID uint) ([]string
|
||||
|
||||
permissions, err := s.permissionStore.GetByIDs(ctx, permIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get permissions: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询权限详情失败")
|
||||
}
|
||||
|
||||
permCodes := make([]string, 0, len(permissions))
|
||||
|
||||
@@ -2,7 +2,6 @@ package carrier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -45,7 +44,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateCarrierRequest) (*d
|
||||
carrier.Creator = currentUserID
|
||||
|
||||
if err := s.carrierStore.Create(ctx, carrier); err != nil {
|
||||
return nil, fmt.Errorf("创建运营商失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建运营商失败")
|
||||
}
|
||||
|
||||
return s.toResponse(carrier), nil
|
||||
@@ -57,7 +56,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*dto.CarrierResponse, error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeCarrierNotFound, "运营商不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取运营商失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
|
||||
}
|
||||
return s.toResponse(carrier), nil
|
||||
}
|
||||
@@ -73,7 +72,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateCarrierReq
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeCarrierNotFound, "运营商不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取运营商失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
|
||||
}
|
||||
|
||||
if req.CarrierName != nil {
|
||||
@@ -85,7 +84,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateCarrierReq
|
||||
carrier.Updater = currentUserID
|
||||
|
||||
if err := s.carrierStore.Update(ctx, carrier); err != nil {
|
||||
return nil, fmt.Errorf("更新运营商失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新运营商失败")
|
||||
}
|
||||
|
||||
return s.toResponse(carrier), nil
|
||||
@@ -97,11 +96,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeCarrierNotFound, "运营商不存在")
|
||||
}
|
||||
return fmt.Errorf("获取运营商失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
|
||||
}
|
||||
|
||||
if err := s.carrierStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除运营商失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除运营商失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -133,7 +132,7 @@ func (s *Service) List(ctx context.Context, req *dto.CarrierListRequest) ([]*dto
|
||||
|
||||
carriers, total, err := s.carrierStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询运营商列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询运营商列表失败")
|
||||
}
|
||||
|
||||
responses := make([]*dto.CarrierResponse, len(carriers))
|
||||
@@ -155,14 +154,14 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeCarrierNotFound, "运营商不存在")
|
||||
}
|
||||
return fmt.Errorf("获取运营商失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
|
||||
}
|
||||
|
||||
carrier.Status = status
|
||||
carrier.Updater = currentUserID
|
||||
|
||||
if err := s.carrierStore.Update(ctx, carrier); err != nil {
|
||||
return fmt.Errorf("更新运营商状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新运营商状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package commission_stats
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -29,7 +28,7 @@ func (s *Service) GetCurrentStats(ctx context.Context, allocationID uint, period
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "统计数据不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取统计数据失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取统计数据失败")
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
@@ -41,7 +40,7 @@ func (s *Service) UpdateStats(ctx context.Context, allocationID uint, periodType
|
||||
|
||||
stats, err := s.statsStore.GetCurrent(ctx, allocationID, periodType, now)
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("查询统计数据失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询统计数据失败")
|
||||
}
|
||||
|
||||
if stats == nil {
|
||||
@@ -69,7 +68,7 @@ func (s *Service) ArchiveCompletedPeriod(ctx context.Context, allocationID uint,
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("查询统计数据失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询统计数据失败")
|
||||
}
|
||||
|
||||
return s.statsStore.CompletePeriod(ctx, stats.ID)
|
||||
|
||||
@@ -3,7 +3,6 @@ package commission_withdrawal
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -76,7 +75,7 @@ func (s *Service) ListWithdrawalRequests(ctx context.Context, req *dto.Withdrawa
|
||||
|
||||
requests, total, err := s.commissionWithdrawalReqStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询提现申请列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询提现申请列表失败")
|
||||
}
|
||||
|
||||
shopIDs := make([]uint, 0)
|
||||
@@ -175,7 +174,7 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveWithdraw
|
||||
now := time.Now()
|
||||
err = s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := s.walletStore.DeductFrozenBalanceWithTx(ctx, tx, wallet.ID, amount); err != nil {
|
||||
return fmt.Errorf("扣除冻结余额失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "扣除冻结余额失败")
|
||||
}
|
||||
|
||||
refType := "withdrawal"
|
||||
@@ -193,7 +192,7 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveWithdraw
|
||||
Creator: currentUserID,
|
||||
}
|
||||
if err := s.walletTransactionStore.CreateWithTx(ctx, tx, transaction); err != nil {
|
||||
return fmt.Errorf("创建交易流水失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建交易流水失败")
|
||||
}
|
||||
|
||||
updates := map[string]interface{}{
|
||||
@@ -232,7 +231,7 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveWithdraw
|
||||
}
|
||||
|
||||
if err := s.commissionWithdrawalReqStore.UpdateStatusWithTx(ctx, tx, id, updates); err != nil {
|
||||
return fmt.Errorf("更新提现申请状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新提现申请状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -274,7 +273,7 @@ func (s *Service) Reject(ctx context.Context, id uint, req *dto.RejectWithdrawal
|
||||
now := time.Now()
|
||||
err = s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := s.walletStore.UnfreezeBalanceWithTx(ctx, tx, wallet.ID, withdrawal.Amount); err != nil {
|
||||
return fmt.Errorf("解冻余额失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "解冻余额失败")
|
||||
}
|
||||
|
||||
refType := "withdrawal"
|
||||
@@ -292,7 +291,7 @@ func (s *Service) Reject(ctx context.Context, id uint, req *dto.RejectWithdrawal
|
||||
Creator: currentUserID,
|
||||
}
|
||||
if err := s.walletTransactionStore.CreateWithTx(ctx, tx, transaction); err != nil {
|
||||
return fmt.Errorf("创建交易流水失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建交易流水失败")
|
||||
}
|
||||
|
||||
updates := map[string]interface{}{
|
||||
@@ -303,7 +302,7 @@ func (s *Service) Reject(ctx context.Context, id uint, req *dto.RejectWithdrawal
|
||||
"remark": req.Remark,
|
||||
}
|
||||
if err := s.commissionWithdrawalReqStore.UpdateStatusWithTx(ctx, tx, id, updates); err != nil {
|
||||
return fmt.Errorf("更新提现申请状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新提现申请状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package commission_withdrawal_setting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -49,10 +48,10 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateWithdrawalSettingRe
|
||||
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := s.commissionWithdrawalSettingStore.DeactivateCurrentWithTx(ctx, tx); err != nil {
|
||||
return fmt.Errorf("失效旧配置失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "失效旧配置失败")
|
||||
}
|
||||
if err := s.commissionWithdrawalSettingStore.CreateWithTx(ctx, tx, setting); err != nil {
|
||||
return fmt.Errorf("创建配置失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建配置失败")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -93,7 +92,7 @@ func (s *Service) List(ctx context.Context, req *dto.WithdrawalSettingListReq) (
|
||||
|
||||
settings, total, err := s.commissionWithdrawalSettingStore.List(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询配置列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询配置列表失败")
|
||||
}
|
||||
|
||||
creatorIDs := make([]uint, 0)
|
||||
@@ -140,7 +139,7 @@ func (s *Service) GetCurrent(ctx context.Context) (*dto.WithdrawalSettingItem, e
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "暂无生效的提现配置")
|
||||
}
|
||||
return nil, fmt.Errorf("查询当前配置失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询当前配置失败")
|
||||
}
|
||||
|
||||
creatorName := ""
|
||||
|
||||
@@ -2,7 +2,6 @@ package customer_account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -69,13 +68,13 @@ func (s *Service) List(ctx context.Context, req *dto.CustomerAccountListReq) (*d
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, fmt.Errorf("统计账号数量失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "统计账号数量失败")
|
||||
}
|
||||
|
||||
var accounts []model.Account
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&accounts).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询账号列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询账号列表失败")
|
||||
}
|
||||
|
||||
shopIDs := make([]uint, 0)
|
||||
@@ -159,7 +158,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateCustomerAccountReq)
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码加密失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码加密失败")
|
||||
}
|
||||
|
||||
account := &model.Account{
|
||||
@@ -174,7 +173,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateCustomerAccountReq)
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.db.WithContext(ctx).Create(account).Error; err != nil {
|
||||
return nil, fmt.Errorf("创建账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建账号失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, req.ShopID)
|
||||
@@ -227,7 +226,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateCustomerAc
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.db.WithContext(ctx).Save(account).Error; err != nil {
|
||||
return nil, fmt.Errorf("更新账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新账号失败")
|
||||
}
|
||||
|
||||
shopName := ""
|
||||
@@ -276,7 +275,7 @@ func (s *Service) UpdatePassword(ctx context.Context, id uint, password string)
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码加密失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码加密失败")
|
||||
}
|
||||
|
||||
return s.db.WithContext(ctx).Model(&model.Account{}).
|
||||
|
||||
@@ -2,7 +2,6 @@ package device_import
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
@@ -55,14 +54,14 @@ func (s *Service) CreateImportTask(ctx context.Context, req *dto.ImportDeviceReq
|
||||
task.Updater = userID
|
||||
|
||||
if err := s.importTaskStore.Create(ctx, task); err != nil {
|
||||
return nil, fmt.Errorf("创建导入任务失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建导入任务失败")
|
||||
}
|
||||
|
||||
payload := DeviceImportPayload{TaskID: task.ID}
|
||||
err := s.queueClient.EnqueueTask(ctx, constants.TaskTypeDeviceImport, payload)
|
||||
if err != nil {
|
||||
s.importTaskStore.UpdateStatus(ctx, task.ID, model.ImportTaskStatusFailed, "任务入队失败: "+err.Error())
|
||||
return nil, fmt.Errorf("任务入队失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "任务入队失败")
|
||||
}
|
||||
|
||||
return &dto.ImportDeviceResponse{
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/queue"
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/hibiken/asynq"
|
||||
@@ -44,7 +45,7 @@ func (s *Service) SendWelcomeEmail(ctx context.Context, userID uint, email strin
|
||||
zap.Uint("user_id", userID),
|
||||
zap.String("email", email),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("序列化邮件任务载荷失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "序列化邮件任务载荷失败")
|
||||
}
|
||||
|
||||
// 提交任务到队列
|
||||
@@ -61,7 +62,7 @@ func (s *Service) SendWelcomeEmail(ctx context.Context, userID uint, email strin
|
||||
zap.Uint("user_id", userID),
|
||||
zap.String("email", email),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("提交欢迎邮件任务失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "提交欢迎邮件任务失败")
|
||||
}
|
||||
|
||||
s.logger.Info("欢迎邮件任务已提交",
|
||||
@@ -86,7 +87,7 @@ func (s *Service) SendPasswordResetEmail(ctx context.Context, email string, rese
|
||||
s.logger.Error("序列化密码重置邮件任务载荷失败",
|
||||
zap.String("email", email),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("序列化密码重置邮件任务载荷失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "序列化密码重置邮件任务载荷失败")
|
||||
}
|
||||
|
||||
// 提交任务到队列(高优先级)
|
||||
@@ -102,7 +103,7 @@ func (s *Service) SendPasswordResetEmail(ctx context.Context, email string, rese
|
||||
s.logger.Error("提交密码重置邮件任务失败",
|
||||
zap.String("email", email),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("提交密码重置邮件任务失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "提交密码重置邮件任务失败")
|
||||
}
|
||||
|
||||
s.logger.Info("密码重置邮件任务已提交",
|
||||
@@ -126,7 +127,7 @@ func (s *Service) SendNotificationEmail(ctx context.Context, to string, subject
|
||||
s.logger.Error("序列化通知邮件任务载荷失败",
|
||||
zap.String("to", to),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("序列化通知邮件任务载荷失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "序列化通知邮件任务载荷失败")
|
||||
}
|
||||
|
||||
// 提交任务到队列(低优先级)
|
||||
@@ -142,7 +143,7 @@ func (s *Service) SendNotificationEmail(ctx context.Context, to string, subject
|
||||
s.logger.Error("提交通知邮件任务失败",
|
||||
zap.String("to", to),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("提交通知邮件任务失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "提交通知邮件任务失败")
|
||||
}
|
||||
|
||||
s.logger.Info("通知邮件任务已提交",
|
||||
|
||||
@@ -2,7 +2,6 @@ package enterprise
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -58,7 +57,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateEnterpriseReq) (*dt
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码加密失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码加密失败")
|
||||
}
|
||||
|
||||
var enterprise *model.Enterprise
|
||||
@@ -83,7 +82,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateEnterpriseReq) (*dt
|
||||
enterprise.Updater = currentUserID
|
||||
|
||||
if err := tx.WithContext(ctx).Create(enterprise).Error; err != nil {
|
||||
return fmt.Errorf("创建企业失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建企业失败")
|
||||
}
|
||||
|
||||
account = &model.Account{
|
||||
@@ -98,7 +97,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateEnterpriseReq) (*dt
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := tx.WithContext(ctx).Create(account).Error; err != nil {
|
||||
return fmt.Errorf("创建企业账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建企业账号失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -215,7 +214,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
enterprise.Status = status
|
||||
enterprise.Updater = currentUserID
|
||||
if err := tx.WithContext(ctx).Save(enterprise).Error; err != nil {
|
||||
return fmt.Errorf("更新企业状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新企业状态失败")
|
||||
}
|
||||
|
||||
if err := tx.WithContext(ctx).Model(&model.Account{}).
|
||||
@@ -224,7 +223,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
"status": status,
|
||||
"updater": currentUserID,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("同步更新企业账号状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "同步更新企业账号状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -244,7 +243,7 @@ func (s *Service) UpdatePassword(ctx context.Context, id uint, password string)
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码加密失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码加密失败")
|
||||
}
|
||||
|
||||
return s.db.WithContext(ctx).Model(&model.Account{}).
|
||||
@@ -291,7 +290,7 @@ func (s *Service) List(ctx context.Context, req *dto.EnterpriseListReq) (*dto.En
|
||||
|
||||
enterprises, total, err := s.enterpriseStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询企业列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询企业列表失败")
|
||||
}
|
||||
|
||||
enterpriseIDs := make([]uint, 0, len(enterprises))
|
||||
|
||||
@@ -2,7 +2,6 @@ package enterprise_card
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -45,7 +44,7 @@ func (s *Service) AllocateCardsPreview(ctx context.Context, enterpriseID uint, r
|
||||
|
||||
var iotCards []model.IotCard
|
||||
if err := s.db.WithContext(ctx).Where("iccid IN ?", req.ICCIDs).Find(&iotCards).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询卡信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡信息失败")
|
||||
}
|
||||
|
||||
cardMap := make(map[string]*model.IotCard)
|
||||
@@ -141,7 +140,7 @@ func (s *Service) AllocateCards(ctx context.Context, enterpriseID uint, req *dto
|
||||
|
||||
existingAuths, err := s.enterpriseCardAuthStore.GetActiveAuthsByCardIDs(ctx, enterpriseID, cardIDsToAllocate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询已有授权失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询已有授权失败")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -163,7 +162,7 @@ func (s *Service) AllocateCards(ctx context.Context, enterpriseID uint, req *dto
|
||||
|
||||
if len(auths) > 0 {
|
||||
if err := s.enterpriseCardAuthStore.BatchCreate(ctx, auths); err != nil {
|
||||
return nil, fmt.Errorf("创建授权记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建授权记录失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +183,7 @@ func (s *Service) RecallCards(ctx context.Context, enterpriseID uint, req *dto.R
|
||||
|
||||
var iotCards []model.IotCard
|
||||
if err := s.db.WithContext(ctx).Where("iccid IN ?", req.ICCIDs).Find(&iotCards).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询卡信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡信息失败")
|
||||
}
|
||||
|
||||
cardMap := make(map[string]*model.IotCard)
|
||||
@@ -198,7 +197,7 @@ func (s *Service) RecallCards(ctx context.Context, enterpriseID uint, req *dto.R
|
||||
|
||||
existingAuths, err := s.enterpriseCardAuthStore.GetActiveAuthsByCardIDs(ctx, enterpriseID, cardIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询已有授权失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询已有授权失败")
|
||||
}
|
||||
|
||||
resp := &dto.RecallCardsResp{
|
||||
@@ -228,7 +227,7 @@ func (s *Service) RecallCards(ctx context.Context, enterpriseID uint, req *dto.R
|
||||
|
||||
if len(cardIDsToRecall) > 0 {
|
||||
if err := s.enterpriseCardAuthStore.BatchUpdateStatus(ctx, enterpriseID, cardIDsToRecall, 0); err != nil {
|
||||
return nil, fmt.Errorf("回收授权失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "回收授权失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +244,7 @@ func (s *Service) ListCards(ctx context.Context, enterpriseID uint, req *dto.Ent
|
||||
|
||||
cardIDs, err := s.enterpriseCardAuthStore.ListCardIDsByEnterprise(ctx, enterpriseID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询授权卡ID失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询授权卡ID失败")
|
||||
}
|
||||
|
||||
if len(cardIDs) == 0 {
|
||||
@@ -280,13 +279,13 @@ func (s *Service) ListCards(ctx context.Context, enterpriseID uint, req *dto.Ent
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, fmt.Errorf("统计卡数量失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "统计卡数量失败")
|
||||
}
|
||||
|
||||
var cards []model.IotCard
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&cards).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询卡列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡列表失败")
|
||||
}
|
||||
|
||||
items := make([]dto.EnterpriseCardItem, 0, len(cards))
|
||||
|
||||
@@ -2,7 +2,6 @@ package enterprise_device
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -62,7 +61,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
|
||||
// 查询所有设备
|
||||
var devices []model.Device
|
||||
if err := s.db.WithContext(ctx).Where("device_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
|
||||
}
|
||||
|
||||
deviceMap := make(map[string]*model.Device)
|
||||
@@ -79,7 +78,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
|
||||
// 检查已授权的设备
|
||||
existingAuths, err := s.enterpriseDeviceAuthStore.GetActiveAuthsByDeviceIDs(ctx, enterpriseID, deviceIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询已有授权失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询已有授权失败")
|
||||
}
|
||||
|
||||
resp := &dto.AllocateDevicesResp{
|
||||
@@ -150,7 +149,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
|
||||
}
|
||||
|
||||
if err := tx.Create(deviceAuths).Error; err != nil {
|
||||
return fmt.Errorf("创建设备授权记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建设备授权记录失败")
|
||||
}
|
||||
|
||||
// 构建设备ID到授权ID的映射
|
||||
@@ -167,7 +166,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
|
||||
|
||||
var bindings []model.DeviceSimBinding
|
||||
if err := tx.Where("device_id IN ? AND bind_status = 1", deviceIDsToQuery).Find(&bindings).Error; err != nil {
|
||||
return fmt.Errorf("查询设备绑定卡失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询设备绑定卡失败")
|
||||
}
|
||||
|
||||
// 3. 为每张绑定的卡创建授权记录
|
||||
@@ -187,7 +186,7 @@ func (s *Service) AllocateDevices(ctx context.Context, enterpriseID uint, req *d
|
||||
}
|
||||
|
||||
if err := tx.Create(cardAuths).Error; err != nil {
|
||||
return fmt.Errorf("创建卡授权记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建卡授权记录失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +234,7 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
|
||||
// 查询设备
|
||||
var devices []model.Device
|
||||
if err := s.db.WithContext(ctx).Where("device_no IN ?", req.DeviceNos).Find(&devices).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
|
||||
}
|
||||
|
||||
deviceMap := make(map[string]*model.Device)
|
||||
@@ -248,7 +247,7 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
|
||||
// 检查授权状态
|
||||
existingAuths, err := s.enterpriseDeviceAuthStore.GetActiveAuthsByDeviceIDs(ctx, enterpriseID, deviceIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询授权状态失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询授权状态失败")
|
||||
}
|
||||
|
||||
resp := &dto.RecallDevicesResp{
|
||||
@@ -292,13 +291,13 @@ func (s *Service) RecallDevices(ctx context.Context, enterpriseID uint, req *dto
|
||||
err := s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 1. 撤销设备授权
|
||||
if err := s.enterpriseDeviceAuthStore.RevokeByIDs(ctx, deviceAuthsToRevoke, currentUserID); err != nil {
|
||||
return fmt.Errorf("撤销设备授权失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "撤销设备授权失败")
|
||||
}
|
||||
|
||||
// 2. 级联撤销卡授权
|
||||
for _, authID := range deviceAuthsToRevoke {
|
||||
if err := s.enterpriseCardAuthStore.RevokeByDeviceAuthID(ctx, authID, currentUserID); err != nil {
|
||||
return fmt.Errorf("撤销卡授权失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "撤销卡授权失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +332,7 @@ func (s *Service) ListDevices(ctx context.Context, enterpriseID uint, req *dto.E
|
||||
|
||||
auths, total, err := s.enterpriseDeviceAuthStore.ListByEnterprise(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询授权记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询授权记录失败")
|
||||
}
|
||||
|
||||
if len(auths) == 0 {
|
||||
@@ -358,7 +357,7 @@ func (s *Service) ListDevices(ctx context.Context, enterpriseID uint, req *dto.E
|
||||
query = query.Where("device_no LIKE ?", "%"+req.DeviceNo+"%")
|
||||
}
|
||||
if err := query.Find(&devices).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
|
||||
}
|
||||
|
||||
// 统计每个设备的绑定卡数量
|
||||
@@ -366,7 +365,7 @@ func (s *Service) ListDevices(ctx context.Context, enterpriseID uint, req *dto.E
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("device_id IN ? AND bind_status = 1", deviceIDs).
|
||||
Find(&bindings).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备绑定卡失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备绑定卡失败")
|
||||
}
|
||||
|
||||
cardCountMap := make(map[uint]int)
|
||||
@@ -410,7 +409,7 @@ func (s *Service) ListDevicesForEnterprise(ctx context.Context, req *dto.Enterpr
|
||||
|
||||
auths, total, err := s.enterpriseDeviceAuthStore.ListByEnterprise(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询授权记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询授权记录失败")
|
||||
}
|
||||
|
||||
if len(auths) == 0 {
|
||||
@@ -435,14 +434,14 @@ func (s *Service) ListDevicesForEnterprise(ctx context.Context, req *dto.Enterpr
|
||||
query = query.Where("device_no LIKE ?", "%"+req.DeviceNo+"%")
|
||||
}
|
||||
if err := query.Find(&devices).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
|
||||
}
|
||||
|
||||
var bindings []model.DeviceSimBinding
|
||||
if err := s.db.WithContext(skipCtx).
|
||||
Where("device_id IN ? AND bind_status = 1", deviceIDs).
|
||||
Find(&bindings).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备绑定卡失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备绑定卡失败")
|
||||
}
|
||||
|
||||
cardCountMap := make(map[uint]int)
|
||||
@@ -485,14 +484,14 @@ func (s *Service) GetDeviceDetail(ctx context.Context, deviceID uint) (*dto.Ente
|
||||
|
||||
var device model.Device
|
||||
if err := s.db.WithContext(skipCtx).Where("id = ?", deviceID).First(&device).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备信息失败")
|
||||
}
|
||||
|
||||
var bindings []model.DeviceSimBinding
|
||||
if err := s.db.WithContext(skipCtx).
|
||||
Where("device_id = ? AND bind_status = 1", deviceID).
|
||||
Find(&bindings).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询设备绑定卡失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询设备绑定卡失败")
|
||||
}
|
||||
|
||||
cardIDs := make([]uint, 0, len(bindings))
|
||||
@@ -504,7 +503,7 @@ func (s *Service) GetDeviceDetail(ctx context.Context, deviceID uint) (*dto.Ente
|
||||
cardInfos := make([]dto.DeviceCardInfo, 0)
|
||||
if len(cardIDs) > 0 {
|
||||
if err := s.db.WithContext(skipCtx).Where("id IN ?", cardIDs).Find(&cards).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询卡信息失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡信息失败")
|
||||
}
|
||||
|
||||
carrierIDs := make([]uint, 0, len(cards))
|
||||
@@ -556,7 +555,7 @@ func (s *Service) SuspendCard(ctx context.Context, deviceID, cardID uint, req *d
|
||||
if err := s.db.WithContext(skipCtx).Model(&model.IotCard{}).
|
||||
Where("id = ?", cardID).
|
||||
Update("network_status", 0).Error; err != nil {
|
||||
return nil, fmt.Errorf("停机操作失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "停机操作失败")
|
||||
}
|
||||
|
||||
return &dto.DeviceCardOperationResp{
|
||||
@@ -574,7 +573,7 @@ func (s *Service) ResumeCard(ctx context.Context, deviceID, cardID uint, req *dt
|
||||
if err := s.db.WithContext(skipCtx).Model(&model.IotCard{}).
|
||||
Where("id = ?", cardID).
|
||||
Update("network_status", 1).Error; err != nil {
|
||||
return nil, fmt.Errorf("复机操作失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "复机操作失败")
|
||||
}
|
||||
|
||||
return &dto.DeviceCardOperationResp{
|
||||
|
||||
@@ -2,7 +2,6 @@ package iot_card_import
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
@@ -85,14 +84,14 @@ func (s *Service) CreateImportTask(ctx context.Context, req *dto.ImportIotCardRe
|
||||
task.Updater = userID
|
||||
|
||||
if err := s.importTaskStore.Create(ctx, task); err != nil {
|
||||
return nil, fmt.Errorf("创建导入任务失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建导入任务失败")
|
||||
}
|
||||
|
||||
payload := IotCardImportPayload{TaskID: task.ID}
|
||||
err = s.queueClient.EnqueueTask(ctx, constants.TaskTypeIotCardImport, payload)
|
||||
if err != nil {
|
||||
s.importTaskStore.UpdateStatus(ctx, task.ID, model.ImportTaskStatusFailed, "任务入队失败: "+err.Error())
|
||||
return nil, fmt.Errorf("任务入队失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "任务入队失败")
|
||||
}
|
||||
|
||||
return &dto.ImportIotCardResponse{
|
||||
|
||||
@@ -166,7 +166,7 @@ func (s *Service) CreateWithdrawalRequest(ctx context.Context, req *dto.CreateMy
|
||||
"balance": gorm.Expr("balance - ?", req.Amount),
|
||||
"frozen_balance": gorm.Expr("frozen_balance + ?", req.Amount),
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("冻结余额失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "冻结余额失败")
|
||||
}
|
||||
|
||||
// 创建提现申请
|
||||
@@ -186,7 +186,7 @@ func (s *Service) CreateWithdrawalRequest(ctx context.Context, req *dto.CreateMy
|
||||
withdrawalRequest.Updater = currentUserID
|
||||
|
||||
if err := tx.WithContext(ctx).Create(withdrawalRequest).Error; err != nil {
|
||||
return fmt.Errorf("创建提现申请失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建提现申请失败")
|
||||
}
|
||||
|
||||
// 创建钱包流水记录
|
||||
@@ -207,7 +207,7 @@ func (s *Service) CreateWithdrawalRequest(ctx context.Context, req *dto.CreateMy
|
||||
}
|
||||
|
||||
if err := tx.WithContext(ctx).Create(transaction).Error; err != nil {
|
||||
return fmt.Errorf("创建钱包流水失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建钱包流水失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -266,13 +266,13 @@ func (s *Service) ListMyWithdrawalRequests(ctx context.Context, req *dto.MyWithd
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, fmt.Errorf("统计提现记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "统计提现记录失败")
|
||||
}
|
||||
|
||||
var requests []model.CommissionWithdrawalRequest
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&requests).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询提现记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询提现记录失败")
|
||||
}
|
||||
|
||||
items := make([]dto.WithdrawalRequestItem, 0, len(requests))
|
||||
@@ -335,13 +335,13 @@ func (s *Service) ListMyCommissionRecords(ctx context.Context, req *dto.MyCommis
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, fmt.Errorf("统计佣金记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "统计佣金记录失败")
|
||||
}
|
||||
|
||||
var records []model.CommissionRecord
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
return nil, fmt.Errorf("查询佣金记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询佣金记录失败")
|
||||
}
|
||||
|
||||
items := make([]dto.MyCommissionRecordItem, 0, len(records))
|
||||
@@ -380,7 +380,7 @@ func (s *Service) GetStats(ctx context.Context, req *dto.CommissionStatsRequest)
|
||||
|
||||
stats, err := s.commissionRecordStore.GetStats(ctx, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取佣金统计失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取佣金统计失败")
|
||||
}
|
||||
|
||||
if stats == nil {
|
||||
@@ -428,7 +428,7 @@ func (s *Service) GetDailyStats(ctx context.Context, req *dto.DailyCommissionSta
|
||||
|
||||
dailyStats, err := s.commissionRecordStore.GetDailyStats(ctx, filters, days)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取每日佣金统计失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取每日佣金统计失败")
|
||||
}
|
||||
|
||||
result := make([]*dto.DailyCommissionStatsResponse, 0, len(dailyStats))
|
||||
|
||||
@@ -58,7 +58,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreatePackageRequest) (*d
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
seriesName = &series.SeriesName
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreatePackageRequest) (*d
|
||||
pkg.Creator = currentUserID
|
||||
|
||||
if err := s.packageStore.Create(ctx, pkg); err != nil {
|
||||
return nil, fmt.Errorf("创建套餐失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建套餐失败")
|
||||
}
|
||||
|
||||
resp := s.toResponse(ctx, pkg)
|
||||
@@ -110,7 +110,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*dto.PackageResponse, error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
resp := s.toResponse(ctx, pkg)
|
||||
@@ -135,7 +135,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageReq
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
var seriesName *string
|
||||
@@ -145,7 +145,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageReq
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
pkg.SeriesID = *req.SeriesID
|
||||
seriesName = &series.SeriesName
|
||||
@@ -190,7 +190,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageReq
|
||||
pkg.Updater = currentUserID
|
||||
|
||||
if err := s.packageStore.Update(ctx, pkg); err != nil {
|
||||
return nil, fmt.Errorf("更新套餐失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新套餐失败")
|
||||
}
|
||||
|
||||
resp := s.toResponse(ctx, pkg)
|
||||
@@ -204,11 +204,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return fmt.Errorf("获取套餐失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
if err := s.packageStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除套餐失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除套餐失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -246,7 +246,7 @@ func (s *Service) List(ctx context.Context, req *dto.PackageListRequest) ([]*dto
|
||||
|
||||
packages, total, err := s.packageStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询套餐列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询套餐列表失败")
|
||||
}
|
||||
|
||||
// 收集所有唯一的 series_id
|
||||
@@ -266,7 +266,7 @@ func (s *Service) List(ctx context.Context, req *dto.PackageListRequest) ([]*dto
|
||||
}
|
||||
seriesList, err := s.packageSeriesStore.GetByIDs(ctx, seriesIDs)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("批量查询套餐系列失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "批量查询套餐系列失败")
|
||||
}
|
||||
for _, series := range seriesList {
|
||||
seriesMap[series.ID] = series.SeriesName
|
||||
@@ -299,7 +299,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return fmt.Errorf("获取套餐失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
pkg.Status = status
|
||||
@@ -310,7 +310,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
}
|
||||
|
||||
if err := s.packageStore.Update(ctx, pkg); err != nil {
|
||||
return fmt.Errorf("更新套餐状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新套餐状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -327,7 +327,7 @@ func (s *Service) UpdateShelfStatus(ctx context.Context, id uint, shelfStatus in
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return fmt.Errorf("获取套餐失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
if shelfStatus == 1 && pkg.Status == constants.StatusDisabled {
|
||||
@@ -338,7 +338,7 @@ func (s *Service) UpdateShelfStatus(ctx context.Context, id uint, shelfStatus in
|
||||
pkg.Updater = currentUserID
|
||||
|
||||
if err := s.packageStore.Update(ctx, pkg); err != nil {
|
||||
return fmt.Errorf("更新套餐上架状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新套餐上架状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package package_series
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -44,7 +43,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreatePackageSeriesReques
|
||||
series.Creator = currentUserID
|
||||
|
||||
if err := s.packageSeriesStore.Create(ctx, series); err != nil {
|
||||
return nil, fmt.Errorf("创建套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建套餐系列失败")
|
||||
}
|
||||
|
||||
return s.toResponse(series), nil
|
||||
@@ -56,7 +55,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*dto.PackageSeriesResponse,
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
return s.toResponse(series), nil
|
||||
}
|
||||
@@ -72,7 +71,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageSer
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
|
||||
if req.SeriesName != nil {
|
||||
@@ -84,7 +83,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageSer
|
||||
series.Updater = currentUserID
|
||||
|
||||
if err := s.packageSeriesStore.Update(ctx, series); err != nil {
|
||||
return nil, fmt.Errorf("更新套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新套餐系列失败")
|
||||
}
|
||||
|
||||
return s.toResponse(series), nil
|
||||
@@ -96,11 +95,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
|
||||
if err := s.packageSeriesStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除套餐系列失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除套餐系列失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -129,7 +128,7 @@ func (s *Service) List(ctx context.Context, req *dto.PackageSeriesListRequest) (
|
||||
|
||||
seriesList, total, err := s.packageSeriesStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询套餐系列列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询套餐系列列表失败")
|
||||
}
|
||||
|
||||
responses := make([]*dto.PackageSeriesResponse, len(seriesList))
|
||||
@@ -151,14 +150,14 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
|
||||
series.Status = status
|
||||
series.Updater = currentUserID
|
||||
|
||||
if err := s.packageSeriesStore.Update(ctx, series); err != nil {
|
||||
return fmt.Errorf("更新套餐系列状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新套餐系列状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -5,7 +5,6 @@ package permission
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
@@ -91,7 +90,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreatePermissionRequest)
|
||||
}
|
||||
|
||||
if err := s.permissionStore.Create(ctx, permission); err != nil {
|
||||
return nil, fmt.Errorf("创建权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建权限失败")
|
||||
}
|
||||
|
||||
return permission, nil
|
||||
@@ -104,7 +103,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*model.Permission, error) {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodePermissionNotFound, "权限不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取权限失败")
|
||||
}
|
||||
return permission, nil
|
||||
}
|
||||
@@ -123,7 +122,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePermission
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodePermissionNotFound, "权限不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取权限失败")
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
@@ -166,7 +165,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePermission
|
||||
permission.Updater = currentUserID
|
||||
|
||||
if err := s.permissionStore.Update(ctx, permission); err != nil {
|
||||
return nil, fmt.Errorf("更新权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新权限失败")
|
||||
}
|
||||
|
||||
return permission, nil
|
||||
@@ -180,11 +179,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodePermissionNotFound, "权限不存在")
|
||||
}
|
||||
return fmt.Errorf("获取权限失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取权限失败")
|
||||
}
|
||||
|
||||
if err := s.permissionStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除权限失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除权限失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -234,7 +233,7 @@ func (s *Service) List(ctx context.Context, req *dto.PermissionListRequest) ([]*
|
||||
func (s *Service) GetTree(ctx context.Context, availableForRoleType *int) ([]*dto.PermissionTreeNode, error) {
|
||||
permissions, err := s.permissionStore.GetAll(ctx, availableForRoleType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取权限列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取权限列表失败")
|
||||
}
|
||||
|
||||
return buildPermissionTree(permissions), nil
|
||||
@@ -300,7 +299,7 @@ func (s *Service) CheckPermission(ctx context.Context, userID uint, permCode str
|
||||
|
||||
roleIDs, err := s.accountRoleStore.GetRoleIDsByAccountID(ctx, userID)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("查询用户角色失败: %w", err)
|
||||
return false, errors.Wrap(errors.CodeInternalError, err, "查询用户角色失败")
|
||||
}
|
||||
if len(roleIDs) == 0 {
|
||||
return false, nil
|
||||
@@ -308,7 +307,7 @@ func (s *Service) CheckPermission(ctx context.Context, userID uint, permCode str
|
||||
|
||||
permIDs, err := s.rolePermStore.GetPermIDsByRoleIDs(ctx, roleIDs)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("查询角色权限失败: %w", err)
|
||||
return false, errors.Wrap(errors.CodeInternalError, err, "查询角色权限失败")
|
||||
}
|
||||
if len(permIDs) == 0 {
|
||||
return false, nil
|
||||
@@ -316,7 +315,7 @@ func (s *Service) CheckPermission(ctx context.Context, userID uint, permCode str
|
||||
|
||||
permissions, err := s.permissionStore.GetByIDs(ctx, permIDs)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("查询权限详情失败: %w", err)
|
||||
return false, errors.Wrap(errors.CodeInternalError, err, "查询权限详情失败")
|
||||
}
|
||||
|
||||
cacheItems := make([]permissionCacheItem, 0, len(permissions))
|
||||
|
||||
@@ -4,12 +4,12 @@ package personal_customer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/service/verification"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/auth"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -60,7 +60,7 @@ func (s *Service) LoginByPhone(ctx context.Context, phone string, code string) (
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return "", nil, fmt.Errorf("验证码验证失败: %w", err)
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
// 查找或创建个人客户
|
||||
@@ -79,7 +79,7 @@ func (s *Service) LoginByPhone(ctx context.Context, phone string, code string) (
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return "", nil, fmt.Errorf("创建个人客户失败: %w", err)
|
||||
return "", nil, errors.Wrap(errors.CodeInternalError, err, "创建个人客户失败")
|
||||
}
|
||||
|
||||
// 创建手机号绑定记录
|
||||
@@ -95,7 +95,7 @@ func (s *Service) LoginByPhone(ctx context.Context, phone string, code string) (
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return "", nil, fmt.Errorf("查询个人客户失败: %w", err)
|
||||
return "", nil, errors.Wrap(errors.CodeInternalError, err, "查询个人客户失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (s *Service) LoginByPhone(ctx context.Context, phone string, code string) (
|
||||
zap.Uint("customer_id", customer.ID),
|
||||
zap.String("phone", phone),
|
||||
)
|
||||
return "", nil, fmt.Errorf("账号已被禁用")
|
||||
return "", nil, errors.New(errors.CodeForbidden, "账号已被禁用")
|
||||
}
|
||||
|
||||
// 生成 Token(临时传递 phone,后续应该从 Token 中移除 phone 字段)
|
||||
@@ -116,7 +116,7 @@ func (s *Service) LoginByPhone(ctx context.Context, phone string, code string) (
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return "", nil, fmt.Errorf("生成 Token 失败: %w", err)
|
||||
return "", nil, errors.Wrap(errors.CodeInternalError, err, "生成 Token 失败")
|
||||
}
|
||||
|
||||
s.logger.Info("个人客户登录成功",
|
||||
@@ -136,7 +136,7 @@ func (s *Service) BindWechat(ctx context.Context, customerID uint, wxOpenID, wxU
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("查询个人客户失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询个人客户失败")
|
||||
}
|
||||
|
||||
// 更新微信信息
|
||||
@@ -148,7 +148,7 @@ func (s *Service) BindWechat(ctx context.Context, customerID uint, wxOpenID, wxU
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新微信信息失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新微信信息失败")
|
||||
}
|
||||
|
||||
s.logger.Info("绑定微信信息成功",
|
||||
@@ -167,7 +167,7 @@ func (s *Service) UpdateProfile(ctx context.Context, customerID uint, nickname,
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("查询个人客户失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询个人客户失败")
|
||||
}
|
||||
|
||||
// 更新资料
|
||||
@@ -183,7 +183,7 @@ func (s *Service) UpdateProfile(ctx context.Context, customerID uint, nickname,
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新个人资料失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新个人资料失败")
|
||||
}
|
||||
|
||||
s.logger.Info("更新个人资料成功",
|
||||
@@ -201,7 +201,7 @@ func (s *Service) GetProfile(ctx context.Context, customerID uint) (*model.Perso
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("查询个人客户失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询个人客户失败")
|
||||
}
|
||||
|
||||
return customer, nil
|
||||
@@ -216,7 +216,7 @@ func (s *Service) GetProfileWithPhone(ctx context.Context, customerID uint) (*mo
|
||||
zap.Uint("customer_id", customerID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, "", fmt.Errorf("查询个人客户失败: %w", err)
|
||||
return nil, "", errors.Wrap(errors.CodeInternalError, err, "查询个人客户失败")
|
||||
}
|
||||
|
||||
// 获取主手机号
|
||||
|
||||
@@ -50,7 +50,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateRoleRequest) (*mode
|
||||
}
|
||||
|
||||
if err := s.roleStore.Create(ctx, role); err != nil {
|
||||
return nil, fmt.Errorf("创建角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建角色失败")
|
||||
}
|
||||
|
||||
return role, nil
|
||||
@@ -63,7 +63,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*model.Role, error) {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateRoleReques
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
@@ -99,7 +99,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateRoleReques
|
||||
role.Updater = currentUserID
|
||||
|
||||
if err := s.roleStore.Update(ctx, role); err != nil {
|
||||
return nil, fmt.Errorf("更新角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新角色失败")
|
||||
}
|
||||
|
||||
return role, nil
|
||||
@@ -113,11 +113,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return fmt.Errorf("获取角色失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
if err := s.roleStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除角色失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除角色失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -163,12 +163,12 @@ func (s *Service) AssignPermissions(ctx context.Context, roleID uint, permIDs []
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
permissions, err := s.permissionStore.GetByIDs(ctx, permIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取权限失败")
|
||||
}
|
||||
|
||||
if len(permissions) != len(permIDs) {
|
||||
@@ -200,7 +200,7 @@ func (s *Service) AssignPermissions(ctx context.Context, roleID uint, permIDs []
|
||||
Status: constants.StatusEnabled,
|
||||
}
|
||||
if err := s.rolePermissionStore.Create(ctx, rp); err != nil {
|
||||
return nil, fmt.Errorf("创建角色-权限关联失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建角色-权限关联失败")
|
||||
}
|
||||
rps = append(rps, rp)
|
||||
}
|
||||
@@ -216,13 +216,13 @@ func (s *Service) GetPermissions(ctx context.Context, roleID uint) ([]*model.Per
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取角色失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
// 获取权限 ID 列表
|
||||
permIDs, err := s.rolePermissionStore.GetPermIDsByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取角色权限 ID 失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取角色权限 ID 失败")
|
||||
}
|
||||
|
||||
if len(permIDs) == 0 {
|
||||
@@ -240,11 +240,11 @@ func (s *Service) RemovePermission(ctx context.Context, roleID, permID uint) err
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return fmt.Errorf("获取角色失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
if err := s.rolePermissionStore.Delete(ctx, roleID, permID); err != nil {
|
||||
return fmt.Errorf("删除角色-权限关联失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除角色-权限关联失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -262,14 +262,14 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeRoleNotFound, "角色不存在")
|
||||
}
|
||||
return fmt.Errorf("获取角色失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取角色失败")
|
||||
}
|
||||
|
||||
role.Status = status
|
||||
role.Updater = currentUserID
|
||||
|
||||
if err := s.roleStore.Update(ctx, role); err != nil {
|
||||
return fmt.Errorf("更新角色状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新角色状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -77,12 +76,12 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopRequest) (*dto.
|
||||
shop.Updater = currentUserID
|
||||
|
||||
if err := s.shopStore.Create(ctx, shop); err != nil {
|
||||
return nil, fmt.Errorf("创建店铺失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建店铺失败")
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.InitPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码哈希失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
|
||||
account := &model.Account{
|
||||
@@ -97,7 +96,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopRequest) (*dto.
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.accountStore.Create(ctx, account); err != nil {
|
||||
return nil, fmt.Errorf("创建初始账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建初始账号失败")
|
||||
}
|
||||
|
||||
return &dto.ShopResponse{
|
||||
@@ -244,7 +243,7 @@ func (s *Service) ListShopResponses(ctx context.Context, req *dto.ShopListReques
|
||||
|
||||
shops, total, err := s.shopStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询店铺列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询店铺列表失败")
|
||||
}
|
||||
|
||||
responses := make([]*dto.ShopResponse, 0, len(shops))
|
||||
@@ -285,12 +284,12 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeShopNotFound, "店铺不存在")
|
||||
}
|
||||
return fmt.Errorf("获取店铺失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
|
||||
}
|
||||
|
||||
accounts, err := s.accountStore.GetByShopID(ctx, shop.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询店铺账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "查询店铺账号失败")
|
||||
}
|
||||
|
||||
if len(accounts) > 0 {
|
||||
@@ -299,12 +298,12 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
accountIDs = append(accountIDs, account.ID)
|
||||
}
|
||||
if err := s.accountStore.BulkUpdateStatus(ctx, accountIDs, constants.StatusDisabled, currentUserID); err != nil {
|
||||
return fmt.Errorf("禁用店铺账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "禁用店铺账号失败")
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.shopStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除店铺失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除店铺失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop_account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -64,7 +63,7 @@ func (s *Service) List(ctx context.Context, req *dto.ShopAccountListRequest) ([]
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询代理商账号列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询代理商账号列表失败")
|
||||
}
|
||||
|
||||
shopMap := make(map[uint]string)
|
||||
@@ -113,7 +112,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopAccountRequest)
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeShopNotFound, "店铺不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取店铺失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
|
||||
}
|
||||
|
||||
existing, err := s.accountStore.GetByUsername(ctx, req.Username)
|
||||
@@ -128,7 +127,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopAccountRequest)
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码哈希失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
|
||||
account := &model.Account{
|
||||
@@ -143,7 +142,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopAccountRequest)
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.accountStore.Create(ctx, account); err != nil {
|
||||
return nil, fmt.Errorf("创建代理商账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建代理商账号失败")
|
||||
}
|
||||
|
||||
return &dto.ShopAccountResponse{
|
||||
@@ -170,7 +169,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopAccoun
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
if account.UserType != constants.UserTypeAgent {
|
||||
@@ -186,7 +185,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopAccoun
|
||||
account.Updater = currentUserID
|
||||
|
||||
if err := s.accountStore.Update(ctx, account); err != nil {
|
||||
return nil, fmt.Errorf("更新代理商账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新代理商账号失败")
|
||||
}
|
||||
|
||||
var shopName string
|
||||
@@ -221,7 +220,7 @@ func (s *Service) UpdatePassword(ctx context.Context, id uint, req *dto.UpdateSh
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
if account.UserType != constants.UserTypeAgent {
|
||||
@@ -230,11 +229,11 @@ func (s *Service) UpdatePassword(ctx context.Context, id uint, req *dto.UpdateSh
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码哈希失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
|
||||
}
|
||||
|
||||
if err := s.accountStore.UpdatePassword(ctx, id, string(hashedPassword), currentUserID); err != nil {
|
||||
return fmt.Errorf("更新密码失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新密码失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -251,7 +250,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, req *dto.UpdateShop
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeAccountNotFound, "账号不存在")
|
||||
}
|
||||
return fmt.Errorf("获取账号失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
|
||||
if account.UserType != constants.UserTypeAgent {
|
||||
@@ -259,7 +258,7 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, req *dto.UpdateShop
|
||||
}
|
||||
|
||||
if err := s.accountStore.UpdateStatus(ctx, id, req.Status, currentUserID); err != nil {
|
||||
return fmt.Errorf("更新账号状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新账号状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package shop_commission
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -58,7 +57,7 @@ func (s *Service) ListShopCommissionSummary(ctx context.Context, req *dto.ShopCo
|
||||
|
||||
shops, total, err := s.shopStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询店铺列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺列表失败")
|
||||
}
|
||||
|
||||
if len(shops) == 0 {
|
||||
@@ -77,22 +76,22 @@ func (s *Service) ListShopCommissionSummary(ctx context.Context, req *dto.ShopCo
|
||||
|
||||
walletSummaries, err := s.walletStore.GetShopCommissionSummaryBatch(ctx, shopIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询店铺钱包汇总失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺钱包汇总失败")
|
||||
}
|
||||
|
||||
withdrawnAmounts, err := s.commissionWithdrawalReqStore.SumAmountByShopIDsAndStatus(ctx, shopIDs, constants.WithdrawalStatusApproved)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询已提现金额失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询已提现金额失败")
|
||||
}
|
||||
|
||||
withdrawingAmounts, err := s.commissionWithdrawalReqStore.SumAmountByShopIDsAndStatus(ctx, shopIDs, constants.WithdrawalStatusPending)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询提现中金额失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询提现中金额失败")
|
||||
}
|
||||
|
||||
primaryAccounts, err := s.accountStore.GetPrimaryAccountsByShopIDs(ctx, shopIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询主账号失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询主账号失败")
|
||||
}
|
||||
|
||||
accountMap := make(map[uint]*model.Account)
|
||||
@@ -198,7 +197,7 @@ func (s *Service) ListShopWithdrawalRequests(ctx context.Context, shopID uint, r
|
||||
|
||||
requests, total, err := s.commissionWithdrawalReqStore.ListByShopID(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询提现记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询提现记录失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, shopID)
|
||||
@@ -354,7 +353,7 @@ func (s *Service) ListShopCommissionRecords(ctx context.Context, shopID uint, re
|
||||
|
||||
records, total, err := s.commissionRecordStore.ListByShopID(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询佣金明细失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询佣金明细失败")
|
||||
}
|
||||
|
||||
items := make([]dto.ShopCommissionRecordItem, 0, len(records))
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop_package_allocation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -57,7 +56,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopPackageAllocati
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取店铺失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
|
||||
}
|
||||
|
||||
if userType == constants.UserTypeAgent {
|
||||
@@ -71,7 +70,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopPackageAllocati
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
seriesAllocation, err := s.seriesAllocationStore.GetByShopAndSeries(ctx, req.ShopID, pkg.SeriesID)
|
||||
@@ -79,7 +78,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopPackageAllocati
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeForbidden, "该套餐的系列未分配给此店铺")
|
||||
}
|
||||
return nil, fmt.Errorf("获取系列分配失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取系列分配失败")
|
||||
}
|
||||
|
||||
existing, _ := s.packageAllocationStore.GetByShopAndPackage(ctx, req.ShopID, req.PackageID)
|
||||
@@ -97,7 +96,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopPackageAllocati
|
||||
allocation.Creator = currentUserID
|
||||
|
||||
if err := s.packageAllocationStore.Create(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("创建分配失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建分配失败")
|
||||
}
|
||||
|
||||
return s.buildResponse(ctx, allocation, targetShop.ShopName, pkg.PackageName, pkg.PackageCode)
|
||||
@@ -109,7 +108,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*dto.ShopPackageAllocationR
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
|
||||
@@ -140,7 +139,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopPackag
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if req.CostPrice != nil {
|
||||
@@ -149,7 +148,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopPackag
|
||||
allocation.Updater = currentUserID
|
||||
|
||||
if err := s.packageAllocationStore.Update(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("更新分配失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新分配失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
|
||||
@@ -175,11 +174,11 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if err := s.packageAllocationStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除分配失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除分配失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -211,7 +210,7 @@ func (s *Service) List(ctx context.Context, req *dto.ShopPackageAllocationListRe
|
||||
|
||||
allocations, total, err := s.packageAllocationStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询分配列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询分配列表失败")
|
||||
}
|
||||
|
||||
responses := make([]*dto.ShopPackageAllocationResponse, len(allocations))
|
||||
@@ -248,11 +247,11 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if err := s.packageAllocationStore.UpdateStatus(ctx, id, status, currentUserID); err != nil {
|
||||
return fmt.Errorf("更新状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -286,7 +285,7 @@ func (s *Service) UpdateCostPrice(ctx context.Context, id uint, newCostPrice int
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if allocation.CostPrice == newCostPrice {
|
||||
@@ -305,13 +304,13 @@ func (s *Service) UpdateCostPrice(ctx context.Context, id uint, newCostPrice int
|
||||
EffectiveFrom: now,
|
||||
}
|
||||
if err := s.priceHistoryStore.Create(ctx, priceHistory); err != nil {
|
||||
return nil, fmt.Errorf("创建价格历史记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建价格历史记录失败")
|
||||
}
|
||||
|
||||
allocation.CostPrice = newCostPrice
|
||||
allocation.Updater = currentUserID
|
||||
if err := s.packageAllocationStore.Update(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("更新成本价失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新成本价失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
|
||||
@@ -337,12 +336,12 @@ func (s *Service) GetPriceHistory(ctx context.Context, allocationID uint) ([]*mo
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
history, err := s.priceHistoryStore.ListByAllocation(ctx, allocationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取价格历史失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取价格历史失败")
|
||||
}
|
||||
|
||||
return history, nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop_package_batch_allocation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -65,7 +64,7 @@ func (s *Service) BatchAllocate(ctx context.Context, req *dto.BatchAllocatePacka
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "目标店铺不存在")
|
||||
}
|
||||
return fmt.Errorf("获取目标店铺失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取目标店铺失败")
|
||||
}
|
||||
|
||||
if userType == constants.UserTypeAgent {
|
||||
@@ -96,7 +95,7 @@ func (s *Service) BatchAllocate(ctx context.Context, req *dto.BatchAllocatePacka
|
||||
}
|
||||
|
||||
if err := tx.Create(seriesAllocation).Error; err != nil {
|
||||
return fmt.Errorf("创建系列分配失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建系列分配失败")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -110,7 +109,7 @@ func (s *Service) BatchAllocate(ctx context.Context, req *dto.BatchAllocatePacka
|
||||
}
|
||||
|
||||
if err := tx.Create(config).Error; err != nil {
|
||||
return fmt.Errorf("创建配置版本失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建配置版本失败")
|
||||
}
|
||||
|
||||
packageAllocations := make([]*model.ShopPackageAllocation, 0, len(packages))
|
||||
@@ -132,7 +131,7 @@ func (s *Service) BatchAllocate(ctx context.Context, req *dto.BatchAllocatePacka
|
||||
}
|
||||
|
||||
if err := tx.CreateInBatches(packageAllocations, 100).Error; err != nil {
|
||||
return fmt.Errorf("批量创建套餐分配失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "批量创建套餐分配失败")
|
||||
}
|
||||
|
||||
if req.EnableTierCommission && req.TierConfig != nil {
|
||||
@@ -154,7 +153,7 @@ func (s *Service) getEnabledPackagesBySeries(ctx context.Context, seriesID uint)
|
||||
|
||||
packages, _, err := s.packageStore.List(ctx, nil, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取套餐列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐列表失败")
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
@@ -185,7 +184,7 @@ func (s *Service) createCommissionTiers(tx *gorm.DB, allocationID uint, config *
|
||||
}
|
||||
|
||||
if err := tx.Create(tier).Error; err != nil {
|
||||
return fmt.Errorf("创建佣金梯度失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建佣金梯度失败")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop_package_batch_pricing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -59,7 +58,7 @@ func (s *Service) BatchUpdatePricing(ctx context.Context, req *dto.BatchUpdateCo
|
||||
|
||||
allocations, _, err := s.packageAllocationStore.List(ctx, nil, filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if len(allocations) == 0 {
|
||||
@@ -90,13 +89,13 @@ func (s *Service) BatchUpdatePricing(ctx context.Context, req *dto.BatchUpdateCo
|
||||
}
|
||||
|
||||
if err := tx.Create(history).Error; err != nil {
|
||||
return fmt.Errorf("创建价格历史失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建价格历史失败")
|
||||
}
|
||||
|
||||
allocation.CostPrice = newPrice
|
||||
allocation.Updater = currentUserID
|
||||
if err := tx.Save(allocation).Error; err != nil {
|
||||
return fmt.Errorf("更新成本价失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新成本价失败")
|
||||
}
|
||||
|
||||
affectedIDs = append(affectedIDs, allocation.ID)
|
||||
|
||||
@@ -2,7 +2,6 @@ package shop_series_allocation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
@@ -63,7 +62,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopSeriesAllocatio
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取店铺失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
|
||||
}
|
||||
|
||||
isPlatformUser := userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform
|
||||
@@ -84,13 +83,13 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopSeriesAllocatio
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取套餐系列失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
|
||||
}
|
||||
|
||||
if userType == constants.UserTypeAgent {
|
||||
myAllocation, err := s.allocationStore.GetByShopAndSeries(ctx, allocatorShopID, req.SeriesID)
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("检查分配权限失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "检查分配权限失败")
|
||||
}
|
||||
if myAllocation == nil || myAllocation.Status != constants.StatusEnabled {
|
||||
return nil, errors.New(errors.CodeForbidden, "您没有该套餐系列的分配权限")
|
||||
@@ -132,14 +131,14 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateShopSeriesAllocatio
|
||||
allocation.Creator = currentUserID
|
||||
|
||||
if err := s.allocationStore.Create(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("创建分配失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建分配失败")
|
||||
}
|
||||
|
||||
// 如果是梯度类型,保存梯度配置
|
||||
if req.EnableOneTimeCommission && req.OneTimeCommissionConfig != nil &&
|
||||
req.OneTimeCommissionConfig.Type == model.OneTimeCommissionTypeTiered {
|
||||
if err := s.saveOneTimeCommissionTiers(ctx, allocation.ID, req.OneTimeCommissionConfig.Tiers, currentUserID); err != nil {
|
||||
return nil, fmt.Errorf("创建一次性佣金梯度配置失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建一次性佣金梯度配置失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +151,7 @@ func (s *Service) Get(ctx context.Context, id uint) (*dto.ShopSeriesAllocationRe
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
|
||||
@@ -181,7 +180,7 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopSeries
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
configChanged := false
|
||||
@@ -239,21 +238,21 @@ func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopSeries
|
||||
|
||||
if configChanged {
|
||||
if err := s.createNewConfigVersion(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("创建配置版本失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "创建配置版本失败")
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.allocationStore.Update(ctx, allocation); err != nil {
|
||||
return nil, fmt.Errorf("更新分配失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新分配失败")
|
||||
}
|
||||
|
||||
if oneTimeCommissionChanged && req.OneTimeCommissionConfig != nil &&
|
||||
req.OneTimeCommissionConfig.Type == model.OneTimeCommissionTypeTiered {
|
||||
if err := s.oneTimeCommissionTierStore.DeleteByAllocationID(ctx, allocation.ID); err != nil {
|
||||
return nil, fmt.Errorf("清理旧梯度配置失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "清理旧梯度配置失败")
|
||||
}
|
||||
if err := s.saveOneTimeCommissionTiers(ctx, allocation.ID, req.OneTimeCommissionConfig.Tiers, currentUserID); err != nil {
|
||||
return nil, fmt.Errorf("更新一次性佣金梯度配置失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "更新一次性佣金梯度配置失败")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,19 +277,19 @@ func (s *Service) Delete(ctx context.Context, id uint) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
hasDependent, err := s.allocationStore.HasDependentAllocations(ctx, allocation.ShopID, allocation.SeriesID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("检查依赖关系失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "检查依赖关系失败")
|
||||
}
|
||||
if hasDependent {
|
||||
return errors.New(errors.CodeConflict, "存在下级依赖,无法删除")
|
||||
}
|
||||
|
||||
if err := s.allocationStore.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("删除分配失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "删除分配失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -328,7 +327,7 @@ func (s *Service) List(ctx context.Context, req *dto.ShopSeriesAllocationListReq
|
||||
|
||||
allocations, total, err := s.allocationStore.List(ctx, opts, filters)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("查询分配列表失败: %w", err)
|
||||
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询分配列表失败")
|
||||
}
|
||||
|
||||
responses := make([]*dto.ShopSeriesAllocationResponse, len(allocations))
|
||||
@@ -363,11 +362,11 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
if err := s.allocationStore.UpdateStatus(ctx, id, status, currentUserID); err != nil {
|
||||
return fmt.Errorf("更新状态失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "更新状态失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -376,12 +375,12 @@ func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
|
||||
func (s *Service) GetParentCostPrice(ctx context.Context, shopID, packageID uint) (int64, error) {
|
||||
pkg, err := s.packageStore.GetByID(ctx, packageID)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("获取套餐失败: %w", err)
|
||||
return 0, errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
|
||||
}
|
||||
|
||||
shop, err := s.shopStore.GetByID(ctx, shopID)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("获取店铺失败: %w", err)
|
||||
return 0, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
|
||||
}
|
||||
|
||||
if shop.ParentID == nil || *shop.ParentID == 0 {
|
||||
@@ -449,7 +448,7 @@ func (s *Service) createNewConfigVersion(ctx context.Context, allocation *model.
|
||||
now := time.Now()
|
||||
|
||||
if err := s.configStore.InvalidateCurrent(ctx, allocation.ID, now); err != nil {
|
||||
return fmt.Errorf("失效当前配置版本失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "失效当前配置版本失败")
|
||||
}
|
||||
|
||||
latestVersion, err := s.configStore.GetLatestVersion(ctx, allocation.ID)
|
||||
@@ -468,7 +467,7 @@ func (s *Service) createNewConfigVersion(ctx context.Context, allocation *model.
|
||||
}
|
||||
|
||||
if err := s.configStore.Create(ctx, newConfig); err != nil {
|
||||
return fmt.Errorf("创建新配置版本失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "创建新配置版本失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -546,7 +545,7 @@ func (s *Service) GetEffectiveConfig(ctx context.Context, allocationID uint, at
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "未找到生效的配置版本")
|
||||
}
|
||||
return nil, fmt.Errorf("获取生效配置失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取生效配置失败")
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
@@ -557,12 +556,12 @@ func (s *Service) ListConfigVersions(ctx context.Context, allocationID uint) ([]
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
|
||||
}
|
||||
return nil, fmt.Errorf("获取分配记录失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
|
||||
}
|
||||
|
||||
configs, err := s.configStore.List(ctx, allocationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取配置版本列表失败: %w", err)
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取配置版本列表失败")
|
||||
}
|
||||
|
||||
return configs, nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/queue"
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/hibiken/asynq"
|
||||
@@ -43,7 +44,7 @@ func (s *Service) SyncSIMStatus(ctx context.Context, iccids []string, forceSync
|
||||
zap.Int("iccid_count", len(iccids)),
|
||||
zap.Bool("force_sync", forceSync),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("序列化 SIM 状态同步任务载荷失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "序列化 SIM 状态同步任务载荷失败")
|
||||
}
|
||||
|
||||
// 提交任务到队列(高优先级)
|
||||
@@ -59,7 +60,7 @@ func (s *Service) SyncSIMStatus(ctx context.Context, iccids []string, forceSync
|
||||
s.logger.Error("提交 SIM 状态同步任务失败",
|
||||
zap.Int("iccid_count", len(iccids)),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("提交 SIM 状态同步任务失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "提交 SIM 状态同步任务失败")
|
||||
}
|
||||
|
||||
s.logger.Info("SIM 状态同步任务已提交",
|
||||
@@ -92,7 +93,7 @@ func (s *Service) SyncData(ctx context.Context, syncType string, startDate strin
|
||||
zap.String("start_date", startDate),
|
||||
zap.String("end_date", endDate),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("序列化数据同步任务载荷失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "序列化数据同步任务载荷失败")
|
||||
}
|
||||
|
||||
// 提交任务到队列(默认优先级)
|
||||
@@ -108,7 +109,7 @@ func (s *Service) SyncData(ctx context.Context, syncType string, startDate strin
|
||||
s.logger.Error("提交数据同步任务失败",
|
||||
zap.String("sync_type", syncType),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("提交数据同步任务失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "提交数据同步任务失败")
|
||||
}
|
||||
|
||||
s.logger.Info("数据同步任务已提交",
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/config"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/sms"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
@@ -33,6 +34,12 @@ func NewService(redisClient *redis.Client, smsClient *sms.Client, logger *zap.Lo
|
||||
|
||||
// SendCode 发送验证码
|
||||
func (s *Service) SendCode(ctx context.Context, phone string) error {
|
||||
// 检查短信服务是否可用
|
||||
if s.smsClient == nil {
|
||||
s.logger.Error("短信服务未配置", zap.String("phone", phone))
|
||||
return errors.New(errors.CodeServiceUnavailable)
|
||||
}
|
||||
|
||||
// 检查发送频率限制
|
||||
limitKey := constants.RedisVerificationCodeLimitKey(phone)
|
||||
exists, err := s.redisClient.Exists(ctx, limitKey).Result()
|
||||
@@ -41,14 +48,14 @@ func (s *Service) SendCode(ctx context.Context, phone string) error {
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("检查验证码发送频率限制失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "检查验证码发送频率限制失败")
|
||||
}
|
||||
|
||||
if exists > 0 {
|
||||
s.logger.Warn("验证码发送过于频繁",
|
||||
zap.String("phone", phone),
|
||||
)
|
||||
return fmt.Errorf("验证码发送过于频繁,请稍后再试")
|
||||
return errors.New(errors.CodeTooManyRequests, "验证码发送过于频繁,请稍后再试")
|
||||
}
|
||||
|
||||
// 生成随机验证码
|
||||
@@ -58,7 +65,7 @@ func (s *Service) SendCode(ctx context.Context, phone string) error {
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("生成验证码失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "生成验证码失败")
|
||||
}
|
||||
|
||||
// 构造短信内容
|
||||
@@ -72,7 +79,7 @@ func (s *Service) SendCode(ctx context.Context, phone string) error {
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("发送验证码短信失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "发送验证码短信失败")
|
||||
}
|
||||
|
||||
// 存储验证码到 Redis
|
||||
@@ -83,7 +90,7 @@ func (s *Service) SendCode(ctx context.Context, phone string) error {
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("存储验证码失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "存储验证码失败")
|
||||
}
|
||||
|
||||
// 设置发送频率限制
|
||||
@@ -121,14 +128,14 @@ func (s *Service) VerifyCode(ctx context.Context, phone string, code string) err
|
||||
s.logger.Warn("验证码不存在或已过期",
|
||||
zap.String("phone", phone),
|
||||
)
|
||||
return fmt.Errorf("验证码不存在或已过期")
|
||||
return errors.New(errors.CodeInvalidParam, "验证码不存在或已过期")
|
||||
}
|
||||
if err != nil {
|
||||
s.logger.Error("获取验证码失败",
|
||||
zap.String("phone", phone),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("获取验证码失败: %w", err)
|
||||
return errors.Wrap(errors.CodeInternalError, err, "获取验证码失败")
|
||||
}
|
||||
|
||||
// 验证码比对
|
||||
@@ -136,7 +143,7 @@ func (s *Service) VerifyCode(ctx context.Context, phone string, code string) err
|
||||
s.logger.Warn("验证码错误",
|
||||
zap.String("phone", phone),
|
||||
)
|
||||
return fmt.Errorf("验证码错误")
|
||||
return errors.New(errors.CodeInvalidParam, "验证码错误")
|
||||
}
|
||||
|
||||
// 验证成功,删除验证码(防止重复使用)
|
||||
|
||||
Reference in New Issue
Block a user