// ==UserScript==
// @name 竞彩助手
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 竞彩足球/篮球增强助手,支持赔率高亮、投注优化、数据分析
// @author You
// @match *://*.sporttery.cn/*
// @match *://*.caibow.com/*
// @match *://*.lottery.cn/*
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @connect *
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// ==================== 配置 ====================
const CONFIG = {
// 高赔率阈值
highOddsThreshold: 3.5,
// 显示联赛筛选
showLeagueFilter: true,
// 开启数据分析
enableStatsAnalysis: true,
// 快捷投注
quickBet: true,
// 主题颜色
themeColor: '#e74c3c',
// 字体大小
fontSize: 14
};
// ==================== 样式 ====================
const STYLES = `
/* 竞彩助手 - 主面板 */
.jingcai-helper-panel {
position: fixed;
top: 20px;
right: 20px;
width: 320px;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0,0,0,0.4);
z-index: 999999;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: #fff;
overflow: hidden;
transition: all 0.3s ease;
}
.jingcai-helper-panel.minimized {
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
.jingcai-helper-panel.minimized .jingcai-panel-content {
display: none;
}
.jingcai-panel-header {
background: ${CONFIG.themeColor};
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: move;
}
.jingcai-panel-header h3 {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.jingcai-panel-header .controls {
display: flex;
gap: 8px;
}
.jingcai-panel-header .btn {
background: rgba(255,255,255,0.2);
border: none;
color: #fff;
width: 24px;
height: 24px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
}
.jingcai-panel-header .btn:hover {
background: rgba(255,255,255,0.3);
}
.jingcai-panel-content {
padding: 16px;
max-height: 500px;
overflow-y: auto;
}
/* 高赔率标记 */
.high-odds {
background: linear-gradient(135deg, #f39c12, #e74c3c) !important;
color: #fff !important;
font-weight: bold;
border-radius: 4px;
padding: 2px 6px;
}
/* 低赔率标记 */
.low-odds {
color: #95a5a6 !important;
}
/* 比赛卡片 */
.match-card {
background: #fff;
border-radius: 8px;
padding: 12px;
margin-bottom: 10px;
color: #333;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.2s;
}
.match-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.match-card .match-time {
font-size: 12px;
color: #666;
margin-bottom: 6px;
}
.match-card .teams {
display: flex;
justify-content: space-between;
font-size: 14px;
font-weight: 500;
margin-bottom: 8px;
}
.match-card .odds-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.match-card .odds-item {
flex: 1;
min-width: 60px;
text-align: center;
padding: 8px 4px;
background: #f5f5f5;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.match-card .odds-item:hover {
background: ${CONFIG.themeColor};
color: #fff;
}
.match-card .odds-item.high {
background: linear-gradient(135deg, #f39c12, #e74c3c);
color: #fff;
}
/* 统计面板 */
.stats-section {
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid rgba(255,255,255,0.1);
}
.stats-section h4 {
margin: 0 0 12px 0;
font-size: 14px;
color: #aaa;
}
.stat-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.stat-item:last-child {
border-bottom: none;
}
.stat-label {
color: #888;
}
.stat-value {
font-weight: 600;
color: ${CONFIG.themeColor};
}
/* 快捷投注按钮 */
.quick-bet-btn {
background: ${CONFIG.themeColor};
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
width: 100%;
margin-top: 12px;
transition: all 0.2s;
}
.quick-bet-btn:hover {
background: #c0392b;
transform: scale(1.02);
}
/* 工具提示 */
.jingcai-tooltip {
position: absolute;
background: #333;
color: #fff;
padding: 8px 12px;
border-radius: 6px;
font-size: 12px;
max-width: 200px;
z-index: 1000000;
pointer-events: none;
}
/* 联赛筛选器 */
.league-filter {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 12px;
}
.league-filter .filter-btn {
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
color: #aaa;
padding: 4px 10px;
border-radius: 20px;
font-size: 11px;
cursor: pointer;
transition: all 0.2s;
}
.league-filter .filter-btn:hover,
.league-filter .filter-btn.active {
background: ${CONFIG.themeColor};
color: #fff;
border-color: ${CONFIG.themeColor};
}
/* 隐藏滚动条但保持功能 */
.jingcai-panel-content::-webkit-scrollbar {
width: 4px;
}
.jingcai-panel-content::-webkit-scrollbar-track {
background: rgba(0,0,0,0.1);
}
.jingcai-panel-content::-webkit-scrollbar-thumb {
background: rgba(255,255,255,0.2);
border-radius: 2px;
}
/* 设置面板 */
.settings-panel {
background: rgba(255,255,255,0.05);
border-radius: 8px;
padding: 12px;
margin-top: 12px;
}
.settings-panel label {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 0;
cursor: pointer;
}
.settings-panel input[type="checkbox"] {
width: 16px;
height: 16px;
accent-color: ${CONFIG.themeColor};
}
.settings-panel input[type="number"] {
width: 60px;
padding: 4px 8px;
border: none;
border-radius: 4px;
background: rgba(255,255,255,0.1);
color: #fff;
}
/* 最小化图标 */
.minimize-icon {
display: none;
}
.jingcai-helper-panel.minimized .minimize-icon {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
font-size: 20px;
}
`;
// ==================== 主类 ====================
class JingCaiHelper {
constructor() {
this.isMinimized = GM_getValue('jingcai_minimized', false);
this.selectedMatches = [];
this.stats = {
totalBets: 0,
highOddsBets: 0,
totalOdds: 0
};
this.init();
}
init() {
this.injectStyles();
this.createPanel();
this.setupEventListeners();
this.enhancePage();
console.log('🎯 竞彩助手已启动');
}
injectStyles() {
GM_addStyle(STYLES);
}
createPanel() {
const panel = document.createElement('div');
panel.id = 'jingcai-helper-panel';
panel.className = `jingcai-helper-panel ${this.isMinimized ? 'minimized' : ''}`;
panel.innerHTML = this.getPanelHTML();
document.body.appendChild(panel);
if (this.isMinimized) {
const icon = panel.querySelector('.minimize-icon');
if (icon) icon.style.display = 'flex';
}
}
getPanelHTML() {
return `
${CONFIG.showLeagueFilter ? `
` : ''}
${CONFIG.enableStatsAnalysis ? `
📈 投注统计
已选比赛
0
总赔率
0.00
预计奖金
¥0.00
` : ''}
⚙️ 设置
`;
}
setupEventListeners() {
// 最小化按钮
document.getElementById('jingcai-toggle-min')?.addEventListener('click', () => {
this.toggleMinimize();
});
// 设置按钮
document.getElementById('jingcai-settings')?.addEventListener('click', () => {
const settingsPanel = document.getElementById('settings-panel');
if (settingsPanel) {
settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
}
});
// 联赛筛选
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
this.filterMatches(e.target.dataset.league);
});
});
// 快速投注
document.getElementById('quick-bet')?.addEventListener('click', () => {
this.executeQuickBet();
});
// 拖拽功能
this.setupDrag();
}
setupDrag() {
const panel = document.getElementById('jingcai-helper-panel');
const header = panel?.querySelector('.jingcai-panel-header');
if (!header) return;
let isDragging = false;
let startX, startY, startLeft, startTop;
header.addEventListener('mousedown', (e) => {
if (e.target.classList.contains('btn')) return;
isDragging = true;
startX = e.clientX;
startY = e.clientY;
const rect = panel.getBoundingClientRect();
startLeft = rect.left;
startTop = rect.top;
panel.style.opacity = '0.9';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
panel.style.left = (startLeft + dx) + 'px';
panel.style.top = (startTop + dy) + 'px';
panel.style.right = 'auto';
});
document.addEventListener('mouseup', () => {
isDragging = false;
panel.style.opacity = '1';
});
}
toggleMinimize() {
const panel = document.getElementById('jingcai-helper-panel');
const icon = panel?.querySelector('.minimize-icon');
this.isMinimized = !this.isMinimized;
GM_setValue('jingcai_minimized', this.isMinimized);
if (panel) {
panel.classList.toggle('minimized', this.isMinimized);
if (icon) {
icon.style.display = this.isMinimized ? 'flex' : 'none';
}
}
}
enhancePage() {
// 高亮高赔率
this.highlightHighOdds();
// 提取比赛数据
this.extractMatches();
// 监听页面变化
this.observePageChanges();
}
highlightHighOdds() {
// 查找赔率元素并高亮
const oddsPatterns = [
/^\d+\.\d{2}$/,
/^\d+\.\d{1}$/
];
document.querySelectorAll('span, div, td').forEach(el => {
const text = el.textContent.trim();
const odds = parseFloat(text);
if (oddsPatterns.some(p => p.test(text)) && odds >= CONFIG.highOddsThreshold) {
// 避免重复添加
if (!el.classList.contains('high-odds') && !el.closest('.jingcai-helper-panel')) {
el.classList.add('high-odds');
}
}
});
}
extractMatches() {
const matches = [];
// 这里应该根据实际页面结构调整选择器
// 示例:从页面提取比赛信息
try {
// 尝试多种选择器模式
const selectors = [
'.match-item',
'.game-item',
'[class*="match"]',
'[class*="game"]',
'tr[data-match]'
];
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(item => {
const match = this.parseMatchItem(item);
if (match) matches.push(match);
});
});
this.renderMatches(matches);
} catch (e) {
console.log('竞彩助手: 页面解析中...');
}
}
parseMatchItem(item) {
try {
const time = item.querySelector('.time, [class*="time"]')?.textContent || '';
const home = item.querySelector('.home, .home-team, [class*="home"]')?.textContent || '';
const away = item.querySelector('.away, .away-team, [class*="away"]')?.textContent || '';
const odds = item.querySelectorAll('.odds, [class*="odds"]');
if (home && away) {
return {
id: Date.now() + Math.random(),
time,
home: home.trim(),
away: away.trim(),
odds: Array.from(odds).map(o => ({
name: o.className.includes('win') ? '胜' :
o.className.includes('draw') ? '平' : '负',
value: parseFloat(o.textContent) || 0
}))
};
}
} catch (e) {}
return null;
}
renderMatches(matches) {
const container = document.getElementById('matches-container');
if (!container) return;
if (matches.length === 0) {
// 模拟一些示例数据
container.innerHTML = this.getSampleMatches();
} else {
container.innerHTML = matches.map(m => this.renderMatchCard(m)).join('');
this.setupMatchCardEvents();
}
}
getSampleMatches() {
return `
`;
}
renderMatchCard(match) {
return `
${match.time}
${match.home}
vs
${match.away}
${match.odds.map(o => `
${o.name} ${o.value.toFixed(2)}
`).join('')}
`;
}
setupMatchCardEvents() {
document.querySelectorAll('.match-card .odds-item').forEach(item => {
item.addEventListener('click', () => {
const card = item.closest('.match-card');
const matchId = card.dataset.id;
const bet = item.dataset.bet;
const odds = parseFloat(item.dataset.odds);
this.selectMatch(matchId, bet, odds, card);
});
});
}
selectMatch(matchId, bet, odds, card) {
// 取消选中同一比赛的其他选项
card.querySelectorAll('.odds-item').forEach(i => i.classList.remove('selected'));
item.classList.add('selected');
// 查找并移除已选比赛
this.selectedMatches = this.selectedMatches.filter(m => m.id !== matchId);
// 添加新选择
this.selectedMatches.push({ id: matchId, bet, odds });
// 更新统计
this.updateStats();
// 显示投注按钮
const betBtn = document.getElementById('quick-bet');
if (betBtn && this.selectedMatches.length > 0) {
betBtn.style.display = 'block';
}
}
updateStats() {
const totalOdds = this.selectedMatches.reduce((acc, m) => acc * m.odds, 1);
const prize = totalOdds * 100; // 假设投注100元
document.getElementById('stat-selected').textContent = this.selectedMatches.length;
document.getElementById('stat-odds').textContent = totalOdds.toFixed(2);
document.getElementById('stat-prize').textContent = `¥${prize.toFixed(2)}`;
}
executeQuickBet() {
if (this.selectedMatches.length === 0) {
alert('请先选择比赛');
return;
}
const totalOdds = this.selectedMatches.reduce((acc, m) => acc * m.odds, 1);
const confirmMsg = `确认投注 ${this.selectedMatches.length} 场比赛\n总赔率: ${totalOdds.toFixed(2)}\n预计奖金: ¥${(totalOdds * 100).toFixed(2)}`;
if (confirm(confirmMsg)) {
// 这里可以添加实际的投注逻辑
alert('🎉 投注成功!祝您中奖!');
this.selectedMatches = [];
this.updateStats();
// 清除选中状态
document.querySelectorAll('.odds-item.selected').forEach(i => {
i.classList.remove('selected');
});
const betBtn = document.getElementById('quick-bet');
if (betBtn) betBtn.style.display = 'none';
}
}
filterMatches(league) {
// 根据联赛筛选比赛
document.querySelectorAll('.match-card').forEach(card => {
const teams = card.querySelector('.teams')?.textContent || '';
if (league === 'all' || teams.includes(league)) {
card.style.display = 'block';
} else {
card.style.display = 'none';
}
});
}
observePageChanges() {
// 监听页面变化,实时更新
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
this.highlightHighOdds();
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
}
// ==================== 启动 ====================
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => new JingCaiHelper());
} else {
new JingCaiHelper();
}
})();