feat(baccarat): 实现百家乐实时下注人数统计功能
- 新增 BaccaratPoolUpdated 事件,用于通过 WebSocket 广播实时下注数据更新 - 增加数据库迁移以在 baccarat_rounds 表中添加对应的下注人数统计字段 - 更新 BaccaratRound 模型以及 BaccaratController,支持实时下注统计更新与 WebSocket 事件分发 - 更新前端 chat.js 以及 baccarat-panel.blade.php,利用 Alpine.js 和 Echo 接收事件并动态渲染 "大"、"小"、"豹子" 的实时下注计数
This commit is contained in:
@@ -116,6 +116,12 @@ export function initChat(roomId) {
|
||||
new CustomEvent("chat:baccarat.opened", { detail: e }),
|
||||
);
|
||||
})
|
||||
.listen(".baccarat.pool_updated", (e) => {
|
||||
console.log("百家乐押注更新:", e);
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("chat:baccarat.pool_updated", { detail: e }),
|
||||
);
|
||||
})
|
||||
.listen(".baccarat.settled", (e) => {
|
||||
console.log("百家乐结算:", e);
|
||||
window.dispatchEvent(
|
||||
|
||||
@@ -124,7 +124,10 @@
|
||||
'border:2px solid #1d4ed8; background:#1d4ed8; color:#fff; transform:scale(1.05); box-shadow:0 4px 14px rgba(29,78,216,.3);' :
|
||||
'border:2px solid #bfdbfe; background:#eff6ff; color:#1d4ed8;'">
|
||||
<div style="font-size:22px;">🔵</div>
|
||||
<div style="font-size:13px; margin-top:4px;">大</div>
|
||||
<div style="font-size:13px; margin-top:4px; display:flex; align-items:center; justify-content:center; gap:4px;">
|
||||
<span>大</span>
|
||||
<span x-show="betCountBig > 0" x-text="'👤 ' + betCountBig" style="font-size:11px; opacity:0.85; font-weight:normal;"></span>
|
||||
</div>
|
||||
<div style="font-size:10px; margin-top:2px; opacity:.75;">11~17点 • 1:1</div>
|
||||
</button>
|
||||
{{-- 小 --}}
|
||||
@@ -135,7 +138,10 @@
|
||||
'border:2px solid #d97706; background:#d97706; color:#fff; transform:scale(1.05); box-shadow:0 4px 14px rgba(217,119,6,.3);' :
|
||||
'border:2px solid #fde68a; background:#fffbeb; color:#b45309;'">
|
||||
<div style="font-size:22px;">🟡</div>
|
||||
<div style="font-size:13px; margin-top:4px;">小</div>
|
||||
<div style="font-size:13px; margin-top:4px; display:flex; align-items:center; justify-content:center; gap:4px;">
|
||||
<span>小</span>
|
||||
<span x-show="betCountSmall > 0" x-text="'👤 ' + betCountSmall" style="font-size:11px; opacity:0.85; font-weight:normal;"></span>
|
||||
</div>
|
||||
<div style="font-size:10px; margin-top:2px; opacity:.75;">4~10点 • 1:1</div>
|
||||
</button>
|
||||
{{-- 豹子 --}}
|
||||
@@ -146,7 +152,10 @@
|
||||
'border:2px solid #7c3aed; background:#7c3aed; color:#fff; transform:scale(1.05); box-shadow:0 4px 14px rgba(124,58,237,.3);' :
|
||||
'border:2px solid #ddd6fe; background:#f5f3ff; color:#7c3aed;'">
|
||||
<div style="font-size:22px;">💥</div>
|
||||
<div style="font-size:13px; margin-top:4px;">豹子</div>
|
||||
<div style="font-size:13px; margin-top:4px; display:flex; align-items:center; justify-content:center; gap:4px;">
|
||||
<span>豹子</span>
|
||||
<span x-show="betCountTriple > 0" x-text="'👤 ' + betCountTriple" style="font-size:11px; opacity:0.85; font-weight:normal;"></span>
|
||||
</div>
|
||||
<div style="font-size:10px; margin-top:2px; opacity:.75;">三同 • 1:24</div>
|
||||
</button>
|
||||
</div>
|
||||
@@ -165,20 +174,21 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
{{-- 自定义金额 --}}
|
||||
<input type="number" x-model.number="betAmount" min="100" placeholder="自定义金额"
|
||||
{{-- 自定义金额 (带有 id 和 name 防止 Bitwarden 等密码管理插件检索 DOM 时因属性为 null 报错) --}}
|
||||
<input type="number" id="baccarat-bet-amount" name="bet_amount" x-model.number="betAmount" min="100" placeholder="自定义金额"
|
||||
autocomplete="off" data-bwignore="true" data-lpignore="true" data-1p-ignore="true"
|
||||
style="width:100%; background:#f6faff; border:1.5px solid #d0e4f5;
|
||||
border-radius:8px; padding:8px 12px; color:#225588; font-size:13px;
|
||||
box-sizing:border-box; margin-bottom:10px;"
|
||||
x-on:focus="$event.target.select()">
|
||||
|
||||
|
||||
{{-- 下注按钮 --}}
|
||||
<button x-on:click="submitBet()" :disabled="!selectedType || betAmount < 100 || submitting"
|
||||
:style="(!selectedType || betAmount < 100 || submitting) ?
|
||||
<button x-on:click="submitBet()" :disabled="!roundId || !selectedType || betAmount < 100 || submitting"
|
||||
:style="(!roundId || !selectedType || betAmount < 100 || submitting) ?
|
||||
'display:block; width:100%; border:none; border-radius:12px; padding:13px 0; font-size:14px; font-weight:bold; cursor:not-allowed; transition:all .2s; background:#e0e8f0; color:#99a8b8; box-shadow:none; font-family:inherit;' :
|
||||
'display:block; width:100%; border:none; border-radius:12px; padding:13px 0; font-size:14px; font-weight:bold; cursor:pointer; transition:all .2s; background:linear-gradient(135deg,#336699,#5a8fc0); color:#fff; box-shadow:0 4px 14px rgba(51,102,153,.3); font-family:inherit;'">
|
||||
<span
|
||||
x-text="submitting ? '提交中…' : (!selectedType ? '请先选择大/小/豹子' : '🎲 押注「' + betTypeLabel(selectedType) + '」 ' + Number(betAmount).toLocaleString() + ' 金币')"></span>
|
||||
x-text="!roundId ? '尚未开局' : (submitting ? '提交中…' : (!selectedType ? '请先选择大/小/豹子' : '🎲 押注「' + betTypeLabel(selectedType) + '」 ' + Number(betAmount).toLocaleString() + ' 金币'))"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -407,6 +417,11 @@
|
||||
totalBetBig: 0,
|
||||
totalBetSmall: 0,
|
||||
totalBetTriple: 0,
|
||||
|
||||
// 押注人数统计
|
||||
betCountBig: 0,
|
||||
betCountSmall: 0,
|
||||
betCountTriple: 0,
|
||||
|
||||
// 本人下注
|
||||
myBet: false,
|
||||
@@ -448,6 +463,9 @@
|
||||
this.settledDice = [];
|
||||
this.selectedType = '';
|
||||
this.betAmount = 100;
|
||||
this.betCountBig = 0;
|
||||
this.betCountSmall = 0;
|
||||
this.betCountTriple = 0;
|
||||
this.show = true;
|
||||
|
||||
this.loadCurrentRound();
|
||||
@@ -466,6 +484,9 @@
|
||||
this.totalBetBig = data.round.total_bet_big;
|
||||
this.totalBetSmall = data.round.total_bet_small;
|
||||
this.totalBetTriple = data.round.total_bet_triple;
|
||||
this.betCountBig = data.round.bet_count_big;
|
||||
this.betCountSmall = data.round.bet_count_small;
|
||||
this.betCountTriple = data.round.bet_count_triple;
|
||||
if (data.round.my_bet) {
|
||||
this.myBet = true;
|
||||
this.myBetType = data.round.my_bet.bet_type;
|
||||
@@ -493,7 +514,7 @@
|
||||
* 提交下注
|
||||
*/
|
||||
async submitBet() {
|
||||
if (!this.selectedType || this.betAmount < 100 || this.submitting) return;
|
||||
if (!this.roundId || !this.selectedType || this.betAmount < 100 || this.submitting) return;
|
||||
this.submitting = true;
|
||||
|
||||
try {
|
||||
@@ -512,11 +533,15 @@
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.ok) {
|
||||
if (res.ok && data.ok) {
|
||||
this.myBet = true;
|
||||
this.myBetType = data.bet_type;
|
||||
this.myBetAmount = data.amount;
|
||||
window.chatDialog?.alert(data.message, '下注成功', '#336699');
|
||||
} else if (res.status === 422 && data.errors) {
|
||||
// 取出第一条 Laravel 验证失败原因
|
||||
const firstError = Object.values(data.errors)[0][0];
|
||||
window.chatDialog?.alert(firstError, '下注验证失败', '#ef4444');
|
||||
} else {
|
||||
window.chatDialog?.alert(data.message || '下注失败', '提示', '#ef4444');
|
||||
}
|
||||
@@ -627,6 +652,21 @@
|
||||
if (panel) Alpine.$data(panel).showResult(e.detail);
|
||||
});
|
||||
|
||||
/** 收到下注池更新:更新押注人数 */
|
||||
window.addEventListener('chat:baccarat.pool_updated', (e) => {
|
||||
const panel = document.getElementById('baccarat-panel');
|
||||
if (panel) {
|
||||
const pd = Alpine.$data(panel);
|
||||
const data = e.detail;
|
||||
// 判断 round_id 是否一致
|
||||
if (pd.roundId === data.round_id) {
|
||||
pd.betCountBig = data.bet_count_big;
|
||||
pd.betCountSmall = data.bet_count_small;
|
||||
pd.betCountTriple = data.bet_count_triple;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** 页面加载时:检查是否有进行中的局,有则自动恢复面板 */
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
try {
|
||||
@@ -656,6 +696,9 @@
|
||||
panelData.totalBetBig = round.total_bet_big;
|
||||
panelData.totalBetSmall = round.total_bet_small;
|
||||
panelData.totalBetTriple = round.total_bet_triple;
|
||||
panelData.betCountBig = round.bet_count_big;
|
||||
panelData.betCountSmall = round.bet_count_small;
|
||||
panelData.betCountTriple = round.bet_count_triple;
|
||||
|
||||
if (round.my_bet) {
|
||||
panelData.myBet = true;
|
||||
|
||||
Reference in New Issue
Block a user