# 佣金冻结功能实现说明 ## 功能需求 当订单单价 >= 配置阈值(默认100元)时,抽取订单单价的配置比例(默认10%)放到冻结余额,冻结配置天数(默认30天)后自动解冻。所有配置项都可在配置表中修改,但配置只在创建任务时读取,已创建的任务不受后续配置修改影响。 ## 实现步骤 ### 1. 运行SQL创建冻结任务表 ```bash # 执行SQL文件 mysql -u用户名 -p数据库名 < deploy/sql/agent_freeze_task_migration.sql ``` ### 2. 生成Model 运行代码生成工具生成 `AgentFreezeTaskModel`: ```bash # 在 ycc-proxy-server 目录下运行 goctl model mysql datasource -url="数据库连接字符串" -table="agent_freeze_task" -dir="./app/main/model" -cache ``` ### 3. 更新ServiceContext 在 `app/main/api/internal/svc/servicecontext.go` 中: #### 3.1 添加字段 ```go AgentFreezeTaskModel model.AgentFreezeTaskModel ``` #### 3.2 初始化Model 在 `NewServiceContext` 函数中添加: ```go agentFreezeTaskModel := model.NewAgentFreezeTaskModel(db, cacheConf) ``` #### 3.3 传递给AgentService 修改 `NewAgentService` 调用,添加参数: ```go agentService := service.NewAgentService(c, orderModel, agentModel, agentWalletModel, agentRelationModel, agentLinkModel, agentOrderModel, agentCommissionModel, agentRebateModel, agentUpgradeModel, agentWithdrawalModel, agentConfigModel, agentProductConfigModel, agentRealNameModel, agentWithdrawalTaxModel, agentFreezeTaskModel) // 添加这个参数 ``` #### 3.4 添加到ServiceContext返回 在返回的 `ServiceContext` 结构体中添加: ```go AgentFreezeTaskModel: agentFreezeTaskModel, ``` ### 4. 添加配置项 在 `agent_config` 表中添加配置: ```sql -- 冻结阈值(订单单价达到此金额才触发冻结,默认100元) INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES ('commission_freeze_threshold', '100', 'rebate', '佣金冻结阈值(订单单价达到此金额才触发冻结,单位:元)'); -- 冻结比例(默认10%) INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES ('commission_freeze_ratio', '0.1', 'rebate', '佣金冻结比例(例如:0.1表示10%)'); -- 解冻天数(默认30天,即1个月) INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES ('commission_freeze_days', '30', 'rebate', '佣金冻结解冻天数(单位:天,例如:30表示30天后解冻)'); ``` ### 5. 代码已完成的修改 #### 5.1 已修改的文件 - ✅ `deploy/sql/agent_freeze_task_migration.sql` - 创建冻结任务表 - ✅ `app/main/api/internal/service/agentService.go` - 修改 `giveAgentCommission` 函数,增加冻结逻辑 - ✅ `app/main/api/internal/service/asynqService.go` - 添加 `SendUnfreezeTask` 方法 - ✅ `app/main/api/internal/queue/unfreezeCommission.go` - 创建解冻任务处理器 - ✅ `app/main/api/internal/queue/routes.go` - 注册解冻任务路由 - ✅ `app/main/api/internal/queue/agentProcess.go` - 在代理处理成功后发送解冻任务 - ✅ `app/main/api/internal/types/taskname.go` - 添加解冻任务类型 - ✅ `app/main/api/internal/types/payload.go` - 添加解冻任务负载类型 #### 5.2 核心逻辑说明 **冻结逻辑**(在 `giveAgentCommission` 中): 1. 判断订单单价是否 >= 100元 2. 如果是,从配置表读取冻结比例(默认10%) 3. 计算冻结金额 = 订单单价 × 冻结比例(不超过佣金金额) 4. 创建冻结任务记录(状态=待解冻,解冻时间=从配置读取的天数后) 5. 更新钱包:`Balance += (佣金金额 - 冻结金额)`,`FrozenBalance += 冻结金额` **解冻逻辑**(在 `unfreezeCommission.go` 中): 1. 查询冻结任务 2. 检查解冻时间是否已到 3. 更新冻结任务状态为已解冻 4. 更新钱包:`FrozenBalance -= 冻结金额`,`Balance += 冻结金额` ### 6. 注意事项 1. **Model生成**:必须先运行SQL并生成Model,否则代码无法编译 2. **配置项**:需要在 `agent_config` 表中添加 `commission_freeze_ratio` 配置项 3. **异步任务**:解冻任务通过 asynq 延迟执行,确保在配置的天数后自动解冻 4. **数据一致性**:所有操作都在事务中执行,保证数据一致性 ### 7. 测试建议 1. 测试订单单价 < 100元:不应冻结 2. 测试订单单价 >= 100元:应冻结订单单价的10% 3. 测试冻结金额超过佣金:应冻结全部佣金 4. 测试解冻任务:在配置的天数后应自动解冻