|
|
@@ -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
|