You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.5 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="lottery-management">
<a-tabs v-model:activeKey="activeTab" @change="handleTabChange">
<a-tab-pane v-for="type in lotteryTypes" :key="type.key" :tab="type.label">
<a-table :columns="columns" :data-source="filteredData" :rowKey="record => record.recordId">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'numbers'">
<span>
{{ getFormattedNumbers(record) }}
</span>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)">编辑</a-button>
<a-button type="link" @click="deleteItem(record)">删除</a-button>
</a-space>
</template>
</template>
</a-table>
</a-tab-pane>
<template #rightExtra>
<a-button type="primary" @click="showAddModal">新增</a-button>
</template>
</a-tabs>
<a-modal
v-model:visible="modalVisible"
:title="(modalMode === 'add' ? '新增' : '编辑') + currentLotteryTypeLabel"
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<a-form-item label="日期" name="todayStr" :rules="[{ required: true, message: '请选择日期' }]">
<a-date-picker v-model:value="formState.todayStr" style="width: 100%" format="YYYY-MM-DD" />
</a-form-item>
<a-form-item label="期数" name="lotteryNo" :rules="[{ required: true, message: '请输入期数' }]">
<a-input v-model:value="formState.lotteryNo" placeholder="例如第250007期" />
</a-form-item>
<a-form-item v-for="i in currentLotteryType.blueCount" :key="`blue${i}`" :label="`蓝球${i}`" :name="`blue${i}`" :rules="[{ required: true, message: '请输入数字' }]">
<a-input-number v-model:value="formState[`blue${i}`]" :min="1" :max="99" />
</a-form-item>
<a-form-item v-for="i in currentLotteryType.redCount" :key="`red${i}`" :label="`红球${i}`" :name="`red${i}`" :rules="[{ required: true, message: '请输入数字' }]">
<a-input-number v-model:value="formState[`red${i}`]" :min="1" :max="99" />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { getLotteryListApi, deleteLotteryApi, saveLotteryApi, updateLotteryApi } from '../../api/lotteryConfig';
const lotteryTypes = [
{ key: 1, label: '超级大乐透', blueCount: 5, redCount: 2 },
{ key: 2, label: '双色球', blueCount: 6, redCount: 1 },
{ key: 3, label: '排列三', blueCount: 3, redCount: 0 },
{ key: 4, label: '排列五', blueCount: 5, redCount: 0 },
{ key: 5, label: '3D', blueCount: 3, redCount: 0 },
{ key: 6, label: '快乐八', blueCount: 20, redCount: 0 },
];
const activeTab = ref(lotteryTypes[0].key);
const modalVisible = ref(false);
const modalMode = ref('add');
const columns = [
{ title: '日期', dataIndex: 'today', key: 'today' },
{ title: '期数', dataIndex: 'lotteryNo', key: 'lotteryNo' },
{ title: '开奖号码', key: 'numbers', width: '300px' },
{ title: '操作', key: 'action' },
];
const data = reactive([]);
const formState = reactive({
recordId: null,
todayStr: '',
classify: 1,
lotteryNo: '',
});
for (let i = 1; i <= 20; i++) {
formState[`blue${i}`] = '';
}
for (let i = 1; i <= 5; i++) {
formState[`red${i}`] = '';
}
const filteredData = computed(() => {
return data.filter(item => item.classify === activeTab.value);
});
const currentLotteryType = computed(() => {
return lotteryTypes.find(type => type.key === activeTab.value) || lotteryTypes[0];
});
const currentLotteryTypeLabel = computed(() => {
return currentLotteryType.value.label;
});
const showAddModal = () => {
modalMode.value = 'add';
Object.assign(formState, {
recordId: null,
todayStr: dayjs(),
classify: activeTab.value,
lotteryNo: '',
});
for (let i = 1; i <= 20; i++) {
formState[`blue${i}`] = '';
}
for (let i = 1; i <= 5; i++) {
formState[`red${i}`] = '';
}
modalVisible.value = true;
};
const editItem = (record) => {
modalMode.value = 'edit';
Object.assign(formState, {
...record,
todayStr: dayjs(record.today),
});
modalVisible.value = true;
};
const deleteItem = async (record) => {
try {
await deleteLotteryApi(record.id);
message.success('删除成功');
fetchData();
} catch (error) {
message.error('删除失败');
}
};
const removeEmptyFields = (obj) => {
return Object.fromEntries(
Object.entries(obj).filter(([_, v]) => v !== '' && v !== null)
);
};
const handleModalOk = async () => {
try {
delete formState.today;
delete formState.createTime;
delete formState.isDeleted;
delete formState.updateTime;
delete formState.week;
let payload = {
...formState,
todayStr: formState.todayStr.format('YYYY-MM-DD'),
classify: activeTab.value,
recordId: formState.id,
};
payload = removeEmptyFields(payload);
if (modalMode.value === 'add') {
await saveLotteryApi(payload);
} else {
await updateLotteryApi(payload);
}
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
}
};
const handleModalCancel = () => {
modalVisible.value = false;
};
const fetchData = async () => {
try {
const response = await getLotteryListApi(1, 100, activeTab.value);
data.splice(0, data.length, ...response.data.records.map(record => ({
...record,
today: dayjs(record.today).format('YYYY-MM-DD')
})));
} catch (error) {
message.error('获取数据失败');
}
};
const handleTabChange = (newActiveKey) => {
activeTab.value = newActiveKey;
fetchData();
};
onMounted(() => {
fetchData();
});
const getFormattedNumbers = (record) => {
const type = lotteryTypes.find(t => t.key === record.classify);
const numbers = [];
for (let i = 1; i <= type.blueCount; i++) {
if (record[`blue${i}`]) numbers.push(record[`blue${i}`]);
}
for (let i = 1; i <= type.redCount; i++) {
if (record[`red${i}`]) numbers.push(record[`red${i}`]);
}
return numbers.join(', ');
};
</script>
<style scoped>
.lottery-management {
padding: 24px;
}
</style>