notfff 7 months ago
parent
commit
6ab407b5eb

+ 0 - 12
app/PlugIn/Uraus/readme.md

@@ -1,12 +0,0 @@
-# ueaus
-
-1. 获取用户信息 ,用户 ID,昵称 
-2. 获取用户上级关系链表 ,各个等级的用户id
-3. 获取下级人数;参数 直推/团队(3代) ;返回: 人数
-
-
-## webhook (得有重试机制)
-1. 注册通知,传入: uid, 三级 上级;返回: 处理成功
-2. 出包, 参:用户ID,usdt数量 ;返回: 成功/失败 
-3. 入包, 参数:用户ID,usdt数量 ;返回: 成功/失败 
-4. 入包检查,参数:用户ID,usdt数量 ;返回: 是否允许,钻石余额 ,本金总数,手续费总数,所需总数

+ 439 - 0
app/PlugIn/Urs/Api.md

@@ -0,0 +1,439 @@
+# Ecology 模块 API 文档
+
+## 概述
+
+Ecology 模块提供生态系统相关的 API 接口,支持用户信息查询、团队关系管理和下级统计等功能。所有接口都采用 AES-256-CBC 加密算法保证数据传输安全。
+
+## 基础信息
+
+- **模块路径**: `app/Module/Ecology`
+- **API 基础路径**: `/api/ecology`
+- **路由前缀**: `ecology`
+- **加密算法**: AES-256-CBC
+- **签名算法**: SHA256
+- **数据有效期**: 300秒(5分钟)
+
+## 路由列表
+
+### 1. 测试接口
+
+#### 1.1 测试加密接口
+- **路径**: `GET /api/ecology/test-encrypt`
+- **控制器**: `TestController@testEncrypt`
+- **中间件**: 无
+- **描述**: 测试数据加密功能
+
+#### 1.2 测试解密接口
+- **路径**: `POST /api/ecology/{ecology_id}/test-decrypt`
+- **控制器**: `TestController@testDecrypt`
+- **中间件**: `EncryptionMiddleware`
+- **描述**: 测试数据解密功能(用于调试)
+
+### 2. 业务接口
+
+#### 2.1 获取用户信息
+- **路径**: `POST /api/ecology/{ecology_id}/userInfo`
+- **控制器**: `EcologyController@getUserInfo`
+- **中间件**: `EncryptionMiddleware`
+- **描述**: 根据用户密钥获取用户ID
+
+#### 2.2 获取用户团队关系
+- **路径**: `POST /api/ecology/{ecology_id}/userTeam`
+- **控制器**: `EcologyController@getUserTeam`
+- **中间件**: `EncryptionMiddleware`
+- **描述**: 获取用户的3级上级关系链
+
+#### 2.3 获取用户下级统计
+- **路径**: `POST /api/ecology/{ecology_id}/userLevelCount`
+- **控制器**: `EcologyController@getLevelCount`
+- **中间件**: `EncryptionMiddleware`
+- **描述**: 获取用户下级人数统计(支持1级和3级)
+
+## 加密机制
+
+### 加密算法
+- **算法**: AES-256-CBC
+- **密钥来源**: `ecology_config` 表的 `app_key` 字段
+- **IV向量**: 随机生成16字节,每次请求不同
+- **签名**: SHA256(data + iv + timestamp + app_key)
+
+### 请求格式
+```json
+{
+    "data": "加密后的请求数据(Base64编码)",
+    "iv": "IV向量(Base64编码)",
+    "timestamp": 1234567890,
+    "sign": "数据签名(SHA256)"
+}
+```
+
+### 响应格式
+```json
+{
+    "data": "加密后的响应数据(Base64编码)",
+    "iv": "IV向量(Base64编码)",
+    "timestamp": 1234567890,
+    "sign": "数据签名(SHA256)"
+}
+```
+
+### 加密流程
+1. 获取生态配置中的 `app_key`
+2. 生成随机IV向量(16字节)
+3. 使用AES-256-CBC加密原始JSON数据
+4. 对加密结果进行Base64编码
+5. 生成签名:`SHA256(data + iv + timestamp + app_key)`
+6. 组装最终请求数据
+
+### 解密流程
+1. 验证时间戳有效性(默认5分钟有效期)
+2. 验证签名:`SHA256(data + iv + timestamp + app_key) == sign`
+3. 使用IV和app_key解密数据
+4. 解析解密后的JSON数据
+
+## API 接口详情
+
+### 1. 测试加密接口
+
+**接口地址**: `GET /api/ecology/test-encrypt`
+
+**请求参数**:
+- 支持任意GET参数,用于测试加密功能
+- 示例:`userId=10002&level=1`
+
+**响应示例**:
+```json
+{
+    "data": "eyJzdGF0dXMiOiJzdWNjZXNzIn0=",
+    "iv": "MTIzNDU2Nzg5MGFiY2RlZg==",
+    "timestamp": 1234567890,
+    "sign": "a1b2c3d4e5f6..."
+}
+```
+
+**错误响应**:
+```json
+{
+    "error": "加密失败: 错误信息"
+}
+```
+
+### 2. 测试解密接口
+
+**接口地址**: `POST /api/ecology/{ecology_id}/test-decrypt`
+
+**路径参数**:
+- `ecology_id`: 生态ID(整数)
+
+**请求参数**:
+- 加密的请求数据(通过中间件自动解密)
+
+**响应**:
+- 直接输出解密后的数据(用于调试)
+
+### 3. 获取用户信息接口
+
+**接口地址**: `POST /api/ecology/{ecology_id}/userInfo`
+
+**路径参数**:
+- `ecology_id`: 生态ID(整数)
+
+**请求参数**(解密后):
+```json
+{
+    "userKey": "用户密钥(字符串,必填)"
+}
+```
+
+**成功响应**:
+```json
+{
+    "userId": 12345
+}
+```
+
+**错误响应**:
+```json
+{
+    "code": 400,
+    "message": "参数错误",
+    "errors": {
+        "userKey": ["userKey字段是必填的"]
+    }
+}
+```
+
+### 4. 获取用户团队关系接口
+
+**接口地址**: `POST /api/ecology/{ecology_id}/userTeam`
+
+**路径参数**:
+- `ecology_id`: 生态ID(整数)
+
+**请求参数**(解密后):
+```json
+{
+    "userId": 12345
+}
+```
+
+**成功响应**:
+```json
+{
+    "team": {
+        "1": 10001,
+        "2": 10002,
+        "3": 10003
+    }
+}
+```
+
+**响应说明**:
+- `team` 对象的键表示级别(1、2、3级上级)
+- 值为对应级别的上级用户ID
+- 如果某级别没有上级,值为 `null`
+
+**错误响应**:
+```json
+{
+    "code": 400,
+    "message": "参数错误",
+    "errors": {
+        "userId": ["userId字段是必填的"]
+    }
+}
+```
+
+### 5. 获取用户下级统计接口
+
+**接口地址**: `POST /api/ecology/{ecology_id}/userLevelCount`
+
+**路径参数**:
+- `ecology_id`: 生态ID(整数)
+
+**请求参数**(解密后):
+```json
+{
+    "userId": 12345,
+    "level": 1
+}
+```
+
+**参数说明**:
+- `userId`: 用户ID(整数,必填)
+- `level`: 统计级别(整数,必填,只能是1或3)
+
+**成功响应**:
+```json
+{
+    "level": 1,
+    "count": 25
+}
+```
+
+**响应说明**:
+- `level`: 请求的统计级别
+- `count`: 对应级别的下级人数
+
+**错误响应**:
+```json
+{
+    "code": 400,
+    "message": "参数错误:level只能是1或3",
+    "errors": {
+        "level": ["level字段必须是1或3"]
+    }
+}
+```
+
+## 服务类说明
+
+### EcologyService 服务类
+
+#### 主要方法
+
+##### 1. getEcologyLink($userId, $ecologyId)
+- **功能**: 生成生态链接
+- **参数**:
+    - `$userId`: 用户ID
+    - `$ecologyId`: 生态ID
+- **返回**: 生态链接字符串
+- **异常**: 当生态配置不存在时抛出异常
+
+##### 2. getUserInfo($userKey)
+- **功能**: 根据用户密钥获取用户ID
+- **参数**: `$userKey` - 用户密钥
+- **返回**: 用户ID
+
+##### 3. getUserTeam($userId)
+- **功能**: 获取用户上级关系链(3级)
+- **参数**: `$userId` - 用户ID
+- **返回**: 数组,包含1、2、3级上级用户ID
+
+##### 4. getLevelCount($userId, $level)
+- **功能**: 获取用户下级人数统计
+- **参数**:
+    - `$userId`: 用户ID
+    - `$level`: 统计级别
+- **返回**: 下级人数
+
+##### 5. getEcologyList($userId)
+- **功能**: 获取用户的生态列表及地址
+- **参数**: `$userId` - 用户ID
+- **返回**: 生态列表数组
+
+##### 6. getCoinType($ecologyId)
+- **功能**: 获取生态交互币种
+- **参数**: `$ecologyId` - 生态ID
+- **返回**: 币种类型
+
+##### 7. callExternalService($url, $params, $method, $appKey)
+- **功能**: 调用外部生态服务
+- **参数**:
+    - `$url`: 服务地址
+    - `$params`: 请求参数
+    - `$method`: 请求方法(GET/POST)
+    - `$appKey`: 应用密钥
+- **返回**: 解密后的响应数据
+
+### CryptoService 加密服务类
+
+#### 主要方法
+
+##### 1. __construct($key, $timeout = 300)
+- **功能**: 构造函数
+- **参数**:
+    - `$key`: 加密密钥
+    - `$timeout`: 数据有效期(秒,默认300秒)
+
+##### 2. encrypt($data)
+- **功能**: 加密数据
+- **参数**: `$data` - 要加密的数据数组
+- **返回**: 包含加密数据和元信息的数组
+- **异常**: 加密失败时抛出 RuntimeException
+
+##### 3. decrypt($encryptedData)
+- **功能**: 解密数据
+- **参数**: `$encryptedData` - 加密数据数组
+- **返回**: 解密后的原始数据
+- **异常**: 数据过期、签名验证失败或解密失败时抛出异常
+
+##### 4. setKey($key)
+- **功能**: 设置加密密钥
+- **参数**: `$key` - 新的加密密钥
+
+##### 5. encryptResponse($response)
+- **功能**: 加密响应数据
+- **参数**: `$response` - 响应对象
+- **返回**: 包含加密数据的JSON响应
+
+## 中间件说明
+
+### EncryptionMiddleware 加密中间件
+
+#### 功能
+- 自动解密POST请求数据
+- 自动加密成功的JSON响应
+- 验证请求签名和时间戳
+- 缓存生态密钥配置
+
+#### 处理流程
+1. 从路由参数获取 `ecology_id`
+2. 从缓存或数据库获取对应的 `app_key`
+3. 设置加密服务的密钥
+4. 解密POST请求数据并存入 `decrypted` 字段
+5. 执行后续请求处理
+6. 对成功的JSON响应进行加密
+
+#### 错误处理
+- 密钥未配置:返回 RuntimeException
+- 解密失败:返回相应错误信息
+- 签名验证失败:返回401状态码
+
+## 数据模型
+
+### EcologyConfig 生态配置模型
+
+**表名**: `ecology_config`
+
+**主要字段**(基于代码推断):
+- `id`: 主键ID
+- `name`: 生态名称
+- `link`: 生态链接
+- `address_prefix`: 地址前缀
+- `app_key`: 应用密钥
+- `coin_type`: 交互币种
+
+### EcologyUser 生态用户模型
+
+**表名**: `ecology_user`
+
+**主要字段**(基于代码推断):
+- `id`: 主键ID
+- `ecology_id`: 生态ID
+- `user_id`: 用户ID
+- `user_key`: 用户密钥
+- `created_at`: 创建时间
+- `updated_at`: 更新时间
+- `deleted_at`: 删除时间(软删除)
+
+## 错误码规范
+
+| 错误码 | 说明 |
+|-------|------|
+| 200   | 请求成功 |
+| 400   | 请求参数错误 |
+| 401   | 签名验证失败 |
+| 403   | 无权限访问 |
+| 408   | 请求超时 |
+| 500   | 服务器内部错误 |
+
+## 使用注意事项
+
+1. **密钥配置**: 确保 `ecology_config` 表中配置了正确的 `app_key`
+2. **时间同步**: 客户端和服务端时间差不能超过5分钟
+3. **签名验证**: 每个加密请求必须包含正确的签名
+4. **数据格式**: 所有加密数据都使用Base64编码
+5. **缓存机制**: 生态密钥会被缓存1小时,提高性能
+6. **安全性**: 生产环境应定期轮换密钥
+7. **日志记录**: 建议记录加密失败日志用于排查问题
+
+## 开发调试
+
+### 测试加密功能
+```bash
+# 测试加密接口
+curl -X GET "http://your-domain/api/ecology/test-encrypt?userId=10002&level=1"
+```
+
+### 测试解密功能
+```bash
+# 需要先通过加密接口获取加密数据,然后发送到解密接口
+curl -X POST "http://your-domain/api/ecology/1/test-decrypt" \
+  -H "Content-Type: application/json" \
+  -d '{"data":"...","iv":"...","timestamp":...,"sign":"..."}'
+```
+
+### 完整的业务接口调用示例
+```bash
+# 获取用户信息
+curl -X POST "http://your-domain/api/ecology/1/userInfo" \
+  -H "Content-Type: application/json" \
+  -d '{"data":"...","iv":"...","timestamp":...,"sign":"..."}'
+
+# 获取用户团队关系
+curl -X POST "http://your-domain/api/ecology/1/userTeam" \
+  -H "Content-Type: application/json" \
+  -d '{"data":"...","iv":"...","timestamp":...,"sign":"..."}'
+
+# 获取用户下级统计
+curl -X POST "http://your-domain/api/ecology/1/userLevelCount" \
+  -H "Content-Type: application/json" \
+  -d '{"data":"...","iv":"...","timestamp":...,"sign":"..."}'
+```
+
+---
+
+**文档版本**: v1.0
+**最后更新**: 2025-06-14
+**维护者**: Ecology 模块开发团队

