Forráskód Böngészése

修复request-log日志记录功能

- 为RequestLogger添加setJsonResponse方法支持JSON响应记录
- 修复WebhookDispatchController中response数据未记录的问题
- 优化post数据记录:JSON请求直接记录JSON格式,表单请求转换为JSON格式
- 解决webhook/urs/check等接口返回数据未记录的问题
- 测试验证:成功记录完整的请求和响应数据
AI Assistant 6 hónapja
szülő
commit
19529c4e15

+ 164 - 0
AiWork/202506/190034-URS推广模块转出手续费配置功能.md

@@ -0,0 +1,164 @@
+# URS推广模块转出手续费配置功能
+
+## 任务概述
+为URS推广模块创建一个转出手续费的配置,监听 FeeCalculatingEvent 来修改手续费,能根据农场房屋等级/达人等级来区分不同的手续费费率,并创建后台管理界面。
+
+## 完成时间
+2025-06-18 16:21:27 - 2025-06-19 00:34:00
+
+## 实现功能
+
+### 1. 数据库设计
+- 创建 `kku_urs_promotion_transfer_fee_configs` 表
+- 支持房屋等级、达人等级、手续费率、优先级等字段
+- 插入12条默认配置数据,覆盖各种等级组合
+
+### 2. 模型层
+- `UrsTransferFeeConfig` 模型:继承自 ModelCore
+- 支持状态管理、匹配条件检查等方法
+- 实现访问器用于显示格式化数据
+
+### 3. 服务层架构
+- `UrsTransferFeeService`:对外服务接口
+- `UrsTransferFeeLogic`:内部业务逻辑
+- `UrsTransferFeeConfigDto`:数据传输对象
+- `UrsTransferFeeConfigRepository`:后台数据访问
+
+### 4. 事件监听
+- `UrsTransferFeeListener`:监听 Transfer 模块的 FeeCalculatingEvent
+- 根据用户房屋等级和达人等级自动应用最优手续费率
+- 支持事件修改和日志记录
+
+### 5. 手续费计算算法
+- 优先级匹配:精确匹配 > 通配符匹配
+- 评分机制:房屋等级匹配(100分) + 达人等级匹配(100分) + 优先级分数
+- 缓存机制:1小时缓存用户手续费率
+
+### 6. 后台管理界面
+- 列表页面:显示所有配置,支持排序和筛选
+- 新增页面:支持房屋等级、达人等级、手续费率等配置
+- 详情页面:显示完整配置信息和匹配条件
+- 编辑页面:支持修改现有配置
+
+### 7. 测试功能
+- `TestUrsTransferFeeCommand`:完整功能测试命令
+- 测试用户手续费率计算
+- 测试不同等级组合的费率
+- 测试事件监听器功能
+- 测试配置管理功能
+
+## 配置规则
+
+### 手续费率配置
+1. **默认费率**:5%(所有用户)
+2. **房屋等级优惠**:
+   - 7级:4%
+   - 10级:3%
+   - 12级:2%
+3. **达人等级优惠**:
+   - 初级达人:4.5%
+   - 中级达人:4%
+   - 高级达人:3.5%
+   - 资深达人:3%
+   - 顶级达人:2%
+4. **组合优惠**:
+   - 房屋10级+高级达人:2.5%
+   - 房屋12级+资深达人:1.5%
+   - 房屋12级+顶级达人:1%
+
+### 优先级规则
+- 数值越大优先级越高
+- 精确匹配优于通配符匹配
+- 组合条件优于单一条件
+
+## 技术特点
+
+### 1. 架构设计
+- 遵循项目规范:Model-Logic-Service-DTO 分层架构
+- 事件驱动:通过监听器实现模块间解耦
+- 缓存优化:提升性能,减少数据库查询
+
+### 2. 扩展性
+- 支持任意房屋等级和达人等级组合
+- 支持动态优先级调整
+- 支持配置的启用/禁用状态管理
+
+### 3. 用户体验
+- 自动应用最优手续费率
+- 透明的优惠计算过程
+- 完整的后台管理界面
+
+## 测试结果
+
+### 功能测试
+- ✅ 用户手续费率计算正常
+- ✅ 不同等级组合费率正确
+- ✅ 事件监听器正常工作
+- ✅ 配置管理功能完整
+- ✅ 后台界面正常显示
+
+### 性能测试
+- ✅ 缓存机制有效
+- ✅ 数据库查询优化
+- ✅ 匹配算法高效
+
+## 文件清单
+
+### 核心文件
+- `app/Module/UrsPromotion/Models/UrsTransferFeeConfig.php`
+- `app/Module/UrsPromotion/Services/UrsTransferFeeService.php`
+- `app/Module/UrsPromotion/Logics/UrsTransferFeeLogic.php`
+- `app/Module/UrsPromotion/Listeners/UrsTransferFeeListener.php`
+
+### 后台管理
+- `app/Module/UrsPromotion/AdminControllers/UrsTransferFeeConfigController.php`
+- `app/Module/UrsPromotion/Repositories/UrsTransferFeeConfigRepository.php`
+
+### 数据传输
+- `app/Module/UrsPromotion/Dtos/UrsTransferFeeConfigDto.php`
+
+### 数据库
+- `app/Module/UrsPromotion/Databases/GenerateSql/urs_promotion_transfer_fee_configs.sql`
+
+### 测试工具
+- `app/Module/UrsPromotion/Commands/TestUrsTransferFeeCommand.php`
+- `app/Module/UrsPromotion/Commands/InsertUrsTransferFeeAdminMenuCommand.php`
+
+## 使用说明
+
+### 测试命令
+```bash
+# 测试功能
+php artisan urs:test-transfer-fee --user-id=1
+
+# 清除缓存并测试
+php artisan urs:test-transfer-fee --user-id=1 --clear-cache
+
+# 创建后台菜单
+php artisan urs:insert-transfer-fee-admin-menu
+```
+
+### 后台管理
+访问:`/admin/urs-promotion/transfer-fee-config`
+
+### API 使用
+```php
+// 获取用户最优手续费率
+$feeRate = UrsTransferFeeService::getBestFeeRateForUser($userId);
+
+// 获取用户手续费优惠信息
+$feeInfo = UrsTransferFeeService::getUserFeeInfo($userId);
+
+// 清除缓存
+UrsTransferFeeService::clearUserFeeRateCache($userId);
+```
+
+## 总结
+成功实现了完整的URS推广模块转出手续费配置功能,包括:
+- 灵活的配置管理系统
+- 智能的费率匹配算法
+- 完整的后台管理界面
+- 高效的缓存机制
+- 全面的测试覆盖
+
+该功能能够根据用户的房屋等级和达人等级自动应用最优的手续费率,为用户提供差异化的优惠服务,提升用户体验和平台竞争力。

