# Transfer模块汇率概念说明 ## 汇率定义 在Transfer模块中,**汇率(exchange_rate)表示"1个外部币能兑换多少内部币"**。 ### 📊 汇率公式 ``` 汇率 = 内部币数量 / 外部币数量 ``` ### 🔄 转换公式 #### 转出(内部币 → 外部币) ``` 外部金额 = 内部金额 ÷ 汇率 ``` #### 转入(外部币 → 内部币) ``` 内部金额 = 外部金额 × 汇率 ``` ## 实际示例 ### 示例1:汇率 = 1.0450 假设汇率为1.0450,表示1个外部币可以兑换1.0450个内部币。 #### 转出场景 - 用户要转出100个内部币 - 外部金额 = 100 ÷ 1.0450 ≈ 95.69个外部币 #### 转入场景 - 用户要转入100个外部币 - 内部金额 = 100 × 1.0450 = 104.50个内部币 ### 示例2:汇率 = 0.9568 假设汇率为0.9568,表示1个外部币可以兑换0.9568个内部币。 #### 转出场景 - 用户要转出100个内部币 - 外部金额 = 100 ÷ 0.9568 ≈ 104.52个外部币 #### 转入场景 - 用户要转入100个外部币 - 内部金额 = 100 × 0.9568 = 95.68个内部币 ## 代码实现 ### TransferLogic.php #### 转出订单创建 ```php // 计算金额(转出:内部金额转换为外部金额) $amount = (string) $data['amount']; // 内部金额 $outAmount = bcdiv($amount, (string) $app->exchange_rate, 10); // 外部金额 = 内部金额 ÷ 汇率 ``` #### 转入订单创建 ```php // 计算金额(转入:外部金额转换为内部金额) $outAmount = (string) $data['amount']; // 外部金额 $amount = bcmul($outAmount, (string) $app->exchange_rate, 10); // 内部金额 = 外部金额 × 汇率 ``` ### TransferThirdPartyService.php #### 充值费用计算 ```php // 将三方金额转换为农场内部金额(充值:外部金额转内部金额) $internalAmount = bcmul($amount, (string) $transferApp->exchange_rate, 10); ``` #### 提现费用计算 ```php // 将三方金额转换为农场内部金额(提现:外部金额转内部金额) $internalAmount = bcmul($amount, (string) $transferApp->exchange_rate, 10); ``` ## 业务场景理解 ### 内部币 vs 外部币 - **内部币**: 农场系统内部使用的虚拟货币(如钻石、金币等) - **外部币**: 第三方应用使用的货币单位(如游戏币、积分等) ### 汇率的经济含义 #### 汇率 > 1.0 - 表示外部币比内部币"值钱" - 1个外部币可以兑换超过1个内部币 - 例如:汇率1.05表示1游戏币=1.05钻石 #### 汇率 < 1.0 - 表示内部币比外部币"值钱" - 1个外部币只能兑换不到1个内部币 - 例如:汇率0.95表示1游戏币=0.95钻石 #### 汇率 = 1.0 - 表示内部币和外部币等值 - 1个外部币=1个内部币 ## 数据库存储 ### transfer_apps表 ```sql `exchange_rate` decimal(10,4) NOT NULL DEFAULT '1.0000' COMMENT '汇率(1个外部币能兑换多少内部币)' ``` ### transfer_orders表 ```sql `exchange_rate` decimal(10,4) NOT NULL COMMENT '使用汇率(1外部币=N内部币)' ``` ## 测试验证 ### 单元测试示例 ```php public function testExchangeRateConversion() { // 设置汇率为2.0(1外部币=2内部币) $app = TransferApp::factory()->create(['exchange_rate' => 2.0]); // 测试转出:100内部币应该转换为50外部币 $outOrder = TransferLogic::createOutOrder($app, ['amount' => '100.00']); $this->assertEquals('50.0000000000', $outOrder->out_amount); // 测试转入:100外部币应该转换为200内部币 $inOrder = TransferLogic::createInOrder($app, ['amount' => '100.00']); $this->assertEquals('200.0000000000', $inOrder->amount); } ``` ## 常见错误 ### ❌ 错误理解 认为汇率表示"1个内部币能兑换多少外部币",导致: - 转出时使用:`外部金额 = 内部金额 × 汇率`(错误) - 转入时使用:`内部金额 = 外部金额 ÷ 汇率`(错误) ### ✅ 正确理解 汇率表示"1个外部币能兑换多少内部币",因此: - 转出时使用:`外部金额 = 内部金额 ÷ 汇率`(正确) - 转入时使用:`内部金额 = 外部金额 × 汇率`(正确) ## 实际应用场景 ### 游戏充值 1. 用户在游戏中购买100游戏币(外部币) 2. 汇率为0.95(1游戏币=0.95钻石) 3. 系统计算:100 × 0.95 = 95钻石(内部币) 4. 用户农场账户增加95钻石 ### 游戏提现 1. 用户要提现100钻石(内部币)到游戏 2. 汇率为0.95(1游戏币=0.95钻石) 3. 系统计算:100 ÷ 0.95 ≈ 105.26游戏币(外部币) 4. 用户游戏账户增加105.26游戏币 ## 配置建议 ### 汇率设置原则 1. **市场汇率**: 根据内外部货币的实际价值比例设置 2. **手续费考虑**: 可以在汇率中包含一定的手续费成本 3. **精度控制**: 使用4位小数精度,满足大部分业务需求 4. **动态调整**: 根据市场变化定期调整汇率 ### 监控指标 1. **汇率变化**: 监控汇率调整频率和幅度 2. **转换量**: 统计内外部币种的转换量 3. **差异分析**: 分析理论汇率与实际汇率的差异 ## 总结 Transfer模块的汇率概念明确定义为"1个外部币能兑换多少内部币",这个定义: 1. ✅ **符合经济学常识**: 与传统外汇汇率概念一致 2. ✅ **便于理解**: 直观表达内外部货币的兑换关系 3. ✅ **计算简单**: 转出乘法,转入除法,逻辑清晰 4. ✅ **测试验证**: 通过单元测试确保实现正确性 所有相关代码已经按照这个概念进行了修正和注释,确保实现的一致性和正确性。