迁移双色球彩票脚本
This commit is contained in:
@@ -406,264 +406,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 双色球彩票面板 Alpine.js 组件
|
||||
*/
|
||||
function lotteryPanel() {
|
||||
return {
|
||||
// ─── 状态 ───
|
||||
show: false,
|
||||
loading: true,
|
||||
ruleOpen: false,
|
||||
buying: false,
|
||||
|
||||
// ─── 期次数据 ───
|
||||
issueNo: '--',
|
||||
status: 'open',
|
||||
isOpen: false,
|
||||
isSuperIssue: false,
|
||||
poolAmount: 0,
|
||||
secondsLeft: 0,
|
||||
drawAt: null,
|
||||
drawRed1: null,
|
||||
drawRed2: null,
|
||||
drawRed3: null,
|
||||
drawBlue: null,
|
||||
|
||||
// ─── 选号 ───
|
||||
selectedReds: [],
|
||||
selectedBlue: null,
|
||||
cart: [], // 待购清单
|
||||
|
||||
// ─── 数据 ───
|
||||
myTickets: [],
|
||||
history: [],
|
||||
|
||||
// ─── 倒计时 ───
|
||||
_timer: null,
|
||||
|
||||
/**
|
||||
* 格式化倒计时文字(如 4h 22m 或 01:59)
|
||||
*/
|
||||
get countdownText() {
|
||||
const s = this.secondsLeft;
|
||||
if (s <= 0) return '即将开奖';
|
||||
if (s >= 3600) return `${Math.floor(s/3600)}h ${Math.floor((s%3600)/60)}m`;
|
||||
const m = Math.floor(s / 60);
|
||||
const sec = s % 60;
|
||||
return `${String(m).padStart(2,'0')}:${String(sec).padStart(2,'0')}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开面板并加载数据
|
||||
*/
|
||||
async open() {
|
||||
this.show = true;
|
||||
await this.loadData();
|
||||
this.startTimer();
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载当期状态、我的购票、历史开奖
|
||||
*/
|
||||
async loadData() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const [currentRes, histRes] = await Promise.all([
|
||||
fetch('/lottery/current', {
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
}),
|
||||
fetch('/lottery/history', {
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
}),
|
||||
]);
|
||||
const current = await currentRes.json();
|
||||
const hist = await histRes.json();
|
||||
|
||||
if (current.issue) {
|
||||
const iss = current.issue;
|
||||
this.issueNo = iss.issue_no;
|
||||
this.status = iss.status;
|
||||
this.isOpen = current.is_open;
|
||||
this.isSuperIssue = iss.is_super_issue;
|
||||
this.poolAmount = iss.pool_amount;
|
||||
this.secondsLeft = iss.seconds_left;
|
||||
this.drawRed1 = iss.red1;
|
||||
this.drawRed2 = iss.red2;
|
||||
this.drawRed3 = iss.red3;
|
||||
this.drawBlue = iss.blue;
|
||||
}
|
||||
this.myTickets = current.my_tickets ?? [];
|
||||
this.history = hist.issues ?? [];
|
||||
} catch (e) {
|
||||
// 网络异常静默处理
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 启动倒计时 ticker
|
||||
*/
|
||||
startTimer() {
|
||||
clearInterval(this._timer);
|
||||
this._timer = setInterval(() => {
|
||||
if (this.secondsLeft > 0) {
|
||||
this.secondsLeft--;
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换红球选择状态
|
||||
*/
|
||||
toggleRed(n) {
|
||||
if (this.selectedReds.includes(n)) {
|
||||
this.selectedReds = this.selectedReds.filter(r => r !== n);
|
||||
} else if (this.selectedReds.length < 3) {
|
||||
this.selectedReds = [...this.selectedReds, n];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 服务端机选号码(立即加入购物车)
|
||||
*/
|
||||
async doQuickPick(count = 1) {
|
||||
try {
|
||||
const res = await fetch(`/lottery/quick-pick?count=${count}`);
|
||||
const data = await res.json();
|
||||
for (const num of data.numbers) {
|
||||
if (this.cart.length < 10) {
|
||||
this.cart.push({
|
||||
reds: num.reds,
|
||||
blue: num.blue,
|
||||
quick: true
|
||||
});
|
||||
}
|
||||
}
|
||||
// 清空当前选号
|
||||
this.selectedReds = [];
|
||||
this.selectedBlue = null;
|
||||
} catch {}
|
||||
},
|
||||
|
||||
/**
|
||||
* 将当前选号加入购物车
|
||||
*/
|
||||
addToCart() {
|
||||
if (this.selectedReds.length !== 3 || !this.selectedBlue) {
|
||||
showLotteryMsg('⚠️ 请选满 3 个红球和 1 个蓝球', false);
|
||||
return;
|
||||
}
|
||||
if (this.cart.length >= 10) {
|
||||
showLotteryMsg('⚠️ 单次最多加入 10 注', false);
|
||||
return;
|
||||
}
|
||||
this.cart.push({
|
||||
reds: [...this.selectedReds].sort((a, b) => a - b),
|
||||
blue: this.selectedBlue,
|
||||
quick: false
|
||||
});
|
||||
// 清空选号等待下一注
|
||||
this.selectedReds = [];
|
||||
this.selectedBlue = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交购物车(批量购买)
|
||||
*/
|
||||
async submitCart() {
|
||||
if (this.cart.length === 0 || this.buying) return;
|
||||
this.buying = true;
|
||||
try {
|
||||
const res = await fetch('/lottery/buy', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
numbers: this.cart.map(c => ({
|
||||
reds: c.reds,
|
||||
blue: c.blue
|
||||
})),
|
||||
quick_pick: false,
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok && data.status === 'success') {
|
||||
showLotteryMsg('✅ ' + data.message, true);
|
||||
this.cart = [];
|
||||
|
||||
// 更新金币余额显示
|
||||
if (window.chatContext) {
|
||||
window.chatContext.userJjb = Math.max(0, (window.chatContext.userJjb ?? 0) - data
|
||||
.count * 100);
|
||||
}
|
||||
|
||||
// 刷新我的购票列表
|
||||
await this.loadData();
|
||||
} else {
|
||||
showLotteryMsg('❌ ' + (data.message || '购票失败'), false);
|
||||
}
|
||||
} catch {
|
||||
showLotteryMsg('🌐 网络异常,请稍后重试', false);
|
||||
}
|
||||
this.buying = false;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示彩票面板内联消息(3s 后自动消失)
|
||||
*
|
||||
* @param {string} msg
|
||||
* @param {boolean} success
|
||||
*/
|
||||
function showLotteryMsg(msg, success) {
|
||||
const el = document.getElementById('lottery-buy-msg');
|
||||
if (!el) return;
|
||||
el.style.background = success ? '#f0fdf4' : '#fff5f5';
|
||||
el.style.border = success ? '1px solid #86efac' : '1px solid #fecaca';
|
||||
el.style.color = success ? '#16a34a' : '#dc2626';
|
||||
el.textContent = msg;
|
||||
el.style.display = 'block';
|
||||
el.style.opacity = '1';
|
||||
clearTimeout(el._t);
|
||||
el._t = setTimeout(() => {
|
||||
el.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
el.style.display = 'none';
|
||||
}, 400);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
/** 打开彩票面板 */
|
||||
window.openLotteryPanel = function() {
|
||||
const panel = document.getElementById('lottery-panel');
|
||||
if (panel) Alpine.$data(panel).open();
|
||||
};
|
||||
|
||||
/** 关闭彩票面板 */
|
||||
window.closeLotteryPanel = function() {
|
||||
const panel = document.getElementById('lottery-panel');
|
||||
if (panel) {
|
||||
const data = Alpine.$data(panel);
|
||||
data.show = false;
|
||||
clearInterval(data._timer);
|
||||
}
|
||||
};
|
||||
|
||||
// 顶部关闭按钮由脚本集中绑定,避免标题栏继续保留内联 onclick。
|
||||
document.querySelectorAll('[data-lottery-panel-close]').forEach(button => {
|
||||
button.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
closeLotteryPanel();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{-- 双色球彩票 Alpine 组件已迁移到 resources/js/chat-room/lottery-panel.js --}}
|
||||
|
||||
Reference in New Issue
Block a user