|
|
@@ -0,0 +1,819 @@
|
|
|
+# URS对接ThirdParty模块方案
|
|
|
+
|
|
|
+## 概述
|
|
|
+
|
|
|
+本文档描述如何将现有的URS(用户推广系统)功能对接到ThirdParty模块中,实现统一的第三方服务管理。URS系统提供用户信息查询、推广关系管理和资金操作等功能,通过ThirdParty模块可以实现更好的服务管理、监控和安全控制。
|
|
|
+
|
|
|
+## 当前URS系统分析
|
|
|
+
|
|
|
+### 核心功能
|
|
|
+1. **API接口**:
|
|
|
+ - 获取用户信息(用户ID、昵称)
|
|
|
+ - 获取用户上级关系链表(各个等级的用户ID)
|
|
|
+ - 获取下级人数统计(直推/团队3代)
|
|
|
+
|
|
|
+2. **Webhook机制**:
|
|
|
+ - 注册通知:传入uid和三级上级
|
|
|
+ - 出包操作:用户ID、USDT数量、交易ID
|
|
|
+ - 入包操作:用户ID、USDT数量、交易ID
|
|
|
+ - 入包检查:用户ID、USDT数量验证
|
|
|
+
|
|
|
+3. **核心流程**:
|
|
|
+ - URS应用访问农场客户端携带ukey
|
|
|
+ - 农场使用ukey获取urs_uid
|
|
|
+ - 创建农场用户并建立关联
|
|
|
+ - 同步推广关系到UrsPromotion模块
|
|
|
+ - 通过webhook进行钻石充值和提取
|
|
|
+
|
|
|
+### 技术特点
|
|
|
+- **加密通信**:使用AES-256-CBC加密算法
|
|
|
+- **签名验证**:SHA256签名确保数据完整性
|
|
|
+- **时间戳验证**:5分钟有效期防止重放攻击
|
|
|
+- **专属资金账户**:使用专属用户ID进行资金操作
|
|
|
+
|
|
|
+## 对接方案设计
|
|
|
+
|
|
|
+### 1. 服务类型定义
|
|
|
+
|
|
|
+在ThirdParty模块中,URS属于**第三方平台类**服务,具体分类为:
|
|
|
+- **服务类型**:SOCIAL(社交平台)
|
|
|
+- **认证类型**:SIGNATURE(签名认证)
|
|
|
+- **主要功能**:用户关系管理、资金操作
|
|
|
+
|
|
|
+### 2. 服务配置结构
|
|
|
+
|
|
|
+#### 2.1 第三方服务配置(kku_thirdparty_services表)
|
|
|
+
|
|
|
+```php
|
|
|
+[
|
|
|
+ 'name' => 'URS用户推广系统',
|
|
|
+ 'code' => 'URS_PROMOTION',
|
|
|
+ 'provider' => 'URS',
|
|
|
+ 'service_type' => 'SOCIAL',
|
|
|
+ 'version' => 'v1',
|
|
|
+ 'base_url' => 'https://urs.example.com/api',
|
|
|
+ 'auth_type' => 'SIGNATURE',
|
|
|
+ 'status' => 'ACTIVE',
|
|
|
+ 'description' => 'URS用户推广关系管理和资金操作系统',
|
|
|
+ 'timeout' => 30,
|
|
|
+ 'retry_times' => 3,
|
|
|
+ 'retry_delay' => 1000,
|
|
|
+ 'health_check_url' => '/health',
|
|
|
+ 'health_check_interval' => 300,
|
|
|
+ 'webhook_url' => '/webhook/urs',
|
|
|
+ 'webhook_secret' => 'urs_webhook_secret_key',
|
|
|
+ 'priority' => 10,
|
|
|
+ 'config' => [
|
|
|
+ 'diamond_ratio' => 300, // 1 USDT = 300 钻石
|
|
|
+ 'fund_user_id' => 15, // 仓库账户用户ID
|
|
|
+ 'control_user_id' => 16, // 调控账户用户ID
|
|
|
+ 'currency_type' => 'DIAMOND', // 币种类型
|
|
|
+ 'precision' => 10, // 小数精度
|
|
|
+ ],
|
|
|
+ 'default_params' => [
|
|
|
+ 'format' => 'json',
|
|
|
+ 'version' => '1.0',
|
|
|
+ ],
|
|
|
+ 'default_headers' => [
|
|
|
+ 'Content-Type' => 'application/json',
|
|
|
+ 'Accept' => 'application/json',
|
|
|
+ 'User-Agent' => 'KKU-Farm/1.0',
|
|
|
+ ],
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+#### 2.2 认证凭证配置(kku_thirdparty_credentials表)
|
|
|
+
|
|
|
+```php
|
|
|
+[
|
|
|
+ 'service_id' => 1, // 对应URS服务ID
|
|
|
+ 'environment' => 'production',
|
|
|
+ 'auth_type' => 'SIGNATURE',
|
|
|
+ 'credentials' => [
|
|
|
+ 'app_key' => 'Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y', // API通讯Key
|
|
|
+ 'timeout' => 300, // 签名有效期(秒)
|
|
|
+ 'algorithm' => 'AES-256-CBC', // 加密算法
|
|
|
+ 'hash_algorithm' => 'sha256', // 签名算法
|
|
|
+ ],
|
|
|
+ 'is_active' => true,
|
|
|
+ 'expires_at' => null, // 永不过期
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+### 3. API接口映射
|
|
|
+
|
|
|
+#### 3.1 用户信息查询接口
|
|
|
+
|
|
|
+**原始接口**:`POST /api/ecology/{ecology_id}/userInfo`
|
|
|
+**ThirdParty调用**:
|
|
|
+```php
|
|
|
+ThirdPartyService::callApi('URS_PROMOTION', 'userInfo', [
|
|
|
+ 'userKey' => $userKey
|
|
|
+], 'POST');
|
|
|
+```
|
|
|
+
|
|
|
+#### 3.2 用户团队关系接口
|
|
|
+
|
|
|
+**原始接口**:`POST /api/ecology/{ecology_id}/userTeam`
|
|
|
+**ThirdParty调用**:
|
|
|
+```php
|
|
|
+ThirdPartyService::callApi('URS_PROMOTION', 'userTeam', [
|
|
|
+ 'userId' => $userId
|
|
|
+], 'POST');
|
|
|
+```
|
|
|
+
|
|
|
+#### 3.3 用户下级统计接口
|
|
|
+
|
|
|
+**原始接口**:`POST /api/ecology/{ecology_id}/userLevelCount`
|
|
|
+**ThirdParty调用**:
|
|
|
+```php
|
|
|
+ThirdPartyService::callApi('URS_PROMOTION', 'userLevelCount', [
|
|
|
+ 'userId' => $userId,
|
|
|
+ 'level' => $level // 1或3
|
|
|
+], 'POST');
|
|
|
+```
|
|
|
+
|
|
|
+### 4. Webhook处理机制
|
|
|
+
|
|
|
+#### 4.1 Webhook路由配置
|
|
|
+
|
|
|
+在ThirdParty模块中添加URS专用的Webhook处理路由:
|
|
|
+```php
|
|
|
+// app/Module/ThirdParty/Routes/webhook.php
|
|
|
+Route::post('/webhook/urs/{action}', [UrsWebhookController::class, 'handle'])
|
|
|
+ ->name('urs.webhook')
|
|
|
+ ->middleware(['throttle:60,1']);
|
|
|
+```
|
|
|
+
|
|
|
+#### 4.2 Webhook处理器
|
|
|
+
|
|
|
+创建专门的URS Webhook处理器:
|
|
|
+```php
|
|
|
+// app/Module/ThirdParty/Controllers/UrsWebhookController.php
|
|
|
+class UrsWebhookController extends Controller
|
|
|
+{
|
|
|
+ public function handle(Request $request, string $action)
|
|
|
+ {
|
|
|
+ // 验证签名
|
|
|
+ $this->validateSignature($request);
|
|
|
+
|
|
|
+ // 根据action分发处理
|
|
|
+ switch ($action) {
|
|
|
+ case 'register':
|
|
|
+ return $this->handleRegister($request);
|
|
|
+ case 'deposit':
|
|
|
+ return $this->handleDeposit($request);
|
|
|
+ case 'withdraw':
|
|
|
+ return $this->handleWithdraw($request);
|
|
|
+ case 'check':
|
|
|
+ return $this->handleCheck($request);
|
|
|
+ default:
|
|
|
+ throw new BadRequestException('不支持的操作类型');
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 5. 加密服务集成
|
|
|
+
|
|
|
+#### 5.1 加密服务适配
|
|
|
+
|
|
|
+将现有的URS CryptoService集成到ThirdParty模块:
|
|
|
+```php
|
|
|
+// app/Module/ThirdParty/Services/Crypto/UrsCryptoService.php
|
|
|
+class UrsCryptoService extends BaseCryptoService
|
|
|
+{
|
|
|
+ public function encrypt(array $data): array
|
|
|
+ {
|
|
|
+ // 使用URS的加密逻辑
|
|
|
+ $iv = random_bytes(16);
|
|
|
+ $timestamp = time();
|
|
|
+ $json = json_encode($data, JSON_UNESCAPED_UNICODE);
|
|
|
+
|
|
|
+ $encrypted = openssl_encrypt(
|
|
|
+ $json,
|
|
|
+ 'AES-256-CBC',
|
|
|
+ $this->key,
|
|
|
+ OPENSSL_RAW_DATA,
|
|
|
+ $iv
|
|
|
+ );
|
|
|
+
|
|
|
+ if ($encrypted === false) {
|
|
|
+ throw new CryptoException('加密失败: ' . openssl_error_string());
|
|
|
+ }
|
|
|
+
|
|
|
+ $dataBase64 = base64_encode($encrypted);
|
|
|
+ $ivBase64 = base64_encode($iv);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'data' => $dataBase64,
|
|
|
+ 'iv' => $ivBase64,
|
|
|
+ 'timestamp' => $timestamp,
|
|
|
+ 'sign' => hash('sha256', $dataBase64 . $ivBase64 . $timestamp . $this->key)
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function decrypt(array $encryptedData): array
|
|
|
+ {
|
|
|
+ // 验证时间戳
|
|
|
+ if (abs(time() - $encryptedData['timestamp']) > $this->timeout) {
|
|
|
+ throw new CryptoException('请求已过期');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证签名
|
|
|
+ $sign = hash('sha256',
|
|
|
+ $encryptedData['data'] .
|
|
|
+ $encryptedData['iv'] .
|
|
|
+ $encryptedData['timestamp'] .
|
|
|
+ $this->key
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!hash_equals($sign, $encryptedData['sign'])) {
|
|
|
+ throw new CryptoException('签名验证失败');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解密数据
|
|
|
+ $decrypted = openssl_decrypt(
|
|
|
+ base64_decode($encryptedData['data']),
|
|
|
+ 'AES-256-CBC',
|
|
|
+ $this->key,
|
|
|
+ OPENSSL_RAW_DATA,
|
|
|
+ base64_decode($encryptedData['iv'])
|
|
|
+ );
|
|
|
+
|
|
|
+ if ($decrypted === false) {
|
|
|
+ throw new CryptoException('解密失败: ' . openssl_error_string());
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = json_decode($decrypted, true);
|
|
|
+ if (json_last_error() !== JSON_ERROR_NONE) {
|
|
|
+ throw new CryptoException('JSON解析失败: ' . json_last_error_msg());
|
|
|
+ }
|
|
|
+
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 5.2 认证头生成
|
|
|
+
|
|
|
+在ThirdParty的认证系统中集成URS签名认证:
|
|
|
+```php
|
|
|
+// app/Module/ThirdParty/Services/Auth/UrsAuthService.php
|
|
|
+class UrsAuthService extends BaseAuthService
|
|
|
+{
|
|
|
+ public function generateAuthHeaders(array $data = []): array
|
|
|
+ {
|
|
|
+ $cryptoService = new UrsCryptoService($this->credential->getAppKey());
|
|
|
+ $encryptedData = $cryptoService->encrypt($data);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'X-Encrypted-Data' => json_encode($encryptedData),
|
|
|
+ 'X-Timestamp' => $encryptedData['timestamp'],
|
|
|
+ 'X-Signature' => $encryptedData['sign'],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 6. 业务逻辑层设计
|
|
|
+
|
|
|
+#### 6.1 URS服务类
|
|
|
+
|
|
|
+创建专门的URS服务类,封装所有URS相关操作:
|
|
|
+```php
|
|
|
+// app/Module/ThirdParty/Services/UrsService.php
|
|
|
+class UrsService
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 获取用户信息
|
|
|
+ */
|
|
|
+ public static function getUserInfo(string $userKey): array
|
|
|
+ {
|
|
|
+ return ThirdPartyService::callApi('URS_PROMOTION', 'userInfo', [
|
|
|
+ 'userKey' => $userKey
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户团队关系
|
|
|
+ */
|
|
|
+ public static function getUserTeam(int $userId): array
|
|
|
+ {
|
|
|
+ return ThirdPartyService::callApi('URS_PROMOTION', 'userTeam', [
|
|
|
+ 'userId' => $userId
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户下级统计
|
|
|
+ */
|
|
|
+ public static function getUserLevelCount(int $userId, int $level): array
|
|
|
+ {
|
|
|
+ if (!in_array($level, [1, 3])) {
|
|
|
+ throw new InvalidArgumentException('level只能是1或3');
|
|
|
+ }
|
|
|
+
|
|
|
+ return ThirdPartyService::callApi('URS_PROMOTION', 'userLevelCount', [
|
|
|
+ 'userId' => $userId,
|
|
|
+ 'level' => $level
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理注册通知
|
|
|
+ */
|
|
|
+ public static function handleRegisterNotification(int $uid, array $superiors): bool
|
|
|
+ {
|
|
|
+ // 记录日志
|
|
|
+ ThirdPartyLog::create([
|
|
|
+ 'service_id' => static::getServiceId(),
|
|
|
+ 'request_type' => 'webhook',
|
|
|
+ 'endpoint' => 'register',
|
|
|
+ 'request_data' => compact('uid', 'superiors'),
|
|
|
+ 'status' => 'success',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理出包操作
|
|
|
+ */
|
|
|
+ public static function handleWithdraw(int $userId, float $usdtAmount, string $transactionId): array
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 防止重复处理
|
|
|
+ if (static::isTransactionProcessed($transactionId)) {
|
|
|
+ throw new DuplicateTransactionException('交易已处理');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算钻石数量
|
|
|
+ $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);
|
|
|
+
|
|
|
+ // 调用Fund模块进行资金操作
|
|
|
+ $result = FundService::transfer(
|
|
|
+ $userId, // 从用户账户
|
|
|
+ config('thirdparty.services.urs.fund_user_id', 15), // 转到专属账户
|
|
|
+ 'DIAMOND', // 币种
|
|
|
+ $diamondAmount, // 数量
|
|
|
+ 'URS出包操作', // 备注
|
|
|
+ $transactionId // 交易ID
|
|
|
+ );
|
|
|
+
|
|
|
+ // 记录成功日志
|
|
|
+ static::logTransaction('withdraw', $userId, $usdtAmount, $transactionId, 'success', $result);
|
|
|
+
|
|
|
+ return ['success' => true, 'data' => $result];
|
|
|
+
|
|
|
+ } catch (Exception $e) {
|
|
|
+ // 记录失败日志
|
|
|
+ static::logTransaction('withdraw', $userId, $usdtAmount, $transactionId, 'failed', $e->getMessage());
|
|
|
+
|
|
|
+ return ['success' => false, 'error' => $e->getMessage()];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理入包操作
|
|
|
+ */
|
|
|
+ public static function handleDeposit(int $userId, float $usdtAmount, string $transactionId): array
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 防止重复处理
|
|
|
+ if (static::isTransactionProcessed($transactionId)) {
|
|
|
+ throw new DuplicateTransactionException('交易已处理');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算钻石数量
|
|
|
+ $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);
|
|
|
+
|
|
|
+ // 调用Fund模块进行资金操作
|
|
|
+ $result = FundService::transfer(
|
|
|
+ config('thirdparty.services.urs.fund_user_id', 15), // 从专属账户
|
|
|
+ $userId, // 转到用户账户
|
|
|
+ 'DIAMOND', // 币种
|
|
|
+ $diamondAmount, // 数量
|
|
|
+ 'URS入包操作', // 备注
|
|
|
+ $transactionId // 交易ID
|
|
|
+ );
|
|
|
+
|
|
|
+ // 记录成功日志
|
|
|
+ static::logTransaction('deposit', $userId, $usdtAmount, $transactionId, 'success', $result);
|
|
|
+
|
|
|
+ return ['success' => true, 'data' => $result];
|
|
|
+
|
|
|
+ } catch (Exception $e) {
|
|
|
+ // 记录失败日志
|
|
|
+ static::logTransaction('deposit', $userId, $usdtAmount, $transactionId, 'failed', $e->getMessage());
|
|
|
+
|
|
|
+ return ['success' => false, 'error' => $e->getMessage()];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理入包检查
|
|
|
+ */
|
|
|
+ public static function handleDepositCheck(int $userId, float $usdtAmount): array
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 计算钻石数量
|
|
|
+ $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);
|
|
|
+
|
|
|
+ // 获取用户钻石余额
|
|
|
+ $balance = FundService::getBalance($userId, 'DIAMOND');
|
|
|
+
|
|
|
+ // 检查是否允许操作(这里可以添加业务规则)
|
|
|
+ $allowed = $balance >= $diamondAmount;
|
|
|
+
|
|
|
+ // 计算费用(如果有手续费)
|
|
|
+ $fee = 0; // 暂时无手续费
|
|
|
+ $total = $diamondAmount + $fee;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'allowed' => $allowed,
|
|
|
+ 'diamond_balance' => $balance,
|
|
|
+ 'principal_amount' => $diamondAmount,
|
|
|
+ 'fee_amount' => $fee,
|
|
|
+ 'total_required' => $total,
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (Exception $e) {
|
|
|
+ throw new ServiceException('入包检查失败: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查交易是否已处理
|
|
|
+ */
|
|
|
+ private static function isTransactionProcessed(string $transactionId): bool
|
|
|
+ {
|
|
|
+ return ThirdPartyLog::where('transaction_id', $transactionId)
|
|
|
+ ->where('status', 'success')
|
|
|
+ ->exists();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录交易日志
|
|
|
+ */
|
|
|
+ private static function logTransaction(string $type, int $userId, float $amount, string $transactionId, string $status, $result = null): void
|
|
|
+ {
|
|
|
+ ThirdPartyLog::create([
|
|
|
+ 'service_id' => static::getServiceId(),
|
|
|
+ 'request_type' => 'webhook',
|
|
|
+ 'endpoint' => $type,
|
|
|
+ 'request_data' => compact('userId', 'amount', 'transactionId'),
|
|
|
+ 'response_data' => $result,
|
|
|
+ 'status' => $status,
|
|
|
+ 'transaction_id' => $transactionId,
|
|
|
+ 'response_time' => 0, // Webhook无响应时间
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取URS服务ID
|
|
|
+ */
|
|
|
+ private static function getServiceId(): int
|
|
|
+ {
|
|
|
+ static $serviceId = null;
|
|
|
+
|
|
|
+ if ($serviceId === null) {
|
|
|
+ $service = ThirdPartyService::where('code', 'URS_PROMOTION')->first();
|
|
|
+ $serviceId = $service ? $service->id : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $serviceId;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 7. 配额管理配置
|
|
|
+
|
|
|
+#### 7.1 URS服务配额设置
|
|
|
+
|
|
|
+```php
|
|
|
+// 在kku_thirdparty_quotas表中配置URS服务的调用配额
|
|
|
+[
|
|
|
+ 'service_id' => 1, // URS服务ID
|
|
|
+ 'quota_type' => 'PER_MINUTE',
|
|
|
+ 'quota_limit' => 100, // 每分钟100次
|
|
|
+ 'current_usage' => 0,
|
|
|
+ 'reset_at' => null,
|
|
|
+ 'is_active' => true,
|
|
|
+],
|
|
|
+[
|
|
|
+ 'service_id' => 1,
|
|
|
+ 'quota_type' => 'PER_DAY',
|
|
|
+ 'quota_limit' => 10000, // 每天10000次
|
|
|
+ 'current_usage' => 0,
|
|
|
+ 'reset_at' => null,
|
|
|
+ 'is_active' => true,
|
|
|
+],
|
|
|
+```
|
|
|
+
|
|
|
+### 8. 监控和告警配置
|
|
|
+
|
|
|
+#### 8.1 健康检查配置
|
|
|
+
|
|
|
+```php
|
|
|
+// URS服务健康检查配置
|
|
|
+'health_check' => [
|
|
|
+ 'enabled' => true,
|
|
|
+ 'interval' => 300, // 5分钟检查一次
|
|
|
+ 'timeout' => 10, // 10秒超时
|
|
|
+ 'retry_times' => 3, // 重试3次
|
|
|
+ 'alert_threshold' => 3, // 连续3次失败后告警
|
|
|
+ 'endpoints' => [
|
|
|
+ 'health' => '/health', // 健康检查端点
|
|
|
+ 'status' => '/status', // 状态检查端点
|
|
|
+ ],
|
|
|
+],
|
|
|
+```
|
|
|
+
|
|
|
+#### 8.2 性能监控配置
|
|
|
+
|
|
|
+```php
|
|
|
+// URS服务性能监控配置
|
|
|
+'performance_monitor' => [
|
|
|
+ 'response_time_threshold' => 5000, // 响应时间阈值(毫秒)
|
|
|
+ 'error_rate_threshold' => 0.05, // 错误率阈值(5%)
|
|
|
+ 'availability_threshold' => 0.99, // 可用性阈值(99%)
|
|
|
+ 'monitor_interval' => 60, // 监控间隔(秒)
|
|
|
+],
|
|
|
+```
|
|
|
+
|
|
|
+## 实施步骤
|
|
|
+
|
|
|
+### 第一阶段:基础配置
|
|
|
+
|
|
|
+1. **服务注册**
|
|
|
+ - 在ThirdParty模块中注册URS服务
|
|
|
+ - 配置基本信息和认证凭证
|
|
|
+ - 设置服务状态为TESTING
|
|
|
+
|
|
|
+2. **加密服务集成**
|
|
|
+ - 将URS的CryptoService集成到ThirdParty模块
|
|
|
+ - 创建URS专用的认证服务类
|
|
|
+ - 测试加密解密功能
|
|
|
+
|
|
|
+3. **API接口适配**
|
|
|
+ - 创建UrsService服务类
|
|
|
+ - 实现用户信息、团队关系、下级统计接口
|
|
|
+ - 进行接口调用测试
|
|
|
+
|
|
|
+### 第二阶段:Webhook集成
|
|
|
+
|
|
|
+1. **Webhook控制器开发**
|
|
|
+ - 创建UrsWebhookController
|
|
|
+ - 实现注册、出包、入包、检查四个操作
|
|
|
+ - 添加签名验证和安全检查
|
|
|
+
|
|
|
+2. **资金操作集成**
|
|
|
+ - 与Fund模块对接
|
|
|
+ - 实现钻石充值和提取逻辑
|
|
|
+ - 添加交易重复检查机制
|
|
|
+
|
|
|
+3. **异步处理优化**
|
|
|
+ - 使用队列处理资金操作
|
|
|
+ - 添加失败重试机制
|
|
|
+ - 实现操作状态跟踪
|
|
|
+
|
|
|
+### 第三阶段:监控和优化
|
|
|
+
|
|
|
+1. **监控系统配置**
|
|
|
+ - 配置健康检查
|
|
|
+ - 设置性能监控阈值
|
|
|
+ - 实现告警通知
|
|
|
+
|
|
|
+2. **配额管理**
|
|
|
+ - 设置合理的调用配额
|
|
|
+ - 实现配额超限处理
|
|
|
+ - 添加配额使用统计
|
|
|
+
|
|
|
+3. **日志和审计**
|
|
|
+ - 完善调用日志记录
|
|
|
+ - 实现敏感操作审计
|
|
|
+ - 添加数据统计分析
|
|
|
+
|
|
|
+### 第四阶段:后台管理
|
|
|
+
|
|
|
+1. **管理界面开发**
|
|
|
+ - URS服务配置管理
|
|
|
+ - 调用日志查看
|
|
|
+ - 监控数据展示
|
|
|
+
|
|
|
+2. **运维工具**
|
|
|
+ - 服务状态检查工具
|
|
|
+ - 配额重置工具
|
|
|
+ - 数据导出功能
|
|
|
+
|
|
|
+## 技术要点
|
|
|
+
|
|
|
+### 1. 安全考虑
|
|
|
+
|
|
|
+- **签名验证**:所有API调用都必须通过签名验证
|
|
|
+- **时间戳检查**:防止重放攻击
|
|
|
+- **敏感数据加密**:认证凭证和交易数据加密存储
|
|
|
+- **访问控制**:基于角色的权限管理
|
|
|
+- **审计日志**:记录所有敏感操作
|
|
|
+
|
|
|
+### 2. 性能优化
|
|
|
+
|
|
|
+- **连接池**:复用HTTP连接减少开销
|
|
|
+- **缓存机制**:缓存用户信息和关系数据
|
|
|
+- **异步处理**:资金操作使用队列异步处理
|
|
|
+- **批量操作**:支持批量查询和更新
|
|
|
+- **数据库优化**:合理的索引和查询优化
|
|
|
+
|
|
|
+### 3. 可靠性保障
|
|
|
+
|
|
|
+- **重试机制**:网络异常时自动重试
|
|
|
+- **熔断器**:服务异常时快速失败
|
|
|
+- **降级策略**:关键功能的降级方案
|
|
|
+- **监控告警**:实时监控服务状态
|
|
|
+- **数据一致性**:确保资金操作的一致性
|
|
|
+
|
|
|
+### 4. 扩展性设计
|
|
|
+
|
|
|
+- **插件化架构**:支持新的第三方服务接入
|
|
|
+- **配置化管理**:通过配置文件管理服务参数
|
|
|
+- **版本兼容**:支持API版本升级
|
|
|
+- **水平扩展**:支持多实例部署
|
|
|
+- **模块解耦**:与其他模块松耦合
|
|
|
+
|
|
|
+## 配置示例
|
|
|
+
|
|
|
+### 1. 环境配置
|
|
|
+
|
|
|
+```php
|
|
|
+// config/thirdparty.php
|
|
|
+'services' => [
|
|
|
+ 'urs' => [
|
|
|
+ 'enabled' => true,
|
|
|
+ 'base_url' => env('URS_BASE_URL', 'https://urs.example.com/api'),
|
|
|
+ 'app_key' => env('URS_APP_KEY', 'Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y'),
|
|
|
+ 'timeout' => env('URS_TIMEOUT', 30),
|
|
|
+ 'diamond_ratio' => env('URS_DIAMOND_RATIO', 300),
|
|
|
+ 'fund_user_id' => env('URS_FUND_USER_ID', 15),
|
|
|
+ 'control_user_id' => env('URS_CONTROL_USER_ID', 16),
|
|
|
+ 'webhook_secret' => env('URS_WEBHOOK_SECRET', 'urs_webhook_secret'),
|
|
|
+ ],
|
|
|
+],
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 数据库初始化
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 插入URS服务配置
|
|
|
+INSERT INTO kku_thirdparty_services (
|
|
|
+ name, code, provider, service_type, version, base_url, auth_type, status,
|
|
|
+ description, timeout, retry_times, retry_delay, health_check_url,
|
|
|
+ health_check_interval, webhook_url, webhook_secret, priority, config,
|
|
|
+ default_params, default_headers, created_at, updated_at
|
|
|
+) VALUES (
|
|
|
+ 'URS用户推广系统',
|
|
|
+ 'URS_PROMOTION',
|
|
|
+ 'URS',
|
|
|
+ 'SOCIAL',
|
|
|
+ 'v1',
|
|
|
+ 'https://urs.example.com/api',
|
|
|
+ 'SIGNATURE',
|
|
|
+ 'ACTIVE',
|
|
|
+ 'URS用户推广关系管理和资金操作系统',
|
|
|
+ 30,
|
|
|
+ 3,
|
|
|
+ 1000,
|
|
|
+ '/health',
|
|
|
+ 300,
|
|
|
+ '/webhook/urs',
|
|
|
+ 'urs_webhook_secret_key',
|
|
|
+ 10,
|
|
|
+ '{"diamond_ratio":300,"fund_user_id":15,"control_user_id":16,"currency_type":"DIAMOND","precision":10}',
|
|
|
+ '{"format":"json","version":"1.0"}',
|
|
|
+ '{"Content-Type":"application/json","Accept":"application/json","User-Agent":"KKU-Farm/1.0"}',
|
|
|
+ NOW(),
|
|
|
+ NOW()
|
|
|
+);
|
|
|
+
|
|
|
+-- 插入认证凭证
|
|
|
+INSERT INTO kku_thirdparty_credentials (
|
|
|
+ service_id, environment, auth_type, credentials, is_active, created_at, updated_at
|
|
|
+) VALUES (
|
|
|
+ 1,
|
|
|
+ 'production',
|
|
|
+ 'SIGNATURE',
|
|
|
+ '{"app_key":"Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y","timeout":300,"algorithm":"AES-256-CBC","hash_algorithm":"sha256"}',
|
|
|
+ 1,
|
|
|
+ NOW(),
|
|
|
+ NOW()
|
|
|
+);
|
|
|
+
|
|
|
+-- 插入配额配置
|
|
|
+INSERT INTO kku_thirdparty_quotas (
|
|
|
+ service_id, quota_type, quota_limit, current_usage, is_active, created_at, updated_at
|
|
|
+) VALUES
|
|
|
+(1, 'PER_MINUTE', 100, 0, 1, NOW(), NOW()),
|
|
|
+(1, 'PER_HOUR', 6000, 0, 1, NOW(), NOW()),
|
|
|
+(1, 'PER_DAY', 100000, 0, 1, NOW(), NOW());
|
|
|
+```
|
|
|
+
|
|
|
+## 测试方案
|
|
|
+
|
|
|
+### 1. 单元测试
|
|
|
+
|
|
|
+```php
|
|
|
+// tests/Unit/ThirdParty/UrsServiceTest.php
|
|
|
+class UrsServiceTest extends TestCase
|
|
|
+{
|
|
|
+ public function testGetUserInfo()
|
|
|
+ {
|
|
|
+ $userKey = '$2y$10$i.h97m13olfIaU.ZTYiyeeXFl8xqn48w2bFiAhcoQsJdU6K3w.Lgu';
|
|
|
+ $result = UrsService::getUserInfo($userKey);
|
|
|
+
|
|
|
+ $this->assertArrayHasKey('userId', $result['data']);
|
|
|
+ $this->assertTrue($result['success']);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testGetUserTeam()
|
|
|
+ {
|
|
|
+ $userId = 10002;
|
|
|
+ $result = UrsService::getUserTeam($userId);
|
|
|
+
|
|
|
+ $this->assertArrayHasKey('team', $result['data']);
|
|
|
+ $this->assertTrue($result['success']);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testHandleDeposit()
|
|
|
+ {
|
|
|
+ $result = UrsService::handleDeposit(10002, 10.0, 'test_tx_001');
|
|
|
+
|
|
|
+ $this->assertTrue($result['success']);
|
|
|
+ $this->assertArrayHasKey('data', $result);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 集成测试
|
|
|
+
|
|
|
+```php
|
|
|
+// tests/Integration/ThirdParty/UrsIntegrationTest.php
|
|
|
+class UrsIntegrationTest extends TestCase
|
|
|
+{
|
|
|
+ public function testWebhookFlow()
|
|
|
+ {
|
|
|
+ // 测试完整的Webhook流程
|
|
|
+ $response = $this->postJson('/api/thirdparty/webhook/urs/deposit', [
|
|
|
+ 'userId' => 10002,
|
|
|
+ 'usdtAmount' => 10.0,
|
|
|
+ 'transactionId' => 'integration_test_001'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $response->assertStatus(200);
|
|
|
+ $response->assertJson(['success' => true]);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 部署清单
|
|
|
+
|
|
|
+### 1. 代码部署
|
|
|
+
|
|
|
+- [ ] 创建UrsService服务类
|
|
|
+- [ ] 创建UrsWebhookController控制器
|
|
|
+- [ ] 创建UrsCryptoService加密服务
|
|
|
+- [ ] 创建UrsAuthService认证服务
|
|
|
+- [ ] 添加Webhook路由配置
|
|
|
+- [ ] 更新ThirdParty服务提供者
|
|
|
+
|
|
|
+### 2. 数据库部署
|
|
|
+
|
|
|
+- [ ] 执行服务配置插入SQL
|
|
|
+- [ ] 执行认证凭证插入SQL
|
|
|
+- [ ] 执行配额配置插入SQL
|
|
|
+- [ ] 创建必要的数据库索引
|
|
|
+
|
|
|
+### 3. 配置部署
|
|
|
+
|
|
|
+- [ ] 更新环境变量配置
|
|
|
+- [ ] 更新ThirdParty模块配置
|
|
|
+- [ ] 配置队列和缓存
|
|
|
+- [ ] 配置监控和告警
|
|
|
+
|
|
|
+### 4. 测试验证
|
|
|
+
|
|
|
+- [ ] 执行单元测试
|
|
|
+- [ ] 执行集成测试
|
|
|
+- [ ] 进行性能测试
|
|
|
+- [ ] 验证监控告警
|
|
|
+
|
|
|
+## 总结
|
|
|
+
|
|
|
+通过将URS系统对接到ThirdParty模块,可以实现:
|
|
|
+
|
|
|
+1. **统一管理**:所有第三方服务在一个模块中统一管理
|
|
|
+2. **安全增强**:标准化的认证和加密机制
|
|
|
+3. **监控完善**:全面的服务监控和告警
|
|
|
+4. **性能优化**:连接池、缓存、异步处理等优化
|
|
|
+5. **运维便利**:完善的后台管理和运维工具
|
|
|
+
|
|
|
+这种对接方案既保持了URS系统的原有功能,又获得了ThirdParty模块提供的企业级服务管理能力,为系统的稳定运行和后续扩展奠定了坚实基础。
|