Ver Fonte

维护Transfer模块相关文档

文档更新内容:
1. 创建Transfer模块完整README文档
   - 核心概念和术语说明
   - 架构设计和模块结构
   - 金额转换逻辑详解
   - 手续费机制说明(额外收取vs扣除模式)
   - 第三方应用集成指南
   - API接口文档和使用示例
   - 数据库设计说明
   - 故障排除指南

2. 更新偏好习惯文档
   - 新增Transfer模块设计偏好
   - 金额转换逻辑规范
   - 手续费处理机制说明
   - 第三方应用集成规范
   - 验证和安全要求

3. 更新当前工作状态文档
   - 记录金额转换和手续费逻辑修复完成
   - 详细的问题分析和解决方案
   - 修复效果对比表格
   - 技术成果总结

文档价值:
- 为Transfer模块提供完整的技术文档
- 建立金额转换和手续费处理的标准规范
- 记录重要的设计决策和修复过程
- 为后续开发和维护提供参考
AI Assistant há 6 meses atrás
pai
commit
86f8c3406d

+ 121 - 0
AiWork/2025年06月/19日0335-修复划转订单金额转换和手续费逻辑.md

@@ -0,0 +1,121 @@
+# 修复划转订单金额转换和手续费逻辑
+
+**时间**: 2025-06-19 03:35  
+**任务**: 修复划转订单44金额转换错误问题,并改进手续费收取逻辑
+
+## 问题分析
+
+### 原始问题(订单44)
+- **输入外部金额**: 2500
+- **错误的外部金额**: 8.3333333333
+- **错误的内部金额**: 2500.0000000000
+- **根本原因**: 第三方应用金额转换逻辑存在双重转换问题
+
+### 手续费逻辑问题(订单51)
+- **用户反馈**: "外部金额10,内部3000,再加上手续费只会更多,怎么还变少了呢?"
+- **原逻辑**: 手续费从转出金额中扣除(转出2990+手续费10=总扣3000)
+- **新需求**: 手续费额外收取(转出3000+手续费10=总扣3010)
+
+## 修复内容
+
+### 1. 修复金额转换双重转换问题
+
+**问题**: 
+- `TransferThirdPartyService::createWithdrawOrder`中转换一次
+- `TransferLogic::createTransferOutForThirdParty`中再转换一次
+
+**修复**:
+- 移除`TransferThirdPartyService`中的金额转换
+- 只在`TransferLogic::createTransferOutForThirdParty`中进行转换
+
+### 2. 修改手续费逻辑为额外收取模式
+
+**修改文件**:
+- `app/Module/Transfer/Logics/TransferLogic.php`
+- `app/Module/Transfer/Models/TransferApp.php`
+- `app/Module/Transfer/Validators/TransferBalanceValidator.php`
+
+**核心变更**:
+```php
+// 原逻辑:转账扣除手续费后的金额
+$tradeResult = $userFundService->trade(
+    $app->fund_to_uid,
+    $order->actual_amount, // 2990(扣除手续费后)
+    'transfer_out',
+    $order->id,
+    "转出到{$app->title}"
+);
+
+// 新逻辑:转账完整金额,手续费额外收取
+$tradeResult = $userFundService->trade(
+    $app->fund_to_uid,
+    $order->amount, // 3000(完整金额)
+    'transfer_out',
+    $order->id,
+    "转出到{$app->title}"
+);
+```
+
+### 3. 新增专用手续费计算方法
+
+**新增方法**: `TransferApp::calculateOutFeeWithExtraCharge`
+```php
+// 计算用户总支付金额(转出金额 + 手续费)
+$actualAmount = bcadd($amountDecimal, $feeAmount, 4);
+```
+
+**保持原方法**: `TransferApp::calculateFee`(用于转入)
+```php
+// 计算实际到账金额(扣除手续费后)
+$actualAmount = bcsub($amountDecimal, $feeAmount, 4);
+```
+
+## 测试验证
+
+### 修复前后对比
+
+| 项目 | 订单44(错误) | 订单51(原逻辑) | 订单52(修复后) |
+|------|---------------|-----------------|-----------------|
+| 外部金额输入 | 2500 | 10 | 10 |
+| 外部金额存储 | 8.3333 | 10.0000 | 10.0000 |
+| 内部金额存储 | 2500.0000 | 3000.0000 | 3000.0000 |
+| 转出到目标账户 | - | 2990钻石 | 3000钻石 |
+| 手续费收取 | - | 10钻石 | 10钻石 |
+| 用户总扣减 | - | 3000钻石 | 3010钻石 |
+| 外部实际收到 | - | 2990钻石 | 3000钻石 |
+
+### 资金日志验证(订单52)
+```
+转出操作: -3000钻石 (transfer_out-52)
+手续费操作: -10钻石 (transfer_out_fee-52)
+总扣减: 3010钻石 ✅
+```
+
+## 技术要点
+
+### 1. 金额转换逻辑
+- **第三方应用**: 外部金额 × 汇率 = 内部金额
+- **普通应用**: 内部金额 ÷ 汇率 = 外部金额
+
+### 2. 手续费模式区分
+- **转出**: 手续费额外收取(用户支付转出金额+手续费)
+- **转入**: 手续费从金额中扣除(用户收到转入金额-手续费)
+
+### 3. 验证器一致性
+- 验证逻辑与执行逻辑保持一致
+- 转出验证:检查转出金额+手续费的总和
+- 转入验证:检查转入金额本身
+
+## 提交记录
+
+**Commit**: eccbff93  
+**Message**: 修改转出订单手续费逻辑为额外收取模式
+
+## 结果
+
+✅ **金额转换问题完全修复**  
+✅ **手续费逻辑改为额外收取模式**  
+✅ **验证器与执行逻辑保持一致**  
+✅ **第三方应用金额处理正确**  
+
+用户现在可以正确理解:转出3000钻石需要额外支付10钻石手续费,总共扣除3010钻石,外部系统收到完整的3000钻石。