+ 26 - 1
app/Module/System/Services/RequestLogger.php

@@ -33,7 +33,21 @@ class RequestLogger
         $this->requestLog->headers      = json_encode($httpRequest->headers->all());
         $this->requestLog->ipaddress    = $httpRequest->ip();
         $this->requestLog->host         = $httpRequest->getHost();
-        $this->requestLog->post         = base64_encode($httpRequest->getContent());
+        // 根据Content-Type决定如何记录post数据
+        $contentType = $httpRequest->header('Content-Type', '');
+        $rawContent = $httpRequest->getContent();
+
+        if (str_contains($contentType, 'application/json') && !empty($rawContent)) {
+            // JSON请求直接记录JSON格式
+            $this->requestLog->post = $rawContent;
+        } elseif (str_contains($contentType, 'application/x-www-form-urlencoded') && !empty($rawContent)) {
+            // 表单请求解码后记录为JSON格式
+            parse_str($rawContent, $formData);
+            $this->requestLog->post = json_encode($formData);
+        } else {
+            // 其他类型使用base64编码
+            $this->requestLog->post = base64_encode($rawContent);
+        }
         $this->requestLog->sale_date    = strtotime(date('Y-m-d'));
 
         $this->requestLog->save();
@@ -53,6 +67,17 @@ class RequestLogger
         $this->response = $response;
     }
 
+    /**
+     * 设置JSON响应数据
+     *
+     * @param string $jsonResponse JSON格式的响应数据
+     * @return void
+     */
+    public function setJsonResponse(string $jsonResponse)
+    {
+        $this->requestLog->response = $jsonResponse;
+    }
+
     public function setError(string $error)
     {
         $this->requestLog->error = $error;

+ 16 - 4
app/Module/ThirdParty/Controllers/WebhookDispatchController.php

@@ -75,11 +75,17 @@ class WebhookDispatchController extends Controller
             // 记录运行时间
             $requestLogger->setRunTime($startTime);
 
-            return response()->json([
+            // 构建响应数据
+            $responseData = [
                 'success' => $result['success'],
                 'data' => $result['data']??[],
                 'request_id' => $requestId,
-            ]);
+            ];
+
+            // 记录JSON响应
+            $requestLogger->setJsonResponse(json_encode($responseData));
+
+            return response()->json($responseData);
 
         } catch (\Exception $e) {
             Log::error("Webhook分发失败", [
@@ -94,11 +100,17 @@ class WebhookDispatchController extends Controller
             $requestLogger->setError($e->getMessage());
             $requestLogger->setRunTime($startTime);
 
-            return response()->json([
+            // 构建错误响应数据
+            $errorResponseData = [
                 'success' => false,
                 'error' => $e->getMessage(),
                 'request_id' => $requestId,
-            ], 400);
+            ];
+
+            // 记录JSON响应
+            $requestLogger->setJsonResponse(json_encode($errorResponseData));
+
+            return response()->json($errorResponseData, 400);
         }
     }