feat: 前台匿名浏览、登录引导、客服入口与返水增强

前台:
- 未登录可浏览首页/赛事/赔率,下注等操作弹出登录引导(去登录/继续浏览)
- 顶部新增客服入口与 iframe 弹窗
- 登录页支持暂不登录返回浏览

API:
- 首页/赛事/冠军盘接口改为公开访问,支持 X-Locale 头
- JWT 守卫支持可选认证

返水:
- 注单新增 is_cashbacked 字段,发放时自动标记
- 预览展示玩家余额,明确平台直发不从代理扣款
- 后台注单列表与玩家历史展示回水状态

其他:
- 串关禁止同场重复选号(SAME_MATCH)
- 补充结算资金流分析文档

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-11 09:36:44 +08:00
parent 785fa4416d
commit 844727c82e
35 changed files with 1007 additions and 49 deletions

View File

@@ -50,7 +50,7 @@ export const useBetSlipStore = defineStore('betSlip', () => {
items.value.push(item);
}
/** 串关页:同场/跨场均可多选,合成一张串关单 */
/** 串关页:须为不同赛事,每场最多 1 项 */
function addParlayLeg(item: SlipItem): ParlayRejectReason | 'MAX_LEGS' | null {
if (mode.value === 'single') items.value = [];
mode.value = 'parlay';
@@ -62,6 +62,11 @@ export const useBetSlipStore = defineStore('betSlip', () => {
return null;
}
if (items.value.some((i) => i.matchId === item.matchId)) {
lastParlayError.value = 'SAME_MATCH';
return 'SAME_MATCH';
}
const check = canSelectForParlay({
marketType: item.marketType,
lineValue: parseLineValue(item.lineValue),
@@ -115,7 +120,8 @@ export const useBetSlipStore = defineStore('betSlip', () => {
() =>
mode.value === 'parlay' &&
items.value.length >= PARLAY_MIN_LEGS &&
items.value.length <= PARLAY_MAX_LEGS,
items.value.length <= PARLAY_MAX_LEGS &&
!hasSameMatch.value,
);
/** 详情页等同场多笔单关(串关模式不走此路径) */