乐于分享
好东西不私藏

通达信小插件——板块资金流向V1 选择日历可以复盘历史数据

通达信小插件——板块资金流向V1 选择日历可以复盘历史数据
通达信小插件——板块资金流向V1 选择日历可以复盘历史数据

板块资金流向V1版本修改旧版涨停全部按照10%计算,科创板和创业板、北交所、ST涨停计算都存在BUG ,新版修改了这些BUG ,主板包块主板ST全部按照10%统计,科创板和创业板包块ST按照20%统计,北交所按照30%统计,这样真实还原涨停的原貌

新版增加了历史数据复盘功能选择日历可以复盘历史数据,历史数据成分股只输出涨停和炸板,当前数据成分股全部显示,增加搜索框输入关键词快速查找板块。版面默认每10秒自动刷新数据,可以点击暂停刷新,板块默认显示流入和流出前10,点击全部显示全部流入板块。

源代码如下:
<!DOCTYPE html><htmllang="zh-CN"><head>    <metacharset="UTF-8">    <metaname="viewport"content="width=device-width, initial-scale=1.0">    <title>板块实时资金流向</title>    <scriptsrc="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js">    </script>    <style>        :root {            --bg#0f0f14;            --card-bg#1a1a24;            --card-bg-hover#22222e;            --text#e0e0e0;            --sub#8b8b9e;            --up#ff5252;            --down#4caf50;            --accent#ff5252;            --border#2a2a38;            --radius12px;        }        * {            margin0;            padding0;            box-sizing: border-box;        }        body {            font-family"Microsoft YaHei""PingFang SC""Helvetica Neue", sans-serif;            backgroundvar(--bg);            min-height100vh;            colorvar(--text);            padding12px;        }        .main-layout {            max-width1800px;            margin0 auto;            display: flex;            gap12px;            align-items: flex-start;        }        .plate-panel {            width320px;            min-width320px;            backgroundvar(--card-bg);            border1px solid var(--border);            border-radiusvar(--radius);            padding12px;            heightcalc(100vh - 24px);            overflow-y: auto;            position: sticky;            top12px;        }        .panel-header {            font-size15px;            font-weight: bold;            color#ff9800;            margin-bottom6px;            display: flex;            flex-wrap: wrap;            justify-content: space-between;            align-items: center;            gap6px;            position: relative;        }        .header-left {            display: flex;            align-items: center;            gap8px;            flex-wrap: wrap;        }        .header-right {            display: flex;            align-items: center;            gap6px;            flex-wrap: wrap;        }        .panel-sub {            font-size11px;            colorvar(--sub);            margin-bottom6px;            display: flex;            gap10px;            align-items: center;        }        .sort-btn {            font-size11px;            color#aaa;            cursor: pointer;            padding2px 6px;            border-radius3px;            transition: all 0.15s;            user-select: none;        }        .sort-btn:hover {            color#ff9800;            backgroundrgba(25515200.1);        }        .sort-btn.active {            color#ff9800;            font-weight: bold;        }        .refresh-bar {            display: flex;            align-items: center;            justify-content: space-between;            padding8px 10px;            backgroundrgba(2552552550.02);            border-radius6px;            margin-bottom10px;            font-size12px;            colorvar(--sub);            gap8px;        }        .select-all-btn {            font-size11px;            color#aaa;            cursor: pointer;            padding3px 10px;            border-radius4px;            border1px solid #444;            background: transparent;            transition: all 0.15s;            white-space: nowrap;            flex-shrink0;        }        .select-all-btn:hover {            color#ff9800;            border-color#ff9800;            backgroundrgba(25515200.1);        }        .select-all-btn.all-selected {            color#ff9800;            border-color#ff9800;        }        .flow-list {            list-style: none;        }        .flow-group-title {            font-size11px;            font-weight: bold;            padding8px 8px 4px;            margin-top6px;            colorvar(--sub);            border-bottom1px dashed rgba(2552552550.06);            margin-bottom4px;            display: flex;            align-items: center;            gap6px;        }        .flow-group-title.in {            colorvar(--up);        }        .flow-group-title.out {            colorvar(--down);        }        .flow-item {            display: flex;            align-items: center;            justify-content: space-between;            padding7px 8px;            border-radius6px;            transition: all 0.15s;            cursor: pointer;            font-size13px;            margin-bottom3px;        }        .flow-item:hover {            backgroundvar(--card-bg-hover);        }        .flow-item.active {            backgroundrgba(25582820.12);            border-left3px solid var(--up);        }        .flow-left {            display: flex;            align-items: center;            gap8px;            overflow: hidden;            flex1;            min-width0;        }        .flow-check {            width16px;            height16px;            border-radius3px;            border2px solid #555;            flex-shrink0;            display: flex;            align-items: center;            justify-content: center;            font-size11px;            font-weight: bold;            cursor: pointer;            transition: all 0.15s;            user-select: none;            line-height1;        }        .flow-check.checked {            border-width0;        }        .flow-check:hover {            opacity0.8;            transformscale(1.1);        }        .flow-name {            colorvar(--text);            white-space: nowrap;            overflow: hidden;            text-overflow: ellipsis;            font-weight500;        }        .flow-change-col {            font-size11px;            font-weight600;            flex-shrink0;            width60px;            text-align: right;        }        .flow-change-col.up {            colorvar(--up);        }        .flow-change-col.down {            colorvar(--down);        }        .flow-value-col {            font-size11px;            font-weight600;            flex-shrink0;            width62px;            text-align: right;        }        .flow-value-col.up {            colorvar(--up);        }        .flow-value-col.down {            colorvar(--down);        }        .right-content {            flex1;            min-width0;            display: flex;            flex-direction: column;            gap12px;        }        .chart-section {            backgroundvar(--card-bg);            border1px solid var(--border);            border-radiusvar(--radius);            padding8px 12px;        }        #barChart {            width100%;            height380px;        }        .chart-container {            position: relative;            width100%;            height380px;        }        .chart-loading {            position: absolute;            top0;            left0;            right0;            bottom0;            display: flex;            flex-direction: column;            align-items: center;            justify-content: center;            backgroundrgba(1515200.8);            z-index10;            border-radiusvar(--radius);        }        .chart-loading .loader {            width40px;            height40px;            border3px solid rgba(25515200.2);            border-top-color#ff9800;            border-radius50%;            animation: spin 0.8s linear infinite;            margin-bottom12px;        }        .chart-loading span {            color#ff9800;            font-size14px;        }        @keyframes spin {            to {                transformrotate(360deg);            }        }        .member-panel {            backgroundvar(--card-bg);            border1px solid var(--border);            border-radiusvar(--radius);            padding12px;            display: flex;            flex-direction: column;            flex1;            min-height0;        }        .member-header {            display: flex;            justify-content: space-between;            align-items: center;            margin-bottom12px;            padding-bottom12px;            border-bottom1px solid var(--border);        }        .member-title {            font-size16px;            font-weight: bold;            color#ff9800;            line-height1.4;        }        .btn-group {            display: flex;            gap8px;        }        .btn {            backgroundrgba(25582820.15);            border1px solid rgba(25582820.3);            color#ff8a80;            padding6px 14px;            border-radius6px;            cursor: pointer;            font-size12px;            transition: all 0.2s;        }        .btn:hover {            backgroundrgba(25582820.25);            transformtranslateY(-1px);        }        .btn-secondary {            backgroundrgba(2552552550.05);            border-colorrgba(2552552550.1);            colorvar(--sub);        }        .member-table-wrapper {            overflow-y: auto;            flex1;            min-height0;        }        table {            width100%;            border-collapse: collapse;            font-size12px;        }        th {            backgroundrgba(2552552550.04);            padding10px 8px;            text-align: left;            font-weight600;            colorvar(--sub);            border-bottom1px solid var(--border);            position: sticky;            top0;            z-index1;        }        td {            padding8px;            border-bottom1px solid rgba(2552552550.03);        }        .stock-row {            cursor: pointer;            transition: background 0.15s;        }        .stock-row:hover {            backgroundrgba(2552552550.03);        }        .stock-code {            color#64b5f6;        }        .loading-text {            text-align: center;            padding40px;            colorvar(--sub);        }        .stock-tooltip {            position: fixed;            background#1a1a2e;            border1px solid #FFD700;            padding12px 16px;            border-radius10px;            font-size14px;            color#FFD700;            z-index9999;            width380px;            max-height450px;            overflow-y: auto;            box-shadow0 4px 20px rgba(25521500.3);            pointer-events: none;            display: none;            line-height1.6;        }        .stock-tooltip .label {            color#fff;            font-weight: bold;        }        .stock-tooltip .value {            color#FFD700;        }        .stock-tooltip .divider {            color#666;            margin0 8px;        }        .stock-tooltip .analysis-section {            margin-top12px;            border-top1px solid #FFD700;            padding-top12px;        }        .stock-tooltip .info-row {            white-space: nowrap;            overflow: hidden;            text-overflow: ellipsis;            margin-bottom6px;        }        .leader-tag {            display: inline-block;            padding2px 6px;            backgroundlinear-gradient(135deg#e74c3c#c0392b);            color#fff;            border-radius10px;            font-size10px;            font-weight600;            margin-left6px;        }        ::-webkit-scrollbar {            width6px;            height6px;        }        ::-webkit-scrollbar-track {            background: transparent;        }        ::-webkit-scrollbar-thumb {            backgroundrgba(2552552550.12);            border-radius3px;        }        ::-webkit-scrollbar-thumb:hover {            backgroundrgba(2552552550.25);        }        .plate-search {            backgroundrgba(2552552550.04);            border1px solid rgba(2552552550.1);            border-radius6px;            padding5px 8px;            colorvar(--text);            font-size12px;            outline: none;            min-width70px;            max-width140px;            transition: all 0.2s;        }        .plate-search::placeholder {            color#666;        }        .plate-search:focus {            border-color#ff9800;            backgroundrgba(25515200.05);            max-width160px;        }        .date-nav {            display: flex;            align-items: center;            gap4px;            backgroundrgba(2552552550.04);            padding3px 6px;            border-radius20px;            border1px solid rgba(2552552550.1);        }        .date-btn {            width24px;            height24px;            backgroundrgba(2552552550.06);            border1px solid rgba(2552552550.15);            border-radius50%;            color#ff9800;            font-size11px;            cursor: pointer;            display: flex;            align-items: center;            justify-content: center;            transition: all 0.2s;        }        .date-btn:hover {            backgroundrgba(25515200.15);            border-color#ff9800;        }        .date-btn:disabled {            opacity0.3;            cursor: not-allowed;        }        .date-display {            background#000;            padding3px 12px;            border-radius12px;            font-weight: bold;            color#00ced1;            cursor: pointer;            min-width90px;            text-align: center;            font-size12px;            border1px solid #1e2430;            transition: all 0.2s;        }        .date-display:hover {            backgroundrgba(25515200.1);            border-color#ff9800;        }        .calendar-popup {            position: absolute;            top50px;            left50%;            transformtranslateX(-50%);            background#12161e;            border1px solid #2a3f5f;            border-radius12px;            padding12px;            z-index1000;            box-shadow0 8px 30px rgba(0000.8);            display: none;            font-size12px;            min-width280px;        }        .calendar-popup.show {            display: block;        }        .cal-header {            display: flex;            justify-content: space-between;            align-items: center;            margin-bottom12px;            padding-bottom8px;            border-bottom1px solid #2a3f5f;        }        .cal-header span {            color#ff9800;            font-weight: bold;            font-size14px;        }        .cal-header button {            background#1a2a3f;            border1px solid #3a5f8f;            color#e4e7f0;            padding2px 10px;            border-radius6px;            cursor: pointer;            font-size12px;            transition: all 0.2s;        }        .cal-header button:hover {            background#2a4a6f;            border-color#ff9800;        }        .cal-grid {            display: grid;            grid-template-columnsrepeat(736px);            gap4px;        }        .cal-day {            width36px;            height32px;            display: flex;            align-items: center;            justify-content: center;            font-size12px;            background#0a0f1f;            border-radius8px;            cursor: pointer;            color#aaa;            border1px solid transparent;            transition: all 0.2s;        }        .cal-day:hover {            background#ff9800;            color#000;        }        .cal-day.selected {            background#ff9800;            color#000;            font-weight: bold;        }        .cal-day.has-data {            border-color#4caf50;        }        .cal-day.other-month {            color#555;        }        .cal-day.today {            box-shadow: inset 0 0 0 2px #42a5f5;        }        .cal-close {            position: absolute;            top8px;            right10px;            cursor: pointer;            font-size14px;            color#888;            transition: color 0.2s;        }        .cal-close:hover {            color#ff9800;        }        * {            scrollbar-width: thin;            scrollbar-colorrgba(2552552550.12) transparent;        }        @media (max-width1200px) {            .main-layout {                flex-direction: column;            }            .plate-panel {                width100%;                min-width: unset;                height: auto;                max-height280px;                position: static;            }        }    </style></head><body>    <divclass="main-layout">        <!-- 左侧板块列表 -->        <divclass="plate-panel">            <divclass="panel-header">                <divclass="header-left">                    <span>🔥 板块资金流向</span>                    <spanstyle="color:red; font-weight:bold; margin-left:4px; font-size:16px;">V1</span>                    <buttonclass="select-all-btn"id="selectAllBtn"onclick="toggleShowAllPlates()">☐ 全部板块</button>                </div>                <divclass="header-right">                    <inputtype="text"id="plateSearch"class="plate-search"placeholder="🔍 搜索板块..." />                    <divclass="date-nav">                        <divclass="date-btn"id="prevDayBtn"></div>                        <divclass="date-display"id="calendarDisplay">今日数据</div>                        <divclass="date-btn"id="nextDayBtn"></div>                    </div>                    <buttonclass="btn btn-secondary"id="refreshBtn">⏸️ 暂停</button>                </div>                <divclass="calendar-popup"id="calendarPopup">                    <spanclass="cal-close"id="calCloseBtn"></span>                    <divclass="cal-header">                        <buttonid="prevMonthCal"></button>                        <spanid="calendarMonth"></span>                        <buttonid="nextMonthCal"></button>                    </div>                    <divclass="cal-grid"id="calendarGrid"></div>                </div>            </div>            <divclass="panel-sub">                <span>单位:亿元</span>                <spanclass="sort-btn active"id="sortNetFlow"onclick="togglePlateSort('netFlow')">净流入 ↕</span>                <spanclass="sort-btn"id="sortChange"onclick="togglePlateSort('change')">涨幅 ↕</span>                <spanstyle="color:#ff5252;font-weight:bold;font-size:12px;margin-left:4px;">白交易</span>            </div>            <divclass="refresh-bar">                <spanid="refreshStatus">⏳ 加载中...</span>                <spanid="updateTime"></span>            </div>            <ulclass="flow-list"id="flowList"></ul>        </div>        <!-- 右侧内容 -->        <divclass="right-content">            <divclass="chart-section">                <divstyle="font-size:16px; font-weight:bold; color:#ff9800; margin-bottom:8px;">💰 板块资金净流入排行</div>                <divclass="chart-container">                    <divid="barChart"></div>                    <divid="chartLoading"class="chart-loading"style="display:none;">                        <divclass="loader"></div>                        <span>加载数据中...</span>                    </div>                </div>            </div>            <divclass="member-panel">                <divclass="member-header">                    <spanclass="member-title"id="memberTitle">🔍 成分股</span>                    <divclass="btn-group">                        <buttonclass="btn"id="exportBtn">📥 导出成分股</button>                    </div>                </div>                <divclass="member-table-wrapper"id="memberWrapper">                    <divclass="loading-text"id="memberPlaceholder">👆 请点击左侧板块名称查看成分股</div>                    <tableid="memberTable"style="display:none">                        <thead>                            <tr>                                <th>代码</th>                                <th>名称</th>                                <th>最新价</th>                                <thstyle="cursor:pointer;color:#ff9800;"onclick="toggleMemberSort('change')">涨跌幅 ↕</th>                                <th>成交额</th>                                <thstyle="cursor:pointer;color:#ff9800;"onclick="toggleMemberSort('netFlow')">净流入 ↕</th>                            </tr>                        </thead>                        <tbodyid="memberTbody"></tbody>                    </table>                </div>            </div>        </div>    </div>    <divid="stockTooltip"class="stock-tooltip"></div>    <script>        // ===================== 全局变量 =====================        let plateList = [];        let activePlateCode = '';        let barChartInstance = null;        let currentMembers = [];        let refreshTimer = null;        let memberSortCol = 'netFlow';        let memberSortDir = 'desc';        let plateSortCol = 'netFlow';        let plateSortDir = 'desc';        let isAutoRefreshPaused = false;        let searchKeyword = '';        let selectedDate = '';        let calendarDateList = [];        let calendarCurrentMonth = new Date();        let isHistoricalMode = false;        let historicalSectorData = [];        const EM_HIST_UT = '7eea3edcaed734bea9cbfc24409ed989';        const EM_HIST_BASE = 'https://push2ex.eastmoney.com';        const TIER_LEVEL = { '五板+'7'五板'6'四板'5'三板'4'二板'3'首板'2'秒板'1 };        const PALETTE = [            '#ff5252''#ff9800''#ffd600''#69f0ae''#40c4ff',            '#e040fb''#f48fb1''#80cbc4''#fff176''#b0bec5',            '#ff7043''#a5d6a7''#4dd0e1''#ce93d8''#ffcc80',            '#ef9a9a''#90caf9''#c5e1a5''#ffe082''#b39ddb',            '#80deea''#ffab91''#bcaaa4''#e6ee9c''#b2dfdb',            '#f8bbd0''#dcedc8''#b3e5fc''#fce4ec''#e8f5e9',            '#ff1744''#ff6d00''#ffd740''#00e676''#00b0ff',            '#d500f9''#651fff''#3d5afe''#1de9b6''#76ff03',            '#ff9100''#ffea00''#c6ff00''#00e5ff''#2979ff',            '#aa00ff''#dd2c00''#ff3d00''#ff6e40''#ffd180',            '#ccff90''#a7ffeb''#80d8ff''#ea80fc''#ff80ab',            '#b9f6ca''#e0f7fa''#e8eaf6''#fbe9e7''#fff8e1'        ];        let plateColorMap = {};        const PLATE_BASE = 'https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=2&invt=2&fid=f62&fs=m:90+t:3&fields=f2,f3,f6,f12,f14,f62';        const PLATES_API_IN = `${PLATE_BASE}&pn=1&pz=100&po=1`;        const PLATES_API_OUT = `${PLATE_BASE}&pn=1&pz=100&po=0`;        // ===================== 工具函数 =====================        function toast(msg) {            let t = document.createElement('div');            t.style.cssText = 'position:fixed;top:80px;right:20px;background:#1e1e2e;border-left:4px solid #ff5252;padding:10px 20px;z-index:9999;color:#fff;font-size:14px;border-radius:4px';            t.textContent = msg;            document.body.appendChild(t);            setTimeout(() => t.remove(), 2000);        }        function formatTime(timestamp) {            if (!timestamp) return '';            const date = new Date(timestamp * 1000);            return date.toLocaleTimeString('zh-CN', { hour'2-digit'minute'2-digit'second'2-digit'hour12false });        }        function formatStockCode(code) {            if (!code) return '';            const cleaned = code.toString().replace(/\.(SS|SZ|SH|HK|US)$/i'');            return cleaned.padStart(6'0');        }        // 获取股票对应的涨停百分比(数值)        // 主板(00、60)→ 10%,科创板(688)和创业板(30)→ 20%,北交所(4、8、9)→ 30%        function getStockLimitPercent(code) {            if (!code) return 10;            const c = code.toString().trim();            if (c.startsWith('00') || c.startsWith('60')) {                return 10;            }            if (c.startsWith('688') || c.startsWith('30')) {                return 20;  // 科创/创业板 20%            }            if (c.startsWith('4') || c.startsWith('8') || c.startsWith('9')) {                return 30;  // 北交所 30%            }            return 10;        }        window.linkToTdx = function(code) {            window.location.href = `http://www.treeid/code_${code}`;            toast(`联动通达信 ${code}`);        };        async function fetchJSON(url) {            try {                const response = await fetch(url, { cache'no-cache' });                return await response.json();            } catch (e) {                console.error('请求失败:', url, e);                return null;            }        }        function assignPlateColors(list) {            list.forEach((plate) => {                if (!plateColorMap[plate.code]) {                    plateColorMap[plate.code] = PALETTE[Object.keys(plateColorMap).length % PALETTE.length];                }            });        }        // ===================== 排序 =====================        function togglePlateSort(col) {            if (plateSortCol === col) {                plateSortDir = plateSortDir === 'desc' ? 'asc' : 'desc';            } else {                plateSortCol = col;                plateSortDir = 'desc';            }            sortPlateList();            renderPlateList();            document.getElementById('sortNetFlow').classList.remove('active');            document.getElementById('sortChange').classList.remove('active');            document.getElementById(col === 'netFlow' ? 'sortNetFlow' : 'sortChange').classList.add('active');        }        function sortPlateList() {            plateList.sort((a, b) => {                let va = parseFloat(a[plateSortCol]) || 0;                let vb = parseFloat(b[plateSortCol]) || 0;                return plateSortDir === 'desc' ? vb - va : va - vb;            });        }        function initDefaultSelection() {            if (selectedPlateCodes.size > 0return;            plateList.slice(06).forEach(p => selectedPlateCodes.add(p.code));            const outPlates = plateList                .filter(p => parseFloat(p.netFlow) < 0)                .sort((a, b) => parseFloat(a.netFlow) - parseFloat(b.netFlow));            outPlates.slice(06).forEach(p => selectedPlateCodes.add(p.code));        }        // ===================== 加载板块数据 =====================        async function loadPlateData() {            try {                document.getElementById('refreshStatus').textContent = '⏳ 加载中...';                document.getElementById('chartLoading').style.display = 'flex';                if (selectedDate) {                    if (!isHistoricalMode) selectedPlateCodes.clear();                    isHistoricalMode = true;                    await loadHistoricalPlateData(selectedDate);                    document.getElementById('chartLoading').style.display = 'none';                    return;                }                if (isHistoricalMode) selectedPlateCodes.clear();                isHistoricalMode = false;                const [inData, outData] = await Promise.all([                    fetchJSON(PLATES_API_IN),                    fetchJSON(PLATES_API_OUT)                ]);                const merged = new Map();                if (inData && inData.data && inData.data.diff) {                    inData.data.diff.forEach(item => {                        merged.set(item.f12, {                            code: item.f12,                            name: item.f14,                            change: item.f3 || 0,                            price: item.f2 || 0,                            amount: item.f6 ? item.f6 / 1e8 : 0,                            netFlow: item.f62 ? item.f62 / 1e8 : 0                        });                    });                }                if (outData && outData.data && outData.data.diff) {                    outData.data.diff.forEach(item => {                        if (!merged.has(item.f12)) {                            merged.set(item.f12, {                                code: item.f12,                                name: item.f14,                                change: item.f3 || 0,                                price: item.f2 || 0,                                amount: item.f6 ? item.f6 / 1e8 : 0,                                netFlow: item.f62 ? item.f62 / 1e8 : 0                            });                        }                    });                }                plateList = Array.from(merged.values());                if (plateList.length === 0throw new Error('无数据');                try {                    const todayStr = getTodayStr();                    const topicEvents = await fetchHistoricalEvents(todayStr);                    if (topicEvents && topicEvents.length > 0) {                        const processed = processHistoricalEvents(topicEvents.map(e => Object.assign({}, e)));                        const topicSectors = buildHistoricalSectorData(processed);                        const topicMap = new Map(topicSectors.map(s => [s.name, s]));                        plateList.forEach(p => {                            const ts = topicMap.get(p.name);                            if (ts) {                                p.ztCount = ts.ztCount;                                p.zbCount = ts.zbCount;                                p.dtCount = ts.dtCount;                                p.maxBoard = ts.maxBoard;                                p.leader = ts.leader;                                p.ztList = ts.ztList;                                p.zbList = ts.zbList;                                p.topicFund = ts.fund;                            }                        });                    }                } catch (topicErr) {                    console.warn('实时涨停池补充数据获取失败:', topicErr);                }                if (!plateSortCol) { plateSortCol = 'netFlow';                    plateSortDir = 'desc'; }                sortPlateList();                assignPlateColors(plateList);                initDefaultSelection();                renderPlateList();                updateBarChart();                document.getElementById('sortNetFlow').classList.toggle('active', plateSortCol === 'netFlow');                document.getElementById('sortChange').classList.toggle('active', plateSortCol === 'change');                document.getElementById('refreshStatus').textContent = '✅ 已更新';                document.getElementById('updateTime').textContent = new Date().toLocaleTimeString();                document.getElementById('chartLoading').style.display = 'none';            } catch (e) {                console.error('获取板块数据失败:', e);                document.getElementById('refreshStatus').textContent = '⚠️ 数据获取失败';                document.getElementById('chartLoading').style.display = 'none';                toast('板块数据获取失败: ' + e.message);            }        }        // ===================== 历史数据相关 =====================        function getPlateFlowKlineUrl(code) {            let url =                `https://push2his.eastmoney.com/api/qt/stock/fflow/kline/get?secid=90.${code}&klt=1&lmt=0&fields1=f1,f2,f3,f7&fields2=f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63,f64,f65&ut=fa5fd1943c7b386f172d6893dbfba10b&_=${Date.now()}`;            if (isHistoricalMode && selectedDate) {                url += `&date=${selectedDate}`;            }            return url;        }        function getMemberUrl(code) {            return `https://push2.eastmoney.com/api/qt/clist/get?pn=1&pz=80&po=1&np=1&fltt=2&invt=2&fid=f3&fs=b:${code}&fields=f2,f3,f6,f12,f14,f62`;        }        async function searchPlateCodeByName(name) {            try {                const url =                    `https://push2.eastmoney.com/api/qt/simple/screen?fltt=2&invt=2&fields=f57,f58,f116&secids=m:90+t:3&_=${Date.now()}`;                const data = await fetchJSON(url);                if (data && data.data && data.data.diff) {                    const matched = data.data.diff.find(item => item.f58 === name);                    if (matched) {                        return matched.f57;                    }                }            } catch (e) {                console.error('搜索板块代码失败:', e);            }            return null;        }        const STOCKS_API = 'https://flash-api.xuangubao.com.cn/api/surge_stock/stocks';        let stockAnalysisCache = {};        function emHistBuildUrl(poolType, dateStr) {            const d = dateStr.replace(/-/g'');            const ts = Date.now();            const sort = poolType === 'dt' ? 'fund:asc' : 'fbt:asc';            const urlMap = {                ztEM_HIST_BASE + '/getTopicZTPool',                zbEM_HIST_BASE + '/getTopicZBPool',                dtEM_HIST_BASE + '/getTopicDTPool'            };            return urlMap[poolType] + '?ut=' + EM_HIST_UT + '&dpt=wz.ztzt&Pageindex=0&Pagesize=500&sort=' + encodeURIComponent(                sort) + '&date=' + d + '&_=' + ts + '&cb=__emCallback';        }        function emHistParseTime(fbt) {            if (!fbt || typeof fbt !== 'number'return 565;            const s = String(Math.round(fbt)).padStart(6'0');            return parseInt(s.substring(02)) * 60 + parseInt(s.substring(24));        }        function emHistParseZT(data) {            const list = [];            const pool = data && data.data && data.data.pool;            if (!pool) return list;            pool.forEach(item => {                list.push({                    name: item.n || '',                    code: item.c || '',                    reason: item.hybk || '其他',                    price: (item.p || 0) / 1000,                    timeemHistParseTime(item.fbt),                    type'zt',                    tierString(item.lbc || 1),                    fund: item.fund || 0,                    zttz: item.zttz || '',                    isSecfalse,                    tag''                });            });            return list;        }        function emHistParseZB(data) {            const list = [];            const pool = data && data.data && data.data.pool;            if (!pool) return list;            pool.forEach(item => {                list.push({                    name: item.n || '',                    code: item.c || '',                    reason: item.hybk || '其他',                    price: (item.p || 0) / 1000,                    timeemHistParseTime(item.fbt),                    type'zb',                    tag'炸',                    fund: item.fund || 0,                    zttz: item.zttz || ''                });            });            return list;        }        function emHistParseDT(data) {            const list = [];            const pool = data && data.data && data.data.pool;            if (!pool) return list;            pool.forEach(item => {                list.push({                    name: item.n || '',                    code: item.c || '',                    reason: item.hybk || '其他',                    price: (item.p || 0) / 1000,                    timeemHistParseTime(item.lbt),                    type'dt',                    tag'跌停',                    fund: item.fund || 0,                    zttz: item.zttz || ''                });            });            return list;        }        function jsonp(url, timeout = 15000) {            return new Promise((resolve, reject) => {                const cbName = '__jsonp_' + Math.random().toString(36).substring(210);                const timer = setTimeout(() => { cleanup();                    reject(new Error('timeout')); }, timeout);                function cleanup() {                    clearTimeout(timer);                    delete window[cbName];                    const s = document.getElementById(cbName);                    if (s && s.parentNode) s.parentNode.removeChild(s);                }                window[cbName] = (data) => { cleanup();                    resolve(data); };                const finalUrl = url.replace(/cb=[^&]*/'cb=' + cbName);                const script = document.createElement('script');                script.id = cbName;                script.src = finalUrl;                script.onerror = () => { cleanup();                    reject(new Error('script load error')); };                document.head.appendChild(script);            });        }        async function fetchHistoricalEvents(dateStr) {            const parsers = { zt: emHistParseZT, zb: emHistParseZB, dt: emHistParseDT };            const promises = ['zt''zb''dt'].map(type =>                jsonp(emHistBuildUrl(type, dateStr)).then(data => parsers[type](data)).catch(() => [])            );            const all = await Promise.all(promises);            return all.reduce((acc, arr) => acc.concat(arr), []);        }        function parseTierNum(tierStr) {            let n = parseInt(tierStr);            if (isNaN(n) || n < 1) n = 1;            const map = { 1'首板'2'二板'3'三板'4'四板'5'五板'6'六板'7'七板'8'八板' };            return map[n] || (n >= 5 ? '五板+' : (n >= 3 ? '三板' : '首板'));        }        function assignStatus(list) {            const ztList = list.filter(e => e.type === 'zt');            ztList.sort((a, b) => {                const la = TIER_LEVEL[a.tier] || 0,                    lb = TIER_LEVEL[b.tier] || 0;                if (la !== lb) return lb - la;                return a.time - b.time;            });            const sectorBest = {};            ztList.forEach(e => {                const r = e.reason,                    lv = TIER_LEVEL[e.tier] || 0;                if (!sectorBest[r] || lv > TIER_LEVEL[sectorBest[r].tier]) sectorBest[r] = e;                else if (lv === TIER_LEVEL[sectorBest[r].tier] && e.time < sectorBest[r].time) sectorBest[r] = e;            });            ztList.forEach(e => {                const r = e.reason,                    lv = TIER_LEVEL[e.tier] || 0;                const isBest = (sectorBest[r] && sectorBest[r] === e);                if (e.isSec && lv >= 4) e.tag = '秒顶一';                else if (e.isSec && lv < 4) e.tag = '秒板';                else if (isBest && lv >= 3) e.tag = '龙头';                else if (!isBest && lv >= 3 && sectorBest[r]) {                    const bl = TIER_LEVEL[sectorBest[r].tier] || 0;                    if (lv === bl && e.time <= sectorBest[r].time + 3) e.tag = '卡位';                    else if (lv >= bl - 1) e.tag = '加强';                    else e.tag = '弹性';                } else if (!isBest && lv >= 2 && sectorBest[r]) {                    const bl2 = TIER_LEVEL[sectorBest[r].tier] || 0;                    e.tag = (lv >= bl2 - 1) ? '弹性' : '后排';                } else if (!isBest && lv <= 2) {                    const hasHigher = ztList.some(x => x.reason === r && x !== e && x.time < e.time && (TIER_LEVEL[x                        .tier] || 0) > lv);                    e.tag = (hasHigher || e.time >= 11 * 60 + 30) ? '后排' : '弹性';                } else e.tag = '后排';            });        }        function processHistoricalEvents(events) {            events.forEach(e => {                if (e.type === 'zt') {                    e.tier = parseTierNum(e.tier);                    e.isSec = (e.time <= 9 * 60 + 25 + 1);                    e.tag = '';                }            });            events.sort((a, b) => a.time - b.time);            assignStatus(events);            return events;        }        function computeStockScore(stock) {            if (stock.type !== 'zt'return 0;            const tierScore = (TIER_LEVEL[stock.tier] || 1) * 30;            const fundScore = (stock.fund / 100000000) * 5;            let timeScore = 0;            if (stock.time <= 9 * 60 + 30) timeScore = 20;            else if (stock.time <= 9 * 60 + 35) timeScore = 18;            else if (stock.time <= 10 * 60) timeScore = 15;            else if (stock.time <= 10 * 60 + 30) timeScore = 12;            else if (stock.time <= 11 * 60 + 30) timeScore = 8;            else if (stock.time <= 13 * 60 + 30) timeScore = 5;            else if (stock.time <= 14 * 60 + 30) timeScore = 3;            else timeScore = 1;            let tagScore = 0;            if (stock.tag === '龙头') tagScore = 10;            else if (stock.tag === '秒顶一') tagScore = 8;            else if (stock.tag === '卡位') tagScore = 6;            else if (stock.tag === '加强') tagScore = 4;            else if (stock.tag === '秒板') tagScore = 5;            else if (stock.tag === '弹性') tagScore = 2;            return Math.round(tierScore + fundScore + timeScore + tagScore);        }        function computeSectorScore(sector) {            const ztScore = sector.ztCount * 15;            const maxBoardScore = sector.maxBoard * 25;            const fundScore = (sector.fund / 100000000) * 8;            let leaderScore = 0;            if (sector.leader) leaderScore = computeStockScore(sector.leader) * 0.1;            const breakPenalty = sector.breakRate * 3;            return Math.round(ztScore + maxBoardScore + fundScore + leaderScore - breakPenalty);        }        function buildHistoricalSectorData(events) {            const map = {};            events.forEach(e => {                const r = e.reason || '其他';                if (!map[r]) map[r] = { name: r, zt: [], zb: [], dt: [], fund0firstTime9999maxBoard0 };                const s = map[r];                s.fund += (e.fund || 0);                if (e.time < s.firstTime) s.firstTime = e.time;                if (e.type === 'zt') {                    s.zt.push(e);                    const bl = TIER_LEVEL[e.tier] || 0;                    if (bl > s.maxBoard) s.maxBoard = bl;                } else if (e.type === 'zb') s.zb.push(e);                else if (e.type === 'dt') s.dt.push(e);            });            const arr = [];            for (const k in map) {                const s = map[k];                const leader = s.zt.sort((a, b) => (TIER_LEVEL[b.tier] || 0) - (TIER_LEVEL[a.tier] || 0) || a.time - b                .time)[0];                const breakRate = s.zt.length > 0 ? (s.zb.length / (s.zt.length + s.zb.length) * 100) : 0;                const sectorObj = {                    name: s.name,                    ztCount: s.zt.length,                    zbCount: s.zb.length,                    dtCount: s.dt.length,                    total: s.zt.length + s.zb.length + s.dt.length,                    fund: s.fund,                    firstTime: s.firstTime,                    maxBoard: s.maxBoard,                    leader: leader,                    breakRate: breakRate,                    ztList: s.zt,                    zbList: s.zb                };                sectorObj.score = computeSectorScore(sectorObj);                arr.push(sectorObj);            }            return arr;        }        async function loadHistoricalPlateData(dateStr) {            try {                const rawEvents = await fetchHistoricalEvents(dateStr);                if (!rawEvents || rawEvents.length === 0throw new Error('无历史数据');                const events = processHistoricalEvents(rawEvents.map(e => Object.assign({}, e)));                historicalSectorData = buildHistoricalSectorData(events);                historicalSectorData.sort((a, b) => b.score - a.score);                plateList = historicalSectorData.map((s, idx) => ({                    code'H' + String(idx + 1).padStart(4'0'),                    name: s.name,                    change: s.ztCount > 0 ? 5.0 : 0.0,                    price0,                    amount: s.fund / 1e8,                    netFlow: s.score / 10,                    score: s.score,                    ztCount: s.ztCount,                    leader: s.leader,                    ztList: s.ztList,                    zbList: s.zbList                }));                if (!plateSortCol) { plateSortCol = 'netFlow';                    plateSortDir = 'desc'; }                sortPlateList();                assignPlateColors(plateList);                initDefaultSelection();                renderPlateList();                updateBarChart();                document.getElementById('sortNetFlow').classList.toggle('active', plateSortCol === 'netFlow');                document.getElementById('sortChange').classList.toggle('active', plateSortCol === 'change');                document.getElementById('refreshStatus').textContent = '✅ 历史数据已更新';                document.getElementById('updateTime').textContent = dateStr + ' ' + new Date().toLocaleTimeString();            } catch (e) {                console.error('获取历史板块数据失败:', e);                toast('历史数据加载失败: ' + e.message);                document.getElementById('refreshStatus').textContent = '⚠️ 历史数据失败';            }        }        // ===================== 渲染板块列表 =====================        function getFilteredPlateList() {            if (!searchKeyword) return plateList;            const kw = searchKeyword.toLowerCase();            return plateList.filter(p => p.name && p.name.toLowerCase().includes(kw));        }        let showAllPlates = false;        let selectedPlateCodes = new Set();        function renderPlateList() {            const list = document.getElementById('flowList');            let html = '';            const displayList = getFilteredPlateList();            const showGroups = (plateSortCol === 'netFlow' && plateSortDir === 'desc' && !searchKeyword);            if (showGroups) {                let inPlates = displayList.filter(p => parseFloat(p.netFlow) >= 0);                let outPlates = displayList.filter(p => parseFloat(p.netFlow) < 0);                outPlates.sort((a, b) => parseFloat(a.netFlow) - parseFloat(b.netFlow));                const inVisible = showAllPlates ? inPlates : inPlates.slice(010);                const outVisible = showAllPlates ? outPlates : outPlates.slice(010);                if (inVisible.length > 0) {                    html += `<li class="flow-group-title in">🟢 资金净流入 ${showAllPlates ? '全部' : 'TOP10'}</li>`;                    inVisible.forEach(plate => { html += buildFlowItemHTML(plate); });                }                if (outVisible.length > 0) {                    html += `<li class="flow-group-title out">🔴 资金净流出 ${showAllPlates ? '全部' : 'TOP10'}</li>`;                    outVisible.forEach(plate => { html += buildFlowItemHTML(plate); });                }            } else {                if (displayList.length === 0) {                    html += `<li style="text-align:center;color:#666;padding:20px 0;font-size:12px;">未找到匹配板块</li>`;                } else {                    displayList.forEach(plate => { html += buildFlowItemHTML(plate); });                }            }            list.innerHTML = html;        }        function buildFlowItemHTML(plate) {            const color = plateColorMap[plate.code] || '#888';            const isUp = parseFloat(plate.change) >= 0;            const netVal = parseFloat(plate.netFlow);            const netUp = netVal >= 0;            const checked = selectedPlateCodes.has(plate.code);            return `                <li class="flow-item ${activePlateCode === plate.code ? 'active' : ''}"                    data-code="${plate.code}" data-name="${plate.name}">                    <div class="flow-left">                        <span class="flow-check ${checked ? 'checked' : ''}"                              style="border-color:${color};${checked ? 'background:' + color + ';color:#fff' : 'color:transparent'}"                              data-action="toggle">✓</span>                        <span style="width:8px; flex-shrink:0;"></span>                        <span class="flow-name">${plate.name}</span>                    </div>                    <span class="flow-change-col ${isUp ? 'up' : 'down'}">                        ${isUp ? '+' : ''}${parseFloat(plate.change).toFixed(2)}%                    </span>                    <span class="flow-value-col ${netUp ? 'up' : 'down'}">                        ${netUp ? '+' : ''}${netVal.toFixed(2)}亿                    </span>                </li>`;        }        document.getElementById('flowList').addEventListener('click'(e) => {            const checkEl = e.target.closest('[data-action="toggle"]');            if (checkEl) {                e.stopPropagation();                const item = checkEl.closest('.flow-item');                const code = item.dataset.code;                if (selectedPlateCodes.has(code)) selectedPlateCodes.delete(code);                else selectedPlateCodes.add(code);                renderPlateList();                updateBarChart();                return;            }            const item = e.target.closest('.flow-item');            if (item) {                const code = item.dataset.code;                const name = item.dataset.name;                if (code) showMembers(code, name);            }        });        // ===================== 柱状图 =====================        function updateBarChart() {            const chartDom = document.getElementById('barChart');            if (!barChartInstance) {                barChartInstance = echarts.init(chartDom);            }            const sorted = [...plateList].sort((a, b) => parseFloat(b.netFlow) - parseFloat(a.netFlow));            const top15 = sorted.slice(015);            const names = top15.map(p => p.name).reverse();            const values = top15.map(p => parseFloat(p.netFlow)).reverse();            const option = {                backgroundColor'transparent',                tooltip: {                    trigger'axis',                    axisPointer: { type'shadow' },                    backgroundColor'#1a1a24',                    borderColor'#2a2a38',                    textStyle: { color'#e0e0e0' },                    formatterfunction(params) {                        const p = params[0];                        const val = parseFloat(p.value);                        return `<div style="font-size:13px;font-weight:bold;">${p.name}</div>                                <div style="font-size:12px;color:${val >= 0 ? '#ff5252' : '#4caf50'};">                                    净流入:${val >= 0 ? '+' : ''}${val.toFixed(2)} 亿                                </div>`;                    }                },                grid: {                    left'3%',                    right'8%',                    bottom'3%',                    top'2%',                    containLabeltrue                },                xAxis: {                    type'value',                    splitLine: { lineStyle: { color'rgba(255,255,255,0.05)' } },                    axisLabel: {                        color'#8b8b9e',                        fontSize10,                        formatterfunction(v) { return v + '亿'; }                    },                    axisLine: { lineStyle: { color'rgba(255,255,255,0.08)' } }                },                yAxis: {                    type'category',                    data: names,                    axisLabel: {                        color'#e0e0e0',                        fontSize11,                        width80,                        overflow'truncate'                    },                    axisLine: { lineStyle: { color'rgba(255,255,255,0.08)' } },                    axisTick: { showfalse }                },                series: [{                    type'bar',                    data: values.map(v => ({                        value: v,                        itemStyle: {                            color: v >= 0 ? '#ff5252' : '#4caf50',                            borderRadius: v >= 0 ? [0440] : [4004]                        }                    })),                    label: {                        showtrue,                        position'right',                        color'#fff',                        fontSize10,                        fontWeight500,                        formatterfunction(params) {                            const v = parseFloat(params.value);                            return (v >= 0 ? '+' : '') + v.toFixed(2) + '亿';                        }                    },                    barWidth'60%',                    barMaxWidth20                }]            };            barChartInstance.setOption(option);        }        // ===================== 成分股 =====================        async function showMembers(code, name) {            activePlateCode = code;            renderPlateList();            document.getElementById('memberTitle').textContent = `🔍 ${name} · 成分股`;            document.getElementById('memberPlaceholder').style.display = 'block';            document.getElementById('memberTable').style.display = 'none';            if (isHistoricalMode) {                await showHistoricalMembers(name);                return;            }            const realtimePlate = plateList.find(p => p.code === code);            if (realtimePlate && (realtimePlate.ztList || realtimePlate.zbList)) {                showTopicPoolMembers(realtimePlate);                return;            }            try {                const data = await fetchJSON(getMemberUrl(code) + '&_=' + Date.now());                if (data && data.data && data.data.diff) {                    currentMembers = data.data.diff.map(item => ({                        code: item.f12,                        name: item.f14,                        price: item.f2 || 0,                        change: item.f3 || 0,                        amount: item.f6 || 0,                        netFlow: item.f62 || 0                    }));                    renderMemberTable();                }            } catch (e) {                console.error('获取成分股失败:', e);                document.getElementById('memberPlaceholder').textContent = '⚠️ 成分股加载失败';                document.getElementById('memberPlaceholder').style.display = 'block';                document.getElementById('memberTable').style.display = 'none';            }        }        function showTopicPoolMembers(plate) {            const members = [];            if (plate.ztList) {                plate.ztList.forEach(stock => {                    const limitPct = getStockLimitPercent(stock.code);                    members.push({                        code: stock.code,                        name: stock.name,                        price: stock.price,                        change: limitPct,                        amount: stock.fund || 0,                        netFlow: stock.fund || 0,                        isLimittrue                    });                });            }            if (plate.zbList) {                plate.zbList.forEach(stock => {                    members.push({                        code: stock.code,                        name: stock.name,                        price: stock.price,                        change5.0,                        amount: stock.fund || 0,                        netFlow: -(stock.fund || 0),                        isLimitfalse                    });                });            }            if (members.length > 0) {                currentMembers = members;                renderMemberTable();            } else {                document.getElementById('memberPlaceholder').textContent = '暂无涨停池成分股数据';                document.getElementById('memberPlaceholder').style.display = 'block';                document.getElementById('memberTable').style.display = 'none';            }        }        async function showHistoricalMembers(name) {            const sector = historicalSectorData.find(s => s.name === name);            if (!sector) {                toast('未找到历史板块成分股');                return;            }            const ztCodeSet = new Set(sector.ztList.map(s => s.code));            const zbCodeSet = new Set(sector.zbList.map(s => s.code));            try {                const plateCode = await searchPlateCodeByName(name);                if (plateCode) {                    const data = await fetchJSON(getMemberUrl(plateCode) + '&_=' + Date.now());                    if (data && data.data && data.data.diff) {                        currentMembers = data.data.diff.map(item => {                            const code = item.f12;                            const isZt = ztCodeSet.has(code);                            const isZb = zbCodeSet.has(code);                            const ztStock = sector.ztList.find(s => s.code === code);                            const zbStock = sector.zbList.find(s => s.code === code);                            const limitPct = getStockLimitPercent(code);                            return {                                code: code,                                name: item.f14,                                price: isZt && ztStock ? ztStock.price : (item.f2 || 0),                                change: isZt ? limitPct : (isZb ? 5.0 : (item.f3 || 0)),                                amount: isZt && ztStock ? ztStock.fund : (isZb && zbStock ? zbStock.fund : (item                                .f6 || 0)),                                netFlow: isZt && ztStock ? ztStock.fund : (isZb && zbStock ? -zbStock.fund : (item                                    .f62 || 0)),                                isZt: isZt,                                isZb: isZb                            };                        });                        renderMemberTable();                        return;                    }                }            } catch (e) {                console.warn('获取历史板块完整成分股失败,回退到涨停池数据:', e);            }            const members = [];            sector.ztList.forEach(stock => {                const limitPct = getStockLimitPercent(stock.code);                members.push({                    code: stock.code,                    name: stock.name,                    price: stock.price,                    change: limitPct,                    amount: stock.fund,                    netFlow: stock.fund,                    isZttrue,                    isZbfalse                });            });            sector.zbList.forEach(stock => {                members.push({                    code: stock.code,                    name: stock.name,                    price: stock.price,                    change5.0,                    amount: stock.fund,                    netFlow: -stock.fund,                    isZtfalse,                    isZbtrue                });            });            currentMembers = members;            renderMemberTable();        }        function renderMemberTable() {            document.getElementById('memberPlaceholder').style.display = 'none';            document.getElementById('memberTable').style.display = 'table';            let sortedMembers = [...currentMembers];            sortedMembers.sort((a, b) => {                let va = parseFloat(a[memberSortCol]);                let vb = parseFloat(b[memberSortCol]);                return memberSortDir === 'asc' ? va - vb : vb - va;            });            const tbody = document.getElementById('memberTbody');            let html = '';            sortedMembers.forEach(stock => {                const isUp = parseFloat(stock.change) >= 0;                const limitPct = getStockLimitPercent(stock.code);                const isLimit = parseFloat(stock.change) >= limitPct - 0.5;                let tagHtml = '';                if (stock.isZt || isLimit) {                    tagHtml += `<span class="leader-tag" style="background:linear-gradient(135deg,#e74c3c,#c0392b)">涨停</span>`;                } else if (stock.isZb) {                    tagHtml += `<span class="leader-tag" style="background:linear-gradient(135deg,#ff9800,#f57c00)">炸板</span>`;                }                html += `                    <tr class="stock-row"                        data-stock-code="${stock.code}"                        data-stock-name="${stock.name}"                        data-stock-pct="${stock.change}"                        data-stock-price="${stock.price}"                        onclick="linkToTdx('${stock.code}')">                        <td><span class="stock-code">${stock.code}</span></td>                        <td>${stock.name}${tagHtml}</td>                        <td>${parseFloat(stock.price).toFixed(2)}</td>                        <td style="color:${isUp ? '#ff5252' : '#4caf50'};font-weight:bold;">                            ${isUp ? '+' : ''}${parseFloat(stock.change).toFixed(2)}%                        </td>                        <td>${formatAmount(stock.amount)}</td>                        <td style="color:${parseFloat(stock.netFlow) >= 0 ? '#ff5252' : '#4caf50'};font-weight:bold;">                            ${parseFloat(stock.netFlow) >= 0 ? '+' : ''}${formatFlow(stock.netFlow)}                        </td>                    </tr>`;            });            tbody.innerHTML = html;        }        function formatAmount(v) {            const n = parseFloat(v) || 0;            if (n >= 1e8return (n / 1e8).toFixed(2) + '亿';            if (n >= 1e4return (n / 1e4).toFixed(1) + '万';            return n.toFixed(2);        }        function formatFlow(v) {            const n = parseFloat(v) || 0;            if (Math.abs(n) >= 1e8return (n / 1e8).toFixed(2) + '亿';            if (Math.abs(n) >= 1e4return (n / 1e4).toFixed(1) + '万';            return n.toFixed(2);        }        function toggleMemberSort(col) {            if (memberSortCol === col) {                memberSortDir = memberSortDir === 'asc' ? 'desc' : 'asc';            } else {                memberSortCol = col;                memberSortDir = 'desc';            }            if (currentMembers.length > 0renderMemberTable();        }        function toggleShowAllPlates() {            const btn = document.getElementById('selectAllBtn');            showAllPlates = !showAllPlates;            btn.textContent = showAllPlates ? '☑ 精简显示' : '☐ 全部板块';            btn.classList.toggle('all-selected', showAllPlates);            renderPlateList();        }        function exportMembers() {            if (currentMembers.length === 0) { toast('无成分股可导出'); return; }            const params = currentMembers.map(s => {                const market = (s.code.startsWith('6') || s.code.startsWith('688')) ? '1' : '0';                return `${market}#${s.code}`;            }).join('|');            window.location.href = `http://www.treeid/AddToBlock_${params}`;            toast(`导出${currentMembers.length}只成分股`);        }        // ===================== 股票分析缓存 =====================        async function updateStockAnalysisCache() {            try {                const response = await fetch(STOCKS_API + '?normal=true&uplimit=true&_=' + Date.now(), { cache'no-cache' });                const data = await response.json();                if (data.code === 20000 && data.data && data.data.items) {                    const newCache = {};                    data.data.items.forEach(item => {                        const stockCode = formatStockCode(item[0]);                        if (stockCode) {                            const changeRate = item[3] !== null && item[3] !== undefined ? ((item[3] * 100).toFixed(                                2)) : '';                            newCache[stockCode] = {                                name: item[1] || '',                                analysis: item[5] || '',                                boards: item[11] || '',                                change: changeRate ? (parseFloat(changeRate) >= 0 ? '+' : '') + changeRate + '%' :                                    '',                                timeformatTime(item[6])                            };                        }                    });                    stockAnalysisCache = newCache;                }            } catch (e) {                console.error('更新股票分析数据失败:', e);            }        }        function getStockAnalysis(code) {            const cleanCode = code?.toString()?.padStart(6'0') || '';            return stockAnalysisCache[cleanCode] || stockAnalysisCache[code] || null;        }        // ===================== 股票提示框 =====================        function initStockTooltip() {            const tooltip = document.getElementById('stockTooltip');            document.addEventListener('mouseover'function(e) {                const stockRow = e.target.closest('tr.stock-row');                if (stockRow) {                    const stockCode = stockRow.getAttribute('data-stock-code');                    const stockName = stockRow.getAttribute('data-stock-name');                    const stockPct = stockRow.getAttribute('data-stock-pct');                    const stockPrice = stockRow.getAttribute('data-stock-price');                    let analysis = getStockAnalysis(stockCode);                    let content = '';                    let row1Parts = [];                    if (stockCode) row1Parts.push(`<span class="label">代码:</span><span class="value">${stockCode}</span>`);                    if (stockName) row1Parts.push(`<span class="label">名称:</span><span class="value">${stockName}</span>`);                    if (row1Parts.length > 0) content += `<div class="info-row">${row1Parts.join('<span class="divider"> | </span>')}</div>`;                    let row2Parts = [];                    if (analysis && analysis.boards) row2Parts.push(`<span class="label">连板:</span><span class="value">${analysis.boards}</span>`);                    if (stockPct) row2Parts.push(`<span class="label">涨跌:</span><span class="value">${parseFloat(stockPct) >= 0 ? '+' : ''}${stockPct}%</span>`);                    if (stockPrice) row2Parts.push(`<span class="label">价格:</span><span class="value">${parseFloat(stockPrice).toFixed(2)}</span>`);                    if (row2Parts.length > 0) content += `<div class="info-row">${row2Parts.join('<span class="divider"> | </span>')}</div>`;                    if (analysis && analysis.analysis && analysis.analysis.trim() !== '') {                        content += `<div class="analysis-section"><span class="label">涨停分析:</span><br><span class="value">${analysis.analysis}</span></div>`;                    } else {                        content += `<div class="analysis-section"><span class="label">公司概况:</span><br><span class="value">暂无详细分析数据</span></div>`;                    }                    tooltip.innerHTML = content;                    tooltip.style.display = 'block';                    const rect = stockRow.getBoundingClientRect();                    tooltip.style.left = rect.right + 15 + 'px';                    tooltip.style.top = rect.top + 'px';                }            });            document.addEventListener('mouseout'function(e) {                if (e.target.closest('tr.stock-row')) tooltip.style.display = 'none';            });            document.addEventListener('mousemove'function(e) {                const stockRow = e.target.closest('tr.stock-row');                if (stockRow) {                    const tooltipRect = tooltip.getBoundingClientRect();                    const viewportHeight = window.innerHeight;                    let top = e.clientY - 100;                    if (top < 10) top = 10;                    if (top + tooltipRect.height > viewportHeight - 10) top = viewportHeight - tooltipRect.height - 10;                    let left = e.clientX + 20;                    if (left + tooltipRect.width > window.innerWidth - 10) left = e.clientX - tooltipRect.width - 20;                    tooltip.style.top = top + 'px';                    tooltip.style.left = left + 'px';                }            });        }        // ===================== 自动刷新控制 =====================        function startAutoRefresh() {            if (refreshTimer) {                clearInterval(refreshTimer);                refreshTimer = null;            }            if (isAutoRefreshPaused) return;            refreshTimer = setInterval(() => {                if (!selectedDate) {                    loadPlateData();                    updateStockAnalysisCache();                }            }, 10000);        }        function toggleAutoRefresh() {            const btn = document.getElementById('refreshBtn');            if (isAutoRefreshPaused) {                isAutoRefreshPaused = false;                btn.innerHTML = '⏸️ 暂停';                startAutoRefresh();                loadPlateData();            } else {                isAutoRefreshPaused = true;                btn.innerHTML = '▶️ 恢复';                if (refreshTimer) {                    clearInterval(refreshTimer);                    refreshTimer = null;                }            }        }        // ===================== 日期选择器 =====================        function generateRecentTradingDays(count) {            const days = [],                today = new Date();            for (let i = 0; i <= count; i++) {                const d = new Date(today);                d.setDate(today.getDate() - i);                const w = d.getDay();                if (w === 0 || w === 6continue;                days.push(formatCalendarDate(d));            }            return days;        }        function formatCalendarDate(date) {            return date.getFullYear() + '-' + String(date.getMonth() + 1).padStart(2'0') + '-' + String(date.getDate())                .padStart(2'0');        }        function getTodayStr() {            const d = new Date();            return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2'0') + '-' + String(d.getDate()).padStart(2,                '0');        }        function updateNavButtons() {            const prevBtn = document.getElementById('prevDayBtn'),                nextBtn = document.getElementById('nextDayBtn');            if (!selectedDate) {                nextBtn.disabled = true;                prevBtn.disabled = false;            } else {                const idx = calendarDateList.indexOf(selectedDate);                nextBtn.disabled = idx <= 0;                prevBtn.disabled = idx >= calendarDateList.length - 1;            }        }        function updateDisplayUI() {            document.getElementById('calendarDisplay').textContent = selectedDate ? selectedDate : '今日数据';            updateNavButtons();        }        async function goPrevDay() {            if (!selectedDate) {                if (calendarDateList.length) selectedDate = calendarDateList[0];                else return;            } else {                const idx = calendarDateList.indexOf(selectedDate);                if (idx !== -1 && idx < calendarDateList.length - 1) selectedDate = calendarDateList[idx + 1];                else return;            }            updateDisplayUI();            await loadPlateData();        }        async function goNextDay() {            if (!selectedDate) return;            const idx = calendarDateList.indexOf(selectedDate);            if (idx === 0) {                selectedDate = '';                updateDisplayUI();                await loadPlateData();            } else if (idx > 0) {                selectedDate = calendarDateList[idx - 1];                updateDisplayUI();                await loadPlateData();            }        }        function buildCalendarPopupHTML() {            const year = calendarCurrentMonth.getFullYear(),                month = calendarCurrentMonth.getMonth();            document.getElementById('calendarMonth').innerText = year + '年' + (month + 1) + '月';            const grid = document.getElementById('calendarGrid');            grid.innerHTML = '';            const firstDay = new Date(year, month, 1);            const lastDay = new Date(year, month + 10);            const startWeek = firstDay.getDay();            const daysInMonth = lastDay.getDate();            const prevLast = new Date(year, month, 0).getDate();            const todayStr = getTodayStr();            function createDayCell(dayNum, ds, isOther) {                const div = document.createElement('div');                div.className = 'cal-day' + (isOther ? ' other-month' : '');                div.textContent = dayNum;                if (ds === todayStr) div.classList.add('today');                if (calendarDateList.includes(ds)) div.classList.add('has-data');                if ((!selectedDate && ds === todayStr) || ds === selectedDate) div.classList.add('selected');                div.dataset.date = ds;                div.onclick = function(e) {                    e.stopPropagation();                    if (this.dataset.date === todayStr) {                        selectedDate = '';                    } else if (calendarDateList.includes(this.dataset.date)) {                        selectedDate = this.dataset.date;                    } else return;                    updateDisplayUI();                    closeCalendarPopup();                    loadPlateData();                };                return div;            }            for (let i = startWeek - 1; i >= 0; i--) {                const dayNum = prevLast - i;                const ds = formatCalendarDate(new Date(year, month - 1, dayNum));                grid.appendChild(createDayCell(dayNum, ds, true));            }            for (let d = 1; d <= daysInMonth; d++) {                const ds = formatCalendarDate(new Date(year, month, d));                grid.appendChild(createDayCell(d, ds, false));            }            const remaining = 42 - (startWeek + daysInMonth);            for (let n = 1; n <= remaining; n++) {                const ds = formatCalendarDate(new Date(year, month + 1, n));                grid.appendChild(createDayCell(n, ds, true));            }        }        function toggleCalendarPopup() {            const pop = document.getElementById('calendarPopup');            if (pop.classList.contains('show')) {                pop.classList.remove('show');            } else {                buildCalendarPopupHTML();                pop.classList.add('show');            }        }        function closeCalendarPopup() {            document.getElementById('calendarPopup').classList.remove('show');        }        function prevMonth() {            calendarCurrentMonth.setMonth(calendarCurrentMonth.getMonth() - 1);            buildCalendarPopupHTML();        }        function nextMonth() {            calendarCurrentMonth.setMonth(calendarCurrentMonth.getMonth() + 1);            buildCalendarPopupHTML();        }        function initDatePicker() {            calendarDateList = generateRecentTradingDays(55);            document.getElementById('prevDayBtn').onclick = goPrevDay;            document.getElementById('nextDayBtn').onclick = goNextDay;            document.getElementById('calendarDisplay').onclick = toggleCalendarPopup;            document.getElementById('calCloseBtn').onclick = closeCalendarPopup;            document.getElementById('prevMonthCal').onclick = prevMonth;            document.getElementById('nextMonthCal').onclick = nextMonth;            document.getElementById('plateSearch').addEventListener('input'function(e) {                searchKeyword = e.target.value.trim();                renderPlateList();            });            document.addEventListener('click'function(e) {                const pop = document.getElementById('calendarPopup');                const display = document.getElementById('calendarDisplay');                if (pop && !pop.contains(e.target) && !display.contains(e.target)) {                    closeCalendarPopup();                }            });            updateDisplayUI();        }        // ===================== 初始化 =====================        async function init() {            initDatePicker();            await loadPlateData();            await updateStockAnalysisCache();            initStockTooltip();            isAutoRefreshPaused = false;            document.getElementById('refreshBtn').innerHTML = '⏸️ 暂停';            startAutoRefresh();            document.getElementById('refreshBtn').onclick = toggleAutoRefresh;            if (plateList.length > 0) {                const first = plateList[0];                showMembers(first.code, first.name);            }            window.addEventListener('resize'() => {                if (barChartInstance) barChartInstance.resize();            });        }        document.getElementById('exportBtn').onclick = exportMembers;        init();    </script></body></html>

大家觉得有用顺手点个赞或者“留言”哟!

竞价擒龙系统,可加我咨询!

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-16 05:32:01 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/862042.html
  2. 运行时间 : 0.169463s [ 吞吐率:5.90req/s ] 内存消耗:5,088.23kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=70842843d19fb3c5110f2a497dc874ee
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000620s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000914s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000347s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000260s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000571s ]
  6. SELECT * FROM `set` [ RunTime:0.000222s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000632s ]
  8. SELECT * FROM `article` WHERE `id` = 862042 LIMIT 1 [ RunTime:0.000912s ]
  9. UPDATE `article` SET `lasttime` = 1784151121 WHERE `id` = 862042 [ RunTime:0.035702s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.003929s ]
  11. SELECT * FROM `article` WHERE `id` < 862042 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001420s ]
  12. SELECT * FROM `article` WHERE `id` > 862042 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.015386s ]
  13. SELECT * FROM `article` WHERE `id` < 862042 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000987s ]
  14. SELECT * FROM `article` WHERE `id` < 862042 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001331s ]
  15. SELECT * FROM `article` WHERE `id` < 862042 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001129s ]
0.171102s