This commit is contained in:
2025-07-31 15:41:00 +08:00
parent f3a3bc84c7
commit 934dce2776
36 changed files with 1614 additions and 264 deletions

View File

@@ -0,0 +1,209 @@
# 支付宝充值赠送功能说明
## 功能概述
本功能实现了支付宝充值的自动赠送机制,根据充值金额自动计算并赠送相应的金额到用户钱包。
## 赠送规则
当前配置的赠送规则如下:
| 充值金额 | 赠送金额 | 说明 |
|---------|---------|------|
| 1000元 | 50元 | 充值1000元及以上赠送50元 |
| 5000元 | 300元 | 充值5000元及以上赠送300元 |
| 10000元 | 800元 | 充值10000元及以上赠送800元 |
**注意**:赠送规则按充值金额从高到低匹配,即充值金额满足多个条件时,按最高档次的赠送金额计算。
## 配置说明
### 1. 配置文件位置
- 主配置文件:`config.yaml`
- 环境配置文件:`configs/env.*.yaml`
### 2. 配置结构
```yaml
wallet:
default_credit_limit: 50.00
# 支付宝充值赠送配置
alipay_recharge_bonus:
- recharge_amount: 1000.00 # 充值1000元
bonus_amount: 50.00 # 赠送50元
- recharge_amount: 5000.00 # 充值5000元
bonus_amount: 300.00 # 赠送300元
- recharge_amount: 10000.00 # 充值10000元
bonus_amount: 800.00 # 赠送800元
```
### 3. 配置结构体
```go
type WalletConfig struct {
DefaultCreditLimit float64 `mapstructure:"default_credit_limit"`
AliPayRechargeBonus []AliPayRechargeBonusRule `mapstructure:"alipay_recharge_bonus"`
}
type AliPayRechargeBonusRule struct {
RechargeAmount float64 `mapstructure:"recharge_amount"` // 充值金额
BonusAmount float64 `mapstructure:"bonus_amount"` // 赠送金额
}
```
## 实现逻辑
### 1. 赠送金额计算
`calculateAlipayRechargeBonus` 函数中实现:
```go
func calculateAlipayRechargeBonus(rechargeAmount decimal.Decimal, walletConfig *config.WalletConfig) decimal.Decimal {
if walletConfig == nil || len(walletConfig.AliPayRechargeBonus) == 0 {
return decimal.Zero
}
// 按充值金额从高到低排序,找到第一个匹配的赠送规则
// 由于配置中规则是按充值金额从低到高排列的,我们需要反向遍历
for i := len(walletConfig.AliPayRechargeBonus) - 1; i >= 0; i-- {
rule := walletConfig.AliPayRechargeBonus[i]
if rechargeAmount.GreaterThanOrEqual(decimal.NewFromFloat(rule.RechargeAmount)) {
return decimal.NewFromFloat(rule.BonusAmount)
}
}
return decimal.Zero
}
```
### 2. 充值成功处理
`HandleAlipayPaymentSuccess` 方法中实现:
1. **计算赠送金额**:根据充值金额计算应赠送的金额
2. **创建赠送记录**:如果有赠送金额,创建一条赠送类型的充值记录
3. **更新钱包余额**:将充值金额和赠送金额的总和添加到用户钱包
```go
// 计算充值赠送金额
bonusAmount := calculateAlipayRechargeBonus(amount, &s.cfg.Wallet)
totalAmount := amount.Add(bonusAmount)
// 如果有赠送金额,创建赠送充值记录
if bonusAmount.GreaterThan(decimal.Zero) {
giftRechargeRecord := entities.NewGiftRechargeRecord(rechargeRecord.UserID, bonusAmount, "充值活动赠送")
_, err = s.rechargeRecordRepo.Create(txCtx, *giftRechargeRecord)
if err != nil {
s.logger.Error("创建赠送充值记录失败", zap.Error(err))
return err
}
}
// 使用钱包聚合服务更新钱包余额(包含赠送金额)
err = s.walletService.Recharge(txCtx, rechargeRecord.UserID, totalAmount)
```
## 数据库记录
### 1. 充值记录表 (recharge_records)
每次支付宝充值成功会产生两条记录:
1. **支付宝充值记录**
- `recharge_type`: "alipay"
- `amount`: 实际充值金额
- `status`: "success"
2. **赠送充值记录**(如果有赠送):
- `recharge_type`: "gift"
- `amount`: 赠送金额
- `notes`: "充值活动赠送"
- `status`: "success"
### 2. 钱包余额
钱包余额会更新为:`原余额 + 充值金额 + 赠送金额`
## 测试用例
### 1. 单元测试
运行测试命令:
```bash
go test ./internal/domains/finance/services -v
```
测试覆盖的场景:
- 充值500元无赠送
- 充值1000元赠送50元
- 充值2000元赠送50元
- 充值5000元赠送300元
- 充值8000元赠送300元
- 充值10000元赠送800元
- 充值15000元赠送800元
### 2. 配置测试
运行配置测试:
```bash
go test ./internal/config -v
```
验证配置文件中的赠送规则是否正确加载。
## 日志记录
系统会记录详细的日志信息:
```
支付宝支付成功回调处理成功
- user_id: 用户ID
- recharge_amount: 充值金额
- bonus_amount: 赠送金额
- total_amount: 总金额(充值+赠送)
- out_trade_no: 支付宝订单号
- trade_no: 支付宝交易号
- recharge_id: 充值记录ID
- order_id: 支付宝订单ID
```
## 扩展说明
### 1. 添加新的赠送规则
在配置文件中添加新的规则:
```yaml
wallet:
alipay_recharge_bonus:
- recharge_amount: 1000.00
bonus_amount: 50.00
- recharge_amount: 5000.00
bonus_amount: 300.00
- recharge_amount: 10000.00
bonus_amount: 800.00
- recharge_amount: 20000.00 # 新增规则
bonus_amount: 2000.00 # 充值20000元赠送2000元
```
### 2. 修改赠送规则
直接修改配置文件中的 `recharge_amount``bonus_amount` 值即可。
### 3. 禁用赠送功能
将配置文件中的 `alipay_recharge_bonus` 设置为空数组:
```yaml
wallet:
alipay_recharge_bonus: []
```
## 注意事项
1. **事务保护**:所有数据库操作都在事务中执行,确保数据一致性
2. **重复处理防护**:系统会检查订单状态,避免重复处理
3. **精确计算**:使用 `decimal.Decimal` 进行金额计算,避免浮点数精度问题
4. **日志记录**:详细记录所有操作,便于问题排查
5. **配置热更新**:修改配置后需要重启服务才能生效