|
|
@@ -21,6 +21,7 @@ use UCore\Helper\Logger;
|
|
|
*/
|
|
|
class MexOrderLogic
|
|
|
{
|
|
|
+
|
|
|
/**
|
|
|
* 创建卖出订单
|
|
|
*
|
|
|
@@ -42,30 +43,30 @@ class MexOrderLogic
|
|
|
// 验证价格配置是否存在(不验证价格范围,挂单阶段无价格验证)
|
|
|
$priceConfig = MexPriceConfig::where('item_id', $itemId)->where('is_enabled', true)->first();
|
|
|
if (!$priceConfig) {
|
|
|
- return ['success' => false, 'message' => '商品未配置价格信息'];
|
|
|
+ return [ 'success' => false, 'message' => '商品未配置价格信息' ];
|
|
|
}
|
|
|
|
|
|
// 直接计算总金额,信任Fund模块的精度处理
|
|
|
- $totalAmount = bcmul($price , $quantity,9);
|
|
|
+ $totalAmount = bcmul($price, $quantity, 9);
|
|
|
|
|
|
try {
|
|
|
// 1. 验证用户是否有足够的物品
|
|
|
$checkResult = ItemService::checkItemQuantity($userId, $itemId, $quantity);
|
|
|
if (!$checkResult->success) {
|
|
|
- return ['success' => false, 'message' => $checkResult->message];
|
|
|
+ return [ 'success' => false, 'message' => $checkResult->message ];
|
|
|
}
|
|
|
|
|
|
// 2. 创建订单记录
|
|
|
$order = MexOrder::create([
|
|
|
- 'user_id' => $userId,
|
|
|
- 'item_id' => $itemId,
|
|
|
- 'currency_type' => $currencyType->value,
|
|
|
- 'order_type' => OrderType::SELL,
|
|
|
- 'quantity' => $quantity,
|
|
|
- 'price' => $price,
|
|
|
- 'total_amount' => $totalAmount,
|
|
|
- 'status' => OrderStatus::PENDING,
|
|
|
- ]);
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'currency_type' => $currencyType->value,
|
|
|
+ 'order_type' => OrderType::SELL,
|
|
|
+ 'quantity' => $quantity,
|
|
|
+ 'price' => $price,
|
|
|
+ 'total_amount' => $totalAmount,
|
|
|
+ 'status' => OrderStatus::PENDING,
|
|
|
+ ]);
|
|
|
|
|
|
// 3. 冻结用户物品
|
|
|
$freezeResult = ItemService::freezeItem(
|
|
|
@@ -76,7 +77,7 @@ class MexOrderLogic
|
|
|
"农贸市场卖出订单冻结,订单ID:{$order->id}",
|
|
|
[
|
|
|
'reason_type' => FREEZE_REASON_TYPE::TRADE_ORDER->value,
|
|
|
- 'source_id' => $order->id,
|
|
|
+ 'source_id' => $order->id,
|
|
|
'source_type' => 'mex_sell_order',
|
|
|
]
|
|
|
);
|
|
|
@@ -89,13 +90,13 @@ class MexOrderLogic
|
|
|
event(new OrderCreatedEvent($order));
|
|
|
|
|
|
return [
|
|
|
- 'success' => true,
|
|
|
- 'order_id' => $order->id,
|
|
|
+ 'success' => true,
|
|
|
+ 'order_id' => $order->id,
|
|
|
'freeze_log_id' => $freezeResult['freeze_log_id'] ?? null,
|
|
|
- 'message' => '卖出订单创建成功,等待撮合'
|
|
|
+ 'message' => '卖出订单创建成功,等待撮合'
|
|
|
];
|
|
|
} catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => '创建订单失败:' . $e->getMessage()];
|
|
|
+ return [ 'success' => false, 'message' => '创建订单失败:' . $e->getMessage() ];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -120,47 +121,46 @@ class MexOrderLogic
|
|
|
// 验证价格配置是否存在(不验证价格范围和保护阈值,挂单阶段无价格验证)
|
|
|
$priceConfig = MexPriceConfig::where('item_id', $itemId)->where('is_enabled', true)->first();
|
|
|
if (!$priceConfig) {
|
|
|
- return ['success' => false, 'message' => '商品未配置价格信息'];
|
|
|
+ return [ 'success' => false, 'message' => '商品未配置价格信息' ];
|
|
|
}
|
|
|
|
|
|
// 直接计算总金额,信任Fund模块的精度处理
|
|
|
- $totalAmount = bcmul($price , $quantity,9) ;
|
|
|
+ $totalAmount = bcmul($price, $quantity, 9);
|
|
|
Logger::debug(" create ");
|
|
|
|
|
|
try {
|
|
|
// 1. 创建订单记录
|
|
|
$order = MexOrder::create([
|
|
|
- 'user_id' => $userId,
|
|
|
- 'item_id' => $itemId,
|
|
|
- 'currency_type' => $currencyType->value,
|
|
|
- 'order_type' => OrderType::BUY,
|
|
|
- 'quantity' => $quantity,
|
|
|
- 'price' => $price,
|
|
|
- 'total_amount' => $totalAmount,
|
|
|
- 'status' => OrderStatus::PENDING,
|
|
|
- 'frozen_amount' => $totalAmount,
|
|
|
- ]);
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'currency_type' => $currencyType->value,
|
|
|
+ 'order_type' => OrderType::BUY,
|
|
|
+ 'quantity' => $quantity,
|
|
|
+ 'price' => $price,
|
|
|
+ 'total_amount' => $totalAmount,
|
|
|
+ 'status' => OrderStatus::PENDING,
|
|
|
+ 'frozen_amount' => $totalAmount,
|
|
|
+ ]);
|
|
|
// 2. 冻结用户资金
|
|
|
$freezeResult = self::freezeOrderFunds($order);
|
|
|
if (!$freezeResult['success']) {
|
|
|
- return ['success' => false, 'message' => '冻结资金失败:' . $freezeResult['message']];
|
|
|
+ return [ 'success' => false, 'message' => '冻结资金失败:' . $freezeResult['message'] ];
|
|
|
}
|
|
|
|
|
|
// 触发订单创建事件
|
|
|
event(new OrderCreatedEvent($order));
|
|
|
|
|
|
return [
|
|
|
- 'success' => true,
|
|
|
+ 'success' => true,
|
|
|
'order_id' => $order->id,
|
|
|
- 'message' => '买入订单创建成功,等待撮合'
|
|
|
+ 'message' => '买入订单创建成功,等待撮合'
|
|
|
];
|
|
|
} catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => '创建订单失败:' . $e->getMessage()];
|
|
|
+ return [ 'success' => false, 'message' => '创建订单失败:' . $e->getMessage() ];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 取消订单
|
|
|
*
|
|
|
@@ -175,36 +175,35 @@ class MexOrderLogic
|
|
|
|
|
|
$order = MexOrder::where('id', $orderId)->where('user_id', $userId)->first();
|
|
|
if (!$order) {
|
|
|
- return ['success' => false, 'message' => '订单不存在'];
|
|
|
+ return [ 'success' => false, 'message' => '订单不存在' ];
|
|
|
}
|
|
|
|
|
|
if ($order->status !== OrderStatus::PENDING) {
|
|
|
- return ['success' => false, 'message' => '只能取消等待中的订单'];
|
|
|
+ return [ 'success' => false, 'message' => '只能取消等待中的订单' ];
|
|
|
}
|
|
|
|
|
|
- try {
|
|
|
- // 1. 更新订单状态为取消
|
|
|
- $order->update(['status' => OrderStatus::CANCELLED]);
|
|
|
-
|
|
|
- // 2. 处理解冻逻辑
|
|
|
- if ($order->order_type === OrderType::SELL) {
|
|
|
- // 卖出订单:解冻物品
|
|
|
- $unfreezeResult = self::unfreezeOrderItems($order);
|
|
|
- if (!$unfreezeResult['success']) {
|
|
|
- return ['success' => false, 'message' => '解冻物品失败:' . $unfreezeResult['message']];
|
|
|
- }
|
|
|
- } elseif ($order->order_type === OrderType::BUY) {
|
|
|
- // 买入订单:解冻资金
|
|
|
- $unfreezeResult = self::unfreezeOrderFunds($order);
|
|
|
- if (!$unfreezeResult['success']) {
|
|
|
- return ['success' => false, 'message' => '解冻资金失败:' . $unfreezeResult['message']];
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- return ['success' => true, 'message' => '订单已取消'];
|
|
|
- } catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => '取消订单失败:' . $e->getMessage()];
|
|
|
+ // 1. 更新订单状态为取消
|
|
|
+ $order->update([ 'status' => OrderStatus::CANCELLED ]);
|
|
|
+
|
|
|
+ // 2. 处理解冻逻辑
|
|
|
+ if ($order->order_type === OrderType::SELL) {
|
|
|
+ // 卖出订单:解冻物品
|
|
|
+ $unfreezeResult = self::unfreezeOrderItems($order);
|
|
|
+ if (!$unfreezeResult['success']) {
|
|
|
+ return [ 'success' => false, 'message' => '解冻物品失败:' . $unfreezeResult['message'] ];
|
|
|
+ }
|
|
|
+ } elseif ($order->order_type === OrderType::BUY) {
|
|
|
+ // 买入订单:解冻资金
|
|
|
+ $unfreezeResult = self::unfreezeOrderFunds($order);
|
|
|
+ if (!$unfreezeResult['success']) {
|
|
|
+ return [ 'success' => false, 'message' => '解冻资金失败:' . $unfreezeResult['message'] ];
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ return [ 'success' => true, 'message' => '订单已取消' ];
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -215,7 +214,7 @@ class MexOrderLogic
|
|
|
* @param int $pageSize 每页数量
|
|
|
* @return array 订单列表
|
|
|
*/
|
|
|
- public static function getUserOrders(int $userId, int $page = 1, int $pageSize = 20, $itemId = null): array
|
|
|
+ public static function getUserOrders(int $userId, int $page = 1, int $pageSize = 20, $itemId = null): array
|
|
|
{
|
|
|
$where['user_id'] = $userId;
|
|
|
if ($itemId) {
|
|
|
@@ -223,12 +222,12 @@ class MexOrderLogic
|
|
|
}
|
|
|
$orders = MexOrder::where($where)
|
|
|
->orderBy('created_at', 'desc')
|
|
|
- ->paginate($pageSize, ['*'], 'page', $page);
|
|
|
+ ->paginate($pageSize, [ '*' ], 'page', $page);
|
|
|
|
|
|
return [
|
|
|
- 'orders' => $orders->items(),
|
|
|
- 'total' => $orders->total(),
|
|
|
- 'page' => $page,
|
|
|
+ 'orders' => $orders->items(),
|
|
|
+ 'total' => $orders->total(),
|
|
|
+ 'page' => $page,
|
|
|
'page_size' => $pageSize,
|
|
|
];
|
|
|
}
|
|
|
@@ -243,6 +242,7 @@ class MexOrderLogic
|
|
|
public static function getOrderDetail(int $userId, int $orderId): ?array
|
|
|
{
|
|
|
$order = MexOrder::where('id', $orderId)->where('user_id', $userId)->first();
|
|
|
+
|
|
|
return $order ? $order->toArray() : null;
|
|
|
}
|
|
|
|
|
|
@@ -254,41 +254,30 @@ class MexOrderLogic
|
|
|
*/
|
|
|
private static function unfreezeOrderItems(MexOrder $order): array
|
|
|
{
|
|
|
- try {
|
|
|
- // 查找该订单相关的冻结记录
|
|
|
- $freezeLogs = \App\Module\GameItems\Models\ItemFreezeLog::where('source_id', $order->id)
|
|
|
- ->where('source_type', 'mex_sell_order')
|
|
|
- ->where('action_type', \App\Module\GameItems\Enums\FREEZE_ACTION_TYPE::FREEZE)
|
|
|
- ->get();
|
|
|
-
|
|
|
- if ($freezeLogs->isEmpty()) {
|
|
|
- return ['success' => true, 'message' => '没有找到需要解冻的物品'];
|
|
|
- }
|
|
|
+ // 查找该订单相关的冻结记录
|
|
|
+ $freezeLogs = \App\Module\GameItems\Models\ItemFreezeLog::where('source_id', $order->id)
|
|
|
+ ->where('source_type', 'mex_sell_order')
|
|
|
+ ->where('action_type', \App\Module\GameItems\Enums\FREEZE_ACTION_TYPE::FREEZE)
|
|
|
+ ->get();
|
|
|
|
|
|
- $unfrozenCount = 0;
|
|
|
- foreach ($freezeLogs as $freezeLog) {
|
|
|
- try {
|
|
|
- // 使用ItemService解冻物品
|
|
|
- \App\Module\GameItems\Services\ItemService::safeUnfreezeItem($freezeLog->id);
|
|
|
- $unfrozenCount++;
|
|
|
- } catch (\Exception $e) {
|
|
|
- // 记录错误但继续处理其他冻结记录
|
|
|
- Logger::error("解冻物品失败", [
|
|
|
- 'order_id' => $order->id,
|
|
|
- 'freeze_log_id' => $freezeLog->id,
|
|
|
- 'error' => $e->getMessage()
|
|
|
- ]);
|
|
|
- }
|
|
|
- }
|
|
|
+ if ($freezeLogs->isEmpty()) {
|
|
|
+ return [ 'success' => true, 'message' => '没有找到需要解冻的物品' ];
|
|
|
+ }
|
|
|
|
|
|
- return [
|
|
|
- 'success' => true,
|
|
|
- 'message' => "成功解冻 {$unfrozenCount} 个冻结记录",
|
|
|
- 'unfrozen_count' => $unfrozenCount
|
|
|
- ];
|
|
|
- } catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => $e->getMessage()];
|
|
|
+ $unfrozenCount = 0;
|
|
|
+ foreach ($freezeLogs as $freezeLog) {
|
|
|
+ // 使用ItemService解冻物品
|
|
|
+ \App\Module\GameItems\Services\ItemService::safeUnfreezeItem($freezeLog->id);
|
|
|
+ $unfrozenCount++;
|
|
|
}
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => "成功解冻 {$unfrozenCount} 个冻结记录",
|
|
|
+ 'unfrozen_count' => $unfrozenCount
|
|
|
+ ];
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -302,10 +291,10 @@ class MexOrderLogic
|
|
|
try {
|
|
|
// 获取可用账户类型和冻结账户类型
|
|
|
$availableAccountType = FundLogic::getAvailableAccountType($order->currency_type);
|
|
|
- $frozenAccountType = FundLogic::getFrozenAccountType($order->currency_type);
|
|
|
+ $frozenAccountType = FundLogic::getFrozenAccountType($order->currency_type);
|
|
|
|
|
|
if (!$availableAccountType || !$frozenAccountType) {
|
|
|
- return ['success' => false, 'message' => '不支持的币种类型'];
|
|
|
+ return [ 'success' => false, 'message' => '不支持的币种类型' ];
|
|
|
}
|
|
|
|
|
|
// 创建Fund服务实例(可用账户)
|
|
|
@@ -313,7 +302,7 @@ class MexOrderLogic
|
|
|
|
|
|
// 验证用户可用余额是否充足
|
|
|
if ($fundService->balance() < $order->frozen_amount) {
|
|
|
- return ['success' => false, 'message' => '可用余额不足'];
|
|
|
+ return [ 'success' => false, 'message' => '可用余额不足' ];
|
|
|
}
|
|
|
|
|
|
// 使用circulation方法将资金从可用账户转移到冻结账户
|
|
|
@@ -326,17 +315,17 @@ class MexOrderLogic
|
|
|
);
|
|
|
|
|
|
if (is_string($circulationResult)) {
|
|
|
- return ['success' => false, 'message' => '资金冻结失败:' . $circulationResult];
|
|
|
+ return [ 'success' => false, 'message' => '资金冻结失败:' . $circulationResult ];
|
|
|
}
|
|
|
|
|
|
return [
|
|
|
- 'success' => true,
|
|
|
- 'message' => '资金冻结成功',
|
|
|
- 'frozen_amount' => $order->frozen_amount,
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => '资金冻结成功',
|
|
|
+ 'frozen_amount' => $order->frozen_amount,
|
|
|
'circulation_id' => $circulationResult->id ?? null
|
|
|
];
|
|
|
} catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => '冻结资金异常:' . $e->getMessage()];
|
|
|
+ return [ 'success' => false, 'message' => '冻结资金异常:' . $e->getMessage() ];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -351,10 +340,10 @@ class MexOrderLogic
|
|
|
try {
|
|
|
// 获取可用账户类型和冻结账户类型
|
|
|
$availableAccountType = FundLogic::getAvailableAccountType($order->currency_type);
|
|
|
- $frozenAccountType = FundLogic::getFrozenAccountType($order->currency_type);
|
|
|
+ $frozenAccountType = FundLogic::getFrozenAccountType($order->currency_type);
|
|
|
|
|
|
if (!$availableAccountType || !$frozenAccountType) {
|
|
|
- return ['success' => false, 'message' => '不支持的币种类型'];
|
|
|
+ return [ 'success' => false, 'message' => '不支持的币种类型' ];
|
|
|
}
|
|
|
|
|
|
// 创建Fund服务实例(冻结账户)
|
|
|
@@ -362,30 +351,30 @@ class MexOrderLogic
|
|
|
|
|
|
// 验证冻结账户余额是否充足
|
|
|
if ($fundService->balance() < $order->frozen_amount) {
|
|
|
- return ['success' => false, 'message' => '冻结账户余额不足,可能已被解冻'];
|
|
|
+ return [ 'success' => false, 'message' => '冻结账户余额不足,可能已被解冻' ];
|
|
|
}
|
|
|
|
|
|
// 使用circulation方法将资金从冻结账户转移回可用账户
|
|
|
$circulationResult = $fundService->circulation(
|
|
|
$availableAccountType,
|
|
|
- (float) $order->frozen_amount,
|
|
|
+ (float)$order->frozen_amount,
|
|
|
$order->id,
|
|
|
'mex_buy_order_cancel',
|
|
|
"农贸市场买入订单取消解冻,订单ID:{$order->id}"
|
|
|
);
|
|
|
|
|
|
if (is_string($circulationResult)) {
|
|
|
- return ['success' => false, 'message' => '资金解冻失败:' . $circulationResult];
|
|
|
+ return [ 'success' => false, 'message' => '资金解冻失败:' . $circulationResult ];
|
|
|
}
|
|
|
|
|
|
return [
|
|
|
- 'success' => true,
|
|
|
- 'message' => '资金解冻成功',
|
|
|
+ 'success' => true,
|
|
|
+ 'message' => '资金解冻成功',
|
|
|
'unfrozen_amount' => $order->frozen_amount,
|
|
|
- 'circulation_id' => $circulationResult->id ?? null
|
|
|
+ 'circulation_id' => $circulationResult->id ?? null
|
|
|
];
|
|
|
} catch (\Exception $e) {
|
|
|
- return ['success' => false, 'message' => '解冻资金异常:' . $e->getMessage()];
|
|
|
+ return [ 'success' => false, 'message' => '解冻资金异常:' . $e->getMessage() ];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -409,4 +398,5 @@ class MexOrderLogic
|
|
|
|
|
|
return $orders->toArray();
|
|
|
}
|
|
|
+
|
|
|
}
|