代理在线充值
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m6s

This commit is contained in:
2026-07-27 16:02:55 +08:00
parent a2166c8011
commit cbf909b878
42 changed files with 3121 additions and 195 deletions

View File

@@ -95,20 +95,16 @@ func (s *Service) SetOfflineCreationService(service *agentrechargeapp.OfflineCre
func (s *Service) Create(ctx context.Context, req *dto.CreateAgentRechargeRequest) (*dto.AgentRechargeResponse, error) {
userID := middleware.GetUserIDFromContext(ctx)
userType := middleware.GetUserTypeFromContext(ctx)
userShopID := middleware.GetShopIDFromContext(ctx)
// 代理只能充自己店铺
if userType == constants.UserTypeAgent && req.ShopID != userShopID {
return nil, errors.New(errors.CodeForbidden, "代理只能为自己的店铺充值")
if req.PaymentMethod != constants.RechargeMethodOffline {
return nil, errors.New(errors.CodeInvalidStatus, "在线充值必须通过代理在线创建用例处理")
}
// 线下充值仅平台可用
if req.PaymentMethod == constants.RechargeMethodOffline && userType != constants.UserTypePlatform && userType != constants.UserTypeSuperAdmin {
if userType != constants.UserTypePlatform && userType != constants.UserTypeSuperAdmin {
return nil, errors.New(errors.CodeForbidden, "线下充值仅平台管理员可操作")
}
// 线下充值必须上传支付凭证
if req.PaymentMethod == constants.RechargeMethodOffline && len(req.PaymentVoucherKey) == 0 {
if req.ShopID == nil || *req.ShopID == 0 {
return nil, errors.New(errors.CodeInvalidParam, "线下充值必须指定目标店铺")
}
if len(req.PaymentVoucherKey) == 0 {
return nil, errors.New(errors.CodeInvalidParam, "线下充值必须上传支付凭证")
}
@@ -117,73 +113,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateAgentRechargeReques
}
rechargeNo := s.generateRechargeNo()
if req.PaymentMethod == constants.RechargeMethodOffline {
return s.createOffline(ctx, req, userID, userType, rechargeNo)
}
// 查找目标店铺的主钱包
wallet, err := s.agentWalletStore.GetMainWallet(ctx, req.ShopID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "目标店铺主钱包不存在")
}
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询店铺主钱包失败")
}
// 查询店铺名称
shop, err := s.shopStore.GetByID(ctx, req.ShopID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
}
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询店铺失败")
}
// 在线支付需要查询生效的支付配置
var paymentConfigID *uint
var paymentChannel string
if req.PaymentMethod == "wechat" {
activeConfig, cfgErr := s.wechatConfigService.GetActiveConfig(ctx)
if cfgErr != nil || activeConfig == nil {
return nil, errors.New(errors.CodeNoPaymentConfig, "当前无可用的支付配置,请联系管理员")
}
paymentConfigID = &activeConfig.ID
paymentChannel = activeConfig.ProviderType
} else {
paymentChannel = "offline"
}
record := &model.AgentRechargeRecord{
UserID: userID,
AgentWalletID: wallet.ID,
ShopID: req.ShopID,
RechargeNo: rechargeNo,
Amount: req.Amount,
PaymentMethod: req.PaymentMethod,
PaymentChannel: &paymentChannel,
PaymentConfigID: paymentConfigID,
PaymentVoucherKey: model.StringJSONBArray(req.PaymentVoucherKey),
Remark: req.Remark,
Status: constants.RechargeStatusPending,
ShopIDTag: wallet.ShopIDTag,
EnterpriseIDTag: wallet.EnterpriseIDTag,
}
if err := s.agentRechargeStore.Create(ctx, record); err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "创建充值订单失败")
}
s.logger.Info("创建代理充值订单成功",
zap.Uint("recharge_id", record.ID),
zap.String("recharge_no", rechargeNo),
zap.Int64("amount", req.Amount),
zap.Uint("shop_id", req.ShopID),
zap.Uint("user_id", userID),
)
resp := toResponse(record, shop.ShopName)
resp.SubmitterName = s.loadSubmitterNameBestEffort(ctx, record.UserID)
return resp, nil
return s.createOffline(ctx, req, userID, userType, rechargeNo)
}
func (s *Service) createOffline(
@@ -199,7 +129,7 @@ func (s *Service) createOffline(
result, err := s.offlineCreation.Execute(ctx, agentrechargeapp.CreateOfflineCommand{
SubmitterAccountID: userID,
SubmitterUserType: userType,
ShopID: req.ShopID,
ShopID: *req.ShopID,
RechargeNo: rechargeNo,
Amount: req.Amount,
PaymentVoucherKeys: req.PaymentVoucherKey,
@@ -522,6 +452,12 @@ func (s *Service) List(ctx context.Context, req *dto.AgentRechargeListRequest) (
if req.Status != nil {
query = query.Where("status = ?", *req.Status)
}
switch req.RechargeSource {
case constants.AgentRechargeSourcePlatformOffline:
query = query.Where("payment_method NOT IN ?", []string{constants.RechargeMethodWechat, constants.RechargeMethodAlipay})
case constants.AgentRechargeSourceAgentOnline:
query = query.Where("payment_method IN ?", []string{constants.RechargeMethodWechat, constants.RechargeMethodAlipay})
}
if req.StartDate != "" {
query = query.Where("created_at >= ?", req.StartDate+" 00:00:00")
}
@@ -590,6 +526,7 @@ func (s *Service) generateRechargeNo() string {
// toResponse 将模型转换为响应 DTO
func toResponse(record *model.AgentRechargeRecord, shopName string) *dto.AgentRechargeResponse {
rechargeSource, rechargeSourceName := constants.GetAgentRechargeSource(record.PaymentMethod)
resp := &dto.AgentRechargeResponse{
ID: record.ID,
RechargeNo: record.RechargeNo,
@@ -598,6 +535,8 @@ func toResponse(record *model.AgentRechargeRecord, shopName string) *dto.AgentRe
AgentWalletID: record.AgentWalletID,
Amount: record.Amount,
PaymentMethod: record.PaymentMethod,
RechargeSource: rechargeSource,
RechargeSourceName: rechargeSourceName,
PaymentVoucherKey: []string(record.PaymentVoucherKey),
Remark: record.Remark,
Status: record.Status,