+ 56 - 1
AiWork/now.md

@@ -1,6 +1,61 @@
 # 当前工作状态
 
-**更新时间**: 2025年06月19日 03:00:00 CST
+**更新时间**: 2025年06月19日 03:35:00 CST
+
+## 🎉 划转订单金额转换和手续费逻辑修复完成 (2025-06-19 03:35)
+
+### 🎯 最新完成任务
+✅ **修复划转订单金额转换和手续费逻辑问题**
+- 时间:2025-06-19 03:35 - 03:35
+- 状态:已完成,Transfer模块逻辑完全正确
+- 任务记录:`AiWork/2025年06月/19日0335-修复划转订单金额转换和手续费逻辑.md`
+
+### 📊 问题解决概览
+
+#### 问题1:金额转换错误(订单44)
+- **输入外部金额**: 2500
+- **错误的外部金额**: 8.3333333333
+- **错误的内部金额**: 2500.0000000000
+- **根本原因**: 第三方应用金额转换逻辑存在双重转换问题
+
+#### 问题2:手续费逻辑概念错误(订单51)
+- **用户反馈**: "外部金额10,内部3000,再加上手续费只会更多,怎么还变少了呢?"
+- **原逻辑**: 手续费从转出金额中扣除(转出2990+手续费10=总扣3000)
+- **新需求**: 手续费额外收取(转出3000+手续费10=总扣3010)
+
+### 🔧 修复措施
+
+#### 1. 修复金额转换双重转换问题
+- **问题**: `TransferThirdPartyService`和`TransferLogic`都进行转换
+- **修复**: 移除`TransferThirdPartyService`中的转换,只在`TransferLogic`中转换
+- **结果**: 外部金额2500正确转换为内部金额750,000
+
+#### 2. 修改手续费逻辑为额外收取模式
+- **转出逻辑**: 转账完整金额,手续费额外收取
+- **新增方法**: `TransferApp::calculateOutFeeWithExtraCharge`
+- **验证器更新**: 检查转出金额+手续费的总和
+- **结果**: 用户支付3010钻石,外部收到3000钻石
+
+#### 3. 保持转入手续费逻辑不变
+- **转入逻辑**: 手续费从转入金额中扣除
+- **保持方法**: `TransferApp::calculateFee`用于转入
+- **用户体验**: 转入50元,实际收到49.5元(扣除手续费)
+
+### 🎯 修复效果对比
+
+| 场景 | 修复前 | 修复后 |
+|------|--------|--------|
+| 外部金额10转出 | 外部收到2990钻石 | 外部收到3000钻石 |
+| 用户扣除 | 总扣除3000钻石 | 总扣除3010钻石 |
+| 手续费模式 | 从转出金额中扣 | 额外收取 |
+| 用户理解 | 困惑"为什么变少" | 清晰"额外收费" |
+
+### 🎯 技术成果
+- **概念修正**: 手续费逻辑改为用户友好的额外收取模式
+- **金额转换**: 彻底解决双重转换问题,确保计算准确
+- **验证一致**: 验证器与执行逻辑完全一致
+- **文档完善**: 创建完整的Transfer模块README文档
+- **偏好维护**: 更新偏好习惯文档,记录Transfer模块设计原则
 
 ## 🎉 划转订单余额验证机制修复完成 (2025-06-19 03:00)
 

