feat: 前台匿名浏览、登录引导、客服入口与返水增强
前台: - 未登录可浏览首页/赛事/赔率,下注等操作弹出登录引导(去登录/继续浏览) - 顶部新增客服入口与 iframe 弹窗 - 登录页支持暂不登录返回浏览 API: - 首页/赛事/冠军盘接口改为公开访问,支持 X-Locale 头 - JWT 守卫支持可选认证 返水: - 注单新增 is_cashbacked 字段,发放时自动标记 - 预览展示玩家余额,明确平台直发不从代理扣款 - 后台注单列表与玩家历史展示回水状态 其他: - 串关禁止同场重复选号(SAME_MATCH) - 补充结算资金流分析文档 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
PARLAY_MIN_LEGS,
|
||||
PARLAY_MAX_LEGS,
|
||||
canSelectForParlay,
|
||||
hasDuplicateParlayMatch,
|
||||
isPreMatchKickoff,
|
||||
isSupportedSport,
|
||||
resolveTranslationFallback,
|
||||
@@ -180,6 +181,11 @@ export class BetsService {
|
||||
selections.push(sel);
|
||||
}
|
||||
|
||||
const matchIds = selections.map((s) => s.market.matchId);
|
||||
if (hasDuplicateParlayMatch(matchIds)) {
|
||||
throw appBadRequest('PARLAY_SAME_MATCH_FORBIDDEN');
|
||||
}
|
||||
|
||||
let totalOdds = new Decimal(1);
|
||||
for (const sel of selections) {
|
||||
totalOdds = totalOdds.mul(sel.odds.toString());
|
||||
@@ -403,6 +409,7 @@ export class BetsService {
|
||||
currency: string;
|
||||
placedAt: Date;
|
||||
settledAt: Date | null;
|
||||
isCashbacked?: boolean;
|
||||
user: { id: bigint; username: string; parent: { username: string } | null };
|
||||
_count: { selections: number };
|
||||
},
|
||||
@@ -424,6 +431,7 @@ export class BetsService {
|
||||
currency: b.currency,
|
||||
placedAt: b.placedAt,
|
||||
settledAt: b.settledAt,
|
||||
isCashbacked: b.isCashbacked ?? false,
|
||||
selectionCount: b._count.selections,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user