|
|
@@ -21,6 +21,9 @@
|
|
|
<el-button type="success" @click="calculateRankings" :loading="rankingLoading">
|
|
|
<el-icon><Trophy /></el-icon> 计算排名
|
|
|
</el-button>
|
|
|
+ <el-button type="warning" @click="handleExport">
|
|
|
+ <el-icon><Download /></el-icon> 导出
|
|
|
+ </el-button>
|
|
|
<el-input
|
|
|
v-model="searchValue"
|
|
|
:placeholder="projectClassification === '0' ? '输入运动员姓名搜索' : '输入队伍名称搜索'"
|
|
|
@@ -56,7 +59,7 @@
|
|
|
<template v-if="projectClassification === '0'">
|
|
|
<el-table-column label="号码" align="center" prop="athleteCode" />
|
|
|
<el-table-column label="姓名" align="center" prop="name" />
|
|
|
- <el-table-column label="姓名" align="center" prop="gender" >
|
|
|
+ <el-table-column label="性别" align="center" prop="gender" >
|
|
|
<template #default="scope">
|
|
|
<dict-tag :options="sys_user_sex" :value="scope.row.gender" />
|
|
|
</template>
|
|
|
@@ -129,13 +132,29 @@
|
|
|
</el-dialog>
|
|
|
|
|
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="handlePagination({page: queryParams.pageNum, limit: queryParams.pageSize})" />
|
|
|
+
|
|
|
+ <!-- 导出设置对话框 -->
|
|
|
+ <el-dialog title="导出成绩详情" v-model="exportDialog.visible" width="400px" append-to-body>
|
|
|
+ <el-form label-width="120px">
|
|
|
+ <el-form-item label="导出前几名:">
|
|
|
+ <el-input-number v-model="exportDialog.topN" :min="0" :precision="0" placeholder="不输入导出所有" style="width: 100%" />
|
|
|
+ <div class="help-block" style="color: #999; font-size: 12px; margin-top: 5px;">提示:输入 0 或不输入表示导出所有成绩</div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="doExport" :loading="exportLoading">确 定</el-button>
|
|
|
+ <el-button @click="exportDialog.visible = false">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup name="GameScoreEdit" lang="ts">
|
|
|
import { onMounted, onUnmounted, ref, reactive, getCurrentInstance, toRefs } from 'vue';
|
|
|
import { useRoute } from 'vue-router';
|
|
|
-import { getProjectScoreData, updateScoreAndRecalculate } from '@/api/system/gameScore/index';
|
|
|
+import { getProjectScoreData, updateScoreAndRecalculate, exportProjectScore } from '@/api/system/gameScore/index';
|
|
|
import { GameScoreForm } from '@/api/system/gameScore/types';
|
|
|
import Pagination from '@/components/Pagination/index.vue';
|
|
|
import type { ComponentInternalInstance } from 'vue';
|
|
|
@@ -150,6 +169,12 @@ const dataList = ref<any[]>([]);
|
|
|
const loading = ref(true);
|
|
|
const total = ref(0);
|
|
|
const pickAthletes = ref('');
|
|
|
+const exportLoading = ref(false);
|
|
|
+
|
|
|
+const exportDialog = reactive({
|
|
|
+ visible: false,
|
|
|
+ topN: undefined as number | undefined
|
|
|
+});
|
|
|
|
|
|
// 定义搜索框状态变量
|
|
|
const searchValue = ref('');
|
|
|
@@ -440,6 +465,40 @@ const submitForm = async () => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+/** 导出按钮操作 */
|
|
|
+const handleExport = () => {
|
|
|
+ exportDialog.topN = undefined;
|
|
|
+ exportDialog.visible = true;
|
|
|
+};
|
|
|
+
|
|
|
+/** 执行导出 */
|
|
|
+const doExport = async () => {
|
|
|
+ try {
|
|
|
+ exportLoading.value = true;
|
|
|
+ const response = await exportProjectScore(eventId, projectId, exportDialog.topN || 0);
|
|
|
+
|
|
|
+ // 生成文件名
|
|
|
+ const classificationStr = projectClassification === '0' ? '个人' : '团体';
|
|
|
+ const fileName = `${classificationStr}_${projectName}_成绩详情.xlsx`;
|
|
|
+
|
|
|
+ // 下载文件
|
|
|
+ const blob = new Blob([response as any]);
|
|
|
+ const link = document.createElement('a');
|
|
|
+ link.href = window.URL.createObjectURL(blob);
|
|
|
+ link.download = fileName;
|
|
|
+ link.click();
|
|
|
+ window.URL.revokeObjectURL(link.href);
|
|
|
+
|
|
|
+ proxy?.$modal.msgSuccess("导出成功");
|
|
|
+ exportDialog.visible = false;
|
|
|
+ } catch (error) {
|
|
|
+ // console.error("导出失败:", error);
|
|
|
+ proxy?.$modal.msgError("导出失败,请稍后再试");
|
|
|
+ } finally {
|
|
|
+ exportLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
// 加载数据方法,支持搜索
|
|
|
const loadData = async (autoCalculateRanking = false) => {
|
|
|
loading.value = true;
|