|
@@ -14,6 +14,7 @@ import {
|
|
|
Pagination,
|
|
Pagination,
|
|
|
Radio,
|
|
Radio,
|
|
|
RadioGroup,
|
|
RadioGroup,
|
|
|
|
|
+ Switch,
|
|
|
Spin,
|
|
Spin,
|
|
|
} from 'ant-design-vue';
|
|
} from 'ant-design-vue';
|
|
|
import dayjs from 'dayjs';
|
|
import dayjs from 'dayjs';
|
|
@@ -55,50 +56,15 @@ type HistoryGamesResponse = {
|
|
|
total: number;
|
|
total: number;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const MARKET_GROUPS = [
|
|
|
|
|
- {
|
|
|
|
|
- keys: [
|
|
|
|
|
- 'ior_mn',
|
|
|
|
|
- 'ior_wmh_1',
|
|
|
|
|
- 'ior_wmh_2',
|
|
|
|
|
- 'ior_wmh_3',
|
|
|
|
|
- 'ior_wmc_1',
|
|
|
|
|
- 'ior_wmc_2',
|
|
|
|
|
- 'ior_wmc_3',
|
|
|
|
|
- ],
|
|
|
|
|
- label: '让平盘',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- keys: ['ior_ot_1', 'ior_ot_2', 'ior_ot_3', 'ior_ot_4', 'ior_ot_5'],
|
|
|
|
|
- label: '进球数',
|
|
|
|
|
- },
|
|
|
|
|
-];
|
|
|
|
|
|
|
+const MARKET_KEYS = ['ior_ot_1', 'ior_ot_2', 'ior_ot_3', 'ior_ot_4'];
|
|
|
|
|
|
|
|
const MARKET_LABELS: Record<string, string> = {
|
|
const MARKET_LABELS: Record<string, string> = {
|
|
|
- ior_mn: '和局',
|
|
|
|
|
ior_ot_1: '总进球 1',
|
|
ior_ot_1: '总进球 1',
|
|
|
ior_ot_2: '总进球 2',
|
|
ior_ot_2: '总进球 2',
|
|
|
ior_ot_3: '总进球 3',
|
|
ior_ot_3: '总进球 3',
|
|
|
ior_ot_4: '总进球 4',
|
|
ior_ot_4: '总进球 4',
|
|
|
- ior_ot_5: '总进球 5',
|
|
|
|
|
- ior_wmc_1: '客胜 1 球',
|
|
|
|
|
- ior_wmc_2: '客胜 2 球',
|
|
|
|
|
- ior_wmc_3: '客胜 3 球',
|
|
|
|
|
- ior_wmh_1: '主胜 1 球',
|
|
|
|
|
- ior_wmh_2: '主胜 2 球',
|
|
|
|
|
- ior_wmh_3: '主胜 3 球',
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const DEFAULT_MARKET_KEYS = [
|
|
|
|
|
- 'ior_mn',
|
|
|
|
|
- 'ior_wmh_1',
|
|
|
|
|
- 'ior_wmh_2',
|
|
|
|
|
- 'ior_wmh_3',
|
|
|
|
|
- 'ior_wmc_1',
|
|
|
|
|
- 'ior_wmc_2',
|
|
|
|
|
- 'ior_wmc_3',
|
|
|
|
|
-];
|
|
|
|
|
-
|
|
|
|
|
const chartRef = ref<EchartsUIType>();
|
|
const chartRef = ref<EchartsUIType>();
|
|
|
const { renderEcharts } = useEcharts(chartRef);
|
|
const { renderEcharts } = useEcharts(chartRef);
|
|
|
|
|
|
|
@@ -108,6 +74,7 @@ const selectedEventId = ref<number>();
|
|
|
const selectedMarkets = ref<string[]>([]);
|
|
const selectedMarkets = ref<string[]>([]);
|
|
|
const loadingGames = ref(false);
|
|
const loadingGames = ref(false);
|
|
|
const loadingHistory = ref(false);
|
|
const loadingHistory = ref(false);
|
|
|
|
|
+const isMultiSelect = ref(false);
|
|
|
const marketType = ref(-1);
|
|
const marketType = ref(-1);
|
|
|
const pageSize = 50;
|
|
const pageSize = 50;
|
|
|
const currentPage = ref(1);
|
|
const currentPage = ref(1);
|
|
@@ -117,7 +84,7 @@ const totalGames = ref(0);
|
|
|
|
|
|
|
|
const availableMarketKeys = computed(() => {
|
|
const availableMarketKeys = computed(() => {
|
|
|
const markets = history.value?.markets ?? {};
|
|
const markets = history.value?.markets ?? {};
|
|
|
- return Object.keys(markets).filter((key) => markets[key]?.length);
|
|
|
|
|
|
|
+ return MARKET_KEYS.filter((key) => markets[key]?.length);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const hasChartData = computed(() => !!history.value && availableMarketKeys.value.length > 0);
|
|
const hasChartData = computed(() => !!history.value && availableMarketKeys.value.length > 0);
|
|
@@ -140,25 +107,18 @@ const isHalfEvent = (eventId?: number) => {
|
|
|
|
|
|
|
|
const marketOptions = computed(() => {
|
|
const marketOptions = computed(() => {
|
|
|
const available = new Set(availableMarketKeys.value);
|
|
const available = new Set(availableMarketKeys.value);
|
|
|
- return MARKET_GROUPS.map((group) => ({
|
|
|
|
|
- ...group,
|
|
|
|
|
- availableKeys: group.keys.filter((key) => available.has(key)),
|
|
|
|
|
- options: group.keys
|
|
|
|
|
- .filter((key) => available.has(key))
|
|
|
|
|
- .map((key) => ({
|
|
|
|
|
- label: MARKET_LABELS[key] ?? key,
|
|
|
|
|
- value: key,
|
|
|
|
|
- })),
|
|
|
|
|
- })).filter((group) => group.options.length);
|
|
|
|
|
|
|
+ return MARKET_KEYS.filter((key) => available.has(key)).map((key) => ({
|
|
|
|
|
+ label: MARKET_LABELS[key] ?? key,
|
|
|
|
|
+ value: key,
|
|
|
|
|
+ }));
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const isGroupSelected = (keys: string[]) => {
|
|
|
|
|
- return keys.length > 0 && keys.every((key) => selectedMarkets.value.includes(key));
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-const selectMarketGroup = (keys: string[]) => {
|
|
|
|
|
- selectedMarkets.value = isGroupSelected(keys) ? [] : [...keys];
|
|
|
|
|
-};
|
|
|
|
|
|
|
+const selectedMarket = computed({
|
|
|
|
|
+ get: () => selectedMarkets.value[0],
|
|
|
|
|
+ set: (key?: string) => {
|
|
|
|
|
+ selectedMarkets.value = key ? [key] : [];
|
|
|
|
|
+ },
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
const formatTime = (time?: number) => {
|
|
const formatTime = (time?: number) => {
|
|
|
return time ? dayjs(time).format('MM-DD HH:mm:ss') : '-';
|
|
return time ? dayjs(time).format('MM-DD HH:mm:ss') : '-';
|
|
@@ -321,8 +281,8 @@ const fetchHistory = async (eventId: number) => {
|
|
|
params: { event_id: eventId },
|
|
params: { event_id: eventId },
|
|
|
});
|
|
});
|
|
|
history.value = data;
|
|
history.value = data;
|
|
|
- const keys = Object.keys(data?.markets ?? {}).filter((key) => data?.markets?.[key]?.length);
|
|
|
|
|
- selectedMarkets.value = DEFAULT_MARKET_KEYS.filter((key) => keys.includes(key));
|
|
|
|
|
|
|
+ const firstKey = MARKET_KEYS.find((key) => data?.markets?.[key]?.length);
|
|
|
|
|
+ selectedMarkets.value = firstKey ? [firstKey] : [];
|
|
|
await nextTick();
|
|
await nextTick();
|
|
|
setTimeout(renderChart);
|
|
setTimeout(renderChart);
|
|
|
}
|
|
}
|
|
@@ -366,6 +326,13 @@ watch(currentPage, () => {
|
|
|
|
|
|
|
|
watch(selectedMarkets, () => {
|
|
watch(selectedMarkets, () => {
|
|
|
renderChart();
|
|
renderChart();
|
|
|
|
|
+}, { deep: true });
|
|
|
|
|
+
|
|
|
|
|
+watch(isMultiSelect, (multiSelect) => {
|
|
|
|
|
+ if (!multiSelect && selectedMarkets.value.length > 1) {
|
|
|
|
|
+ selectedMarkets.value = [selectedMarkets.value[0]!];
|
|
|
|
|
+ }
|
|
|
|
|
+ renderChart();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
@@ -435,16 +402,21 @@ onMounted(() => {
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="market-selector" v-if="marketOptions.length">
|
|
<div class="market-selector" v-if="marketOptions.length">
|
|
|
- <div v-for="group in marketOptions" :key="group.label" class="market-group">
|
|
|
|
|
- <button
|
|
|
|
|
- class="market-group-label"
|
|
|
|
|
- :class="{ active: isGroupSelected(group.availableKeys) }"
|
|
|
|
|
- type="button"
|
|
|
|
|
- @click="selectMarketGroup(group.availableKeys)"
|
|
|
|
|
- >
|
|
|
|
|
- {{ group.label }}
|
|
|
|
|
- </button>
|
|
|
|
|
- <CheckboxGroup v-model:value="selectedMarkets" :options="group.options" />
|
|
|
|
|
|
|
+ <div class="market-mode">
|
|
|
|
|
+ <span>盘口选择</span>
|
|
|
|
|
+ <Switch
|
|
|
|
|
+ v-model:checked="isMultiSelect"
|
|
|
|
|
+ checked-children="多选"
|
|
|
|
|
+ un-checked-children="单选"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="market-options">
|
|
|
|
|
+ <CheckboxGroup
|
|
|
|
|
+ v-if="isMultiSelect"
|
|
|
|
|
+ v-model:value="selectedMarkets"
|
|
|
|
|
+ :options="marketOptions"
|
|
|
|
|
+ />
|
|
|
|
|
+ <RadioGroup v-else v-model:value="selectedMarket" :options="marketOptions" />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -577,34 +549,23 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.market-selector {
|
|
.market-selector {
|
|
|
- display: grid;
|
|
|
|
|
- gap: 8px;
|
|
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 16px;
|
|
|
padding: 12px 16px;
|
|
padding: 12px 16px;
|
|
|
border-bottom: 1px solid hsl(var(--border));
|
|
border-bottom: 1px solid hsl(var(--border));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.market-group {
|
|
|
|
|
|
|
+.market-mode {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: flex-start;
|
|
|
|
|
- gap: 12px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.market-group-label {
|
|
|
|
|
- width: 64px;
|
|
|
|
|
- flex: none;
|
|
|
|
|
- padding: 0;
|
|
|
|
|
- border: 0;
|
|
|
|
|
- background: transparent;
|
|
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
color: hsl(var(--foreground) / 0.66);
|
|
color: hsl(var(--foreground) / 0.66);
|
|
|
- cursor: pointer;
|
|
|
|
|
font-size: 13px;
|
|
font-size: 13px;
|
|
|
- line-height: 24px;
|
|
|
|
|
- text-align: left;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.market-group-label.active,
|
|
|
|
|
-.market-group-label:hover {
|
|
|
|
|
- color: hsl(var(--primary));
|
|
|
|
|
|
|
+.market-options {
|
|
|
|
|
+ min-width: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.chart-wrap {
|
|
.chart-wrap {
|
|
@@ -637,5 +598,10 @@ onMounted(() => {
|
|
|
.chart-wrap {
|
|
.chart-wrap {
|
|
|
height: 420px;
|
|
height: 420px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .market-selector {
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|