DailyTransferChart.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. namespace App\Module\Transfer\AdminControllers\Metrics;
  3. use UCore\DcatAdmin\Metrics\Examples\NewUsersDou;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Facades\DB;
  6. use App\Module\Transfer\Models\TransferOrder;
  7. use App\Module\Transfer\Enums\TransferType;
  8. use App\Module\Transfer\Enums\TransferStatus;
  9. use Carbon\Carbon;
  10. /**
  11. * 每日转入转出统计折线图
  12. * 显示每日转入和转出的数量和金额趋势
  13. */
  14. class DailyTransferChart extends NewUsersDou
  15. {
  16. /**
  17. * 图表默认高度
  18. *
  19. * @var int
  20. */
  21. protected $chartHeight = 200;
  22. /**
  23. * 初始化卡片内容
  24. */
  25. protected function init()
  26. {
  27. parent::init();
  28. $this->title('每日转入/转出统计');
  29. $this->dropdown([
  30. '7' => '最近 7 天',
  31. '14' => '最近 14 天',
  32. '30' => '最近 30 天',
  33. '90' => '最近 90 天',
  34. ]);
  35. }
  36. /**
  37. * 处理请求
  38. *
  39. * @param Request $request
  40. * @return mixed|void
  41. */
  42. public function handle(Request $request)
  43. {
  44. $days = (int)$request->get('option', 7);
  45. $chartData = $this->getTransferData($days);
  46. // 计算总交易数量作为卡片内容
  47. $totalTransfers = array_sum($chartData['data']['transfer_in']) + array_sum($chartData['data']['transfer_out']);
  48. // 卡片内容
  49. $this->withContent(number_format($totalTransfers));
  50. // 图表数据
  51. $this->withChart($chartData['series'], $chartData['categories']);
  52. }
  53. /**
  54. * 获取转账统计数据
  55. *
  56. * @param int $days
  57. * @return array
  58. */
  59. protected function getTransferData(int $days): array
  60. {
  61. // 生成日期范围
  62. $endDate = Carbon::today();
  63. $startDate = $endDate->copy()->subDays($days - 1);
  64. $dates = [];
  65. for ($date = $startDate->copy(); $date->lte($endDate); $date->addDay()) {
  66. $dates[] = $date->format('Y-m-d');
  67. }
  68. // 查询转账数据 - 按日期和类型分组统计
  69. $transferData = DB::table('transfer_orders')
  70. ->select([
  71. DB::raw('DATE(created_at) as date'),
  72. 'type',
  73. DB::raw('COUNT(*) as count'),
  74. DB::raw('SUM(amount) as total_amount'),
  75. DB::raw('SUM(actual_amount) as total_actual_amount')
  76. ])
  77. ->where('status', TransferStatus::COMPLETED->value) // 只统计已完成的订单
  78. ->where('created_at', '>=', $startDate)
  79. ->where('created_at', '<=', $endDate->endOfDay())
  80. ->groupBy(['date', 'type'])
  81. ->orderBy('date')
  82. ->get()
  83. ->groupBy(['date', 'type']);
  84. // 构建图表数据
  85. $transferInCounts = [];
  86. $transferOutCounts = [];
  87. $transferInAmounts = [];
  88. $transferOutAmounts = [];
  89. foreach ($dates as $date) {
  90. $dayData = $transferData->get($date, collect());
  91. // 转入数据
  92. $transferInData = $dayData->get(TransferType::IN->value, collect())->first();
  93. $transferInCounts[] = $transferInData ? (int)$transferInData->count : 0;
  94. $transferInAmounts[] = $transferInData ? (float)$transferInData->total_actual_amount : 0;
  95. // 转出数据
  96. $transferOutData = $dayData->get(TransferType::OUT->value, collect())->first();
  97. $transferOutCounts[] = $transferOutData ? (int)$transferOutData->count : 0;
  98. $transferOutAmounts[] = $transferOutData ? (float)$transferOutData->total_actual_amount : 0;
  99. }
  100. // 构建多线图表数据
  101. $series = [
  102. [
  103. 'name' => '转入笔数',
  104. 'data' => $transferInCounts,
  105. 'color' => '#28a745', // 绿色
  106. ],
  107. [
  108. 'name' => '转出笔数',
  109. 'data' => $transferOutCounts,
  110. 'color' => '#dc3545', // 红色
  111. ],
  112. [
  113. 'name' => '转入金额',
  114. 'data' => $transferInAmounts,
  115. 'color' => '#17a2b8', // 蓝色
  116. 'yAxis' => 1, // 使用第二个Y轴
  117. ],
  118. [
  119. 'name' => '转出金额',
  120. 'data' => $transferOutAmounts,
  121. 'color' => '#fd7e14', // 橙色
  122. 'yAxis' => 1, // 使用第二个Y轴
  123. ],
  124. ];
  125. return [
  126. 'series' => $series,
  127. 'categories' => $dates,
  128. 'data' => [
  129. 'transfer_in' => $transferInCounts,
  130. 'transfer_out' => $transferOutCounts,
  131. 'transfer_in_amounts' => $transferInAmounts,
  132. 'transfer_out_amounts' => $transferOutAmounts,
  133. ],
  134. ];
  135. }
  136. /**
  137. * 设置图表数据
  138. *
  139. * @param array $series
  140. * @param array $categories
  141. * @return $this
  142. */
  143. public function withChart(array $series, array $categories = [])
  144. {
  145. return $this->chart([
  146. 'series' => $series,
  147. 'xaxis' => [
  148. 'categories' => $categories,
  149. 'title' => [
  150. 'text' => '日期'
  151. ]
  152. ],
  153. 'yaxis' => [
  154. [
  155. 'title' => [
  156. 'text' => '交易笔数'
  157. ],
  158. 'labels' => [
  159. 'formatter' => 'function(val) { return val.toFixed(0); }'
  160. ]
  161. ],
  162. [
  163. 'opposite' => true,
  164. 'title' => [
  165. 'text' => '交易金额'
  166. ],
  167. 'labels' => [
  168. 'formatter' => 'function(val) { return val.toFixed(2); }'
  169. ]
  170. ]
  171. ],
  172. 'tooltip' => [
  173. 'shared' => true,
  174. 'intersect' => false,
  175. ],
  176. 'legend' => [
  177. 'position' => 'top',
  178. 'horizontalAlign' => 'left'
  179. ]
  180. ]);
  181. }
  182. }