args[0] ?? 'user_id'; $itemIdKey = $this->args[1] ?? 'itemId'; $numKey = $this->args[2] ?? 'num'; $priceKey = $this->args[3] ?? 'price'; $currencyTypeKey = $this->args[4] ?? 'currency_type'; // 新增币种字段 $userId = $data[$userIdKey] ?? null; $itemId = $data[$itemIdKey] ?? null; $quantity = $data[$numKey] ?? null; $price = $data[$priceKey] ?? null; $currencyTypeValue = $data[$currencyTypeKey] ?? null; if (!$userId || !$itemId || !$quantity || !$price) { $this->addError('订单参数不完整'); return false; } // 解析币种类型 $currencyType = null; if ($currencyTypeValue !== null) { $currencyType = FUND_CURRENCY_TYPE::tryFrom($currencyTypeValue); } // 如果没有指定币种或币种无效,使用默认币种(钻石) $currencyType = $currencyType ?? FundLogic::getDefaultCurrency(); try { if ($direction === MEX_DIRECTION::SELL) { return $this->validateSellOrder($userId, $itemId, $quantity, $price); } elseif ($direction === MEX_DIRECTION::BUY) { return $this->validateBuyOrder($userId, $itemId, $quantity, $price, $currencyType); } else { $this->addError('无效的交易方向'); return false; } } catch (\Exception $e) { Log::error('农贸市场订单验证失败', [ 'user_id' => $userId, 'item_id' => $itemId, 'quantity' => $quantity, 'price' => $price, 'direction' => $direction, 'currency_type' => $currencyType?->value, 'error' => $e->getMessage() ]); $this->addError('订单验证时发生错误'); return false; } } /** * 验证卖出订单 * * @param int $userId 用户ID * @param int $itemId 物品ID * @param int $quantity 数量 * @param float $price 价格 * @return bool */ private function validateSellOrder(int $userId, int $itemId, int $quantity, float $price): bool { // 验证用户是否拥有足够的物品 if (!$this->validateUserItemQuantity($userId, $itemId, $quantity)) { return false; } return true; } /** * 验证买入订单 * * @param int $userId 用户ID * @param int $itemId 物品ID * @param int $quantity 数量 * @param float $price 价格 * @param FUND_CURRENCY_TYPE|null $currencyType 币种类型,默认使用钻石 * @return bool */ private function validateBuyOrder(int $userId, int $itemId, int $quantity, float $price, ?FUND_CURRENCY_TYPE $currencyType = null): bool { // 计算所需资金 $totalCost = $quantity * $price; // 验证用户是否有足够的资金(使用指定币种) if (!$this->validateUserFundBalance($userId, $totalCost, $currencyType)) { return false; } return true; } /** * 验证用户物品数量(检查可用数量,排除已冻结的物品) * * @param int $userId 用户ID * @param int $itemId 物品ID * @param int $requiredQuantity 需要的数量 * @return bool */ private function validateUserItemQuantity(int $userId, int $itemId, int $requiredQuantity): bool { // 使用ItemService获取可用数量(排除已冻结的物品) $availableQuantity = \App\Module\GameItems\Services\ItemService::getAvailableQuantity($userId, $itemId); if ($availableQuantity < $requiredQuantity) { $this->addError("可用物品数量不足,当前可用 {$availableQuantity} 个,需要 {$requiredQuantity} 个"); return false; } return true; } /** * 验证用户资金余额 * 使用Fund模块的验证器进行数额验证,信任Fund模块的数据处理 * * @param int $userId 用户ID * @param float $requiredAmount 需要的金额 * @param FUND_CURRENCY_TYPE|null $currencyType 币种类型,默认使用钻石 * @return bool */ private function validateUserFundBalance(int $userId, float $requiredAmount, ?FUND_CURRENCY_TYPE $currencyType = null): bool { // 获取币种类型,默认使用钻石 $currencyType = $currencyType ?? FundLogic::getDefaultCurrency(); // 获取对应的可用账户类型 $availableAccountType = FundLogic::getAvailableAccountType($currencyType); if (!$availableAccountType) { $this->addError('不支持的币种类型'); return false; } // 使用Fund模块的FundService进行资金验证,信任Fund模块的数据处理 $fundService = new FundService($userId, $availableAccountType->value); $balance = $fundService->balance(); // 直接比较,不进行精度转换,信任Fund模块的数据处理 if ($balance < $requiredAmount) { $this->addError("资金不足,当前{$currencyType->getCurrencyName()}余额 {$balance},需要 {$requiredAmount}"); return false; } return true; } }