Răsfoiți Sursa

为CancelHandler添加Validation验证机制

- 创建MatchexchangeCancelValidation验证类,规范参数验证
- 创建MexOrderExistsValidator验证器,验证订单存在性和可操作性
- 重构CancelHandler使用Validation模式,与其他Handler保持一致
- 增强验证功能:订单ID验证、用户权限验证、订单状态验证

验证功能:
- 订单ID必须是大于0的整数
- 订单必须存在且属于当前用户
- 只能取消状态为PENDING的订单
- 提供具体的错误信息(如订单状态描述)

测试验证:
- 无效订单ID:返回参数验证错误
- 不存在订单:返回订单不存在错误
- 已取消订单:返回状态错误和具体描述
- 正常订单:成功取消
dongasai 6 luni în urmă
părinte
comite
1fc2f5d719

+ 15 - 15
app/Module/AppGame/Handler/Matchexchange/CancelHandler.php

@@ -3,6 +3,7 @@
 namespace App\Module\AppGame\Handler\Matchexchange;
 
 use App\Module\AppGame\Handler\BaseHandler;
+use App\Module\AppGame\Validations\MatchexchangeCancelValidation;
 use App\Module\Mex\Services\MexOrderService;
 use Google\Protobuf\Internal\Message;
 use Uraus\Kku\Request\RequestMatchexchangeCancel;
@@ -30,21 +31,20 @@ class CancelHandler extends BaseHandler
      */
     public function handle(Message $data): Message
     {
+        // 创建验证对象
+        $validation = MatchexchangeCancelValidation::makeByProrobufUser($data);
+
+        // 验证请求数据
+        $validation->validated();
+
+        // 获取验证后的安全数据
+        $orderId = $validation->getOrderId();
+        $userId = $validation->getUserId();
+
         // 创建响应对象
         $response = new ResponseMatchexchangeCancel();
 
         try {
-            // 获取请求参数
-            $orderId = $data->getId();
-            $userId = $this->user_id;
-
-            // 参数验证
-            if (!$orderId || $orderId <= 0) {
-                $this->response->setCode(RESPONSE_CODE::VALIDATE_ERROR);
-                $this->response->setMsg("订单ID无效");
-                return $response;
-            }
-
             // 调用服务取消订单
             $result = MexOrderService::cancelOrder($userId, $orderId);
 
@@ -65,8 +65,8 @@ class CancelHandler extends BaseHandler
         } catch (LogicException $e) {
             // 业务逻辑异常
             Log::warning('取消挂单业务异常', [
-                'user_id' => $this->user_id,
-                'order_id' => $orderId ?? 0,
+                'user_id' => $userId,
+                'order_id' => $orderId,
                 'error' => $e->getMessage()
             ]);
 
@@ -76,8 +76,8 @@ class CancelHandler extends BaseHandler
         } catch (\Exception $e) {
             // 系统异常
             Log::error('取消挂单系统异常', [
-                'user_id' => $this->user_id,
-                'order_id' => $orderId ?? 0,
+                'user_id' => $userId,
+                'order_id' => $orderId,
                 'error' => $e->getMessage(),
                 'trace' => $e->getTraceAsString()
             ]);

+ 86 - 0
app/Module/AppGame/Validations/MatchexchangeCancelValidation.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Module\AppGame\Validations;
+
+use App\Module\Mex\Validators\MexOrderExistsValidator;
+
+/**
+ * 农贸市场取消挂单验证类
+ *
+ * 用于验证取消挂单请求的参数,包括订单ID验证、订单所有权验证等
+ */
+class MatchexchangeCancelValidation extends ValidationBase
+{
+
+    /**
+     * 验证规则
+     *
+     * @param array $rules 自定义规则
+     * @return array
+     */
+    public function rules($rules = []): array
+    {
+        return [
+            // 基础参数验证
+            [
+                'user_id,id', 'required'
+            ],
+
+            [
+                'id', 'integer', 'min' => 1,
+                'msg' => '订单ID必须是大于0的整数'
+            ],
+
+            [
+                'user_id', 'integer', 'min' => 1,
+                'msg' => '用户ID必须是大于0的整数'
+            ],
+
+            // 验证订单是否存在且属于当前用户
+            [
+                'id', new MexOrderExistsValidator($this),
+                'msg' => '订单不存在或不属于当前用户'
+            ]
+        ];
+    }
+
+    /**
+     * 设置默认值
+     *
+     * @return array
+     */
+    public function default(): array
+    {
+        return [];
+    }
+
+    /**
+     * 数据预处理
+     *
+     * @return bool
+     */
+    public function beforeValidate(): bool
+    {
+        return true;
+    }
+
+    /**
+     * 获取订单ID
+     *
+     * @return int
+     */
+    public function getOrderId(): int
+    {
+        return $this->getSafe('id');
+    }
+
+    /**
+     * 获取用户ID
+     *
+     * @return int
+     */
+    public function getUserId(): int
+    {
+        return $this->getSafe('user_id');
+    }
+}

+ 87 - 0
app/Module/Mex/Validators/MexOrderExistsValidator.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace App\Module\Mex\Validators;
+
+use App\Module\Mex\Models\MexOrder;
+use App\Module\Mex\Enums\OrderStatus;
+use UCore\Validator;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * 农贸市场订单存在性验证器
+ *
+ * 验证订单是否存在、是否属于当前用户、是否可以取消等
+ */
+class MexOrderExistsValidator extends Validator
+{
+    /**
+     * 验证订单存在性和可操作性
+     *
+     * @param mixed $value 订单ID
+     * @param array $data 所有数据
+     * @return bool 验证是否通过
+     */
+    public function validate(mixed $value, array $data): bool
+    {
+        $orderId = (int)$value;
+        $userId = $data['user_id'] ?? null;
+
+        if (!$orderId || $orderId <= 0) {
+            $this->addError('订单ID无效');
+            return false;
+        }
+
+        if (!$userId || $userId <= 0) {
+            $this->addError('用户ID无效');
+            return false;
+        }
+
+        try {
+            // 查找订单
+            $order = MexOrder::where('id', $orderId)
+                ->where('user_id', $userId)
+                ->first();
+
+            if (!$order) {
+                $this->addError('订单不存在');
+                return false;
+            }
+
+            // 验证订单状态是否可以取消
+            if ($order->status !== OrderStatus::PENDING) {
+                $statusText = $this->getOrderStatusText($order->status);
+                $this->addError("只能取消等待中的订单,当前订单状态:{$statusText}");
+                return false;
+            }
+
+            return true;
+
+        } catch (\Exception $e) {
+            Log::error('农贸市场订单存在性验证失败', [
+                'order_id' => $orderId,
+                'user_id' => $userId,
+                'error' => $e->getMessage()
+            ]);
+
+            $this->addError('订单验证时发生错误');
+            return false;
+        }
+    }
+
+    /**
+     * 获取订单状态描述
+     *
+     * @param OrderStatus $status 订单状态
+     * @return string
+     */
+    private function getOrderStatusText(OrderStatus $status): string
+    {
+        return match ($status) {
+            OrderStatus::PENDING => '等待中',
+            OrderStatus::COMPLETED => '已完成',
+            OrderStatus::CANCELLED => '已取消',
+            OrderStatus::FAILED => '已失败',
+            default => '未知状态'
+        };
+    }
+}