<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Binance C2C 柬埔寨市场监控 - KH-USDT Monitor</title>
    <!-- 使用生产版本的Vue，避免开发模式警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        // 禁用Vue开发模式警告（生产环境）
        // 注意：使用生产版本后，这些配置可能不需要，但保留以防万一
        window.addEventListener('DOMContentLoaded', function() {
            if (typeof Vue !== 'undefined' && Vue.config) {
                Vue.config.devtools = false;
                Vue.config.productionTip = false;
            }
        });
        // resources/views/dashboard.blade.php
        const response = await axios.get('/api/market/historical-trend', {
                                     params: { limit: 720 } // 默认30天（720小时）
        });
    </script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: #0a0e27;
            color: #e4e4e4;
            padding: 20px;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
        }
        
        /* 顶部看板 */
        .ticker-board {
            background: linear-gradient(135deg, #1a1f3a 0%, #2a2f4a 100%);
            border-radius: 12px;
            padding: 30px;
            margin-bottom: 20px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }
        
        .ticker-title {
            font-size: 14px;
            color: #8b8b8b;
            margin-bottom: 10px;
        }
        
        .ticker-price {
            font-size: 48px;
            font-weight: bold;
            color: #f0b90b;
            margin-bottom: 15px;
        }
        
        .ticker-stats {
            display: flex;
            gap: 30px;
            flex-wrap: wrap;
        }
        
        .stat-item {
            display: flex;
            flex-direction: column;
        }
        
        .stat-label {
            font-size: 12px;
            color: #8b8b8b;
            margin-bottom: 5px;
        }
        
        .stat-value {
            font-size: 18px;
            font-weight: 600;
        }
        
        .stat-value.positive {
            color: #0ecb81;
        }
        
        .stat-value.negative {
            color: #f6465d;
        }
        
        /* 图表区域 */
        .chart-section {
            background: #1a1f3a;
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }
        
        .chart-tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            border-bottom: 1px solid #2a2f4a;
        }
        
        .chart-tab {
            padding: 12px 24px;
            background: transparent;
            border: none;
            color: #8b8b8b;
            cursor: pointer;
            font-size: 14px;
            border-bottom: 2px solid transparent;
            transition: all 0.3s;
        }
        
        .chart-tab.active {
            color: #f0b90b;
            border-bottom-color: #f0b90b;
        }
        
        .chart-tab:hover {
            color: #e4e4e4;
        }
        
        .chart-container {
            width: 100%;
            height: 400px;
        }
        
        /* 历史走势统计信息 */
        .trend-statistics {
            background: #1a1f3a;
            border-radius: 8px;
            padding: 15px;
            margin-bottom: 15px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        }
        
        .trend-statistics .stat-row {
            display: grid;
            grid-template-columns: repeat(6, 1fr);
            gap: 15px;
        }
        
        .trend-statistics .stat-box {
            text-align: center;
            padding: 10px;
            background: rgba(42, 47, 74, 0.5);
            border-radius: 6px;
        }
        
        .trend-statistics .stat-label {
            font-size: 12px;
            color: #8b8b8b;
            margin-bottom: 5px;
        }
        
        .trend-statistics .stat-value {
            font-size: 16px;
            font-weight: 600;
            color: #e4e4e4;
        }
        
        .trend-statistics .stat-value.highlight {
            color: #f0b90b;
            font-size: 18px;
        }
        
        .trend-statistics .stat-value.positive {
            color: #0ecb81;
        }
        
        .trend-statistics .stat-value.negative {
            color: #f6465d;
        }
        
        .trend-statistics .stat-time {
            font-size: 10px;
            color: #666;
            margin-top: 3px;
        }
        
        @media (max-width: 1400px) {
            .trend-statistics .stat-row {
                grid-template-columns: repeat(3, 1fr);
            }
        }
        
        @media (max-width: 768px) {
            .trend-statistics .stat-row {
                grid-template-columns: repeat(2, 1fr);
            }
        }
        
        /* 订单簿 */
        .orderbook-section {
            background: #1a1f3a;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }
        
        .orderbook-container {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 20px;
            margin-top: 20px;
        }
        
        .orderbook-item {
            background: #1a1f3a;
            border-radius: 12px;
            padding: 15px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
            min-height: 400px;
            display: flex;
            flex-direction: column;
        }
        
        .orderbook-item .orderbook-table {
            flex: 1;
            overflow-y: auto;
        }
        
        .orderbook-title {
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 20px;
            color: #f0b90b;
        }
        
        .orderbook-subtitle {
            font-size: 12px;
            color: #8b8b8b;
            margin-bottom: 15px;
        }
        
        .orderbook-table {
            width: 100%;
            border-collapse: collapse;
            font-size: 12px;
        }
        
        .orderbook-table th {
            text-align: left;
            padding: 8px 6px;
            font-size: 11px;
            color: #8b8b8b;
            border-bottom: 1px solid #2a2f4a;
            font-weight: 600;
        }
        
        .orderbook-table td {
            padding: 8px 6px;
            border-bottom: 1px solid #2a2f4a;
            font-size: 11px;
        }
        
        .orderbook-table tr:hover {
            background: #2a2f4a;
        }
        
        @media (max-width: 1400px) {
            .orderbook-container {
                grid-template-columns: 1fr;
            }
        }
        
        .bank-tag {
            display: inline-block;
            padding: 2px 8px;
            background: #f0b90b;
            color: #0a0e27;
            border-radius: 4px;
            font-size: 11px;
            font-weight: 600;
            margin-right: 4px;
        }
        
        .loading {
            text-align: center;
            padding: 40px;
            color: #8b8b8b;
        }
        
        .error {
            text-align: center;
            padding: 40px;
            color: #f6465d;
        }
    </style>
</head>
<body>
    <div id="app" class="container">
        <!-- 顶部行情看板 -->
        <div class="ticker-board">
            <div class="ticker-title">当前最优价 (Best Ask)</div>
            <div class="ticker-price">{{ formatPrice(ticker.best_price) }}</div>
            <div class="ticker-stats">
                <div class="stat-item">
                    <div class="stat-label">24h 涨跌幅</div>
                    <div class="stat-value" :class="ticker.change_percent_24h >= 0 ? 'positive' : 'negative'">
                        {{ ticker.change_percent_24h >= 0 ? '+' : '' }}{{ ticker.change_percent_24h.toFixed(2) }}%
                    </div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">市场深度样本</div>
                    <div class="stat-value">共扫描 {{ ticker.active_merchants }} 位商家，记录前 10 档</div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">数据统计</div>
                    <div class="stat-value">样本总数: {{ ticker.total_samples || 0 }} | 采集次数: {{ ticker.total_scans || 0 }}</div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">最近更新</div>
                    <div class="stat-value">{{ ticker.updated_at || '--' }}</div>
                </div>
            </div>
        </div>

        <!-- 图表区域 -->
        <div class="chart-section">
            <div class="chart-tabs">
                <button class="chart-tab" :class="{ active: activeTab === 'timeseries' }" @click="switchTab('timeseries')">
                    分时走势
                </button>
                <button class="chart-tab" :class="{ active: activeTab === 'trend' }" @click="switchTab('trend')">
                    历史走势
                </button>
            </div>
            <!-- 历史走势统计信息 -->
            <div v-if="activeTab === 'trend' && trendStatistics" class="trend-statistics">
                <div class="stat-row">
                    <div class="stat-box">
                        <div class="stat-label">当前值</div>
                        <div class="stat-value highlight">{{ formatPrice(trendStatistics.current_value) }}</div>
                    </div>
                    <div class="stat-box">
                        <div class="stat-label">历史最高</div>
                        <div class="stat-value positive">{{ formatPrice(trendStatistics.historical_high) }}</div>
                        <div class="stat-time">{{ trendStatistics.historical_high_time }}</div>
                    </div>
                    <div class="stat-box">
                        <div class="stat-label">历史最低</div>
                        <div class="stat-value negative">{{ formatPrice(trendStatistics.historical_low) }}</div>
                        <div class="stat-time">{{ trendStatistics.historical_low_time }}</div>
                    </div>
                    <div class="stat-box">
                        <div class="stat-label">总涨跌</div>
                        <div class="stat-value" :class="trendStatistics.total_change >= 0 ? 'positive' : 'negative'">
                            {{ trendStatistics.total_change >= 0 ? '+' : '' }}{{ trendStatistics.total_change_percent.toFixed(2) }}%
                        </div>
                    </div>
                    <div class="stat-box">
                        <div class="stat-label">平均波动率</div>
                        <div class="stat-value">{{ trendStatistics.avg_volatility.toFixed(2) }}%</div>
                    </div>
                    <div class="stat-box">
                        <div class="stat-label">涨跌比</div>
                        <div class="stat-value">{{ trendStatistics.up_count }}↑ / {{ trendStatistics.down_count }}↓ ({{ trendStatistics.up_ratio }}%)</div>
                    </div>
                </div>
            </div>
            <div class="chart-container" ref="chartContainer"></div>
        </div>

        <!-- 订单簿 - 三个排名并排显示 -->
        <div class="orderbook-section">
            <div class="orderbook-title">报价排名对比</div>
            <div class="orderbook-container">
                <!-- 实时最优报价排名 -->
                <div class="orderbook-item">
                    <div class="orderbook-title">实时最优报价排名</div>
                    <div class="orderbook-subtitle">当前最新采集数据</div>
                    <div v-if="orderbookLoading" class="loading">加载中...</div>
                    <div v-else-if="orderbookError" class="error">{{ orderbookError }}</div>
                    <table v-else class="orderbook-table">
                        <thead>
                            <tr>
                                <th>排名</th>
                                <th>商家</th>
                                <th>价格</th>
                                <th>数量</th>
                                <th>支付方式</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="order in orderbook" :key="order.rank">
                                <td>{{ order.rank }}</td>
                                <td style="font-size: 12px;">{{ order.merchant }}</td>
                                <td style="color: #f0b90b; font-weight: 600;">{{ formatPrice(order.price) }}</td>
                                <td style="font-size: 11px;">{{ formatAmount(order.amount) }}</td>
                                <td>
                                    <span v-for="bank in getBanks(order.banks).slice(0, 2)" :key="bank" class="bank-tag">{{ bank }}</span>
                                </td>
                            </tr>
                            <tr v-if="orderbook.length === 0">
                                <td colspan="5" style="text-align: center; color: #8b8b8b; font-size: 12px;">暂无数据</td>
                            </tr>
                        </tbody>
                    </table>
                </div>

                <!-- 历史最优报价排名 -->
                <div class="orderbook-item">
                    <div class="orderbook-title">历史最优报价排名</div>
                    <div class="orderbook-subtitle">所有采集数据最低价</div>
                    <div v-if="historicalBestLoading" class="loading">加载中...</div>
                    <div v-else-if="historicalBestError" class="error">{{ historicalBestError }}</div>
                    <table v-else class="orderbook-table">
                        <thead>
                            <tr>
                                <th>排名</th>
                                <th>商家</th>
                                <th>价格</th>
                                <th>数量</th>
                                <th>支付方式</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="order in historicalBest" :key="order.rank">
                                <td>{{ order.rank }}</td>
                                <td style="font-size: 12px;">{{ order.merchant }}</td>
                                <td style="color: #0ecb81; font-weight: 600;">{{ formatPrice(order.price) }}</td>
                                <td style="font-size: 11px;">{{ formatAmount(order.amount) }}</td>
                                <td>
                                    <span v-for="bank in getBanks(order.banks).slice(0, 2)" :key="bank" class="bank-tag">{{ bank }}</span>
                                </td>
                            </tr>
                            <tr v-if="historicalBest.length === 0">
                                <td colspan="5" style="text-align: center; color: #8b8b8b; font-size: 12px;">暂无数据</td>
                            </tr>
                        </tbody>
                    </table>
                </div>

                <!-- 历史最高价排名 -->
                <div class="orderbook-item">
                    <div class="orderbook-title">历史最高价排名</div>
                    <div class="orderbook-subtitle">所有采集数据最高价</div>
                    <div v-if="historicalHighestLoading" class="loading">加载中...</div>
                    <div v-else-if="historicalHighestError" class="error">{{ historicalHighestError }}</div>
                    <table v-else class="orderbook-table">
                        <thead>
                            <tr>
                                <th>排名</th>
                                <th>商家</th>
                                <th>价格</th>
                                <th>数量</th>
                                <th>支付方式</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="order in historicalHighest" :key="order.rank">
                                <td>{{ order.rank }}</td>
                                <td style="font-size: 12px;">{{ order.merchant }}</td>
                                <td style="color: #f6465d; font-weight: 600;">{{ formatPrice(order.price) }}</td>
                                <td style="font-size: 11px;">{{ formatAmount(order.amount) }}</td>
                                <td>
                                    <span v-for="bank in getBanks(order.banks).slice(0, 2)" :key="bank" class="bank-tag">{{ bank }}</span>
                                </td>
                            </tr>
                            <tr v-if="historicalHighest.length === 0">
                                <td colspan="5" style="text-align: center; color: #8b8b8b; font-size: 12px;">暂无数据</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 确保只初始化一次，避免重复加载警告
        (function() {
            'use strict';
            
            // 检查是否已经初始化
            if (window.appInitialized) {
                console.warn('应用已经初始化，跳过重复初始化');
                return;
            }
            window.appInitialized = true;
            
            const { createApp } = Vue;

            createApp({
            data() {
                return {
                    ticker: {
                        best_price: 0,
                        change_percent_24h: 0,
                        active_merchants: 0,
                        updated_at: '--'
                    },
                    activeTab: 'timeseries',
                    chart: null,
                    orderbook: [],
                    orderbookLoading: false,
                    orderbookError: null,
                    historicalBest: [],
                    historicalBestLoading: false,
                    historicalBestError: null,
                    historicalHighest: [],
                    historicalHighestLoading: false,
                    historicalHighestError: null,
                    trendStatistics: null,
                    refreshInterval: null
                };
            },
            mounted() {
                this.initChart();
                this.loadTicker();
                this.loadOrderBook();
                this.loadHistoricalBest();
                this.loadHistoricalHighest();
                this.loadChartData();
                
                // 每30秒刷新一次数据
                this.refreshInterval = setInterval(() => {
                    this.loadTicker();
                    this.loadOrderBook();
                    if (this.activeTab === 'timeseries' || this.activeTab === 'trend') {
                        this.loadChartData();
                    }
                }, 30000);
            },
            beforeUnmount() {
                if (this.refreshInterval) {
                    clearInterval(this.refreshInterval);
                }
                if (this.chart) {
                    this.chart.dispose();
                }
            },
            methods: {
                async loadTicker() {
                    try {
                        const response = await axios.get('/api/market/ticker');
                        if (response.data.success) {
                            this.ticker = response.data.data;
                        } else {
                            console.error('API返回错误:', response.data.message);
                            // 显示错误信息
                            if (!this.ticker.best_price) {
                                this.ticker = {
                                    best_price: 0,
                                    avg_price: 0,
                                    change_percent_24h: 0,
                                    active_merchants: 0,
                                    total_samples: 0,
                                    total_scans: 0,
                                    updated_at: '暂无数据',
                                    error: response.data.message || '暂无数据'
                                };
                            }
                        }
                    } catch (error) {
                        console.error('加载行情数据失败:', error);
                        // 显示网络错误
                        if (!this.ticker.best_price) {
                            this.ticker = {
                                best_price: 0,
                                avg_price: 0,
                                change_percent_24h: 0,
                                active_merchants: 0,
                                total_samples: 0,
                                total_scans: 0,
                                updated_at: '连接失败',
                                error: '无法连接到服务器，请检查网络或API配置'
                            };
                        }
                    }
                },
                async loadOrderBook() {
                    this.orderbookLoading = true;
                    this.orderbookError = null;
                    try {
                        const response = await axios.get('/api/market/orderbook');
                        if (response.data.success) {
                            this.orderbook = response.data.data.orders;
                        } else {
                            this.orderbookError = response.data.message;
                        }
                    } catch (error) {
                        this.orderbookError = '加载订单簿失败';
                        console.error('加载订单簿失败:', error);
                    } finally {
                        this.orderbookLoading = false;
                    }
                },
                async loadHistoricalBest() {
                    this.historicalBestLoading = true;
                    this.historicalBestError = null;
                    try {
                        const response = await axios.get('/api/market/historical-best', {
                            params: { limit: 10 }
                        });
                        if (response.data.success) {
                            this.historicalBest = response.data.data.orders;
                        } else {
                            this.historicalBestError = response.data.message;
                        }
                    } catch (error) {
                        this.historicalBestError = '加载历史最优报价失败';
                        console.error('加载历史最优报价失败:', error);
                    } finally {
                        this.historicalBestLoading = false;
                    }
                },
                async loadHistoricalHighest() {
                    this.historicalHighestLoading = true;
                    this.historicalHighestError = null;
                    try {
                        const response = await axios.get('/api/market/historical-highest', {
                            params: { limit: 10 }
                        });
                        if (response.data.success) {
                            this.historicalHighest = response.data.data.orders;
                        } else {
                            this.historicalHighestError = response.data.message;
                        }
                    } catch (error) {
                        this.historicalHighestError = '加载历史最高价失败';
                        console.error('加载历史最高价失败:', error);
                    } finally {
                        this.historicalHighestLoading = false;
                    }
                },
                async loadChartData() {
                    if (this.activeTab === 'timeseries') {
                        await this.loadTimeSeries();
                    } else if (this.activeTab === 'trend') {
                        await this.loadHistoricalTrend();
                    }
                },
                async loadTimeSeries() {
                    try {
                        const response = await axios.get('/api/market/timeseries', {
                            params: { hours: 24 }
                        });
                        if (response.data.success) {
                            if (response.data.data && response.data.data.length > 0) {
                                this.renderTimeSeriesChart(response.data.data);
                            } else {
                                this.renderTimeSeriesEmpty('暂无分时数据');
                            }
                        } else {
                            console.error('API返回错误:', response.data.message);
                            this.renderTimeSeriesEmpty(response.data.message || '暂无分时数据');
                        }
                    } catch (error) {
                        console.error('加载分时数据失败:', error);
                        this.renderTimeSeriesEmpty('加载分时数据失败，请稍后重试');
                    }
                },
                async loadHistoricalTrend() {
                    try {
                        const response = await axios.get('/api/market/historical-trend', {
                            params: { limit: 720 } // 默认30天（720小时，30*24）
                        });
                        if (response.data.success) {
                            if (response.data.data && response.data.data.length > 0) {
                                this.trendStatistics = response.data.statistics;
                                this.renderHistoricalTrendChart(response.data.data, response.data.statistics);
                            } else {
                                this.trendStatistics = null;
                                this.renderHistoricalTrendEmpty();
                            }
                        } else {
                            console.error('API返回错误:', response.data.message);
                            this.trendStatistics = null;
                            this.renderHistoricalTrendEmpty(response.data.message || '暂无历史走势数据');
                        }
                    } catch (error) {
                        console.error('加载历史走势数据失败:', error);
                        this.trendStatistics = null;
                        this.renderHistoricalTrendEmpty('加载历史走势数据失败，请稍后重试');
                    }
                },
                switchTab(tab) {
                    this.activeTab = tab;
                    // 切换标签时先清空图表，避免显示混乱
                    if (this.chart) {
                        this.chart.clear();
                    }
                    // 使用 nextTick 确保 DOM 更新后再加载数据
                    this.$nextTick(() => {
                        this.loadChartData();
                    });
                },
                initChart() {
                    this.chart = echarts.init(this.$refs.chartContainer);
                    window.addEventListener('resize', () => {
                        if (this.chart) {
                            this.chart.resize();
                        }
                    });
                },
                renderTimeSeriesChart(data) {
                    if (!this.chart) return;
                    if (!data || data.length === 0) {
                        this.renderTimeSeriesEmpty();
                        return;
                    }

                    const times = data.map(item => item.time);
                    const bestPrices = data.map(item => item.best_price);
                    const avgPrices = data.map(item => item.avg_price);

                    // 计算价格范围，优化Y轴显示
                    const allPrices = [...bestPrices, ...avgPrices].filter(p => p > 0);
                    const minPrice = Math.min(...allPrices);
                    const maxPrice = Math.max(...allPrices);
                    const priceRange = maxPrice - minPrice;
                    const centerPrice = (minPrice + maxPrice) / 2;
                    
                    // 设置Y轴范围，确保波动明显可见
                    // 如果波动范围太小（小于0.001），设置最小显示范围
                    const minRange = 0.001; // 最小显示范围
                    const actualRange = Math.max(priceRange, minRange);
                    const yAxisMin = centerPrice - actualRange * 0.6;
                    const yAxisMax = centerPrice + actualRange * 0.6;

                    const option = {
                        backgroundColor: 'transparent',
                        textStyle: {
                            color: '#e4e4e4'
                        },
                            tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross'
                            },
                            formatter: function(params) {
                                let result = params[0].name + '<br/>';
                                params.forEach(function(item) {
                                    result += item.marker + item.seriesName + ': ' + item.value.toFixed(4) + '<br/>';
                                });
                                return result;
                            },
                            backgroundColor: 'rgba(26, 31, 58, 0.9)',
                            borderColor: '#2a2f4a',
                            textStyle: {
                                color: '#e4e4e4'
                            }
                        },
                        legend: {
                            data: ['最优价', '加权均价'],
                            textStyle: {
                                color: '#e4e4e4'
                            }
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            containLabel: true
                        },
                        xAxis: {
                            type: 'category',
                            boundaryGap: false,
                            data: times,
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            }
                        },
                        yAxis: {
                            type: 'value',
                            min: yAxisMin,
                            max: yAxisMax,
                            scale: false, // 固定范围，让波动更明显
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            splitLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            axisLabel: {
                                formatter: function(value) {
                                    return value.toFixed(4);
                                }
                            }
                        },
                        series: [
                            {
                                name: '最优价',
                                type: 'line',
                                data: bestPrices,
                                smooth: true,
                                lineStyle: {
                                    color: '#f0b90b',
                                    width: 2
                                },
                                itemStyle: {
                                    color: '#f0b90b'
                                },
                                symbol: 'circle',
                                symbolSize: 4,
                                emphasis: {
                                    focus: 'series'
                                }
                            },
                            {
                                name: '加权均价',
                                type: 'line',
                                data: avgPrices,
                                smooth: true,
                                lineStyle: {
                                    color: '#0ecb81',
                                    width: 2,
                                    type: 'dashed'
                                },
                                itemStyle: {
                                    color: '#0ecb81'
                                },
                                symbol: 'circle',
                                symbolSize: 4,
                                emphasis: {
                                    focus: 'series'
                                }
                            }
                        ]
                    };

                    // 使用 notMerge: true 确保完全替换之前的配置
                    this.chart.setOption(option, true);
                },
                renderTimeSeriesEmpty(message) {
                    if (!this.chart) return;
                    
                    const option = {
                        backgroundColor: 'transparent',
                        title: {
                            text: message || '暂无分时数据',
                            left: 'center',
                            top: 'middle',
                            textStyle: {
                                color: '#8b8b8b',
                                fontSize: 16
                            },
                            subtext: '等待数据采集...',
                            subtextStyle: {
                                color: '#666',
                                fontSize: 12
                            }
                        },
                        xAxis: { show: false },
                        yAxis: { show: false },
                        series: []
                    };
                    
                    this.chart.setOption(option, true);
                },
                renderHistoricalTrendEmpty(message) {
                    if (!this.chart) return;
                    
                    const option = {
                        backgroundColor: 'transparent',
                        title: {
                            text: message || '暂无历史走势数据',
                            left: 'center',
                            top: 'middle',
                            textStyle: {
                                color: '#8b8b8b',
                                fontSize: 16
                            },
                            subtext: '请运行命令生成1小时K线数据：php artisan p2p:generate-klines --period=1h',
                            subtextStyle: {
                                color: '#666',
                                fontSize: 12
                            }
                        },
                        xAxis: { show: false },
                        yAxis: { show: false },
                        series: []
                    };
                    
                    this.chart.setOption(option, true);
                },
                renderHistoricalTrendChart(data, statistics) {
                    if (!this.chart) return;
                    if (!data || data.length === 0) {
                        this.renderHistoricalTrendEmpty();
                        return;
                    }

                    // K线数据格式：[开盘, 收盘, 最低, 最高]
                    const klineData = data.map(item => [
                        parseFloat(item.open),
                        parseFloat(item.close),
                        parseFloat(item.low),
                        parseFloat(item.high)
                    ]);
                    const times = data.map(item => item.time);
                    
                    // 涨跌幅数据（用于颜色区分）
                    const changes = data.map(item => item.change_percent || 0);
                    
                    // 找出最高点和最低点的索引（用于标记）
                    let maxHighIndex = 0;
                    let minLowIndex = 0;
                    let maxHigh = data[0].high;
                    let minLow = data[0].low;
                    
                    data.forEach((item, index) => {
                        if (item.high > maxHigh) {
                            maxHigh = item.high;
                            maxHighIndex = index;
                        }
                        if (item.low < minLow) {
                            minLow = item.low;
                            minLowIndex = index;
                        }
                    });

                    // 计算价格范围，优化Y轴显示
                    const allPrices = klineData.flat();
                    const minPrice = Math.min(...allPrices);
                    const maxPrice = Math.max(...allPrices);
                    const priceRange = maxPrice - minPrice;
                    const minRange = 0.001;
                    const actualRange = Math.max(priceRange, minRange);
                    const yAxisMin = minPrice - actualRange * 0.1;
                    const yAxisMax = maxPrice + actualRange * 0.1;

                    // 标记点数据（最高点和最低点）
                    const markPoints = [];
                    if (statistics) {
                        markPoints.push({
                            name: '历史最高',
                            coord: [maxHighIndex, maxHigh],
                            value: maxHigh.toFixed(4),
                            itemStyle: { color: '#0ecb81' },
                            label: {
                                formatter: '最高: {c}',
                                position: 'top'
                            }
                        });
                        markPoints.push({
                            name: '历史最低',
                            coord: [minLowIndex, minLow],
                            value: minLow.toFixed(4),
                            itemStyle: { color: '#f6465d' },
                            label: {
                                formatter: '最低: {c}',
                                position: 'bottom'
                            }
                        });
                    }

                    const option = {
                        backgroundColor: 'transparent',
                        textStyle: {
                            color: '#e4e4e4'
                        },
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross'
                            },
                            formatter: function(params) {
                                if (params && params.length > 0) {
                                    const param = params[0];
                                    const index = param.dataIndex;
                                    const item = data[index];
                                    let result = param.name + '<br/>';
                                    
                                    if (param.seriesName === 'K线') {
                                        const kline = param.data;
                                        if (Array.isArray(kline) && kline.length >= 4) {
                                            result += '开盘: ' + parseFloat(kline[0]).toFixed(4) + '<br/>';
                                            result += '收盘: ' + parseFloat(kline[1]).toFixed(4) + '<br/>';
                                            result += '最低: ' + parseFloat(kline[2]).toFixed(4) + '<br/>';
                                            result += '最高: ' + parseFloat(kline[3]).toFixed(4) + '<br/>';
                                        }
                                    } else {
                                        result += param.marker + param.seriesName + ': ' + param.value.toFixed(4) + '<br/>';
                                    }
                                    
                                    if (item.change_percent !== null) {
                                        const changeColor = item.is_up ? '#0ecb81' : '#f6465d';
                                        result += '<span style="color:' + changeColor + '">涨跌: ' + 
                                            (item.change_percent >= 0 ? '+' : '') + item.change_percent.toFixed(2) + '%</span><br/>';
                                    }
                                    if (item.volatility !== null) {
                                        result += '波动率: ' + item.volatility.toFixed(2) + '%<br/>';
                                    }
                                    
                                    return result;
                                }
                                return '';
                            },
                            backgroundColor: 'rgba(26, 31, 58, 0.9)',
                            borderColor: '#2a2f4a',
                            textStyle: {
                                color: '#e4e4e4'
                            }
                        },
                        grid: {
                            left: '10%',
                            right: '10%',
                            bottom: '15%',
                            top: '10%'
                        },
                        xAxis: {
                            type: 'category',
                            data: times,
                            scale: true,
                            boundaryGap: false,
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            splitLine: {
                                show: false
                            },
                            axisLabel: {
                                formatter: function(value) {
                                    // 只显示日期和时间，不显示秒
                                    return value.substring(0, 16);
                                },
                                rotate: 45
                            }
                        },
                        yAxis: {
                            type: 'value',
                            min: yAxisMin,
                            max: yAxisMax,
                            scale: false,
                            splitArea: {
                                show: true,
                                areaStyle: {
                                    color: ['rgba(42, 47, 74, 0.1)', 'rgba(42, 47, 74, 0.05)']
                                }
                            },
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            splitLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            axisLabel: {
                                formatter: function(value) {
                                    return value.toFixed(4);
                                }
                            }
                        },
                        dataZoom: [
                            {
                                type: 'inside',
                                start: Math.max(0, 100 - (720 / data.length) * 100), // 默认显示最近30天（720小时）
                                end: 100
                            },
                            {
                                show: true,
                                type: 'slider',
                                top: '90%',
                                start: Math.max(0, 100 - (720 / data.length) * 100), // 默认显示最近30天
                                end: 100
                            }
                        ],
                        series: [
                            {
                                name: 'K线',
                                type: 'candlestick',
                                data: klineData,
                                markPoint: {
                                    data: markPoints,
                                    label: {
                                        color: '#e4e4e4'
                                    }
                                },
                                itemStyle: {
                                    color: '#0ecb81', // 涨（绿色）
                                    color0: '#f6465d', // 跌（红色）
                                    borderColor: '#0ecb81',
                                    borderColor0: '#f6465d'
                                }
                            },
                            {
                                name: '收盘价趋势',
                                type: 'line',
                                data: data.map(item => item.close),
                                smooth: true,
                                lineStyle: {
                                    color: '#f0b90b',
                                    width: 2
                                },
                                itemStyle: {
                                    color: '#f0b90b'
                                },
                                symbol: 'none',
                                emphasis: {
                                    focus: 'series'
                                }
                            }
                        ]
                    };

                    this.chart.setOption(option, true);
                },
                renderKLineChart(data) {
                    if (!this.chart) return;
                    if (!data || data.length === 0) {
                        this.renderKLineEmpty();
                        return;
                    }

                    // ECharts candlestick数据格式：[开盘, 收盘, 最低, 最高]
                    const klineData = data.map(item => [
                        parseFloat(item.open),
                        parseFloat(item.close),
                        parseFloat(item.low),
                        parseFloat(item.high)
                    ]);
                    const times = data.map(item => item.time);

                    // 计算价格范围，优化Y轴显示
                    const allPrices = klineData.flat();
                    const minPrice = Math.min(...allPrices);
                    const maxPrice = Math.max(...allPrices);
                    const priceRange = maxPrice - minPrice;
                    const minRange = 0.001; // 最小显示范围
                    const actualRange = Math.max(priceRange, minRange);
                    const yAxisMin = minPrice - actualRange * 0.1;
                    const yAxisMax = maxPrice + actualRange * 0.1;

                    const option = {
                        backgroundColor: 'transparent',
                        textStyle: {
                            color: '#e4e4e4'
                        },
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross'
                            },
                            formatter: function(params) {
                                if (params && params.length > 0 && params[0].data && Array.isArray(params[0].data)) {
                                    const data = params[0].data;
                                    if (data.length >= 4) {
                                        return params[0].name + '<br/>' +
                                            '开盘: ' + parseFloat(data[0]).toFixed(4) + '<br/>' +
                                            '收盘: ' + parseFloat(data[1]).toFixed(4) + '<br/>' +
                                            '最低: ' + parseFloat(data[2]).toFixed(4) + '<br/>' +
                                            '最高: ' + parseFloat(data[3]).toFixed(4);
                                    }
                                }
                                return '';
                            },
                            backgroundColor: 'rgba(26, 31, 58, 0.9)',
                            borderColor: '#2a2f4a',
                            textStyle: {
                                color: '#e4e4e4'
                            }
                        },
                        grid: {
                            left: '10%',
                            right: '10%',
                            bottom: '15%'
                        },
                        xAxis: {
                            type: 'category',
                            data: times,
                            scale: true,
                            boundaryGap: false,
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            splitLine: {
                                show: false
                            },
                            min: 'dataMin',
                            max: 'dataMax'
                        },
                        yAxis: {
                            type: 'value',
                            min: yAxisMin,
                            max: yAxisMax,
                            scale: false, // 固定范围，让K线更明显
                            splitArea: {
                                show: true
                            },
                            axisLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            splitLine: {
                                lineStyle: {
                                    color: '#2a2f4a'
                                }
                            },
                            axisLabel: {
                                formatter: function(value) {
                                    return value.toFixed(4);
                                }
                            }
                        },
                        dataZoom: [
                            {
                                type: 'inside',
                                start: 50,
                                end: 100
                            },
                            {
                                show: true,
                                type: 'slider',
                                top: '90%',
                                start: 50,
                                end: 100
                            }
                        ],
                        series: [
                            {
                                name: 'K线',
                                type: 'candlestick',
                                data: klineData,
                                itemStyle: {
                                    color: '#0ecb81',
                                    color0: '#f6465d',
                                    borderColor: '#0ecb81',
                                    borderColor0: '#f6465d'
                                }
                            }
                        ]
                    };

                    // 使用 notMerge: true 确保完全替换之前的配置
                    this.chart.setOption(option, true);
                },
                formatPrice(price) {
                    if (!price) return '0.0000';
                    return parseFloat(price).toFixed(4);
                },
                formatAmount(amount) {
                    if (!amount) return '0';
                    if (amount >= 1000) {
                        return (amount / 1000).toFixed(1) + 'K';
                    }
                    return parseFloat(amount).toFixed(0);
                },
                getBanks(banksStr) {
                    if (!banksStr) return [];
                    return banksStr.split(',').map(b => b.trim()).filter(b => b);
                }
            }
            }).mount('#app');
        })();
    </script>
</body>
</html>

