Greasy Fork

Greasy Fork is available in English.

雷速体育亚盘统计

在雷速移动端网页展示指数Tab,并加入统计功能,点击统计会对当前赛事执行1次统计,可在多场赛事中执行统计累加,点击命中会在最下方显示统计数据。

当前为 2025-03-15 提交的版本,查看 最新版本

// ==UserScript==
// @name         雷速体育亚盘统计
// @namespace    http://dol.freevar.com/
// @version      0.2
// @description  在雷速移动端网页展示指数Tab,并加入统计功能,点击统计会对当前赛事执行1次统计,可在多场赛事中执行统计累加,点击命中会在最下方显示统计数据。
// @author       Dolphin
// @match        https://m.leisu.com/*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 修改UserAgent
    Object.defineProperty(navigator, 'userAgent', {
        value: "Mozilla/5.0 (Linux; Android 14; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36 MicroMessenger/6.7.3.1360(0x26070336) NetType/WIFI Language/zh_CN",
        configurable: false,
        enumerable: true,
        writable: false
    });

    let initialized = false;
    const observerConfig = {
        childList: true,
        subtree: true
    };

    // 主初始化函数
    const mainInit = () => {
        if (initialized) return;

        const liveTab = document.querySelector('.live-tab');
        if (!liveTab) return;

        // 防止重复初始化
        initialized = true;

        // 插入控制按钮
        const addControlButtons = () => {
            const existingButtons = liveTab.querySelectorAll('.stats-control');
            if (existingButtons.length > 0) return;

            const targetTab = Array.from(liveTab.children).find(el => el.textContent.includes('指数'));
            if (!targetTab) return;

            const createButton = (text) => {
                const btn = document.createElement('div');
                btn.className = 'tab-son stats-control';
                btn.innerHTML = `${text}`;
                return btn;
            };

            ['统计', '命中', '清除'].forEach(text => {
                liveTab.insertBefore(createButton(text), targetTab);
            });
        };

        // 绑定事件
        const bindEvents = () => {
            liveTab.addEventListener('click', (e) => {
                const target = e.target.closest('.stats-control');
                if (!target) return;

                const text = target.textContent.trim();
                if (text === '统计') updateStats();
                if (text === '清除') {
                    localStorage.removeItem('asia-handicap-stats');
                    alert('各个公司的亚盘统计数据已清除');
                }
                if (text === '命中') showStats();
            });
        };

        addControlButtons();
        bindEvents();
    };

    // 启动观察者
    const observer = new MutationObserver((mutations) => {
        if (!document.querySelector('table.tab-team')) {
            initialized = false;
            return;
        }
        mainInit();
    });

    // DOM就绪后立即检查
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            observer.observe(document.body, observerConfig);
            mainInit();
        });
    } else {
        observer.observe(document.body, observerConfig);
        mainInit();
    }

    /* 以下原有功能函数保持不变(稍作格式优化) */
    // 计算比分差值
    const getScoreDiff = () => {
        const scoreEl = document.querySelector('.realscore > p');
        const score = scoreEl.textContent.split('-').map(s => parseInt(s.trim()));
        return score[0] - score[1];
    };

    // 解析公司数据
    const parseCompanyData = () => {
        const companies = [];
        document.querySelectorAll('.tab-team tr:not(:first-child)').forEach(tr => {
            const name = tr.querySelector('.w-77').textContent.trim();
            const initSpans = tr.querySelectorAll('td:nth-child(2) span');
            const data = {
                name,
                home: parseFloat(initSpans[0].textContent),
                handicap: parseFloat(initSpans[1].textContent),
                away: parseFloat(initSpans[2].textContent)
            };
            companies.push(data);
        });
        return companies;
    };

    // 命中判断逻辑
    const checkHit = (company, diff) => {
        if (diff === company.handicap) return true;
        if (company.home === company.away) return false;

        const resultDiff = diff - company.handicap;
        if (resultDiff > 0 && company.home < company.away) return true;
        if (resultDiff < 0 && company.away < company.home) return true;
        return false;
    };

    // 更新统计数据
    const updateStats = () => {
        const diff = getScoreDiff();
        const companies = parseCompanyData();
        const stats = JSON.parse(localStorage.getItem('asia-handicap-stats') || '{}');

        companies.forEach(company => {
            const key = company.name;
            const hit = checkHit(company, diff);

            if (!stats[key]) stats[key] = { hit: 0, total: 0 };
            stats[key].total++;
            if (hit) stats[key].hit++;
        });

        localStorage.setItem('asia-handicap-stats', JSON.stringify(stats));
    };

    // 显示统计结果
    const showStats = () => {
        const stats = JSON.parse(localStorage.getItem('asia-handicap-stats') || '{}');
        const table = document.querySelector('.tab-team');

        // 清除旧数据
        document.querySelectorAll('.stats-row').forEach(el => el.remove());

        Object.entries(stats).forEach(([name, data]) => {
            const row = document.createElement('tr');
            row.className = 'stats-row';
            row.style.borderBottom = '1px solid #fcc';
            row.innerHTML = `
                <td class="w-77">${name}</td>
                <td>命中:${data.hit}  开盘:${data.total}</td>
                <td>命中率:${(data.hit/data.total*100).toFixed(2)}%</td>
            `;
            table.appendChild(row);
        });
    };
})();