新球体育网亚盘分析

新球体育网(球探)手机端网页,比赛的分析页面根据开盘时间列出各家公司,勾选所需公司后点击按钮生成表格,通过各家公司的让球走势分析赛果。

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         新球体育网亚盘分析
// @namespace    http://dol.freevar.com/
// @version      0.3
// @description  新球体育网(球探)手机端网页,比赛的分析页面根据开盘时间列出各家公司,勾选所需公司后点击按钮生成表格,通过各家公司的让球走势分析赛果。
// @author       Dolphin
// @match        https://m.titan007.com/Analy/Analysis/*
// @match        https://m.titan007.com/analy/Analysis/*
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 公司列表及对应的ID
    const companies = [
        { companyId: 1, nameCn: "澳门" },
        { companyId: 8, nameCn: "Bet365" },
        { companyId: 12, nameCn: "易胜博" },
        { companyId: 14, nameCn: "伟德" },
        { companyId: 17, nameCn: "明陞" },
        { companyId: 23, nameCn: "金宝博" },
        { companyId: 24, nameCn: "12Bet" },
        { companyId: 31, nameCn: "利记" },
        { companyId: 35, nameCn: "盈禾" },
        { companyId: 42, nameCn: "18Bet" },
        { companyId: 47, nameCn: "平博" },
        { companyId: 48, nameCn: "香港" },
        { companyId: 9, nameCn: "威廉" },
        { companyId: 19, nameCn: "Inter" },
        { companyId: 50, nameCn: "1xBet" }
    ];

    // 已选择的公司
    let selectedComp = [];

    // 格式化ModifyTime(yyyyMMddHHmmss)为日月时分
    function formatModifyTime(timeStr) {
        if (!timeStr || timeStr.length !== 14) return "";
        const month = timeStr.substr(4, 2);
        const day = timeStr.substr(6, 2);
        const hour = timeStr.substr(8, 2);
        const minute = timeStr.substr(10, 2);
        return `${month}-${day} ${hour}:${minute}`;
    }

    // 将10位时间戳转换为日期对象
    function timestampToDate(timestamp) {
        return new Date(parseInt(timestamp) * 1000);
    }

    // 将日期对象转换为ModifyTime格式字符串
    function dateToModifyTimeStr(date) {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        const hour = String(date.getHours()).padStart(2, '0');
        const minute = String(date.getMinutes()).padStart(2, '0');
        const second = String(date.getSeconds()).padStart(2, '0');
        return `${year}${month}${day}${hour}${minute}${second}`;
    }

    // 将ModifyTime字符串转换为日期对象
    function modifyTimeToDate(timeStr) {
        if (!timeStr || timeStr.length !== 14) return null;
        const year = parseInt(timeStr.substr(0, 4));
        const month = parseInt(timeStr.substr(4, 2)) - 1;
        const day = parseInt(timeStr.substr(6, 2));
        const hour = parseInt(timeStr.substr(8, 2));
        const minute = parseInt(timeStr.substr(10, 2));
        const second = parseInt(timeStr.substr(12, 2));
        return new Date(year, month, day, hour, minute, second);
    }

    // 检查时间是否在比赛期间
    function isInMatchPeriod(timeStr, matchTimestamp) {
        const time = modifyTimeToDate(timeStr);
        if (!time || !matchTimestamp) return false;

        const matchStart = timestampToDate(matchTimestamp);
        const matchEnd = new Date(matchStart.getTime() + 2 * 60 * 60 * 1000); // 比赛开始后2小时

        return time >= matchStart && time <= matchEnd;
    }

    // 获取公司赔率数据
    async function fetchOddsData(company) {
        try {
            const response = await fetch(`/HandicapDataInterface.ashx?scheid=${scheduleId}&type=3&oddskind=0&companyid=${company.companyId}&isHalf=0`);
            if (!response.ok) {
                throw new Error(`HTTP状态码: ${response.status}`);
            }
            const data = await response.json();
            // 过滤出HappenTime为空的数据
            return {
                company,
                odds: data.filter(item => item.HappenTime === "")
            };
        } catch (error) {
            alert(`获取${company.nameCn}数据失败: ${error.message}`);
            return { company, odds: [] };
        }
    }

    // 创建主表格
    function createMainTable(companiesData, homeMatchTime, awayMatchTime) {
        const table = document.createElement('table');
        table.style.textAlign = 'center';
        table.style.margin = '0 auto';
        table.style.borderCollapse = 'collapse';

        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            .odds-table td, .odds-table th {
                border: 1px solid #888;
            }
            .match-period {
                background-color: #fee;
            }
        `;
        document.head.appendChild(style);
        table.className = 'odds-table';

        // 准备所有行数据
        let rows = [];

        // 添加公司数据行
        companiesData.forEach(companyData => {
            if (companyData.odds.length > 0) {
                // 按ModifyTime排序,取最早的记录
                const sortedOdds = [...companyData.odds].sort((a, b) => b.ModifyTime.localeCompare(a.ModifyTime));
                const earliestOdds = sortedOdds[sortedOdds.length - 1];

                rows.push({
                    type: 'company',
                    time: earliestOdds.ModifyTime,
                    data: companyData,
                    odds: earliestOdds
                });
            }
        });

        // 添加比赛时间标记
        const homeStart = timestampToDate(homeMatchTime);
        const homeEnd = new Date(homeStart.getTime() + 2 * 60 * 60 * 1000);
        const awayStart = timestampToDate(awayMatchTime);
        const awayEnd = new Date(awayStart.getTime() + 2 * 60 * 60 * 1000);

        rows.push({
            type: 'match',
            time: dateToModifyTimeStr(homeStart),
            label: '主队比赛开始'
        });

        rows.push({
            type: 'match',
            time: dateToModifyTimeStr(homeEnd),
            label: '主队比赛结束'
        });

        rows.push({
            type: 'match',
            time: dateToModifyTimeStr(awayStart),
            label: '客队比赛开始'
        });

        rows.push({
            type: 'match',
            time: dateToModifyTimeStr(awayEnd),
            label: '客队比赛结束'
        });

        // 按时间降序排序
        rows.sort((a, b) => b.time.localeCompare(a.time));

        // 创建表格行
        rows.forEach(row => {
            const tr = document.createElement('tr');

            // 检查是否在比赛期间
            const inHomeMatch = homeMatchTime && isInMatchPeriod(row.time, homeMatchTime);
            const inAwayMatch = awayMatchTime && isInMatchPeriod(row.time, awayMatchTime);
            if (inHomeMatch || inAwayMatch) {
                tr.classList.add('match-period');
            }

            // 时间单元格
            const timeCell = document.createElement('td');
            timeCell.textContent = formatModifyTime(row.time);
            tr.appendChild(timeCell);

            // 公司名称单元格
            const companyCell = document.createElement('td');
            if (row.type === 'company') {
                companyCell.textContent = row.data.company.nameCn;
            }
            if (row.type === 'match') {
                companyCell.colSpan = '2';
                companyCell.textContent = row.label;
            }
            tr.appendChild(companyCell);

            // 复选框单元格
            if (row.type === 'company') {
                const checkboxCell = document.createElement('td');
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.style.position = 'initial';
                checkbox.value = row.data.company.companyId;
                checkbox.addEventListener('change', function () {
                    if (this.checked) {
                        selectedComp.push(row.data);
                    } else {
                        selectedComp = selectedComp.filter(c => c.company.companyId !== row.data.company.companyId);
                    }
                });
                checkboxCell.appendChild(checkbox);
                tr.appendChild(checkboxCell);
            }

            table.appendChild(tr);
        });

        return table;
    }

    // 创建对比表格
    function createComparisonTable(homeMatchTime, awayMatchTime) {
        if (selectedComp.length === 0) {
            alert('请先选择至少一个公司');
            return null;
        }

        const table = document.createElement('table');
        table.style.textAlign = 'center';
        table.style.borderCollapse = 'collapse';
        table.style.margin = '10px auto 0';
        table.className = 'odds-table';

        // 收集所有赔率数据
        let allOdds = [];
        selectedComp.forEach(companyData => {
            companyData.odds.forEach(odd => {
                allOdds.push({...odd, company: companyData.company});
            });
        });

        // 获取所有时间点
        const uniqueTimes = [...new Set(allOdds.map(odd => odd.ModifyTime))];

        // 比赛时间点
        const homeStart = timestampToDate(homeMatchTime);
        const homeEnd = new Date(homeStart.getTime() + 2 * 60 * 60 * 1000);
        const awayStart = timestampToDate(awayMatchTime);
        const awayEnd = new Date(awayStart.getTime() + 2 * 60 * 60 * 1000);

        const matchTimes = [
            { time: dateToModifyTimeStr(homeStart), label: '主队比赛开始' },
            { time: dateToModifyTimeStr(homeEnd), label: '主队比赛结束' },
            { time: dateToModifyTimeStr(awayStart), label: '客队比赛开始' },
            { time: dateToModifyTimeStr(awayEnd), label: '客队比赛结束' }
        ];

        // 合并并排序所有时间点
        const allTimes = [...uniqueTimes, ...matchTimes.map(mt => mt.time)];
        const sortedTimes = [...new Set(allTimes)].sort((a, b) => b.localeCompare(a));

        // 创建表头
        const headerRow = document.createElement('tr');
        const timeHeader = document.createElement('th');
        timeHeader.textContent = '时间';
        headerRow.appendChild(timeHeader);

        // 添加各公司的列
        selectedComp.forEach(companyData => {
            const panKouHeader = document.createElement('th');
            panKouHeader.textContent = `${companyData.company.nameCn}让球`;
            headerRow.appendChild(panKouHeader);

            const diffHeader = document.createElement('th');
            diffHeader.textContent = `${companyData.company.nameCn}水差`;
            headerRow.appendChild(diffHeader);
        });

        table.appendChild(headerRow);

        // 创建数据行
        sortedTimes.forEach(time => {
            const tr = document.createElement('tr');

            // 检查是否在比赛期间
            const inHomeMatch = homeMatchTime && isInMatchPeriod(time, homeMatchTime);
            const inAwayMatch = awayMatchTime && isInMatchPeriod(time, awayMatchTime);
            if (inHomeMatch || inAwayMatch) {
                tr.classList.add('match-period');
            }

            // 时间单元格
            const timeCell = document.createElement('td');
            timeCell.textContent = formatModifyTime(time);
            tr.appendChild(timeCell);

            // 各公司数据
            selectedComp.forEach(companyData => {
                // 让球数单元格
                const panKouCell = document.createElement('td');
                // 赔率差单元格
                const diffCell = document.createElement('td');

                // 查找该时间点的赔率数据
                const odd = companyData.odds.find(o => o.ModifyTime === time);

                if (odd) {
                    panKouCell.textContent = odd.PanKou + '⚽';
                    const diff = (parseFloat(odd.AwayOdds) - parseFloat(odd.HomeOdds)).toFixed(2);
                    diffCell.textContent = diff;
                }

                tr.appendChild(panKouCell);
                tr.appendChild(diffCell);
            });

            table.appendChild(tr);
        });

        return table;
    }

    // 主函数
    async function init() {
        try {
            // 获取所有公司的赔率数据
            const companiesData = await Promise.all(companies.map(fetchOddsData));

            // 过滤有数据的公司
            const validData = companiesData.filter(data => data.odds.length > 0);

            // 获取主客队上一场比赛时间
            const homeMatchTime = jsonData?.nearMatches?.homeMatches?.matches?.[0]?.matchTime || "";
            const awayMatchTime = jsonData?.nearMatches?.awayMatches?.matches?.[0]?.matchTime || "";

            // 创建主表格
            const mainTable = createMainTable(validData, homeMatchTime, awayMatchTime);

            // 创建对比按钮
            const compareBtn = document.createElement('button');
            compareBtn.textContent = '对比选中的公司';
            compareBtn.style.background = '#bdf';
            compareBtn.style.padding = '5px 10px';
            compareBtn.style.marginTop = '10px';
            compareBtn.addEventListener('click', () => {
                // 移除已存在的对比表格
                const oldTable = document.getElementById('comparison-table');
                if (oldTable) oldTable.remove();

                // 创建新对比表格
                const comparisonTable = createComparisonTable(homeMatchTime, awayMatchTime);
                if (comparisonTable) {
                    comparisonTable.id = 'comparison-table';
                    compareBtn.parentNode.insertBefore(comparisonTable, compareBtn.nextSibling);
                }
            });

            // 创建容器并添加到页面
            const container = document.createElement('div');
            container.style.textAlign = 'center';
            container.style.fontSize = '16px'
            container.appendChild(mainTable);
            container.appendChild(compareBtn);

            const contentDiv = document.getElementById('content');
            if (contentDiv) {
                if (contentDiv.firstChild) {
                    contentDiv.insertBefore(container, contentDiv.firstChild);
                } else {
                    contentDiv.appendChild(container);
                }
            } else {
                document.body.insertBefore(container, document.body.firstChild);
            }
        } catch (error) {
            alert(`脚本执行出错: ${error.message}`);
            console.error(error);
        }
    }

    // 启动脚本
    init();
})();