false, 'message' => '不支持的币种类型']; } // 1. 验证用户是否有足够的物品 $checkResult = ItemService::checkItemQuantity($userId, $itemId, $quantity); if (!$checkResult->success) { DB::rollBack(); return ['success' => false, 'message' => $checkResult->message]; } // 2. 从用户扣除物品 $consumeResult = ItemService::consumeItem($userId, $itemId, null, $quantity, [ 'reason' => 'mex_sell', 'order_id' => $orderId, 'remark' => "农贸市场卖出物品,订单ID:{$orderId}" ]); if (!$consumeResult['success']) { DB::rollBack(); return ['success' => false, 'message' => '扣除用户物品失败:' . ($consumeResult['message'] ?? '未知错误')]; } // 3. 给仓库账户添加物品 $addResult = ItemService::addItem(self::WAREHOUSE_USER_ID, $itemId, $quantity, [ 'reason' => 'mex_warehouse_buy', 'source_type' => REWARD_SOURCE_TYPE::MEX_BUY, 'source_id' => $orderId, 'order_id' => $orderId, 'remark' => "农贸市场仓库收购物品,订单ID:{$orderId}" ]); if (!$addResult['success']) { DB::rollBack(); return ['success' => false, 'message' => '仓库添加物品失败:' . ($addResult['message'] ?? '未知错误')]; } // 4. 从仓库账户转出资金给用户 $warehouseFundService = new FundService(self::WAREHOUSE_USER_ID, $availableAccountType->value); $precision = $currencyType->getPrecision(); $fundAmount = (int)bcmul($totalAmount, bcpow('10', $precision), 0); // 根据币种精度转换 $transferResult = $warehouseFundService->trade( $userId, $fundAmount, 'mex_sell', $orderId, "农贸市场卖出收款,订单ID:{$orderId}" ); if (is_string($transferResult)) { DB::rollBack(); return ['success' => false, 'message' => '资金转移失败:' . $transferResult]; } // 5. 更新仓库统计 $warehouseResult = MexWarehouseLogic::addStock($itemId, $quantity, $totalAmount); if (!$warehouseResult) { DB::rollBack(); return ['success' => false, 'message' => '更新仓库统计失败']; } // 6. 创建成交记录 $transactionResult = MexTransactionLogic::createTransaction([ 'sell_order_id' => $orderId, 'buyer_id' => self::WAREHOUSE_USER_ID, 'seller_id' => $userId, 'item_id' => $itemId, 'currency_type' => $currencyType->value, 'quantity' => $quantity, 'price' => $price, 'total_amount' => $totalAmount, 'transaction_type' => TransactionType::USER_SELL, 'is_admin_operation' => false, ]); if (!$transactionResult) { DB::rollBack(); return ['success' => false, 'message' => '创建成交记录失败']; } DB::commit(); return [ 'success' => true, 'message' => '卖出订单处理成功', 'transaction_id' => $transactionResult->id, 'fund_transfer' => $transferResult, 'item_consume' => $consumeResult, 'warehouse_add' => $addResult ]; } catch (\Exception $e) { DB::rollBack(); Log::error('Mex卖出订单处理失败', [ 'user_id' => $userId, 'item_id' => $itemId, 'quantity' => $quantity, 'order_id' => $orderId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return ['success' => false, 'message' => '系统错误:' . $e->getMessage()]; } } /** * 处理用户买入订单的账户流转 * 用户买入:资金从用户转入仓库、物品从仓库转出到用户 * * @param int $userId 用户ID * @param int $itemId 商品ID * @param int $quantity 数量 * @param string $price 单价 * @param string $totalAmount 总金额 * @param int $orderId 订单ID * @param FUND_CURRENCY_TYPE|null $currencyType 币种类型,默认使用钻石 * @return array 操作结果 */ public static function processBuyOrder(int $userId, int $itemId, int $quantity, string $price, string $totalAmount, int $orderId, ?FUND_CURRENCY_TYPE $currencyType = null): array { try { DB::beginTransaction(); // 获取币种类型,默认使用钻石 $currencyType = $currencyType ?? FundLogic::getDefaultCurrency(); // 获取对应的账户类型 $availableAccountType = FundLogic::getAvailableAccountType($currencyType); if (!$availableAccountType) { DB::rollBack(); return ['success' => false, 'message' => '不支持的币种类型']; } // 1. 验证仓库是否有足够的物品 if (!MexWarehouseLogic::checkStockSufficient($itemId, $quantity)) { DB::rollBack(); return ['success' => false, 'message' => '仓库库存不足']; } // 2. 验证用户是否有足够的资金 $userFundService = new FundService($userId, $availableAccountType->value); $precision = $currencyType->getPrecision(); $fundAmount = (int)bcmul($totalAmount, bcpow('10', $precision), 0); // 根据币种精度转换 if ($userFundService->balance() < $fundAmount) { DB::rollBack(); return ['success' => false, 'message' => '用户资金不足']; } // 3. 从用户转出资金到仓库 $transferResult = $userFundService->trade( self::WAREHOUSE_USER_ID, $fundAmount, 'mex_buy', $orderId, "农贸市场买入付款,订单ID:{$orderId}" ); if (is_string($transferResult)) { DB::rollBack(); return ['success' => false, 'message' => '资金转移失败:' . $transferResult]; } // 4. 从仓库扣除物品 $consumeResult = ItemService::consumeItem(self::WAREHOUSE_USER_ID, $itemId, null, $quantity, [ 'reason' => 'mex_warehouse_sell', 'order_id' => $orderId, 'remark' => "农贸市场仓库出售物品,订单ID:{$orderId}" ]); if (!$consumeResult['success']) { DB::rollBack(); return ['success' => false, 'message' => '仓库扣除物品失败:' . ($consumeResult['message'] ?? '未知错误')]; } // 5. 给用户添加物品 $addResult = ItemService::addItem($userId, $itemId, $quantity, [ 'reason' => 'mex_buy', 'source_type' => REWARD_SOURCE_TYPE::MEX_BUY, 'source_id' => $orderId, 'order_id' => $orderId, 'remark' => "农贸市场买入物品,订单ID:{$orderId}" ]); if (!$addResult['success']) { DB::rollBack(); return ['success' => false, 'message' => '用户添加物品失败:' . ($addResult['message'] ?? '未知错误')]; } // 6. 更新仓库统计 $warehouseResult = MexWarehouseLogic::reduceStock($itemId, $quantity, $totalAmount); if (!$warehouseResult) { DB::rollBack(); return ['success' => false, 'message' => '更新仓库统计失败']; } // 7. 创建成交记录 $transactionResult = MexTransactionLogic::createTransaction([ 'buy_order_id' => $orderId, 'buyer_id' => $userId, 'seller_id' => self::WAREHOUSE_USER_ID, 'item_id' => $itemId, 'currency_type' => $currencyType->value, 'quantity' => $quantity, 'price' => $price, 'total_amount' => $totalAmount, 'transaction_type' => TransactionType::USER_BUY, 'is_admin_operation' => false, ]); if (!$transactionResult) { DB::rollBack(); return ['success' => false, 'message' => '创建成交记录失败']; } DB::commit(); return [ 'success' => true, 'message' => '买入订单处理成功', 'transaction_id' => $transactionResult->id, 'fund_transfer' => $transferResult, 'item_consume' => $consumeResult, 'user_add' => $addResult ]; } catch (\Exception $e) { DB::rollBack(); Log::error('Mex买入订单处理失败', [ 'user_id' => $userId, 'item_id' => $itemId, 'quantity' => $quantity, 'order_id' => $orderId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return ['success' => false, 'message' => '系统错误:' . $e->getMessage()]; } } /** * 检查仓库账户资金余额 * * @param FUND_CURRENCY_TYPE|null $currencyType 币种类型,默认使用钻石 * @return int 余额(按币种精度存储的整数) */ public static function getWarehouseFundBalance(?FUND_CURRENCY_TYPE $currencyType = null): int { $currencyType = $currencyType ?? FundLogic::getDefaultCurrency(); $availableAccountType = FundLogic::getAvailableAccountType($currencyType); if (!$availableAccountType) { return 0; } $warehouseFundService = new FundService(self::WAREHOUSE_USER_ID, $availableAccountType->value); return $warehouseFundService->balance(); } /** * 检查调控账户资金余额 * * @param FUND_CURRENCY_TYPE|null $currencyType 币种类型,默认使用钻石 * @return int 余额(按币种精度存储的整数) */ public static function getRegulationFundBalance(?FUND_CURRENCY_TYPE $currencyType = null): int { $currencyType = $currencyType ?? FundLogic::getDefaultCurrency(); $availableAccountType = FundLogic::getAvailableAccountType($currencyType); if (!$availableAccountType) { return 0; } $regulationFundService = new FundService(self::REGULATION_USER_ID, $availableAccountType->value); return $regulationFundService->balance(); } }