+ 104 - 0
app/PlugIn/Urs/CryptoService.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace App\PlugIn\Uraus;
+
+use UCore\Exception\LogicException;
+
+class CryptoService
+{
+
+    private string $key;
+    private int    $timeout;
+    
+
+    public function __construct(string $key, int $timeout = 300)
+    {
+        $this->key     = $key;
+        $this->timeout = $timeout;
+    }
+
+
+    /**
+     * 加密
+     * @param array $data
+     * @return array
+     * @throws LogicException
+     * @throws \Random\RandomException
+     */
+    public function encrypt(array $data): array
+    {
+        $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 LogicException('加密失败: ' . 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)
+        ];
+    }
+
+    /**
+     * 解密
+     *
+     * @param array $encryptedData
+     * @return array
+     * @throws LogicException
+     */
+    public function decrypt(array $encryptedData): array
+    {
+        // 验证时间戳
+        if (abs(time() - $encryptedData['timestamp']) > $this->timeout) {
+            throw new LogicException('请求已过期');
+        }
+
+        // 验证签名
+        $sign = hash('sha256',
+                     $encryptedData['data'] .
+                     $encryptedData['iv'] .
+                     $encryptedData['timestamp'] .
+                     $this->key
+        );
+
+        if (!hash_equals($sign, $encryptedData['sign'])) {
+            throw new LogicException('签名验证失败');
+        }
+
+        // 解密数据
+        $decrypted = openssl_decrypt(
+            base64_decode($encryptedData['data']),
+            'AES-256-CBC',
+            $this->key,
+            OPENSSL_RAW_DATA,
+            base64_decode($encryptedData['iv'])
+        );
+
+        if ($decrypted === false) {
+            throw new LogicException('解密失败: ' . openssl_error_string());
+        }
+
+        $data = json_decode($decrypted, true);
+        if (json_last_error() !== JSON_ERROR_NONE) {
+            throw new LogicException('JSON解析失败: ' . json_last_error_msg());
+        }
+
+        return $data;
+    }
+
+}

