itemId = $itemId; $this->itemName = $itemName; parent::__construct(); } /** * 初始化卡片内容 * * @return void */ protected function init() { parent::init(); $title = $this->itemName ? "{$this->itemName} - 成交趋势" : '成交趋势'; $this->title($title); $this->height(400); $this->chartHeight(300); // 设置下拉选项 $this->dropdown([ '7' => '最近 7 天', '14' => '最近 14 天', '30' => '最近 30 天', '90' => '最近 90 天', ]); } /** * 处理请求 * * @param Request $request * @return mixed|void */ public function handle(Request $request) { $days = (int) $request->get('option', 7); $itemId = $this->itemId ?? $request->get('item_id'); $currencyType = $request->get('currency_type', FUND_CURRENCY_TYPE::ZUANSHI->value); $data = $this->getVolumeTrendData($days, $itemId, $currencyType); // 卡片内容 - 显示总成交量 $totalVolume = $data['total_volume'] ?? 0; $volumeChange = $data['volume_change'] ?? 0; $changePercent = $data['change_percent'] ?? 0; $changeText = $volumeChange >= 0 ? "+{$changePercent}%" : "{$changePercent}%"; $this->withContent(number_format($totalVolume), $changeText); // 添加详细信息 $dataCount = count($data['dates']); $this->subTitle("数据点: {$dataCount} | 时间范围: {$days}天"); // 图表数据 - 多线图 $this->withMultiLineChart($data); } /** * 获取成交趋势数据 * * @param int $days * @param int|null $itemId * @param int $currencyType * @return array */ protected function getVolumeTrendData(int $days, ?int $itemId = null, int $currencyType = 2): array { $startDate = now()->subDays($days - 1)->toDateString(); $endDate = now()->toDateString(); // 构建基础查询 $query = MexTransaction::selectRaw(' DATE(created_at) as trade_date, transaction_type, SUM(quantity) as total_quantity, COUNT(*) as transaction_count ') ->whereBetween(DB::raw('DATE(created_at)'), [$startDate, $endDate]) ->where('currency_type', $currencyType) ->groupBy(DB::raw('DATE(created_at)'), 'transaction_type') ->orderBy(DB::raw('DATE(created_at)')); if ($itemId) { $query->where('item_id', $itemId); } $transactions = $query->get(); // 生成日期范围 $dates = []; $current = now()->subDays($days - 1); for ($i = 0; $i < $days; $i++) { $dates[] = $current->format('m-d'); $current->addDay(); } // 初始化数据数组 $buyVolumes = array_fill(0, $days, 0); $sellVolumes = array_fill(0, $days, 0); // 填充数据 foreach ($transactions as $transaction) { $tradeDate = \Carbon\Carbon::parse($transaction->trade_date); $dateIndex = now()->subDays($days - 1)->diffInDays($tradeDate); if ($dateIndex >= 0 && $dateIndex < $days) { if ($transaction->transaction_type == TransactionType::USER_BUY->value) { $buyVolumes[$dateIndex] = (int) $transaction->total_quantity; } elseif ($transaction->transaction_type == TransactionType::USER_SELL->value) { $sellVolumes[$dateIndex] = (int) $transaction->total_quantity; } } } // 计算总成交量和变化 $totalVolume = array_sum($buyVolumes) + array_sum($sellVolumes); $recentVolume = end($buyVolumes) + end($sellVolumes); $firstVolume = $buyVolumes[0] + $sellVolumes[0]; $volumeChange = $recentVolume - $firstVolume; $changePercent = $firstVolume > 0 ? round(($volumeChange / $firstVolume) * 100, 2) : 0; return [ 'dates' => $dates, 'buy_volumes' => $buyVolumes, 'sell_volumes' => $sellVolumes, 'total_volume' => $totalVolume, 'volume_change' => $volumeChange, 'change_percent' => $changePercent, ]; } /** * 设置多线图表数据 * * @param array $data * @return $this */ public function withMultiLineChart(array $data) { $series = [ [ 'name' => '买入量', 'data' => $data['buy_volumes'], ], [ 'name' => '卖出量', 'data' => $data['sell_volumes'], ], ]; // 定义不同线条的颜色 $colors = [ '#52c41a', // 绿色 - 买入量 '#f5222d', // 红色 - 卖出量 ]; return $this->chart([ 'series' => $series, 'colors' => $colors, 'xaxis' => [ 'categories' => $data['dates'], 'labels' => [ 'show' => true, ], ], 'legend' => [ 'show' => true, 'position' => 'bottom', 'horizontalAlign' => 'center' ], 'tooltip' => [ 'shared' => true, 'intersect' => false, ], 'yaxis' => [ 'title' => [ 'text' => '成交量' ] ], ]); } }