# 代理配置表分析和优化建议 ## 一、当前配置表结构分析 ### 1.1 数据库表结构 **表名**: `agent_config` ```sql CREATE TABLE `agent_config` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `config_key` varchar(100) NOT NULL COMMENT '配置键(唯一)', `config_value` varchar(500) NOT NULL COMMENT '配置值', `config_type` varchar(50) NOT NULL COMMENT '配置类型:price=价格,bonus=等级加成,upgrade=升级费用,rebate=返佣,tax=税费', `description` varchar(500) DEFAULT NULL COMMENT '配置描述', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `delete_time` datetime DEFAULT NULL, `del_state` tinyint NOT NULL DEFAULT 0, `version` bigint NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `uk_config_key` (`config_key`), KEY `idx_config_type` (`config_type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 1.2 配置表设计评估 **优点**: ✅ **键值对存储灵活**:使用 `config_key` 和 `config_value` 的键值对模式,易于扩展新配置项 ✅ **类型分类清晰**:`config_type` 字段将配置分为 price、bonus、upgrade、rebate、tax 等类型,便于管理 ✅ **唯一索引合理**:`config_key` 的唯一索引确保配置键不重复 ✅ **版本控制**:包含 `version` 字段支持乐观锁,适合配置更新场景 ✅ **软删除支持**:支持软删除,保留历史配置记录 **缺点/问题**: ❌ **配置值类型限制**:`config_value` 为 `varchar(500)`,所有值都存储为字符串,需要在使用时转换 ❌ **缺少验证机制**:数据库层面无法验证配置值的格式和范围 ❌ **配置值长度限制**:对于复杂配置(如JSON对象),500字符可能不够 --- ## 二、当前配置项清单 ### 2.1 SQL初始化脚本中的配置项 根据 `agent_system_migration.sql` 文件,当前初始化的配置项: | 配置键 | 配置值 | 类型 | 说明 | | ------------------------------- | ------- | ------- | ------------------------ | | `base_price` | 0.00 | price | 系统基础底价 | | `system_max_price` | 9999.99 | price | 系统价格上限 | | `price_threshold` | 0.00 | price | 提价标准阈值 | | `price_fee_rate` | 0.0000 | price | 提价手续费比例 | | `level_bonus_normal` | 6.00 | bonus | 普通代理等级加成 | | `level_bonus_gold` | 3.00 | bonus | 黄金代理等级加成 | | `level_bonus_diamond` | 0.00 | bonus | 钻石代理等级加成 | | `upgrade_fee_normal_to_gold` | 199.00 | upgrade | 普通→黄金升级费用 | | `upgrade_fee_to_diamond` | 980.00 | upgrade | 升级为钻石费用 | | `upgrade_rebate_normal_to_gold` | 139.00 | upgrade | 普通→黄金返佣金额 | | `upgrade_rebate_to_diamond` | 680.00 | upgrade | 升级为钻石返佣金额 | | `direct_parent_amount_diamond` | 6.00 | rebate | 直接上级是钻石的返佣金额 | | `direct_parent_amount_gold` | 3.00 | rebate | 直接上级是黄金的返佣金额 | | `direct_parent_amount_normal` | 2.00 | rebate | 直接上级是普通的返佣金额 | | `max_gold_rebate_amount` | 3.00 | rebate | 黄金代理最大返佣金额 | | `tax_rate` | 0.0600 | tax | 提现税率(6%) | **共15个配置项** ### 2.2 代码中使用的配置键 #### 2.2.1 AgentService 中使用的配置键 - `base_price` - 基础底价 ✅ - `price_threshold` - 提价标准阈值 ✅ - `price_fee_rate` - 提价手续费比例 ✅ - `level_bonus` - **硬编码,未从配置表读取** ❌ #### 2.2.2 AdminGetAgentConfigLogic 中使用的配置键 - `level_1_bonus` - 普通代理等级加成 ❌ **配置键不匹配** - `level_2_bonus` - 黄金代理等级加成 ❌ **配置键不匹配** - `level_3_bonus` - 钻石代理等级加成 ❌ **配置键不匹配** - `upgrade_to_gold_fee` - 升级为黄金费用 ❌ **配置键不匹配** - `upgrade_to_diamond_fee` - 升级为钻石费用 ❌ **配置键不匹配** - `upgrade_to_gold_rebate` - 升级为黄金返佣 ❌ **配置键不匹配** - `upgrade_to_diamond_rebate` - 升级为钻石返佣 ❌ **配置键不匹配** - `tax_rate` - 税率 ✅ - `tax_exemption_amount` - 免税额度 ❌ **配置项缺失** --- ## 三、发现的问题 ### 3.1 🔴 严重问题:价格配置不应在系统配置表中 **问题描述**: 价格相关配置(底价、上限、提价阈值、手续费比例)应该按产品配置,而不是全局系统配置。当前这些配置同时存在于 `agent_config` 和 `agent_product_config` 表中,但代码只从系统配置表读取,没有实现产品级别的配置覆盖。 **问题影响**: - ❌ 不同产品无法设置不同的底价和价格策略 - ❌ 代码中只读取系统配置,忽略了产品配置(`AgentService.AgentProcess`、`PaymentLogic`) - ❌ 产品配置表虽然存在,但在订单处理逻辑中未被使用 **应该移除的系统配置项**: - `base_price` - 应该只在产品配置表中 - `system_max_price` - 应该只在产品配置表中 - `price_threshold` - 应该只在产品配置表中(可选) - `price_fee_rate` - 应该只在产品配置表中(可选) **正确的设计**: - ✅ 所有价格相关配置都应该在 `agent_product_config` 表中按产品配置 - ✅ 系统配置表只保留全局配置(等级加成、升级费用、税费等) - ✅ 代码应该优先从产品配置读取,如果产品未配置,则使用默认值 ### 3.2 🔴 严重问题:配置键命名不一致 **问题描述**: SQL初始化脚本和代码逻辑中使用的配置键命名不一致,导致配置无法正确读取。 **具体情况**: | 配置项 | SQL初始化脚本 | 代码逻辑期望 | 状态 | | ---------------- | ------------------------------- | --------------------------- | -------- | | 普通代理等级加成 | `level_bonus_normal` | `level_1_bonus` | ❌ 不匹配 | | 黄金代理等级加成 | `level_bonus_gold` | `level_2_bonus` | ❌ 不匹配 | | 钻石代理等级加成 | `level_bonus_diamond` | `level_3_bonus` | ❌ 不匹配 | | 升级为黄金费用 | `upgrade_fee_normal_to_gold` | `upgrade_to_gold_fee` | ❌ 不匹配 | | 升级为钻石费用 | `upgrade_fee_to_diamond` | `upgrade_to_diamond_fee` | ❌ 不匹配 | | 升级为黄金返佣 | `upgrade_rebate_normal_to_gold` | `upgrade_to_gold_rebate` | ❌ 不匹配 | | 升级为钻石返佣 | `upgrade_rebate_to_diamond` | `upgrade_to_diamond_rebate` | ❌ 不匹配 | **影响**: - 后台管理系统无法正确读取和显示配置值 - 配置更新可能无法正常工作 ### 3.3 🔴 严重问题:代码中硬编码等级加成 **问题位置**: ```go // agentService.go:144-155 func (s *AgentService) getLevelBonus(level int64) int64 { switch level { case 1: // 普通 return 6 // ❌ 硬编码,应该从配置表读取 case 2: // 黄金 return 3 // ❌ 硬编码,应该从配置表读取 case 3: // 钻石 return 0 // ❌ 硬编码,应该从配置表读取 default: return 0 } } ``` **问题影响**: - 等级加成值无法通过后台配置动态调整 - 必须修改代码才能更改等级加成 - 违反了配置化的设计原则 ### 3.4 🟡 中等问题:缺少配置项 **缺失的配置项**: 1. `tax_exemption_amount` - 免税额度(前端接口需要,但SQL初始化脚本中未包含) 2. `upgrade_fee_gold_to_diamond` - 黄金→钻石升级费用(如果独立配置) ### 3.5 🟡 中等问题:配置键命名规范不统一 **当前问题**: - 部分使用下划线分隔:`level_bonus_normal` - 部分使用数字后缀:`level_1_bonus` - 部分使用驼峰式:`upgrade_fee_normal_to_gold` **建议**:统一命名规范 ### 3.6 🟢 轻微问题:配置值存储方式 **当前方式**:所有配置值以字符串形式存储,需要在使用时转换 - `strconv.ParseFloat()` 转换为浮点数 - `strconv.ParseInt()` 转换为整数 **影响**:每次读取都需要类型转换,性能影响较小,但容易出错 --- ## 四、配置使用情况分析 ### 4.1 实际使用的配置项 **在业务逻辑中使用的配置**: 1. ✅ `base_price` - 订单处理时使用 2. ✅ `price_threshold` - 计算提价成本时使用 3. ✅ `price_fee_rate` - 计算提价成本时使用 4. ❌ `level_bonus_*` - **未使用,代码中硬编码** **在后台管理中使用的配置**: 1. ❌ `level_1_bonus` - 读取配置(但键名不匹配) 2. ❌ `level_2_bonus` - 读取配置(但键名不匹配) 3. ❌ `level_3_bonus` - 读取配置(但键名不匹配) 4. ❌ `upgrade_to_gold_fee` - 读取配置(但键名不匹配) 5. ❌ `upgrade_to_diamond_fee` - 读取配置(但键名不匹配) 6. ❌ `upgrade_to_gold_rebate` - 读取配置(但键名不匹配) 7. ❌ `upgrade_to_diamond_rebate` - 读取配置(但键名不匹配) 8. ✅ `tax_rate` - 读取配置 9. ❌ `tax_exemption_amount` - 读取配置(但配置项缺失) ### 4.2 未使用的配置项 以下配置项在SQL中初始化了,但在代码中**似乎未使用**: - `direct_parent_amount_diamond` - 直接上级是钻石的返佣金额 - `direct_parent_amount_gold` - 直接上级是黄金的返佣金额 - `direct_parent_amount_normal` - 直接上级是普通的返佣金额 - `max_gold_rebate_amount` - 黄金代理最大返佣金额 **说明**:这些配置项可能被硬编码在 `distributeNormalAgentBonus` 等函数中,需要确认是否需要配置化。 --- ## 五、优化建议 ### 5.1 🔴 立即修复:移除系统配置表中的价格配置 **问题**: 价格相关配置(`base_price`、`system_max_price`、`price_threshold`、`price_fee_rate`)应该完全由产品配置表管理,系统配置表中不应该存在这些配置。 **修复步骤**: 1. **从系统配置表中删除价格相关配置**: ```sql -- 删除系统配置表中的价格相关配置 DELETE FROM `agent_config` WHERE `config_key` IN ( 'base_price', 'system_max_price', 'price_threshold', 'price_fee_rate' ); ``` 2. **修改订单处理逻辑,从产品配置表读取**: 需要修改的文件: - `app/main/api/internal/service/agentService.go` - `AgentProcess` 方法 - `app/main/api/internal/logic/pay/paymentlogic.go` - 创建订单时的价格计算 **示例代码修改**(`agentService.go`): ```go // AgentProcess 处理代理订单(新系统) func (s *AgentService) AgentProcess(ctx context.Context, order *model.Order) error { // ... 前面的代码不变 ... // 4. 获取产品配置(优先使用产品配置,如果不存在则使用默认值) productConfig, err := s.AgentProductConfigModel.FindOneByProductId(ctx, order.ProductId) if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询产品配置失败, productId: %d", order.ProductId) } // 使用产品配置的底价,如果产品未配置则使用默认值0 basePrice := 0.0 if productConfig != nil { basePrice = productConfig.BasePrice } // ... 使用basePrice计算实际底价 ... // 6.2 计算提价成本(使用产品配置) priceThreshold := 0.0 priceFeeRate := 0.0 if productConfig != nil { if productConfig.PriceThreshold.Valid { priceThreshold = productConfig.PriceThreshold.Float64 } if productConfig.PriceFeeRate.Valid { priceFeeRate = productConfig.PriceFeeRate.Float64 } } priceCost := s.calculatePriceCost(agentOrder.SetPrice, priceThreshold, priceFeeRate) // ... 后续代码 ... } ``` 3. **更新后台管理系统**: - 移除系统配置页面中的价格相关配置项 - 确保产品配置页面可以正确配置这些价格参数 ### 5.2 🔴 立即修复:统一配置键命名 **方案一:修改SQL初始化脚本,使用代码期望的键名** ```sql -- 修改等级加成配置键 UPDATE `agent_config` SET `config_key` = 'level_1_bonus' WHERE `config_key` = 'level_bonus_normal'; UPDATE `agent_config` SET `config_key` = 'level_2_bonus' WHERE `config_key` = 'level_bonus_gold'; UPDATE `agent_config` SET `config_key` = 'level_3_bonus' WHERE `config_key` = 'level_bonus_diamond'; -- 修改升级费用配置键 UPDATE `agent_config` SET `config_key` = 'upgrade_to_gold_fee' WHERE `config_key` = 'upgrade_fee_normal_to_gold'; UPDATE `agent_config` SET `config_key` = 'upgrade_to_diamond_fee' WHERE `config_key` = 'upgrade_fee_to_diamond'; -- 修改升级返佣配置键 UPDATE `agent_config` SET `config_key` = 'upgrade_to_gold_rebate' WHERE `config_key` = 'upgrade_rebate_normal_to_gold'; UPDATE `agent_config` SET `config_key` = 'upgrade_to_diamond_rebate' WHERE `config_key` = 'upgrade_rebate_to_diamond'; ``` **方案二:修改代码逻辑,使用SQL中的键名** 需要修改的文件: - `app/main/api/internal/logic/admin_agent/admingetagentconfiglogic.go` - `app/main/api/internal/logic/admin_agent/adminupdateagentconfiglogic.go` **推荐方案一**,因为: - 代码中的命名更清晰(`level_1_bonus` 比 `level_bonus_normal` 更直观) - 数字后缀与等级数字(1/2/3)对应,易于理解 ### 5.3 🔴 立即修复:从配置表读取等级加成 **修改 `agentService.go` 中的 `getLevelBonus` 函数**: ```go // getLevelBonus 获取等级加成(从配置表读取) func (s *AgentService) getLevelBonus(ctx context.Context, level int64) (int64, error) { var configKey string switch level { case 1: configKey = "level_1_bonus" case 2: configKey = "level_2_bonus" case 3: configKey = "level_3_bonus" default: return 0, nil } bonus, err := s.getConfigFloat(ctx, configKey) if err != nil { // 配置不存在时返回默认值 switch level { case 1: return 6, nil case 2: return 3, nil case 3: return 0, nil } return 0, nil } return int64(bonus), nil } ``` **修改调用处**: ```go // agentService.go:108 levelBonus, err := s.getLevelBonus(ctx, agent.Level) if err != nil { return errors.Wrapf(err, "获取等级加成配置失败") } actualBasePrice := basePrice + float64(levelBonus) ``` ### 5.4 🟡 补充缺失的配置项 **添加 `tax_exemption_amount` 配置**: ```sql INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES ('tax_exemption_amount', '0.00', 'tax', '提现免税额度(元,默认0)'); ``` ### 5.5 🟡 规范化配置键命名 **建议统一使用以下命名规范**: ``` {类型}_{编号/级别}_{属性} ``` **示例**: - ✅ `level_1_bonus` - 等级1的加成 - ✅ `level_2_bonus` - 等级2的加成 - ✅ `level_3_bonus` - 等级3的加成 - ✅ `upgrade_to_gold_fee` - 升级到黄金的费用 - ✅ `upgrade_to_diamond_fee` - 升级到钻石的费用 - ✅ `upgrade_to_gold_rebate` - 升级到黄金的返佣 - ✅ `upgrade_to_diamond_rebate` - 升级到钻石的返佣 ### 5.6 🟢 优化建议:添加配置验证 **在更新配置时添加验证逻辑**: ```go // 验证配置值的合理性 func validateConfigValue(key string, value float64) error { switch key { case "tax_rate": if value < 0 || value > 1 { return errors.New("税率必须在0-1之间") } case "price_fee_rate": if value < 0 || value > 1 { return errors.New("提价费率必须在0-1之间") } case "base_price", "system_max_price": if value < 0 { return errors.New("价格配置不能为负数") } } return nil } ``` --- ## 六、配置项完整清单(修正后) ### 6.1 价格相关配置(应移除,改为产品配置) **⚠️ 重要说明**:以下配置项应该从系统配置表(`agent_config`)中移除,改为在产品配置表(`agent_product_config`)中按产品配置。 | 配置键 | 说明 | 配置位置 | | ---------------------- | ----------------------------- | ----------------------------- | | ~~`base_price`~~ | ~~系统基础底价~~ | ✅ 应在 `agent_product_config` | | ~~`system_max_price`~~ | ~~系统价格上限~~ | ✅ 应在 `agent_product_config` | | ~~`price_threshold`~~ | ~~提价标准阈值~~ | ✅ 应在 `agent_product_config` | | ~~`price_fee_rate`~~ | ~~提价手续费比例(0-1之间)~~ | ✅ 应在 `agent_product_config` | **产品配置表结构**(`agent_product_config`): - `base_price` - 产品基础底价(必填) - `system_max_price` - 产品价格上限(必填) - `price_threshold` - 提价标准阈值(可选,NULL时表示不设阈值) - `price_fee_rate` - 提价手续费比例(可选,NULL时表示不收费) ### 6.2 等级加成配置(bonus类型) | 配置键 | 默认值 | 说明 | | --------------- | ------ | ---------------------- | | `level_1_bonus` | 6.00 | 普通代理等级加成(元) | | `level_2_bonus` | 3.00 | 黄金代理等级加成(元) | | `level_3_bonus` | 0.00 | 钻石代理等级加成(元) | ### 6.3 升级费用配置(upgrade类型) | 配置键 | 默认值 | 说明 | | --------------------------- | ------ | ------------------------ | | `upgrade_to_gold_fee` | 199.00 | 普通→黄金升级费用(元) | | `upgrade_to_diamond_fee` | 980.00 | 升级为钻石费用(元) | | `upgrade_to_gold_rebate` | 139.00 | 普通→黄金返佣金额(元) | | `upgrade_to_diamond_rebate` | 680.00 | 升级为钻石返佣金额(元) | **注意**:`gold_to_diamond` 的费用和返佣可以通过计算得出: - 费用:`upgrade_to_diamond_fee - upgrade_to_gold_fee = 980 - 199 = 781元` - 返佣:可以通过前端或后端计算,不单独存储 ### 6.4 返佣规则配置(rebate类型) | 配置键 | 默认值 | 说明 | | ------------------------------ | ------ | ------------------------------ | | `direct_parent_amount_diamond` | 6.00 | 直接上级是钻石的返佣金额(元) | | `direct_parent_amount_gold` | 3.00 | 直接上级是黄金的返佣金额(元) | | `direct_parent_amount_normal` | 2.00 | 直接上级是普通的返佣金额(元) | | `max_gold_rebate_amount` | 3.00 | 黄金代理最大返佣金额(元) | **建议**:这些配置项目前在代码中硬编码,建议配置化。 ### 6.5 税费配置(tax类型) | 配置键 | 默认值 | 说明 | | ---------------------- | ------ | ---------------------- | | `tax_rate` | 0.0600 | 提现税率(6%,即0.06) | | `tax_exemption_amount` | 0.00 | 免税额度(元,默认0) | --- ## 七、配置表的合理性评估 ### 7.1 表结构设计 | 评估项 | 评分 | 说明 | | ------------ | ----- | ---------------------------- | | **灵活性** | ⭐⭐⭐⭐⭐ | 键值对设计非常灵活,易于扩展 | | **可维护性** | ⭐⭐⭐⭐ | 类型分类清晰,便于管理 | | **性能** | ⭐⭐⭐⭐ | 唯一索引优化查询,缓存支持 | | **类型安全** | ⭐⭐⭐ | 所有值都是字符串,需要转换 | | **验证机制** | ⭐⭐ | 缺少数据库层面的验证 | ### 7.2 总体评价 **设计优点**: ✅ 采用键值对存储,扩展性强 ✅ 类型分类清晰,便于管理 ✅ 支持版本控制和软删除 **存在的问题**: ❌ **价格配置应该在产品配置表,而不是系统配置表**(严重设计问题) ❌ 配置键命名不一致(严重) ❌ 部分配置硬编码(严重) ❌ 缺少部分配置项(中等) ❌ 缺少配置验证机制(中等) **总体评分**:⭐⭐⭐(3/5) **结论**:配置表的设计思路基本合理,但存在**价格配置位置设计错误**的严重问题。价格相关配置应该完全由产品配置表管理,系统配置表只应该包含全局配置(等级加成、升级费用、税费等)。修复这些问题后,配置表设计将更加完善和符合项目规范。 --- ## 八、修复后的完整配置SQL ```sql -- ============================================ -- 代理系统配置初始化(修正版) -- ============================================ -- 删除价格相关配置(应该在产品配置表中) DELETE FROM `agent_config` WHERE `config_key` IN ( 'base_price', 'system_max_price', 'price_threshold', 'price_fee_rate' ); -- 删除旧的不一致配置(如果存在) DELETE FROM `agent_config` WHERE `config_key` IN ( 'level_bonus_normal', 'level_bonus_gold', 'level_bonus_diamond', 'upgrade_fee_normal_to_gold', 'upgrade_fee_to_diamond', 'upgrade_rebate_normal_to_gold', 'upgrade_rebate_to_diamond' ); -- 插入修正后的配置项 INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES -- 注意:价格相关配置(base_price, system_max_price, price_threshold, price_fee_rate) -- 已从系统配置表中移除,改为在产品配置表(agent_product_config)中按产品配置 -- 等级加成配置(修正键名) ('level_1_bonus', '6.00', 'bonus', '普通代理等级加成(6元)'), ('level_2_bonus', '3.00', 'bonus', '黄金代理等级加成(3元)'), ('level_3_bonus', '0.00', 'bonus', '钻石代理等级加成(0元)'), -- 升级费用配置(修正键名) ('upgrade_to_gold_fee', '199.00', 'upgrade', '普通→黄金升级费用(199元)'), ('upgrade_to_diamond_fee', '980.00', 'upgrade', '升级为钻石费用(980元)'), -- 升级返佣配置(修正键名) ('upgrade_to_gold_rebate', '139.00', 'upgrade', '普通→黄金返佣金额(139元)'), ('upgrade_to_diamond_rebate', '680.00', 'upgrade', '升级为钻石返佣金额(680元)'), -- 返佣规则配置 ('direct_parent_amount_diamond', '6.00', 'rebate', '直接上级是钻石的返佣金额(6元)'), ('direct_parent_amount_gold', '3.00', 'rebate', '直接上级是黄金的返佣金额(3元)'), ('direct_parent_amount_normal', '2.00', 'rebate', '直接上级是普通的返佣金额(2元)'), ('max_gold_rebate_amount', '3.00', 'rebate', '黄金代理最大返佣金额(3元)'), -- 税费配置 ('tax_rate', '0.0600', 'tax', '提现税率(6%,即0.06)'), ('tax_exemption_amount', '0.00', 'tax', '提现免税额度(元,默认0)') ON DUPLICATE KEY UPDATE `config_value` = VALUES(`config_value`), `update_time` = NOW(); ``` --- ## 九、建议的改进方案 ### 方案A:保持当前键值对设计(推荐) **优点**: - 灵活性强,易于扩展 - 不需要修改表结构 - 符合项目当前架构 **需要做的修改**: 1. 统一配置键命名 2. 修复代码硬编码问题 3. 补充缺失的配置项 4. 添加配置验证逻辑 ### 方案B:改为结构化JSON配置(可选) **如果配置项继续增长,可以考虑**: - 将相关配置组合成JSON对象存储在 `config_value` 中 - 例如:`level_bonus_config` 存储 `{"1": 6, "2": 3, "3": 0}` **缺点**: - 需要修改所有读取配置的代码 - 不利于单个配置项的独立更新 **建议**:当前配置项数量不多(约15个),保持键值对设计更合适。 --- ## 十、总结 ### 当前状态 - ✅ 配置表设计思路合理 - ❌ **价格配置设计错误**(应该在产品配置表,不在系统配置表) - ❌ 配置键命名不一致(需要立即修复) - ❌ 部分配置硬编码(需要立即修复) - ⚠️ 缺少部分配置项(需要补充) ### 修复优先级 1. **P0(紧急)**:移除系统配置表中的价格配置,改为完全由产品配置表管理 2. **P0(紧急)**:修改订单处理逻辑,从产品配置表读取价格参数 3. **P0(紧急)**:统一配置键命名,修复不一致问题 4. **P0(紧急)**:修改代码,从配置表读取等级加成,移除硬编码 5. **P1(重要)**:补充缺失的配置项(`tax_exemption_amount`) 6. **P2(建议)**:添加配置验证逻辑 7. **P2(建议)**:将返佣规则配置化(当前硬编码) ### 是否符合项目 **配置表设计**:✅ 基本符合,但价格配置的位置设计错误 **存在的问题**: 1. ❌ **价格配置应该在产品配置表中,而不是系统配置表**(严重设计问题) 2. ❌ 配置键命名不一致 3. ❌ 部分配置硬编码 4. ⚠️ 缺少部分配置项 **结论**:需要修复上述问题后才能完全符合项目的配置化设计理念。**最重要的是将价格配置从系统配置表移除,改为完全由产品配置表管理。** --- ## 十一、产品配置表使用规范 ### 11.1 产品配置表结构 **表名**: `agent_product_config` 每个产品都应该有对应的配置记录,包含以下字段: | 字段 | 类型 | 必填 | 说明 | | ------------------ | ------------- | ---- | ----------------------------------------- | | `product_id` | bigint | ✅ 是 | 产品ID(唯一) | | `product_name` | varchar(100) | ✅ 是 | 产品名称 | | `base_price` | decimal(10,2) | ✅ 是 | 产品基础底价 | | `system_max_price` | decimal(10,2) | ✅ 是 | 产品价格上限 | | `price_threshold` | decimal(10,2) | ❌ 否 | 提价标准阈值(NULL表示不设阈值) | | `price_fee_rate` | decimal(5,4) | ❌ 否 | 提价手续费比例(NULL表示不收费,0-1之间) | ### 11.2 配置优先级和默认值 **规则**: 1. 所有价格参数必须从产品配置表读取 2. 如果产品配置记录不存在,应该报错或使用合理的默认值(建议报错,强制每个产品必须配置) 3. 可选字段(`price_threshold`、`price_fee_rate`)如果为NULL,表示不启用该功能 - `price_threshold = NULL` → 不设提价阈值 - `price_fee_rate = NULL` → 不收取提价手续费 ### 11.3 代码修改示例 #### 修改 AgentService.AgentProcess 方法 ```go // AgentProcess 处理代理订单(新系统) func (s *AgentService) AgentProcess(ctx context.Context, order *model.Order) error { // 1-3. 前面的代码不变... // 4. 获取产品配置(必须存在) productConfig, err := s.AgentProductConfigModel.FindOneByProductId(ctx, order.ProductId) if err != nil { if errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "产品配置不存在, productId: %d,请先在后台配置产品价格参数", order.ProductId) } return errors.Wrapf(err, "查询产品配置失败, productId: %d", order.ProductId) } // 使用产品配置的底价 basePrice := productConfig.BasePrice // 6. 使用事务处理订单 return s.AgentWalletModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error { // 6.1 计算实际底价和代理收益 levelBonus, err := s.getLevelBonus(ctx, agent.Level) if err != nil { return errors.Wrapf(err, "获取等级加成配置失败") } actualBasePrice := basePrice + float64(levelBonus) // 6.2 计算提价成本(使用产品配置) priceThreshold := 0.0 priceFeeRate := 0.0 if productConfig.PriceThreshold.Valid { priceThreshold = productConfig.PriceThreshold.Float64 } if productConfig.PriceFeeRate.Valid { priceFeeRate = productConfig.PriceFeeRate.Float64 } priceCost := s.calculatePriceCost(agentOrder.SetPrice, priceThreshold, priceFeeRate) // 6.3 计算代理收益 agentProfit := agentOrder.SetPrice - actualBasePrice - priceCost // ... 后续代码不变 ... }) } ``` #### 修改 PaymentLogic 创建订单时的价格计算 ```go // 如果是代理推广订单,创建完整的代理订单记录 if data.AgentIdentifier != "" && agentLinkModel != nil { // ... 获取代理信息 ... // 获取产品配置(必须存在) productConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, product.Id) if err != nil { if errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单失败,产品配置不存在, productId: %d,请先在后台配置产品价格参数", product.Id) } return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 查询产品配置失败: %+v", err) } // 使用产品配置的底价 basePrice := productConfig.BasePrice // 计算实际底价(基础底价+等级加成) levelBonus, _ := l.getLevelBonus(agent.Level) actualBasePrice := basePrice + float64(levelBonus) // 计算提价成本(使用产品配置) priceThreshold := 0.0 priceFeeRate := 0.0 if productConfig.PriceThreshold.Valid { priceThreshold = productConfig.PriceThreshold.Float64 } if productConfig.PriceFeeRate.Valid { priceFeeRate = productConfig.PriceFeeRate.Float64 } priceCost := 0.0 if agentLinkModel.SetPrice > priceThreshold { priceCost = (agentLinkModel.SetPrice - priceThreshold) * priceFeeRate } // 计算代理收益 agentProfit := agentLinkModel.SetPrice - actualBasePrice - priceCost // ... 创建代理订单记录 ... } ``` ### 11.4 需要修改的文件清单 需要修改以支持产品配置的代码文件: 1. **`app/main/api/internal/service/agentService.go`** - `AgentProcess()` 方法:从产品配置表读取价格参数 2. **`app/main/api/internal/logic/pay/paymentlogic.go`** - 创建订单时的价格计算:从产品配置表读取价格参数 3. **`app/main/api/internal/logic/agent/getagentproductconfiglogic.go`** - 移除从系统配置表读取价格参数的逻辑(只保留从产品配置表读取) 4. **`app/main/api/internal/logic/admin_agent/admingetagentconfiglogic.go`** - 移除价格相关配置项的返回 5. **`app/main/api/internal/logic/admin_agent/adminupdateagentconfiglogic.go`** - 移除价格相关配置项的更新逻辑 6. **后台管理系统前端** - 系统配置页面:移除价格相关配置项 - 产品配置页面:确保可以正确配置所有价格参数