feat(admin,api,player): 结算预览分页、统计图表与返水限额
完善结算计算与预览 API(含后端分页),加强管理端结算/返水/权限,并优化玩家端投注单与队徽展示。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,7 +34,7 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
return Number.isFinite(n) ? n : null;
|
||||
}
|
||||
|
||||
/** 球赛/详情页:仅单关,且投注单同时只能有 1 项 */
|
||||
/** 球赛/详情页:同场可多选,分笔单关;再点同一项可取消 */
|
||||
function addItem(item: SlipItem) {
|
||||
if (mode.value === 'parlay') items.value = [];
|
||||
mode.value = 'single';
|
||||
@@ -44,13 +44,13 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
(i) => i.selectionId === item.selectionId,
|
||||
);
|
||||
if (existing >= 0) {
|
||||
items.value = [];
|
||||
items.value.splice(existing, 1);
|
||||
return;
|
||||
}
|
||||
items.value = [item];
|
||||
items.value.push(item);
|
||||
}
|
||||
|
||||
/** 串关页专用:跨场组合,同场只保留一个选项 */
|
||||
/** 串关页:同场/跨场均可多选,合成一张串关单 */
|
||||
function addParlayLeg(item: SlipItem): ParlayRejectReason | 'MAX_LEGS' | null {
|
||||
if (mode.value === 'single') items.value = [];
|
||||
mode.value = 'parlay';
|
||||
@@ -77,7 +77,6 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
return 'MAX_LEGS';
|
||||
}
|
||||
|
||||
items.value = items.value.filter((i) => i.matchId !== item.matchId);
|
||||
items.value.push(item);
|
||||
lastParlayError.value = null;
|
||||
return null;
|
||||
@@ -101,10 +100,10 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
|
||||
const potentialReturn = computed(() => {
|
||||
if (!items.value.length) return 0;
|
||||
if (mode.value === 'parlay' && items.value.length >= PARLAY_MIN_LEGS) {
|
||||
if (mode.value === 'parlay' && canPlaceParlay.value) {
|
||||
return stake.value * totalOdds.value;
|
||||
}
|
||||
return stake.value * items.value[0].odds;
|
||||
return items.value.reduce((acc, i) => acc + stake.value * i.odds, 0);
|
||||
});
|
||||
|
||||
const hasSameMatch = computed(() => {
|
||||
@@ -116,8 +115,16 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
() =>
|
||||
mode.value === 'parlay' &&
|
||||
items.value.length >= PARLAY_MIN_LEGS &&
|
||||
items.value.length <= PARLAY_MAX_LEGS &&
|
||||
!hasSameMatch.value,
|
||||
items.value.length <= PARLAY_MAX_LEGS,
|
||||
);
|
||||
|
||||
/** 详情页等同场多笔单关(串关模式不走此路径) */
|
||||
const canPlaceBatchSingles = computed(
|
||||
() => mode.value === 'single' && items.value.length >= 1,
|
||||
);
|
||||
|
||||
const canSubmit = computed(
|
||||
() => canPlaceParlay.value || canPlaceBatchSingles.value,
|
||||
);
|
||||
|
||||
const drawerOpen = ref(false);
|
||||
@@ -140,6 +147,8 @@ export const useBetSlipStore = defineStore('betSlip', () => {
|
||||
potentialReturn,
|
||||
hasSameMatch,
|
||||
canPlaceParlay,
|
||||
canPlaceBatchSingles,
|
||||
canSubmit,
|
||||
lastParlayError,
|
||||
drawerOpen,
|
||||
addItem,
|
||||
|
||||
Reference in New Issue
Block a user