+ 32 - 0
AiWork/偏好习惯.md

@@ -198,6 +198,38 @@
 - 钻石操作使用FUND_TYPE::FUND2类型,支持10位小数精度
 - 包含完整的验证、事务处理和操作日志记录机制
 
+### Transfer模块(划转系统)
+#### 核心概念
+- 转入订单:用户充值/存入资金到农场系统
+- 转出订单:用户提现/转出资金到外部系统
+- 外部金额:第三方系统的金额单位
+- 内部金额:农场系统的钻石数量
+- 汇率:外部金额与内部金额的转换比例
+
+#### 金额转换逻辑
+- 第三方应用转出:外部金额 × 汇率 = 内部金额
+- 普通应用转出:内部金额 ÷ 汇率 = 外部金额
+- 转入:外部金额 × 汇率 = 内部金额
+- 避免双重转换:只在TransferLogic层进行一次转换
+
+#### 手续费处理机制
+- 转出:手续费额外收取(用户支付转出金额+手续费,外部收到完整转出金额)
+- 转入:手续费从金额中扣除(用户收到转入金额-手续费)
+- 手续费计算:支持最低/最高限制,按比例计算后应用限制
+- 手续费收取账户:默认UID=1,可配置专用账户
+
+#### 第三方应用集成
+- TransferThirdPartyService专门处理第三方应用需求
+- createTransferOutForThirdParty方法跳过密码验证
+- 支持回调机制:配置回调URL时发送状态通知
+- 应用权限控制:独立控制转入/转出操作权限
+
+#### 验证和安全
+- 余额验证:转出检查转出金额+手续费总和
+- 事务处理:Fund模块trade方法要求在事务中执行
+- 汇率验证:确保汇率大于0,避免计算异常
+- 重复订单检查:外部订单ID唯一性验证
+
 ### 系统模块概况
 - 系统包含35个模块
 - Promotionurs模块已被移除,创建新的UrsPromotion模块替代

+ 388 - 0
app/Module/Transfer/README.md

