新球体育网亚盘统计

新球体育网(球探)手机端网页,在分析页面右上角加入“选赛”和“统计”按钮。点击“选赛”后,勾选需要统计亚盘的比赛,选好后再点击统计,即可在对赛往绩下显示亚盘统计表格。让球水位高亮显示。

// ==UserScript==
// @name         新球体育网亚盘统计
// @namespace    http://dol.freevar.com/
// @version      0.85
// @description  新球体育网(球探)手机端网页,在分析页面右上角加入“选赛”和“统计”按钮。点击“选赛”后,勾选需要统计亚盘的比赛,选好后再点击统计,即可在对赛往绩下显示亚盘统计表格。让球水位高亮显示。
// @author       Dolphin
// @run-at       document-idle
// @match        https://m.titan007.com/analy/Analysis/*
// @match        https://m.titan007.com/Analy/Analysis/*
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    GM_addStyle(`
        #statsContainer table {border-collapse: collapse; margin:auto;}
        #statsContainer tr:nth-child(odd) {background-color: #eee;}
        #statsContainer td, #statsContainer th {border: 1px solid #ccf; font-size: 16px; text-align: center;padding:0 5px;}
    `);

    let selectedMatches = new Map();
    let statsData = [];
    let isSelecting = false;
    let isStatisticsShowing = false;

    // 创建操作按钮
    function createControlButtons() {
        const btnContainer = document.querySelector('.btns');
        if (!btnContainer) return;

        const selectBtn = document.createElement('div');
        selectBtn.className = 'btn';
        selectBtn.textContent = '选赛';
        selectBtn.style.backgroundColor = '#d43';
        selectBtn.addEventListener('click', toggleSelection);

        const statsBtn = document.createElement('div');
        statsBtn.className = 'btn';
        statsBtn.textContent = '统计';
        statsBtn.style.backgroundColor = '#3b6';
        statsBtn.addEventListener('click', toggleStatistics);

        btnContainer.insertBefore(statsBtn, btnContainer.firstChild);
        btnContainer.insertBefore(selectBtn, btnContainer.firstChild);
    }

    // 切换选择模式
    function toggleSelection() {
        const btn = this;
        isSelecting = !isSelecting;
        btn.textContent = isSelecting ? '还原' : '选赛';

        const trList = document.querySelectorAll('tr[align="center"][onclick^="GoAnalyUrl"]');
        trList.forEach(tr => {
            const td = tr.children[2];
            const scoreDiv = td.querySelector('div');
            const checkbox = td.querySelector('input[type="checkbox"]');

            if (isSelecting) {
                scoreDiv.style.display = 'none';
                if (!checkbox) {
                    const cb = document.createElement('input');
                    cb.type = 'checkbox';
                    cb.style.position = 'static';
                    cb.addEventListener('click', handleCheckboxClick);
                    td.appendChild(cb);
                }
            } else {
                scoreDiv.style.display = '';
                if (checkbox) checkbox.remove();
                selectedMatches.clear();
            }
        });
    }

    // 处理复选框点击
    function handleCheckboxClick(event) {
        event.stopPropagation();
        const tr = event.target.closest('tr');
        const matchId = parseInt(tr.getAttribute('onclick').match(/GoAnalyUrl\((\d+)\)/)[1]);
        const scoreText = tr.querySelector('.Score').textContent;
        const [homeScore, awayScore] = scoreText.split('-').map(Number);
        const diff = homeScore - awayScore;

        if (event.target.checked) {
            selectedMatches.set(matchId, diff);
        } else {
            selectedMatches.delete(matchId);
        }
    }

    // 切换统计显示
    async function toggleStatistics() {
        const btn = this;
        if (isStatisticsShowing) {
            btn.textContent = '统计';
            removeStatsTables();
            isStatisticsShowing = false;
            return;
        }

        if (selectedMatches.size === 0) {
            alert('请先选择比赛!');
            return;
        }

        try {
            btn.textContent = '加载中';
            await processStatistics();
            isStatisticsShowing = true;
            btn.textContent = '隐藏';
        } catch (error) {
            alert(error.message);
        }
    }

    // 处理统计逻辑
    async function processStatistics() {
        statsData = [];
        const requests = Array.from(selectedMatches).map(([id, diff]) =>
            fetchData(`/HandicapDataInterface.ashx?scheid=${id}&type=1&oddskind=0&isHalf=0`, id)
        );

        const responses = await Promise.all(requests);
        responses.forEach(({ data, matchId }) => {
            if (!data.companies) return;
            data.companies.forEach(company => {
                const detail = company.details.find(d => d.num === 1);
                if (!detail) return;

                processCompanyData(company, detail, selectedMatches.get(matchId));
            });
        });

        await processCurrentMatch();
        createStatsTables();
    }

    // 处理公司数据
    function processCompanyData(company, detail, diff) {
        const companyData = statsData.find(c => c.companyName === company.nameCn) || {
            companyName: company.nameCn,
            init: { count: 0, hit: 0 },
            live: { count: 0, hit: 0 }
        };

        const draw = detail.firstDrawOdds || 0;
        const isHit = calculateHit(detail.firstHomeOdds, draw, detail.firstAwayOdds, diff);
        companyData.init.count++;
        if (isHit) companyData.init.hit++;

        if (detail.homeOdds) {
            const liveHit = calculateHit(detail.homeOdds, detail.drawOdds || 0, detail.awayOdds, diff);
            companyData.live.count++;
            if (liveHit) companyData.live.hit++;
        }

        if (!statsData.includes(companyData)) statsData.push(companyData);
    }

    // 计算是否命中
    function calculateHit(home, draw, away, diff) {
        if (diff === draw) return true;
        if (diff > draw && home < away) return true;
        if (diff < draw && away < home) return true;
        return false;
    }

    // 处理当前比赛数据
    async function processCurrentMatch() {
        const currentData = await fetchData(`/HandicapDataInterface.ashx?scheid=${scheduleId}&type=1&oddskind=0&isHalf=0`, scheduleId);

        currentData.data.companies.forEach(company => {
            const detail = company.details.find(d => d.num === 1);
            if (!detail) return;

            const companyData = statsData.find(c => c.companyName === company.nameCn) || {
                companyName: company.nameCn,
                init: { count: 0, hit: 0 },
                live: { count: 0, hit: 0 }
            };

            companyData.init.home = detail.firstHomeOdds;
            companyData.init.draw = detail.firstDrawOdds || 0;
            companyData.init.away = detail.firstAwayOdds;

            if (detail.homeOdds) {
                companyData.live.home = detail.homeOdds;
                companyData.live.draw = detail.drawOdds || 0;
                companyData.live.away = detail.awayOdds;
            }

            if (!statsData.includes(companyData)) statsData.push(companyData);
        });
    }

    // 创建统计表格
    function createStatsTables() {
        const container = document.createElement('div');
        container.id = 'statsContainer';

        // 初盘表格
        const initTable = createTable('初', 'init');
        // 即时盘表格
        const liveTable = createTable('即', 'live');

        container.appendChild(initTable);
        container.appendChild(liveTable);
        document.querySelector('#againstDiv').after(container);
    }

    // 创建表格
    function createTable(title, type) {
        const table = document.createElement('table');
        const header = `<tr><th>公司</th><th>${title}开</th><th>${title}中</th><th>命中率</th><th>主水</th><th>让球</th><th>客水</th></tr>`;

        const sortedData = [...statsData].sort((a, b) =>
            (b[type].hit / b[type].count || 0) - (a[type].hit / a[type].count || 0)
        );

        const rows = sortedData.map(company => {
            const rate = company[type].count ?
                `${(company[type].hit / company[type].count * 100).toFixed(1)}%` : '';

            return `<tr>
                <td>${company.companyName}</td>
                <td>${company[type].count}</td>
                <td>${company[type].hit}</td>
                <td>${rate}</td>
                ${createOddsCells(company[type])}
            </tr>`;
        }).join('');

        table.innerHTML = header + rows;
        return table;
    }

    // 创建赔率单元格
    function createOddsCells(data) {
        if (!data.home) return '<td></td><td></td><td></td>';

        const home = data.home.toFixed(2);
        const away = data.away.toFixed(2);
        const homeColor = home < away ? '#cfc' : home > away ? '#fcc' : '';
        const awayColor = away < home ? '#cfc' : away > home ? '#fcc' : '';

        return `
            <td style="background:${homeColor}">${home}</td>
            <td>${data.draw}</td>
            <td style="background:${awayColor}">${away}</td>
        `;
    }

    // 移除统计表格
    function removeStatsTables() {
        const container = document.getElementById('statsContainer');
        if (container) container.remove();
    }

    // 通用请求函数
    function fetchData(url, matchId) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.onload = () => {
                if (xhr.status === 200) {
                    resolve({ data: JSON.parse(xhr.responseText), matchId });
                } else {
                    reject(new Error(`请求失败: ${matchId}`));
                }
            };
            xhr.onerror = () => reject(new Error(`请求失败: ${matchId}`));
            xhr.send();
        });
    }

    // 初始化
    createControlButtons();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址