Files
thebet365/apps/player/src/stores/betSlip.ts
Mars 14e49374ac 初始化足球投注平台 MVP Monorepo
包含 NestJS 后端、三端前端、Prisma 数据模型、结算引擎测试与 PRD 文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 14:35:48 +08:00

75 lines
1.7 KiB
TypeScript

import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
export interface SlipItem {
selectionId: string;
oddsVersion: string;
matchId: string;
matchName: string;
selectionName: string;
odds: number;
marketType: string;
}
export const useBetSlipStore = defineStore('betSlip', () => {
const items = ref<SlipItem[]>([]);
const stake = ref<number>(10);
const mode = ref<'single' | 'parlay'>('single');
const count = computed(() => items.value.length);
const isParlay = computed(() => items.value.length >= 2);
function addItem(item: SlipItem) {
const existing = items.value.findIndex(
(i) => i.selectionId === item.selectionId,
);
if (existing >= 0) {
items.value.splice(existing, 1);
return;
}
items.value.push(item);
if (items.value.length >= 2) mode.value = 'parlay';
}
function removeItem(selectionId: string) {
items.value = items.value.filter((i) => i.selectionId !== selectionId);
if (items.value.length < 2) mode.value = 'single';
}
function clear() {
items.value = [];
mode.value = 'single';
}
const totalOdds = computed(() =>
items.value.reduce((acc, i) => acc * i.odds, 1),
);
const potentialReturn = computed(() =>
mode.value === 'parlay'
? stake.value * totalOdds.value
: items.value.length === 1
? stake.value * items.value[0].odds
: 0,
);
const hasSameMatch = computed(() => {
const matchIds = items.value.map((i) => i.matchId);
return new Set(matchIds).size !== matchIds.length;
});
return {
items,
stake,
mode,
count,
isParlay,
totalOdds,
potentialReturn,
hasSameMatch,
addItem,
removeItem,
clear,
};
});