@@ -0,0 +1,388 @@
+# Transfer模块 - 划转系统
+
+Transfer模块是农场游戏系统的资金划转核心模块,负责处理用户与外部系统之间的资金转入转出操作。
+
+## 📋 目录
+
+- [核心概念](#核心概念)
+- [架构设计](#架构设计)
+- [金额转换逻辑](#金额转换逻辑)
+- [手续费机制](#手续费机制)
+- [第三方应用集成](#第三方应用集成)
+- [API接口](#api接口)
+- [数据库设计](#数据库设计)
+- [配置说明](#配置说明)
+- [使用示例](#使用示例)
+- [故障排除](#故障排除)
+
+## 🎯 核心概念
+
+### 基本术语
+
+| 术语 | 说明 | 示例 |
+|------|------|------|
+| **转入订单** | 用户充值/存入资金到农场系统 | URS用户充值100元到农场 |
+| **转出订单** | 用户提现/转出资金到外部系统 | 农场用户提现30000钻石到URS |
+| **外部金额** | 第三方系统的金额单位 | URS系统的100元 |
+| **内部金额** | 农场系统的钻石数量 | 农场系统的30000钻石 |
+| **汇率** | 外部金额与内部金额的转换比例 | 1元 = 300钻石 |
+
+### 订单状态
+
+```php
+enum TransferStatus: int
+{
+    case CREATED = 100;     // 已创建
+    case PROCESSING = 200;  // 处理中
+    case COMPLETED = 300;   // 已完成
+    case FAILED = 400;      // 失败
+    case CANCELLED = 500;   // 已取消
+}
+```
+
+### 订单类型
+
+```php
+enum TransferType: int
+{
+    case IN = 1;   // 转入
+    case OUT = 2;  // 转出
+}
+```
+
+## 🏗️ 架构设计
+
+### 模块结构
+
+```
+app/Module/Transfer/
+├── Controllers/           # 后台管理控制器
+├── Dtos/                 # 数据传输对象
+├── Enums/                # 枚举类
+├── Events/               # 事件类
+├── Handlers/             # API处理器
+├── Logics/               # 业务逻辑层
+├── Models/               # 数据模型
+├── Repositories/         # 数据仓库层
+├── Services/             # 服务层
+├── Validations/          # 验证类
+└── Validators/           # 验证器
+```
+
+### 核心类说明
+
+| 类名 | 职责 | 说明 |
+|------|------|------|
+| `TransferLogic` | 核心业务逻辑 | 处理转入转出订单创建和执行 |
+| `TransferThirdPartyService` | 第三方服务 | 专门处理第三方应用集成 |
+| `TransferApp` | 应用配置模型 | 管理划转应用配置和手续费计算 |
+| `TransferOrder` | 订单模型 | 划转订单数据模型 |
+| `OrderLogic` | 订单处理逻辑 | 处理订单状态变更和外部API调用 |
+| `CallbackLogic` | 回调处理逻辑 | 处理外部系统回调通知 |
+
+## 💱 金额转换逻辑
+
+### 转换规则
+
+#### 第三方应用转出
+```
+外部金额 × 汇率 = 内部金额
+示例:100元 × 300 = 30000钻石
+```
+
+#### 普通应用转出
+```
+内部金额 ÷ 汇率 = 外部金额
+示例:30000钻石 ÷ 300 = 100元
+```
+
+#### 转入操作
+```
+外部金额 × 汇率 = 内部金额
+示例:50元 × 300 = 15000钻石
+```
+
+### 重要原则
+
+1. **避免双重转换**:只在`TransferLogic`层进行一次转换
+2. **精度处理**:使用`bcmath`函数确保计算精度
+3. **汇率验证**:确保汇率大于0,避免计算异常
+
+## 💰 手续费机制
+
+### 手续费模式
+
+#### 转出:手续费额外收取
+```php
+用户想转出:3000钻石
+手续费:10钻石
+用户总扣除:3010钻石
+外部实际收到:3000钻石(完整金额)
+```
+
+#### 转入:手续费从金额中扣除
+```php
+外部转入:3000钻石
+手续费:10钻石
+用户实际收到:2990钻石
+```
+
+### 手续费计算
+
+```php
+// 按比例计算
+$feeAmount = $amount * $feeRate;
+
+// 应用最低限制
+if ($feeAmount < $minFee) {
+    $feeAmount = $minFee;
+}
+
+// 应用最高限制
+if ($maxFee > 0 && $feeAmount > $maxFee) {
+    $feeAmount = $maxFee;
+}
+```
+
+### 手续费配置
+
+| 字段 | 说明 | 示例 |
+|------|------|------|
+| `fee_out_rate` | 转出手续费率 | 0.01 (1%) |
+| `fee_out_min` | 转出最低手续费 | 0.5钻石 |
+| `fee_out_max` | 转出最高手续费 | 10钻石 |
+| `fee_in_rate` | 转入手续费率 | 0.005 (0.5%) |
+| `fee_in_min` | 转入最低手续费 | 1钻石 |
+| `fee_in_max` | 转入最高手续费 | 50钻石 |
+
+## 🔌 第三方应用集成
+
+### 核心服务
+
+`TransferThirdPartyService`专门处理第三方应用需求:
+
+```php
+// 创建提现订单
+$result = TransferThirdPartyService::createWithdrawOrder(
+    thirdPartyAppId: 11,
+    farmUserId: 39027,
+    thirdPartyUserId: '10002',
+    thirdPartyAmount: '100',  // 外部金额
+    remark: 'URS提取',
+    callbackData: ['operation_type' => 'withdraw']
+);
+
+// 创建充值订单
+$result = TransferThirdPartyService::createDepositOrder(
+    thirdPartyAppId: 11,
+    farmUserId: 39027,
+    thirdPartyUserId: '10002',
+    thirdPartyAmount: '50',   // 外部金额
+    remark: 'URS充值',
+    callbackData: ['operation_type' => 'deposit']
+);
+```
+
+### 特殊功能
+
+1. **跳过密码验证**:第三方应用无需用户输入密码
+2. **自动金额转换**:自动处理外部金额与内部金额转换
+3. **回调支持**:支持状态变更回调通知
+4. **权限控制**:独立控制转入/转出操作权限
+
+## 📡 API接口
+
+### 转出接口
+
+```http
+POST /api/transfer/out
+Content-Type: application/json
+
+{
+    "transfer_app_id": 1,
+    "amount": "30000",
+    "password": "123456",
+    "out_user_id": "user123",
+    "remark": "提现到银行卡"
+}
+```
+
+### 转入接口
+
+```http
+POST /api/transfer/in
+Content-Type: application/json
+
+{
+    "transfer_app_id": 1,
+    "business_id": "ORDER_20250619001",
+    "amount": "15000",
+    "out_user_id": "user123",
+    "remark": "银行卡充值"
+}
+```
+
+### 回调接口
+
+```http
+POST /api/transfer/callback
+Content-Type: application/json
+
+{
+    "business_id": "ORDER_20250619001",
+    "out_id": 1,
+    "success": true,
+    "message": "处理成功"
+}
+```
+
+## 🗄️ 数据库设计
+
+### 主要数据表
+
+#### transfer_apps - 划转应用配置表
+```sql
+CREATE TABLE `kku_transfer_apps` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `title` varchar(100) NOT NULL COMMENT '应用名称',
+  `exchange_rate` decimal(10,4) NOT NULL DEFAULT '1.0000' COMMENT '汇率',
+  `allow_transfer_in` tinyint(1) NOT NULL DEFAULT '1' COMMENT '允许转入',
+  `allow_transfer_out` tinyint(1) NOT NULL DEFAULT '1' COMMENT '允许转出',
+  `fee_out_rate` decimal(8,6) NOT NULL DEFAULT '0.000000' COMMENT '转出手续费率',
+  `fee_out_min` decimal(20,10) NOT NULL DEFAULT '0.0000000000' COMMENT '转出最低手续费',
+  `fee_out_max` decimal(20,10) NOT NULL DEFAULT '0.0000000000' COMMENT '转出最高手续费',
+  -- 更多字段...
+  PRIMARY KEY (`id`)
+);
+```
+
+#### transfer_orders - 划转订单表
+```sql
+CREATE TABLE `kku_transfer_orders` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `transfer_app_id` int NOT NULL COMMENT '划转应用ID',
+  `out_order_id` varchar(100) NOT NULL COMMENT '外部订单ID',
+  `user_id` int NOT NULL COMMENT '用户ID',
+  `type` tinyint NOT NULL COMMENT '类型:1转入,2转出',
+  `status` int NOT NULL COMMENT '状态',
+  `out_amount` decimal(30,10) NOT NULL COMMENT '外部金额',
+  `amount` decimal(30,10) NOT NULL COMMENT '内部金额',
+  `exchange_rate` decimal(10,4) NOT NULL COMMENT '汇率',
+  `fee_amount` decimal(30,10) NOT NULL DEFAULT '0.0000000000' COMMENT '手续费',
+  `actual_amount` decimal(30,10) NOT NULL COMMENT '实际金额',
+  -- 更多字段...
+  PRIMARY KEY (`id`)
+);
+```
+
+## ⚙️ 配置说明
+
+### 应用配置
+
+在后台管理界面配置划转应用:
+
+1. **基本信息**:应用名称、描述
+2. **汇率设置**:外部金额与内部金额转换比例
+3. **权限控制**:允许转入/转出操作
+4. **手续费配置**:费率、最低/最高限制
+5. **账户配置**:转入来源账户、转出目标账户
+6. **API配置**:外部API地址、回调URL
+
+### 环境配置
+
+```env
+# Transfer模块配置
+TRANSFER_DEFAULT_FEE_ACCOUNT_UID=1
+TRANSFER_CALLBACK_TIMEOUT=30
+TRANSFER_API_TIMEOUT=60
+```
+
+## 📝 使用示例
+
+### 基本转出操作
+
+```php
+use App\Module\Transfer\Services\TransferService;
+
+// 创建转出订单
+$order = TransferService::createTransferOut(
+    transferAppId: 1,
+    userId: 12345,
+    amount: '30000',
+    password: '123456',
+    outUserId: 'user123',
+    remark: '提现到银行卡'
+);
+
+echo "订单ID: {$order->id}";
+echo "外部订单ID: {$order->out_order_id}";
+echo "状态: {$order->status->name}";
+```
+
+### URS第三方集成示例
+
+```php
+use App\Module\Transfer\Services\TransferThirdPartyService;
+
+// URS提现
+$result = TransferThirdPartyService::createWithdrawOrder(
+    thirdPartyAppId: 11,
+    farmUserId: 39027,
+    thirdPartyUserId: '10002',
+    thirdPartyAmount: '100',
+    remark: 'URS提取',
+    callbackData: [
+        'operation_type' => 'withdraw',
+        'urs_order_id' => 'URS_20250619001'
+    ]
+);
+
+if (is_string($result)) {
+    echo "创建失败: {$result}";
+} else {
+    echo "创建成功,订单ID: {$result->id}";
+}
+```
+
+## 🔧 故障排除
+
+### 常见问题
+
+#### 1. 金额转换错误
+**问题**:外部金额2500变成内部金额2500  
+**原因**:双重转换问题  
+**解决**:确保只在TransferLogic层进行一次转换
+
+#### 2. 手续费计算异常
+**问题**:手续费从转出金额中扣除,用户困惑  
+**原因**:手续费模式理解错误  
+**解决**:转出使用额外收取模式,转入使用扣除模式
+
+#### 3. 余额验证失败
+**问题**:用户余额充足但验证失败  
+**原因**:验证逻辑与执行逻辑不一致  
+**解决**:确保验证器检查转出金额+手续费总和
+
+#### 4. 事务级别错误
+**问题**:transaction level is 0错误  
+**原因**:Fund模块trade方法需要在事务中执行  
+**解决**:在调用前开启事务
+
+### 调试工具
+
+```bash
+# 重现错误请求
+php artisan debug:reproduce-error {request_log_id}
+
+# 检查订单状态
+php artisan transfer:order:status {order_id}
+
+# 重试失败订单
+php artisan transfer:order:retry {order_id}
+```
+
+---
+
+**版本**: v1.0  
+**最后更新**: 2025-06-19  
+**维护者**: AI Assistant