MexMatchLogLogic.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace App\Module\Mex\Logic;
  3. use App\Module\Mex\Models\MexMatchLog;
  4. use App\Module\Mex\Enums\MatchType;
  5. /**
  6. * 农贸市场撮合日志逻辑
  7. *
  8. * 处理撮合日志相关的核心业务逻辑
  9. */
  10. class MexMatchLogLogic
  11. {
  12. /**
  13. * 记录撮合日志
  14. *
  15. * @param MatchType $matchType 撮合类型
  16. * @param int $itemId 商品ID
  17. * @param int $batchSize 批处理大小
  18. * @param array $result 撮合结果
  19. * @param int|null $executionTimeMs 执行时间(毫秒)
  20. * @param string|null $errorMessage 错误消息
  21. * @return MexMatchLog 撮合日志记录
  22. */
  23. public static function logMatch(
  24. MatchType $matchType,
  25. int $itemId,
  26. int $batchSize,
  27. array $result,
  28. ?int $executionTimeMs = null,
  29. ?string $errorMessage = null
  30. ): MexMatchLog {
  31. return MexMatchLog::create([
  32. 'match_type' => $matchType,
  33. 'item_id' => $itemId,
  34. 'batch_size' => $batchSize,
  35. 'matched_orders' => $result['matched_orders'] ?? 0,
  36. 'total_amount' => $result['total_amount'] ?? '0.00000',
  37. 'success' => $result['success'] ?? false,
  38. 'message' => $result['message'] ?? '',
  39. 'execution_time_ms' => $executionTimeMs,
  40. 'error_message' => $errorMessage,
  41. ]);
  42. }
  43. /**
  44. * 获取最后撮合时间信息
  45. *
  46. * @return array 最后撮合时间信息
  47. */
  48. public static function getLastMatchTimes(): array
  49. {
  50. // 获取最后的卖出撮合时间
  51. $lastSellMatch = MexMatchLog::where('match_type', MatchType::USER_SELL)
  52. ->orderBy('created_at', 'desc')
  53. ->first();
  54. // 获取最后的买入撮合时间
  55. $lastBuyMatch = MexMatchLog::where('match_type', MatchType::USER_BUY)
  56. ->orderBy('created_at', 'desc')
  57. ->first();
  58. return [
  59. 'last_sell_match_time' => $lastSellMatch ? $lastSellMatch->created_at : null,
  60. 'last_buy_match_time' => $lastBuyMatch ? $lastBuyMatch->created_at : null,
  61. ];
  62. }
  63. /**
  64. * 获取撮合统计信息
  65. *
  66. * @param int $days 统计天数
  67. * @return array 统计信息
  68. */
  69. public static function getMatchStats(int $days = 7): array
  70. {
  71. $startDate = now()->subDays($days)->startOfDay();
  72. // 总体统计
  73. $totalStats = MexMatchLog::where('created_at', '>=', $startDate)
  74. ->selectRaw('
  75. COUNT(*) as total_matches,
  76. SUM(matched_orders) as total_matched_orders,
  77. SUM(total_amount) as total_amount,
  78. AVG(execution_time_ms) as avg_execution_time,
  79. SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) as successful_matches
  80. ')
  81. ->first();
  82. // 按类型统计
  83. $typeStats = MexMatchLog::where('created_at', '>=', $startDate)
  84. ->groupBy('match_type')
  85. ->selectRaw('
  86. match_type,
  87. COUNT(*) as count,
  88. SUM(matched_orders) as matched_orders,
  89. SUM(total_amount) as amount,
  90. SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) as successful_count
  91. ')
  92. ->get()
  93. ->keyBy('match_type');
  94. return [
  95. 'period' => $days,
  96. 'start_date' => $startDate,
  97. 'end_date' => now(),
  98. 'total' => [
  99. 'matches' => $totalStats->total_matches ?? 0,
  100. 'matched_orders' => $totalStats->total_matched_orders ?? 0,
  101. 'total_amount' => $totalStats->total_amount ?? '0.00000',
  102. 'avg_execution_time' => $totalStats->avg_execution_time ? round($totalStats->avg_execution_time, 2) : 0,
  103. 'successful_matches' => $totalStats->successful_matches ?? 0,
  104. 'success_rate' => $totalStats->total_matches > 0
  105. ? round(($totalStats->successful_matches / $totalStats->total_matches) * 100, 2)
  106. : 0,
  107. ],
  108. 'by_type' => [
  109. 'USER_BUY' => [
  110. 'matches' => $typeStats['USER_BUY']->count ?? 0,
  111. 'matched_orders' => $typeStats['USER_BUY']->matched_orders ?? 0,
  112. 'amount' => $typeStats['USER_BUY']->amount ?? '0.00000',
  113. 'successful_count' => $typeStats['USER_BUY']->successful_count ?? 0,
  114. ],
  115. 'USER_SELL' => [
  116. 'matches' => $typeStats['USER_SELL']->count ?? 0,
  117. 'matched_orders' => $typeStats['USER_SELL']->matched_orders ?? 0,
  118. 'amount' => $typeStats['USER_SELL']->amount ?? '0.00000',
  119. 'successful_count' => $typeStats['USER_SELL']->successful_count ?? 0,
  120. ],
  121. ],
  122. ];
  123. }
  124. /**
  125. * 获取商品撮合历史
  126. *
  127. * @param int $itemId 商品ID
  128. * @param int $limit 限制数量
  129. * @return array 撮合历史
  130. */
  131. public static function getItemMatchHistory(int $itemId, int $limit = 20): array
  132. {
  133. $logs = MexMatchLog::where('item_id', $itemId)
  134. ->orderBy('created_at', 'desc')
  135. ->limit($limit)
  136. ->get();
  137. return $logs->toArray();
  138. }
  139. }