fix: 修复赛事管理excel导出

This commit is contained in:
Shu Guang 2025-05-17 19:22:42 +08:00
parent 87d3ffdf39
commit 724731f52a

View File

@ -20,25 +20,28 @@
>
<template #header>
<a-button-group>
<a-button type="primary" v-if="$store.state.user.userPrivileges!=2" @click="addRace">
<a-button
type="primary"
v-if="$store.state.user.userPrivileges != 2"
@click="addRace"
>
添加赛事
</a-button>
<a-button type="primary" v-if="$store.state.user.userPrivileges==2" @click="addBao">
<a-button
type="primary"
v-if="$store.state.user.userPrivileges == 2"
@click="addBao"
>
我要报名
</a-button>
<a-button
v-if="$store.state.user.userPrivileges!=2"
v-if="$store.state.user.userPrivileges != 2"
:disabled="!selectedKeys.length"
@click="batchDelete"
>
批量删除 ({{ selectedKeys.length }})
</a-button>
<a-button
:loading="exporting"
@click="exportAll"
>
<a-button :loading="exporting" @click="exportAll">
全量导出
</a-button>
</a-button-group>
@ -47,18 +50,18 @@
<a-space>
<!-- 成绩录入 -->
<a-tooltip v-if="isStudent" title="无权限">
<a>
无权限
</a>
<a> 无权限 </a>
</a-tooltip>
<!--编辑-->
<a @click="editRace(record)" v-if="$store.state.user.userPrivileges!=2">
<a
@click="editRace(record)"
v-if="$store.state.user.userPrivileges != 2"
>
<a-icon type="edit" />
</a>
<!--删除-->
<a-popconfirm
v-if="$store.state.user.userPrivileges!=2"
v-if="$store.state.user.userPrivileges != 2"
title="确认删除?"
placement="left"
@confirm="deleteRace(record)"
@ -75,18 +78,19 @@
</template>
<script>
import { raceLevelMap, raceLevels,competitionStatus } from '@/utils/const';
import { AllUser } from '@/api';
import { exportData } from '@/utils/excel';
import EditRace from '@/components/edit/EditRace';
import Baoming from '@/components/edit/Baoming';
import AddRecord from '@/components/record/AddRecord';
import dayjs from 'dayjs';
import { raceLevelMap, raceLevels, competitionStatus } from "@/utils/const";
import { AllUser } from "@/api";
import { exportData } from "@/utils/excel";
import EditRace from "@/components/edit/EditRace";
import Baoming from "@/components/edit/Baoming";
import AddRecord from "@/components/record/AddRecord";
import dayjs from "dayjs";
import * as XLSX from "xlsx";
export default {
name: 'Race',
name: "Race",
metaInfo: {
title: '赛事管理',
title: "赛事管理",
},
data() {
return {
@ -96,8 +100,8 @@ export default {
races: [],
users: [], //
current: 1,
originalRaces: [],
query:{},
originalRaces: [],
query: {},
pageSize: 10,
total: 0,
tableColumns: [],
@ -116,12 +120,14 @@ export default {
return this.$store.state.user.userPrivileges == 2;
},
},
async mounted() {
async mounted() {
await this.getAllUsers(); //
this.$watch(() => [this.pageSize, this.current], this.getData, { immediate: true });
this.$watch(() => [this.pageSize, this.current], this.getData, {
immediate: true,
});
},
methods: {
async getAllUsers() {
async getAllUsers() {
try {
const response = await AllUser();
this.users = response.data;
@ -129,89 +135,95 @@ export default {
} catch (error) {
console.error("Failed to load users", error);
}
},createTableColumns(users) {
const competitionStatusMap = [
{ label: '进行中', value: 0 },
{ label: '已终止', value: 1 },
];
console.log(users)
return [
{ title: '赛事名称', dataIndex: 'competitionName', align: 'center' },
},
createTableColumns(users) {
const competitionStatusMap = [
{ label: "进行中", value: 0 },
{ label: "已终止", value: 1 },
];
console.log(users);
return [
{ title: "赛事名称", dataIndex: "competitionName", align: "center" },
{
title: '负责人',
dataIndex: 'userId',
customRender: (text) => {
if (!text) {
return '无';
}
const user = users.find(u => u.userId === text);
return user ? user.userName : '无';
}, align: 'center'
},
{
title: '开始时间',
dataIndex: 'registrationStartTime',
customRender: (text, record) => formatDate(record.registrationStartTime)
, align: 'center'
},
{
title: '结束时间',
dataIndex: 'registrationEndTime',
customRender: (text, record) => formatDate(record.registrationEndTime)
, align: 'center'
},
{ title: '参考材料', dataIndex: 'announcementLink' , align: 'center'},
{
title: '状态',
dataIndex: 'competitionStatus',
customRender: (text, record) => {
const statusObject = competitionStatusMap.find(item => item.value === record.competitionStatus);
return statusObject ? statusObject.label : '未知状态';
title: "负责人",
dataIndex: "userId",
customRender: (text) => {
if (!text) {
return "无";
}
, align: 'center'
const user = users.find((u) => u.userId === text);
return user ? user.userName : "无";
},
align: "center",
},
{
title: '操作',
align: 'center',
scopedSlots: {
customRender: 'action',
},
title: "开始时间",
dataIndex: "registrationStartTime",
customRender: (text, record) =>
formatDate(record.registrationStartTime),
align: "center",
},
];
},createSearchOptions() {
return [
{
label: '赛事名称',
key: 'title',
default: '',
component: 'input',
},
{
label: '负责人',
key: 'sponsor',
default: '',
component: 'input',
},
{
label: '状态',
key: 'collageId',
default: undefined,
component: 'select',
props: {
options: competitionStatus,
},
{
title: "结束时间",
dataIndex: "registrationEndTime",
customRender: (text, record) =>
formatDate(record.registrationEndTime),
align: "center",
},
{ title: "参考材料", dataIndex: "announcementLink", align: "center" },
{
title: "状态",
dataIndex: "competitionStatus",
customRender: (text, record) => {
const statusObject = competitionStatusMap.find(
(item) => item.value === record.competitionStatus
);
return statusObject ? statusObject.label : "未知状态";
},
align: "center",
},
{
title: "操作",
align: "center",
scopedSlots: {
customRender: "action",
},
},
];
},
createSearchOptions() {
return [
{
label: "赛事名称",
key: "title",
default: "",
component: "input",
},
{
label: "负责人",
key: "sponsor",
default: "",
component: "input",
},
{
label: "状态",
key: "collageId",
default: undefined,
component: "select",
props: {
options: competitionStatus,
},
},
{
label: '时间',
key: 'date',
default: () => [],
mapper: ({ date }) => date.join('~'),
component: 'range-picker',
{
label: "时间",
key: "date",
default: () => [],
mapper: ({ date }) => date.join("~"),
component: "range-picker",
},
];
},
];
},
changePage({ pageSize, current }) {
Object.assign(this, { pageSize, current });
},
@ -220,194 +232,263 @@ export default {
this.getData();
},
getData() {
this.query = this.$refs.searchForm.getResult();
console.log(this.query)
this.query = this.$refs.searchForm.getResult();
console.log(this.query);
this.loading = true;
this.$api.AllCompetition({
}).then(data => {
this.originalRaces = data.data;
this.filterRaces(); //
this.total = data.data.length;
}).catch(e => {
console.error(e);
this.$message.error(e.msg || '获取数据失败');
}).finally(() => {
this.loading = false;
});
this.$api
.AllCompetition({})
.then((data) => {
this.originalRaces = data.data;
this.filterRaces(); //
this.total = data.data.length;
})
.catch((e) => {
console.error(e);
this.$message.error(e.msg || "获取数据失败");
})
.finally(() => {
this.loading = false;
});
},
//
filterRaces() {
let filteredRaces = this.originalRaces.slice(); //
console.log(filteredRaces)
//
if (this.query.collageId) {
filteredRaces = filteredRaces.filter(user => user.competitionStatus == this.query.collageId);
}
//
if (this.query.title) {
filteredRaces = filteredRaces.filter(user => user.competitionName.includes(this.query.title));
}
//
if (this.query.sponsor) {
filteredRaces = filteredRaces.filter(user => user.userName.includes(this.query.sponsor));
}
//
filterRaces() {
let filteredRaces = this.originalRaces.slice(); //
console.log(filteredRaces);
//
if (this.query.collageId) {
filteredRaces = filteredRaces.filter(
(user) => user.competitionStatus == this.query.collageId
);
}
//
if (this.query.title) {
filteredRaces = filteredRaces.filter((user) =>
user.competitionName.includes(this.query.title)
);
}
//
if (this.query.sponsor) {
filteredRaces = filteredRaces.filter((user) =>
user.userName.includes(this.query.sponsor)
);
}
this.races = filteredRaces;
},
//
this.races = filteredRaces;
},
//
addBao() {
let vnode;
this.$confirm({
title: '我要报名',
content: h => (vnode = <Baoming />),
title: "我要报名",
content: (h) => (vnode = <Baoming />),
onOk: async () => {
const values = await vnode.componentInstance.validate();
const data = {
studentId: this.$store.state.user.userId,
competitionId: values.competitionId,
teamLeaderId: values.teamLeaderId,
competitionType: values.competitionType,
registrationTime: dayjs(new Date).format('YYYY-M-D HH:mm:ss'),
registrationStatus: '等待学校审核',
};
console.log(data)
return this.$api.Enroll(data).then(data => {
this.$message.success("报名成功");
}).catch(e => {
this.$message.error(e.msg || '报名失败');
throw e;
});
const data = {
studentId: this.$store.state.user.userId,
competitionId: values.competitionId,
teamLeaderId: values.teamLeaderId,
competitionType: values.competitionType,
registrationTime: dayjs(new Date()).format("YYYY-M-D HH:mm:ss"),
registrationStatus: "等待学校审核",
};
console.log(data);
return this.$api
.Enroll(data)
.then((data) => {
this.$message.success("报名成功");
})
.catch((e) => {
this.$message.error(e.msg || "报名失败");
throw e;
});
},
});
},
//
//
addRace() {
let vnode;
this.$confirm({
title: '新增赛事',
content: h => (vnode = <EditRace />),
title: "新增赛事",
content: (h) => (vnode = <EditRace />),
onOk: async () => {
const values = await vnode.componentInstance.validate();
const data = {
competitionName: values.competitionName,
userId: values.userId,
registrationStartTime: values.registrationStartTime,
registrationEndTime: values.registrationEndTime,
announcementLink: values.announcementLink,
competitionStatus: values.competitionStatus,
};
return this.$api.AddCompetition(data).then(data => {
this.$message.success("添加成功");
this.getData();
}).catch(e => {
this.$message.error(e.msg || '添加失败');
throw e;
});
const data = {
competitionName: values.competitionName,
userId: values.userId,
registrationStartTime: values.registrationStartTime,
registrationEndTime: values.registrationEndTime,
announcementLink: values.announcementLink,
competitionStatus: values.competitionStatus,
};
return this.$api
.AddCompetition(data)
.then((data) => {
this.$message.success("添加成功");
this.getData();
})
.catch((e) => {
this.$message.error(e.msg || "添加失败");
throw e;
});
},
});
},//
formatDateTime(isoDateTime) {
const date = new Date(isoDateTime);
const formattedDateTime = `${date.getFullYear()}-${this.padZero(date.getMonth() + 1)}-${this.padZero(date.getDate())} ${this.padZero(date.getHours())}:${this.padZero(date.getMinutes())}:${this.padZero(date.getSeconds())}`;
return formattedDateTime;
},
//
padZero(num) {
return num < 10 ? '0' + num : num;
},
//
}, //
formatDateTime(isoDateTime) {
const date = new Date(isoDateTime);
const formattedDateTime = `${date.getFullYear()}-${this.padZero(
date.getMonth() + 1
)}-${this.padZero(date.getDate())} ${this.padZero(
date.getHours()
)}:${this.padZero(date.getMinutes())}:${this.padZero(date.getSeconds())}`;
return formattedDateTime;
},
//
padZero(num) {
return num < 10 ? "0" + num : num;
},
//
editRace(race) {
let vnode;
this.$confirm({
title: '编辑赛事',
content: h => (vnode = <EditRace data={race} />),
title: "编辑赛事",
content: (h) => (vnode = <EditRace data={race} />),
onOk: async () => {
const values = await vnode.componentInstance.validate();
// formatDateTime
values.registrationStartTime = this.formatDateTime(values.registrationStartTime);
values.registrationEndTime = this.formatDateTime(values.registrationEndTime);
// formatDateTime
values.registrationStartTime = this.formatDateTime(
values.registrationStartTime
);
values.registrationEndTime = this.formatDateTime(
values.registrationEndTime
);
values.competitionId = race.competitionId;
const data = {
competitionId: values.competitionId,
competitionName: values.competitionName,
userId: values.userId,
registrationStartTime: values.registrationStartTime,
registrationEndTime: values.registrationEndTime,
announcementLink: values.announcementLink,
competitionStatus: values.competitionStatus,
};
const data = {
competitionId: values.competitionId,
competitionName: values.competitionName,
userId: values.userId,
registrationStartTime: values.registrationStartTime,
registrationEndTime: values.registrationEndTime,
announcementLink: values.announcementLink,
competitionStatus: values.competitionStatus,
};
return this.$api.UpCompetition(data).then(data => {
this.$message.success('修改成功');
this.getData();
}).catch(e => {
this.$message.error(e.msg || '修改失败');
throw e;
});
return this.$api
.UpCompetition(data)
.then((data) => {
this.$message.success("修改成功");
this.getData();
})
.catch((e) => {
this.$message.error(e.msg || "修改失败");
throw e;
});
},
});
},
//
//
deleteRace(race) {
this.loading = true;
this.$api.DeleteCompetition([race.competitionId]).then(data => {
this.$message.success(data.msg);
this.getData();
}).catch(e => {
console.error(e);
this.$message.error(e.msg || '删除失败');
}).finally(() => {
this.loading = false;
});
this.$api
.DeleteCompetition([race.competitionId])
.then((data) => {
this.$message.success(data.msg);
this.getData();
})
.catch((e) => {
console.error(e);
this.$message.error(e.msg || "删除失败");
})
.finally(() => {
this.loading = false;
});
},
batchDelete() {
this.$modal.confirm({
title: `确认删除选中的${this.selectedKeys.length}项数据?`,
onOk: () => this.$api.deleteRace(this.selectedKeys)
.then(() => {
this.$message.success('删除成功!');
this.selectedKeys.splice(0);
this.getData();
}).catch(e => {
this.$message.error(e.msg || '删除失败!');
throw e;
}),
onOk: () =>
this.$api
.deleteRace(this.selectedKeys)
.then(() => {
this.$message.success("删除成功!");
this.selectedKeys.splice(0);
this.getData();
})
.catch((e) => {
this.$message.error(e.msg || "删除失败!");
throw e;
}),
});
},
addRecord(race) {
let vnode;
this.$confirm({
title: '成绩录入',
content: h => (vnode = <AddRecord />),
title: "成绩录入",
content: (h) => (vnode = <AddRecord />),
onOk: async () => {
const form = vnode.componentInstance;
const values = await form.validate();
return this.$api.addRecord({
race_id: race.race_id,
sid: this.$store.state.user.account,
score: values.score,
tid: values.tid,
}).then(data => {
this.$message.success(data.msg);
}).catch(e => {
this.$message.error(e.msg || '系统错误');
throw e;
});
return this.$api
.addRecord({
race_id: race.race_id,
sid: this.$store.state.user.account,
score: values.score,
tid: values.tid,
})
.then((data) => {
this.$message.success(data.msg);
})
.catch((e) => {
this.$message.error(e.msg || "系统错误");
throw e;
});
},
});
},
exportAll() {
this.exporting = true;
this.$api.AllCompetition(this.query).then(data => {
return exportExcel(data.data);
}).catch(e => {
console.error(e);
this.$message.error(e.msg || '导出失败');
}).finally(() => {
// script
// methods exportAll
async exportAll() {
try {
this.exporting = true;
const response = await this.$api.AllCompetition();
if (response.code === 200 && response.data) {
//
const exportData = response.data.map((item) => {
const user = this.users.find((u) => u.userId === item.userId);
return {
赛事名称: item.competitionName,
负责人: user ? user.userName : "未知",
开始时间: this.formatDateTime(item.registrationStartTime),
结束时间: this.formatDateTime(item.registrationEndTime),
参考材料: item.announcementLink,
状态: item.competitionStatus === 0 ? "进行中" : "已终止",
报名人数: item.registrationCount || "0",
};
});
// 簿
const wb = XLSX.utils.book_new();
//
const ws = XLSX.utils.json_to_sheet(exportData);
// 簿
XLSX.utils.book_append_sheet(wb, ws, "赛事信息");
//
XLSX.writeFile(wb, `赛事信息表-${dayjs().format("YYYY-MM-DD")}.xlsx`);
this.$message.success("导出成功");
} else {
this.$message.error("导出失败:没有数据");
}
} catch (error) {
console.error("导出失败:", error);
this.$message.error("导出失败:" + (error.message || "系统错误"));
} finally {
this.exporting = false;
});
}
},
// exportExcel
},
};
@ -416,26 +497,26 @@ function formatDate(dateString) {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
console.error(`Invalid date: ${dateString}`);
return 'Invalid Date';
return "Invalid Date";
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
function exportExcel(data) {
const header = this.createTableColumns().map(v => v.title);
const header = this.createTableColumns().map((v) => v.title);
header.pop(); //
return exportData({
name: '赛事信息',
name: "赛事信息",
data,
header,
keyMap: {
competitionName: '赛事名称',
userId: '主办方',
announcementLink: '参考资料',
registrationStartTime: '开始时间',
registrationEndTime: '结束时间',
competitionName: "赛事名称",
userId: "主办方",
announcementLink: "参考资料",
registrationStartTime: "开始时间",
registrationEndTime: "结束时间",
},
});
}