diff --git a/src/api/match/eventregistration.js b/src/api/match/eventregistration.js
index d0fa4f7..1364f4f 100644
--- a/src/api/match/eventregistration.js
+++ b/src/api/match/eventregistration.js
@@ -108,4 +108,19 @@ export const eventregistrationDeleteDelete = (data) => {
*/
export const eventregistrationSetstatusPatch = (data) => {
return http.patch('/eventregistration/setstatus', data);
+};
+
+/**
+ * 获取报名统计数据
+ * @param {number} eventId - 赛事ID
+ * @returns {Promise<{
+ * totalParticipants: number,
+ * individualParticipants: number,
+ * teamCount: number,
+ * teamParticipants: number,
+ * pendingReview: number
+ * }>}
+ */
+export const eventregistrationStatsGet = (eventId) => {
+ return http.get(`/eventregistration/stats/${eventId}`);
};
\ No newline at end of file
diff --git a/src/views/match/manage/work.vue b/src/views/match/manage/work.vue
index 926a700..1ad0f09 100644
--- a/src/views/match/manage/work.vue
+++ b/src/views/match/manage/work.vue
@@ -13,6 +13,36 @@
+
+
+
+
+
+
报名总人数
+
{{ animatedCounts.totalParticipants }}人
+
+
+
+
个人项目
+
{{ animatedCounts.individualParticipants }}人
+
+
+
+
团队项目
+
+ {{ animatedCounts.teamCount }}队
+ /
+ {{ animatedCounts.teamParticipants }}人
+
+
+
+
+
待审核
+
{{ animatedCounts.pendingReview }}
+
+
+
+
@@ -290,7 +320,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
import { Check, View, Download, Rank, Warning } from '@element-plus/icons-vue';
import { eventDetailGet } from '/@/api/match/event';
import { eventarrangementListGet, eventarrangementPut, eventarrangementExportPost, eventarrangementPreviewPost } from '/@/api/match/eventarrangement';
-import { eventregistrationPagePost, eventregistrationBatchauditPost, eventregistrationMaterialurlsPost } from '/@/api/match/eventregistration';
+import { eventregistrationPagePost, eventregistrationBatchauditPost, eventregistrationMaterialurlsPost, eventregistrationStatsGet } from '/@/api/match/eventregistration';
import { eventscorePageathletePost, eventscorePagecoachleaderPost, eventscoreImportscorePost, eventscoreDownloadtemplateGet, eventscoreExportcertificatePost, eventscoreIssuecertificatePost, eventscoreGetCertificateDetailGet, eventscoreIssuepointsPost } from '/@/api/match/eventscore';
import { certificateListGet } from '/@/api/match/certificate';
import Step1BasicInfo from './Steps/Step1BasicInfo.vue';
@@ -326,6 +356,24 @@ const selectedCertificateId = ref();
const issuingCertificate = ref(false);
const certificateForm = ref({});
const certificateList = ref([]);
+
+// 报名统计相关
+const registrationStats = ref({
+ totalParticipants: 0,
+ individualParticipants: 0,
+ teamCount: 0,
+ teamParticipants: 0,
+ pendingReview: 0
+});
+const statsLoading = ref(false);
+const animatedCounts = ref({
+ totalParticipants: 0,
+ individualParticipants: 0,
+ teamCount: 0,
+ teamParticipants: 0,
+ pendingReview: 0
+});
+
// 表单数据(响应式对象)
const formData = ref({
// 步骤1:基本信息
@@ -441,6 +489,9 @@ const openDialog = async (id) => {
// 等待对话框渲染完成后刷新表格数据
await nextTick()
refreshScoreTable()
+
+ // 获取报名统计数据
+ await fetchRegistrationStats();
};
const initSortable = () => {
@@ -619,11 +670,58 @@ const columns = reactive([
{ prop: 'action', label: '操作', align: 'center', width: 140, fixed: 'right' },
]);
+// 获取报名统计数据
+const fetchRegistrationStats = async () => {
+ if (!initParam.value.eventId) return;
+
+ statsLoading.value = true;
+ try {
+ const res = await eventregistrationStatsGet(initParam.value.eventId);
+ if (res?.succeeded && res?.data) {
+ registrationStats.value = res.data;
+ // 启动数字动画
+ animateNumbers(res.data);
+ }
+ } catch (error) {
+ console.error('获取统计数据失败:', error);
+ } finally {
+ statsLoading.value = false;
+ }
+};
+
+// 数字动画函数
+const animateNumbers = (targetStats) => {
+ const duration = 1500; // 动画持续时间(毫秒)
+ const startTime = Date.now();
+
+ const animate = () => {
+ const elapsed = Date.now() - startTime;
+ const progress = Math.min(elapsed / duration, 1);
+
+ // 使用 easeOutQuart 缓动函数
+ const easeProgress = 1 - Math.pow(1 - progress, 4);
+
+ animatedCounts.value.totalParticipants = Math.floor(targetStats.totalParticipants * easeProgress);
+ animatedCounts.value.individualParticipants = Math.floor(targetStats.individualParticipants * easeProgress);
+ animatedCounts.value.teamCount = Math.floor(targetStats.teamCount * easeProgress);
+ animatedCounts.value.teamParticipants = Math.floor(targetStats.teamParticipants * easeProgress);
+ animatedCounts.value.pendingReview = Math.floor(targetStats.pendingReview * easeProgress);
+
+ if (progress < 1) {
+ requestAnimationFrame(animate);
+ }
+ };
+
+ animate();
+};
+
const onSureOrder = async (id) => {
const res = await eventregistrationBatchauditPost({ ids: [id], 'paymentStatus': 1 });
if (res.succeeded) {
ElMessage.success('操作成功!');
initParam.value.refresh = !initParam.value.refresh;
+ // 审核完成后刷新统计数据
+ await fetchRegistrationStats();
}
};
const selectListIds = ref()
@@ -800,6 +898,8 @@ const allSure = async () => {
if (res.succeeded) {
ElMessage.success('操作成功!');
initParam.value.refresh = !initParam.value.refresh;
+ // 审核完成后刷新统计数据
+ await fetchRegistrationStats();
}
}
@@ -1409,6 +1509,81 @@ defineExpose({