feat: OpenAPI 契约对齐与框架优化
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:
2026-01-30 11:40:36 +08:00
parent 1290160728
commit 409a68d60b
88 changed files with 27358 additions and 990 deletions

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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 := ""

View File

@@ -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{}).

View File

@@ -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{

View File

@@ -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("通知邮件任务已提交",

View File

@@ -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))

View File

@@ -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))

View File

@@ -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{

View File

@@ -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{

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -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, "查询个人客户失败")
}
// 获取主手机号

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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, "创建佣金梯度失败")
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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("数据同步任务已提交",

View File

@@ -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, "验证码错误")
}
// 验证成功,删除验证码(防止重复使用)