first(); if (!$config) { return null; } return [ 'item_id' => $config->item_id, 'min_price' => $config->min_price, 'max_price' => $config->max_price, 'protection_threshold' => $config->protection_threshold, 'is_enabled' => $config->is_enabled, 'price_range' => $config->min_price . ' - ' . $config->max_price, 'price_range_width' => bcsub($config->max_price, $config->min_price, 5), 'created_at' => $config->created_at, 'updated_at' => $config->updated_at, ]; }); } /** * 获取多个商品的价格配置 * * @param array $itemIds 商品ID数组 * @return array 价格配置列表 */ public static function getItemsPriceConfig(array $itemIds): array { $result = []; foreach ($itemIds as $itemId) { $config = self::getItemPriceConfig($itemId); if ($config) { $result[$itemId] = $config; } } return $result; } /** * 验证卖出价格 * * @param int $itemId 商品ID * @param string $price 价格 * @return array 验证结果 */ public static function validateSellPrice(int $itemId, string $price): array { $config = self::getItemPriceConfig($itemId); if (!$config) { return [ 'valid' => false, 'message' => '商品未配置价格信息', 'error_code' => 'CONFIG_NOT_FOUND' ]; } if (!$config['is_enabled']) { return [ 'valid' => false, 'message' => '商品价格配置已禁用', 'error_code' => 'CONFIG_DISABLED' ]; } // 卖出价格不能低于最低价 if (bccomp($price, $config['min_price'], 5) < 0) { return [ 'valid' => false, 'message' => "卖出价格不能低于最低价 {$config['min_price']}", 'error_code' => 'PRICE_TOO_LOW', 'min_price' => $config['min_price'] ]; } // 卖出价格不能高于最高价 if (bccomp($price, $config['max_price'], 5) > 0) { return [ 'valid' => false, 'message' => "卖出价格不能高于最高价 {$config['max_price']}", 'error_code' => 'PRICE_TOO_HIGH', 'max_price' => $config['max_price'] ]; } return [ 'valid' => true, 'message' => '价格验证通过', 'config' => $config ]; } /** * 验证买入价格 * * @param int $itemId 商品ID * @param string $price 价格 * @return array 验证结果 */ public static function validateBuyPrice(int $itemId, string $price): array { $config = self::getItemPriceConfig($itemId); if (!$config) { return [ 'valid' => false, 'message' => '商品未配置价格信息', 'error_code' => 'CONFIG_NOT_FOUND' ]; } if (!$config['is_enabled']) { return [ 'valid' => false, 'message' => '商品价格配置已禁用', 'error_code' => 'CONFIG_DISABLED' ]; } if (bccomp($price, $config['max_price'], 5) < 0) { return [ 'valid' => false, 'message' => "买入价格不能低于最高价 {$config['max_price']}", 'error_code' => 'PRICE_TOO_LOW', 'max_price' => $config['max_price'] ]; } return [ 'valid' => true, 'message' => '价格验证通过', 'config' => $config ]; } /** * 验证订单数量 * * @param int $itemId 商品ID * @param int $quantity 数量 * @return array 验证结果 */ public static function validateOrderQuantity(int $itemId, int $quantity): array { $config = self::getItemPriceConfig($itemId); if (!$config) { return [ 'valid' => false, 'message' => '商品未配置价格信息', 'error_code' => 'CONFIG_NOT_FOUND' ]; } if (!$config['is_enabled']) { return [ 'valid' => false, 'message' => '商品价格配置已禁用', 'error_code' => 'CONFIG_DISABLED' ]; } if ($quantity > $config['protection_threshold']) { return [ 'valid' => false, 'message' => "订单数量不能超过保护阈值 {$config['protection_threshold']}", 'error_code' => 'QUANTITY_OVER_THRESHOLD', 'protection_threshold' => $config['protection_threshold'] ]; } return [ 'valid' => true, 'message' => '数量验证通过', 'config' => $config ]; } /** * 获取所有启用的价格配置 * * @return array 价格配置列表 */ public static function getEnabledConfigs(): array { $cacheKey = self::CACHE_PREFIX . 'enabled_all'; return Cache::remember($cacheKey, self::CACHE_TTL, function () { $configs = MexPriceConfig::where('is_enabled', true) ->orderBy('item_id', 'asc') ->get(); $result = []; foreach ($configs as $config) { $result[] = [ 'item_id' => $config->item_id, 'min_price' => $config->min_price, 'max_price' => $config->max_price, 'protection_threshold' => $config->protection_threshold, 'price_range' => $config->min_price . ' - ' . $config->max_price, 'price_range_width' => bcsub($config->max_price, $config->min_price, 5), ]; } return $result; }); } /** * 清除价格配置缓存 * * @param int|null $itemId 商品ID,null表示清除所有 * @return bool 操作结果 */ public static function clearCache(?int $itemId = null): bool { if ($itemId) { $cacheKey = self::CACHE_PREFIX . $itemId; return Cache::forget($cacheKey); } // 清除所有相关缓存 Cache::forget(self::CACHE_PREFIX . 'enabled_all'); // 这里可以根据需要清除特定商品的缓存 // 由于无法直接获取所有缓存键,建议在配置更新时调用具体的清除方法 return true; } /** * 挂单阶段参数验证(不验证价格和保护阈值) * 根据文档要求:挂单阶段无价格验证,所有订单都可以挂单并冻结资金/物品 * * @param int $itemId 商品ID * @param string $price 价格(仅做基本格式验证) * @param int $quantity 数量(不验证保护阈值) * @param string $orderType 订单类型 (BUY/SELL) * @return array 验证结果 */ public static function validateOrderParamsForPlacement(int $itemId, string $price, int $quantity, string $orderType): array { // 注意:$orderType 参数保留用于接口一致性,挂单阶段不区分买卖类型的验证 // 只验证价格配置是否存在,不验证价格范围 $config = self::getItemPriceConfig($itemId); if (!$config) { return [ 'valid' => false, 'message' => '商品未配置价格信息', 'error_code' => 'CONFIG_NOT_FOUND' ]; } if (!$config['is_enabled']) { return [ 'valid' => false, 'message' => '商品价格配置已禁用', 'error_code' => 'CONFIG_DISABLED' ]; } // 基本的价格格式验证(确保是有效数字) if (!is_numeric($price) || bccomp($price, '0', 5) <= 0) { return [ 'valid' => false, 'message' => '价格必须是大于0的数字', 'error_code' => 'INVALID_PRICE_FORMAT' ]; } // 基本的数量验证(确保是正整数) if (!is_int($quantity) || $quantity <= 0) { return [ 'valid' => false, 'message' => '数量必须是大于0的整数', 'error_code' => 'INVALID_QUANTITY' ]; } return [ 'valid' => true, 'message' => '挂单参数验证通过', 'config' => $config ]; } /** * 撮合阶段价格和数量验证(用于撮合时的严格验证) * * @param int $itemId 商品ID * @param string $price 价格 * @param int $quantity 数量 * @param string $orderType 订单类型 (BUY/SELL) * @return array 验证结果 */ public static function validateOrderParamsForMatching(int $itemId, string $price, int $quantity, string $orderType): array { // 验证价格 if ($orderType === 'SELL') { $priceResult = self::validateSellPrice($itemId, $price); } else { $priceResult = self::validateBuyPrice($itemId, $price); } if (!$priceResult['valid']) { return $priceResult; } // 验证数量(只对买入订单验证保护阈值) if ($orderType === 'BUY') { $quantityResult = self::validateOrderQuantity($itemId, $quantity); if (!$quantityResult['valid']) { return $quantityResult; } } return [ 'valid' => true, 'message' => '撮合参数验证通过', 'config' => $priceResult['config'] ]; } /** * 批量验证价格和数量(已废弃,请使用validateOrderParamsForPlacement或validateOrderParamsForMatching) * * @deprecated 请根据使用场景选择validateOrderParamsForPlacement(挂单)或validateOrderParamsForMatching(撮合) * @param int $itemId 商品ID * @param string $price 价格 * @param int $quantity 数量 * @param string $orderType 订单类型 (BUY/SELL) * @return array 验证结果 */ public static function validateOrderParams(int $itemId, string $price, int $quantity, string $orderType): array { // 为了向后兼容,默认使用挂单验证 return self::validateOrderParamsForPlacement($itemId, $price, $quantity, $orderType); } /** * 获取商品价格建议 * * @param int $itemId 商品ID * @return array 价格建议 */ public static function getPriceSuggestion(int $itemId): array { $config = self::getItemPriceConfig($itemId); if (!$config) { return [ 'has_suggestion' => false, 'message' => '商品未配置价格信息' ]; } // 获取最新成交价格作为参考 $latestPrice = MexTransactionLogic::getLatestPrice($itemId); return [ 'has_suggestion' => true, 'min_price' => $config['min_price'], 'max_price' => $config['max_price'], 'latest_price' => $latestPrice, 'sell_suggestion' => $config['min_price'], 'buy_suggestion' => $config['max_price'], 'protection_threshold' => $config['protection_threshold'], ]; } }