+ 34 - 0
app/PlugIn/Urs/readme.md

@@ -0,0 +1,34 @@
+# urs
+
+## Api 参考 ./Api.md
+1. 获取用户信息 ,用户 ID,昵称 
+2. 获取用户上级关系链表 ,各个等级的用户id
+3. 获取下级人数;参数 直推/团队(3代) ;返回: 人数
+
+
+## webhook (得有重试机制)
+1. 注册通知,传入: uid, 三级 上级;返回: 处理成功
+    - 目前仅返回成功,不做实际处理
+2. 出包, 参:用户ID,usdt数量,交易ID ;返回: 成功/失败 
+    - 充值钻石,根据比例1:300进行钻石充值,异步操作,根据交易ID防止重复
+3. 入包, 参数:用户ID,usdt数量,交易ID ;返回: 成功/失败 
+    - 充值钻石,根据比例1:300进行钻石充值,异步操作,根据交易ID防止重复
+4. 入包检查,参数:用户ID,usdt数量 ;返回: 是否允许,钻石余额 ,本金总数,手续费总数,所需总数
+
+## 
+
+核心流程
+
+1. urs应用 ,访问农场客户端 携带  ukey
+2. 农场 使用 ukey 到 urs获取到用户的 urs.user_id  ,urs.user——id 称为 urs_uid
+    - 为urs用户创建农场用户,建立关联 (创建 urs_user表)
+3. 农场获取到urs的推广关系,同步到 UrsPromotion 模块
+4. 根据webhook进行钻石的充值和提取
+
+> 设计资金系统操作,需要创建专属 充值资金操作用户ID,充值的资金如钻石从 这个专属用户账户 转移到 用户账户; 提取钻石 专属操作用户ID,提取钻石 从用户账户 转移到 这个专属用户账户
+
+
+## urs 服务
+Api通讯 Key Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y
+
+用户Key (测试用,实际通过客户端传递) ukey : $2y$10$i.h97m13olfIaU.ZTYiyeeXFl8xqn48w2bFiAhcoQsJdU6K3w.Lgu

+ 819 - 0
app/PlugIn/Urs/urs对接文档.md

@@ -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模块提供的企业级服务管理能力,为系统的稳定运行和后续扩展奠定了坚实基础。

+ 1 - 1
app/PlugIn/readme.md

@@ -1,4 +1,4 @@
 # Plug 插件(外部模块,第三方相关)
 
 
-> Uraus
+> Urs