Browse Source

feat:成绩模块

wenkai 2 days ago
parent
commit
52785edc2a

+ 60 - 29
src/views/system/gameEvent/components/bibViewerDialog.vue

@@ -6,7 +6,7 @@
         <!-- 左侧配置面板 -->
         <el-col :span="12">
           <el-form :model="bibForm" label-width="100px">
-            <el-form-item label="背景图片">
+            <el-form-item label="背景图片" required>
               <el-upload ref="bgUploadRef" :limit="1" :auto-upload="false" :on-change="handleBgImageChange" accept="image/*" drag>
                 <el-icon class="el-icon--upload">
                   <i-ep-upload-filled />
@@ -16,7 +16,7 @@
               </el-upload>
             </el-form-item>
 
-            <el-form-item label="Logo图片">
+            <el-form-item label="Logo图片" required>
               <el-upload ref="logoUploadRef" :limit="1" :auto-upload="false" :on-change="handleLogoImageChange" accept="image/*" drag>
                 <el-icon class="el-icon--upload">
                   <i-ep-upload-filled />
@@ -49,9 +49,9 @@
                 v-if="logoImageUrl"
                 class="draggable-element logo-element"
                 :style="{
-                    left: bibForm.logoX + 'px',
-                    top: bibForm.logoY + 'px'
-                  }"
+                  left: bibForm.logoX + 'px',
+                  top: bibForm.logoY + 'px'
+                }"
                 @mousedown="startDrag($event, 'logo')"
               >
                 <img :src="logoImageUrl" alt="Logo" style="max-width: 80px; max-height: 80px" />
@@ -61,9 +61,9 @@
               <div
                 class="draggable-element barcode-element"
                 :style="{
-                    left: bibForm.qRCodeX + 'px',
-                    top: bibForm.qRCodeY + 'px'
-                  }"
+                  left: bibForm.qRCodeX + 'px',
+                  top: bibForm.qRCodeY + 'px'
+                }"
                 @mousedown="startDrag($event, 'barcode')"
               >
                 <svg
@@ -99,10 +99,10 @@
               <div
                 class="event-name-preview"
                 :style="{
-                    fontSize: Math.min(28, Math.max(18, bibForm.fontSize * 0.7)) + 'px',
-                    color: 'black',
-                    fontFamily: '黑体'
-                  }"
+                  fontSize: Math.min(28, Math.max(18, bibForm.fontSize * 0.7)) + 'px',
+                  color: 'black',
+                  fontFamily: '黑体'
+                }"
               >
                 赛事名称
               </div>
@@ -111,13 +111,13 @@
               <div
                 class="draggable-element number-element"
                 :style="{
-                    left: '50%',
-                    top: '50%',
-                    transform: 'translate(-50%, -50%)',
-                    fontSize: Math.min(bibForm.fontSize, 56) + 'px',
-                    color: bibForm.fontColorHex,
-                    fontFamily: bibForm.fontName
-                  }"
+                  left: '50%',
+                  top: '50%',
+                  transform: 'translate(-50%, -50%)',
+                  fontSize: Math.min(bibForm.fontSize, 56) + 'px',
+                  color: bibForm.fontColorHex,
+                  fontFamily: bibForm.fontName
+                }"
               >
                 1234
               </div>
@@ -250,6 +250,9 @@ const handleBgImageChange = async (file: any) => {
     } catch (error) {
       console.error('获取图片尺寸失败:', error);
     }
+
+    // 添加成功提示
+    proxy?.$modal.msgSuccess('背景图片上传成功');
   }
 };
 
@@ -262,6 +265,9 @@ const handleLogoImageChange = (file: any) => {
       logoImageUrl.value = e.target?.result as string;
     };
     reader.readAsDataURL(file.raw);
+
+    // 添加成功提示
+    proxy?.$modal.msgSuccess('Logo图片上传成功');
   }
 };
 
@@ -396,14 +402,18 @@ const processImageToRatio = (file: File, targetRatio: number, targetRatio2: numb
       ctx.drawImage(img, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, newWidth, newHeight);
 
       // 转换为Blob
-      canvas.toBlob((blob) => {
-        if (blob) {
-          const processedFile = new File([blob], file.name, { type: file.type });
-          resolve(processedFile);
-        } else {
-          resolve(file);
-        }
-      }, file.type || 'image/jpeg', 0.9);
+      canvas.toBlob(
+        (blob) => {
+          if (blob) {
+            const processedFile = new File([blob], file.name, { type: file.type });
+            resolve(processedFile);
+          } else {
+            resolve(file);
+          }
+        },
+        file.type || 'image/jpeg',
+        0.9
+      );
     };
     img.src = URL.createObjectURL(file);
   });
@@ -411,11 +421,17 @@ const processImageToRatio = (file: File, targetRatio: number, targetRatio2: numb
 
 // 生成参赛证文件
 const handleGenerateBibFile = async () => {
+  // 校验必须上传背景图和logo
   if (!bgImageFile.value) {
     proxy?.$modal.msgError('请上传背景图片');
     return;
   }
 
+  if (!logoImageFile.value) {
+    proxy?.$modal.msgError('请上传Logo图片');
+    return;
+  }
+
   bibDialog.loading = true;
   try {
     let qRCodeX = bibForm.qRCodeX;
@@ -545,7 +561,6 @@ defineExpose({
 </script>
 
 <style scoped lang="scss">
-
 /* 生成参赛证样式 */
 .bib-generator {
   padding: 20px;
@@ -558,6 +573,22 @@ defineExpose({
   text-align: center;
 }
 
+/* 必填项样式 */
+.bib-generator .el-form-item.is-required .el-form-item__label::before {
+  content: '*';
+  color: #f56c6c;
+  margin-right: 4px;
+}
+
+/* 上传成功状态样式 */
+.bib-generator .el-upload--success {
+  border-color: #67c23a;
+}
+
+.bib-generator .el-upload--success .el-upload__text {
+  color: #67c23a;
+}
+
 .preview-container {
   border: 2px dashed #ddd;
   border-radius: 8px;
@@ -629,7 +660,7 @@ defineExpose({
 
 .event-name-preview {
   position: absolute;
-  top: 20%;
+  top: 5%;
   left: 50%;
   transform: translateX(-50%);
   font-weight: bold;

+ 1 - 13
src/views/system/gameEvent/index.vue

@@ -15,9 +15,6 @@
                 <el-option v-for="dict in game_event_type" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
-            <el-form-item label="开始时间" prop="startTime">
-              <el-date-picker clearable v-model="queryParams.startTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开始时间" />
-            </el-form-item>
             <el-form-item label="是否默认赛事" prop="isDefault">
               <el-select v-model="queryParams.isDefault" placeholder="请选择是否默认赛事" clearable>
                 <el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" />
@@ -348,14 +345,7 @@
 </template>
 
 <script setup name="GameEvent" lang="ts">
-import {
-  listGameEvent,
-  changeEventDefault,
-  delGameEvent,
-  addGameEvent,
-  updateGameEvent,
-  generateNumberTable
-} from '@/api/system/gameEvent';
+import { listGameEvent, changeEventDefault, delGameEvent, addGameEvent, updateGameEvent, generateNumberTable } from '@/api/system/gameEvent';
 import { GameEventVO, GameEventQuery, GameEventForm } from '@/api/system/gameEvent/types';
 import { getEventMdByEventAndType, editEventMd } from '@/api/system/eventMd';
 import { EventMdVO, EventMdForm } from '@/api/system/eventMd/types';
@@ -970,7 +960,6 @@ const handleGenerateBib = () => {
   }
 };
 
-
 onMounted(() => {
   // 获取默认赛事信息
   gameEventStore.fetchDefaultEvent();
@@ -1018,7 +1007,6 @@ onActivated(() => {
   justify-content: center;
 }
 
-
 .operation-buttons .el-button:hover {
   transform: translateY(-1px);
   box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);

+ 26 - 48
src/views/system/gameEventGroup/index.vue

@@ -6,22 +6,12 @@
           <el-form ref="queryFormRef" :model="queryParams" :inline="true">
             <el-form-item label="项目类型" prop="projectTypeFilter">
               <el-select v-model="projectTypeFilter" placeholder="请选择项目类型" clearable @change="handleProjectTypeFilterChange">
-                <el-option
-                  v-for="dict in game_project_type"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
+                <el-option v-for="dict in game_project_type" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
             <el-form-item label="项目" prop="projectId">
               <el-select v-model="queryParams.projectId" placeholder="请选择项目" clearable>
-                <el-option
-                  v-for="project in filteredProjectList"
-                  :key="project.projectId"
-                  :label="project.projectName"
-                  :value="project.projectId"
-                />
+                <el-option v-for="project in filteredProjectList" :key="project.projectId" :label="project.projectName" :value="project.projectId" />
               </el-select>
             </el-form-item>
             <el-form-item label="组别" prop="groupName">
@@ -79,9 +69,7 @@
         <el-table-column label="场地数量" align="center" prop="fieldNum" v-if="columns[7].visible" />
         <el-table-column label="每组用时(分钟)" align="center" prop="duration" v-if="columns[8].visible" />
         <el-table-column label="比赛时间" align="center" v-if="columns[9].visible">
-          <template #default="scope">
-            {{ scope.row.beginTime }} - {{ scope.row.endTime }}
-          </template>
+          <template #default="scope"> {{ scope.row.beginTime }} - {{ scope.row.endTime }} </template>
         </el-table-column>
         <el-table-column label="成员性别" align="center" prop="memberGender" v-if="columns[10].visible">
           <template #default="scope">
@@ -112,27 +100,22 @@
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="项目类型" prop="projectTypeFilter">
-              <el-select 
-                v-model="formProjectTypeFilter" 
-                placeholder="请选择项目类型" 
+              <el-select
+                v-model="formProjectTypeFilter"
+                placeholder="请选择项目类型"
                 style="width: 100%"
                 @change="handleFormProjectTypeFilterChange"
                 :disabled="!!form.groupId"
               >
-                <el-option
-                  v-for="dict in game_project_type"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
+                <el-option v-for="dict in game_project_type" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="项目" prop="projectId">
-              <el-select 
-                v-model="form.projectId" 
-                placeholder="请选择项目" 
+              <el-select
+                v-model="form.projectId"
+                placeholder="请选择项目"
                 style="width: 100%"
                 @change="handleFormProjectChange"
                 :disabled="!formProjectTypeFilter || !!form.groupId"
@@ -147,7 +130,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="组别名称" prop="groupName">
@@ -157,12 +140,7 @@
           <el-col :span="12">
             <el-form-item label="成员性别" prop="memberGender">
               <el-select v-model="form.memberGender" placeholder="请选择性别" style="width: 100%">
-                <el-option
-                  v-for="dict in sys_user_sex"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                />
+                <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value" />
               </el-select>
             </el-form-item>
           </el-col>
@@ -276,7 +254,7 @@ const columns = ref<FieldOption[]>([
   { key: 7, label: '场地数量', visible: true },
   { key: 8, label: '每组用时(分钟)', visible: true },
   { key: 9, label: '比赛时间', visible: true },
-  { key: 10, label: '成员性别', visible: true },
+  { key: 10, label: '成员性别', visible: true }
 ]);
 
 const queryFormRef = ref<ElFormInstance>();
@@ -336,26 +314,26 @@ const { queryParams, form, rules } = toRefs(data);
 // 过滤后的项目列表(用于查询)
 const filteredProjectList = computed(() => {
   if (!projectTypeFilter.value) return projectList.value;
-  return projectList.value.filter(project => project.projectType === projectTypeFilter.value);
+  return projectList.value.filter((project) => project.projectType === projectTypeFilter.value);
 });
 
 // 过滤后的项目列表(用于表单)
 const filteredFormProjectList = computed(() => {
   if (!formProjectTypeFilter.value) return [];
-  return projectList.value.filter(project => project.projectType === formProjectTypeFilter.value);
+  return projectList.value.filter((project) => project.projectType === formProjectTypeFilter.value);
 });
 
 // 根据项目ID获取项目类型
 const getProjectTypeByProjectId = (projectId: string | number) => {
   if (!projectId) return '';
-  const project = projectList.value.find(p => p.projectId === projectId);
+  const project = projectList.value.find((p) => p.projectId === projectId);
   return project?.projectType || '';
 };
 
 // 根据项目ID获取项目名称
 const getProjectNameByProjectId = (projectId: string | number) => {
   if (!projectId) return '';
-  const project = projectList.value.find(p => p.projectId === projectId);
+  const project = projectList.value.find((p) => p.projectId === projectId);
   return project?.projectName || '';
 };
 
@@ -364,11 +342,11 @@ const calculatedEndTime = computed(() => {
   if (!form.value.beginTime || !form.value.duration || !form.value.includeGroupNum) {
     return '';
   }
-  
+
   const beginTime = new Date(`2000-01-01 ${form.value.beginTime}`);
   const totalMinutes = form.value.duration * form.value.includeGroupNum;
   const endTime = new Date(beginTime.getTime() + totalMinutes * 60 * 1000);
-  
+
   return endTime.toTimeString().slice(0, 5); // 返回 HH:mm 格式
 });
 
@@ -410,7 +388,7 @@ const handleFormProjectTypeFilterChange = () => {
 // 表单中项目变化
 const handleFormProjectChange = () => {
   if (form.value.projectId) {
-    const selectedProject = projectList.value.find(p => p.projectId === form.value.projectId);
+    const selectedProject = projectList.value.find((p) => p.projectId === form.value.projectId);
     if (selectedProject) {
       // 可以在这里设置一些默认值或者进行其他处理
       console.log('选中的项目:', selectedProject);
@@ -471,7 +449,7 @@ const handleUpdate = async (row?: GameEventGroupVO) => {
 
   // 根据项目ID设置项目类型过滤器
   if (res.data.projectId) {
-    const project = projectList.value.find(p => p.projectId === res.data.projectId);
+    const project = projectList.value.find((p) => p.projectId === res.data.projectId);
     if (project) {
       formProjectTypeFilter.value = project.projectType;
     }
@@ -511,19 +489,19 @@ const submitForm = () => {
       if (form.value.beginTime && form.value.endTime) {
         const beginTime = new Date(`2000-01-01 ${form.value.beginTime}`);
         const endTime = new Date(`2000-01-01 ${form.value.endTime}`);
-        
+
         if (beginTime >= endTime) {
           proxy?.$modal.msgError('组别结束时间必须晚于开始时间');
           return;
         }
-        
+
         // 验证组别时间是否在项目时间范围内
         if (form.value.projectId) {
-          const selectedProject = projectList.value.find(p => p.projectId === form.value.projectId);
+          const selectedProject = projectList.value.find((p) => p.projectId === form.value.projectId);
           if (selectedProject && selectedProject.startTime && selectedProject.endTime) {
             const projectStart = new Date(`2000-01-01 ${selectedProject.startTime}`);
             const projectEnd = new Date(`2000-01-01 ${selectedProject.endTime}`);
-            
+
             if (beginTime < projectStart || endTime > projectEnd) {
               proxy?.$modal.msgError('组别比赛时间必须在项目比赛时间范围内');
               return;
@@ -534,7 +512,7 @@ const submitForm = () => {
 
       buttonLoading.value = true;
       const submitForm = { ...form.value };
-      
+
       if (form.value.groupId) {
         await updateGameEventGroup(submitForm).finally(() => (buttonLoading.value = false));
       } else {

+ 47 - 36
src/views/system/gameEventProject/index.vue

@@ -53,7 +53,7 @@
             <dict-tag :options="game_project_type" :value="scope.row.projectType || ''" />
           </template>
         </el-table-column>
-        <el-table-column label="项目归类" align="center" prop="classification" v-if="columns[3].visible" >
+        <el-table-column label="项目归类" align="center" prop="classification" v-if="columns[3].visible">
           <template #default="scope">
             <dict-tag :options="game_project_classification" :value="scope.row.classification || '未知'" />
           </template>
@@ -76,15 +76,15 @@
         </el-table-column>
         <el-table-column label="裁判组" align="center" prop="refereeGroup" v-if="columns[8].visible">
           <template #default="scope">
-            <el-button 
-              v-if="scope.row.refereeGroups" 
-              type="primary" 
-              size="small" 
+            <el-button
+              v-if="scope.row.refereeGroups"
+              type="primary"
+              size="small"
               @click="handleViewRefereeGroup(scope.row.refereeGroups, scope.row.projectName)"
             >
               查看裁判组 ({{ scope.row.refereeGroups.length }}人)
             </el-button>
-            <span v-else style="color: #999;">暂无裁判</span>
+            <span v-else style="color: #999">暂无裁判</span>
           </template>
         </el-table-column>
         <!-- <el-table-column label="参赛组数" align="center" prop="groupNum" />
@@ -191,7 +191,7 @@
         </div>
       </template>
     </el-dialog>
-    
+
     <!-- 裁判组查看对话框 -->
     <RefereeGroupDialog ref="refereeGroupDialogRef" />
   </div>
@@ -210,7 +210,9 @@ import { GameEventProjectVO, GameEventProjectQuery, GameEventProjectForm } from
 import RefereeGroupDialog from './RefereeGroupDialog.vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { game_score_type, game_project_type, game_project_classification } = toRefs<any>(proxy?.useDict('game_score_type', 'game_project_type','game_project_classification'));
+const { game_score_type, game_project_type, game_project_classification } = toRefs<any>(
+  proxy?.useDict('game_score_type', 'game_project_type', 'game_project_classification')
+);
 
 const gameEventGroupList = ref<any[]>([]); // 赛事分组列表
 
@@ -251,7 +253,7 @@ const columns = ref<FieldOption[]>([
   { key: 8, label: '裁判组', visible: true },
   { key: 9, label: '轮次', visible: true },
   { key: 10, label: '排序方式', visible: true },
-  { key: 11, label: '积分分值', visible: true },
+  { key: 11, label: '积分分值', visible: true }
 ]);
 
 const initFormData: GameEventProjectForm = {
@@ -283,13 +285,13 @@ const data = reactive<PageData<GameEventProjectForm, GameEventProjectQuery>>({
     pageSize: 10,
     classification: undefined,
     orderByColumn: undefined,
-    isAsc: undefined,
+    isAsc: undefined
   },
   rules: {
     projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
     projectType: [{ required: true, message: '项目类型不能为空', trigger: 'change' }],
     classification: [{ required: true, message: '归类不能为空', trigger: 'change' }],
-    orderType: [{ required: true, message: '排序方式不能为空', trigger: 'change' }],
+    orderType: [{ required: true, message: '排序方式不能为空', trigger: 'change' }]
   }
 });
 
@@ -310,7 +312,7 @@ const getGameEventGroupList = async () => {
     pageNum: 1,
     pageSize: 10,
     orderByColumn: undefined,
-    isAsc: undefined,
+    isAsc: undefined
   });
   gameEventGroupList.value = res.data;
 };
@@ -341,7 +343,7 @@ const resetQuery = () => {
 
 /** 多选框选中数据 */
 const handleSelectionChange = (selection: any[]) => {
-  ids.value = selection.map(item => item.projectId);
+  ids.value = selection.map((item) => item.projectId);
   single.value = selection.length !== 1;
   multiple.value = !selection.length;
 };
@@ -357,7 +359,7 @@ const handleAdd = () => {
 const handleUpdate = (row?: GameEventProjectVO) => {
   reset();
   const projectId = row?.projectId || ids.value.at(0);
-  getGameEventProject(projectId).then(response => {
+  getGameEventProject(projectId).then((response) => {
     Object.assign(form.value, response.data);
     dialog.visible = true;
     dialog.title = '修改赛事项目';
@@ -366,25 +368,29 @@ const handleUpdate = (row?: GameEventProjectVO) => {
 
 /** 提交按钮 */
 const submitForm = () => {
-  gameEventProjectFormRef.value?.validate(valid => {
+  gameEventProjectFormRef.value?.validate((valid) => {
     if (valid) {
       buttonLoading.value = true;
       if (form.value.projectId !== undefined) {
-        updateGameEventProject(form.value).then(response => {
-          proxy?.$modal.msgSuccess('修改成功');
-          dialog.visible = false;
-          getList();
-        }).finally(() => {
-          buttonLoading.value = false;
-        });
+        updateGameEventProject(form.value)
+          .then((response) => {
+            proxy?.$modal.msgSuccess('修改成功');
+            dialog.visible = false;
+            getList();
+          })
+          .finally(() => {
+            buttonLoading.value = false;
+          });
       } else {
-        addGameEventProject(form.value).then(response => {
-          proxy?.$modal.msgSuccess('新增成功');
-          dialog.visible = false;
-          getList();
-        }).finally(() => {
-          buttonLoading.value = false;
-        });
+        addGameEventProject(form.value)
+          .then((response) => {
+            proxy?.$modal.msgSuccess('新增成功');
+            dialog.visible = false;
+            getList();
+          })
+          .finally(() => {
+            buttonLoading.value = false;
+          });
       }
     }
   });
@@ -393,12 +399,18 @@ const submitForm = () => {
 /** 删除按钮操作 */
 const handleDelete = (row?: GameEventProjectVO) => {
   const projectIds = row?.projectId || ids.value;
-  proxy?.$modal.confirm('是否确认删除赛事项目编号为"' + projectIds + '"的数据项?').then(function () {
-    return delGameEventProject(projectIds);
-  }).then(() => {
-    getList();
-    proxy?.$modal.msgSuccess('删除成功');
-  }).catch(() => {proxy?.$modal.msgSuccess('删除失败');});
+  proxy?.$modal
+    .confirm('是否确认删除赛事项目编号为"' + projectIds + '"的数据项?')
+    .then(function () {
+      return delGameEventProject(projectIds);
+    })
+    .then(() => {
+      getList();
+      proxy?.$modal.msgSuccess('删除成功');
+    })
+    .catch(() => {
+      proxy?.$modal.msgSuccess('删除失败');
+    });
 };
 
 /** 导出按钮操作 */
@@ -421,5 +433,4 @@ onMounted(() => {
   getList();
   // getGameEventGroupList();
 });
-
 </script>

+ 59 - 58
src/views/system/gameScore/index.vue

@@ -6,11 +6,7 @@
           <el-form ref="queryFormRef" :model="queryParams" :inline="true">
             <el-form-item label="项目" prop="projectId">
               <el-select v-model="queryParams.projectId" placeholder="请选择项目" clearable filterable>
-                <el-option
-                  v-for="project in projectList"
-                  :key="project.projectId"
-                  :label="project.projectName"
-                  :value="project.projectId">
+                <el-option v-for="project in projectList" :key="project.projectId" :label="project.projectName" :value="project.projectId">
                 </el-option>
               </el-select>
             </el-form-item>
@@ -56,12 +52,12 @@
       <el-table v-loading="loading" border :data="projectList" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="ID" align="center" prop="projectId" v-if="columns[0].visible" />
-        <el-table-column label="项目类型" align="center" prop="projectType" v-if="columns[2].visible" >
+        <el-table-column label="项目类型" align="center" prop="projectType" v-if="columns[2].visible">
           <template #default="scope">
             <dict-tag :options="game_project_type" :value="scope.row.projectType" />
           </template>
         </el-table-column>
-        <el-table-column label="归类" align="center" prop="classification" v-if="columns[3].visible" >
+        <el-table-column label="归类" align="center" prop="classification" v-if="columns[3].visible">
           <template #default="scope">
             <el-tag :type="scope.row.classification === '0' ? 'success' : 'warning'">
               {{ scope.row.classification === '0' ? '个人项目' : '团体项目' }}
@@ -70,7 +66,7 @@
         </el-table-column>
         <el-table-column label="项目" align="center" prop="projectName" v-if="columns[1].visible" />
         <!-- <el-table-column label="分组" align="center" prop="groupType" v-if="columns[2].visible" /> -->
-        
+
         <el-table-column label="状态" align="center" prop="status" v-if="columns[4].visible">
           <template #default="scope">
             <el-select v-model="scope.row.status" placeholder="请选择状态">
@@ -96,8 +92,16 @@
 </template>
 
 <script setup name="GameScore" lang="ts">
-import { listGameScore, getGameScore, delGameScore, addGameScore, updateGameScore, getProjectScoreData, exportScoresSummary } from '@/api/system/gameScore';
-import { getDefaultEvent } from '@/api/system/gameEvent'
+import {
+  listGameScore,
+  getGameScore,
+  delGameScore,
+  addGameScore,
+  updateGameScore,
+  getProjectScoreData,
+  exportScoresSummary
+} from '@/api/system/gameScore';
+import { getDefaultEvent } from '@/api/system/gameEvent';
 import { listGameEventProject } from '@/api/system/gameEventProject';
 import { getGameTeam } from '@/api/system/gameTeam';
 import { getGameAthlete } from '@/api/system/gameAthlete';
@@ -134,7 +138,7 @@ const columns = ref<FieldOption[]>([
   { key: 3, label: '归类', visible: true },
   { key: 4, label: '状态', visible: true },
   { key: 5, label: '比赛时间', visible: true },
-  { key: 6, label: '更新时间', visible: true },
+  { key: 6, label: '更新时间', visible: true }
 ]);
 
 // 下拉框数据
@@ -159,9 +163,9 @@ const initFormData: GameScoreForm = {
   statusFlag: undefined,
   status: undefined,
   remark: undefined
-}
+};
 const data = reactive<PageData<GameScoreForm, GameScoreQuery>>({
-  form: {...initFormData},
+  form: { ...initFormData },
   queryParams: {
     pageNum: 1,
     pageSize: 10,
@@ -186,7 +190,7 @@ const getList = async () => {
   gameScoreList.value = res.rows;
   total.value = res.total;
   loading.value = false;
-}
+};
 
 /**
  * 刷新数据
@@ -203,14 +207,12 @@ const printScores = async () => {
       text: '正在准备打印数据...',
       background: 'rgba(0, 0, 0, 0.7)'
     });
-    
+
     let projectsToPrint = [];
-    
+
     // 如果有选择项目,则打印选中的项目
     if (ids.value.length > 0) {
-      projectsToPrint = projectList.value.filter(project => 
-        ids.value.includes(project.projectId)
-      );
+      projectsToPrint = projectList.value.filter((project) => ids.value.includes(project.projectId));
     } else {
       // 如果没有选择项目,提示用户是否打印所有项目
       try {
@@ -238,30 +240,30 @@ const printScores = async () => {
             projectId: project.projectId,
             classification: project.classification,
             pageNum: 1,
-            pageSize: 1000 
+            pageSize: 1000
           });
-          
+
           // 获取成绩数据并补充队伍和运动员信息
           const scores = scoreRes.rows || [];
-          
+
           // 按积分排序,取前3名
           const sortedScores = scores
-            .filter(score => score.scorePoint && score.scorePoint > 0) // 只显示有积分的成绩
+            .filter((score) => score.scorePoint && score.scorePoint > 0) // 只显示有积分的成绩
             .sort((a: any, b: any) => (b.scorePoint || 0) - (a.scorePoint || 0)) // 按积分降序排列
             .slice(0, 3); // 只取前3名
-          
+
           const scoresWithDetails = await Promise.all(
             sortedScores.map(async (score: any) => {
               let teamName = '-';
               let athleteName = '-';
-              
+
               try {
                 // 获取队伍信息
                 if (score.teamId) {
                   const teamRes = await getGameTeam(score.teamId);
                   teamName = teamRes.data.teamName || `队伍${score.teamId}`;
                 }
-                
+
                 // 获取运动员信息
                 if (score.athleteId) {
                   const athleteRes = await getGameAthlete(score.athleteId);
@@ -270,7 +272,7 @@ const printScores = async () => {
               } catch (error) {
                 console.warn('获取队伍或运动员信息失败:', error);
               }
-              
+
               return {
                 ...score,
                 teamName,
@@ -278,7 +280,7 @@ const printScores = async () => {
               };
             })
           );
-          
+
           return {
             ...project,
             scores: scoresWithDetails
@@ -298,18 +300,18 @@ const printScores = async () => {
 
     // 构建打印HTML内容
     const printHtml = buildPrintHtml(projectsWithScores);
-    
+
     // 使用 Blob 和 URL.createObjectURL 来避免弹窗拦截问题
     const blob = new Blob([printHtml], { type: 'text/html' });
     const url = URL.createObjectURL(blob);
-    
+
     // 创建隐藏的 iframe 来处理打印
     const iframe = document.createElement('iframe');
     iframe.style.position = 'absolute';
     iframe.style.top = '-9999px';
     iframe.style.left = '-9999px';
     document.body.appendChild(iframe);
-    
+
     iframe.onload = () => {
       try {
         // 打印完成后清理
@@ -321,14 +323,14 @@ const printScores = async () => {
         console.error('清理打印资源失败:', error);
       }
     };
-    
+
     // 在 iframe 中加载并打印
     const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
     if (iframeDoc) {
       iframeDoc.open();
       iframeDoc.write(printHtml);
       iframeDoc.close();
-      
+
       // 等待内容加载后打印
       setTimeout(() => {
         try {
@@ -359,7 +361,7 @@ const printScores = async () => {
  */
 const buildPrintHtml = (projects: any[]) => {
   const printTime = new Date().toLocaleString('zh-CN');
-  
+
   let html = `
     <!DOCTYPE html>
     <html>
@@ -392,16 +394,16 @@ const buildPrintHtml = (projects: any[]) => {
   `;
 
   // 为每个项目添加成绩表格
-  projects.forEach(project => {
+  projects.forEach((project) => {
     const scores = project.scores || [];
-    
+
     html += `
       <div class="project-section">
         <div class="project-title">
-          <span class="title-label">${project.projectId}</span>  
-          <span class="title-label">${getProjectTypeName(project.projectType)} ${project.projectName}</span> 
+          <span class="title-label">${project.projectId}</span>
+          <span class="title-label">${getProjectTypeName(project.projectType)} ${project.projectName}</span>
         </div>
-        
+
         <table class="score-table">
           <thead>
             <tr>
@@ -469,14 +471,14 @@ const formatScore = (score: number | string) => {
 const getProjectTypeName = (type: string) => {
   const typeMap: Record<string, string> = {
     '1': '田径',
-    '2': '游泳', 
+    '2': '游泳',
     '3': '球类',
     '4': '其他'
   };
   return typeMap[type] || '未知';
 };
 
-const exportScoresNames = async () => { 
+const exportScoresNames = async () => {
   try {
     // 显示加载状态
     const loadingInstance = ElLoading.service({
@@ -488,7 +490,7 @@ const exportScoresNames = async () => {
     // 获取默认赛事ID
     const event = gameEventStore.defaultEventInfo;
     const eventId = event?.eventId;
-    
+
     if (!eventId) {
       proxy?.$modal.msgWarning('未指定赛事,无法导出');
       loadingInstance.close();
@@ -497,7 +499,7 @@ const exportScoresNames = async () => {
 
     // 调用导出接口
     const response = await exportScoresSummary(eventId);
-    
+
     // 校验响应是否为有效的二进制数据
     if (!response || !response.data || !(response.data instanceof Blob)) {
       proxy?.$modal.msgError('导出失败:服务器返回数据异常');
@@ -506,10 +508,10 @@ const exportScoresNames = async () => {
     }
 
     // 创建Blob时,明确指定类型
-    const blob = new Blob([response.data], { 
-      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
+    const blob = new Blob([response.data], {
+      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
     });
-    
+
     // 验证Blob大小是否合理(防止空文件)
     if (blob.size === 0) {
       proxy?.$modal.msgError('导出失败:生成的文件为空');
@@ -525,14 +527,13 @@ const exportScoresNames = async () => {
     link.click();
     document.body.removeChild(link);
     window.URL.revokeObjectURL(url);
-    
+
     loadingInstance.close();
     proxy?.$modal.msgSuccess('导出成功');
-    
   } catch (error) {
     console.error('导出失败:', error);
     let errorMessage = '未知错误';
-    
+
     if (error instanceof Error) {
       errorMessage = error.message;
     } else if (typeof error === 'string') {
@@ -540,7 +541,7 @@ const exportScoresNames = async () => {
     } else if (error && typeof error === 'object' && 'message' in error) {
       errorMessage = String(error.message);
     }
-    
+
     // 尝试获取更详细的错误信息
     if (error && typeof error === 'object' && 'response' in error) {
       const response = (error as any).response;
@@ -549,7 +550,7 @@ const exportScoresNames = async () => {
           if (response.data instanceof Blob) {
             // 如果是blob,尝试读取错误信息
             const reader = new FileReader();
-            reader.onload = function(e) {
+            reader.onload = function (e) {
               try {
                 const text = e.target?.result as string;
                 const errorObj = JSON.parse(text);
@@ -571,7 +572,7 @@ const exportScoresNames = async () => {
         }
       }
     }
-    
+
     proxy?.$modal.msgError('导出失败:' + errorMessage);
   }
 };
@@ -581,7 +582,7 @@ const exportScoresNames = async () => {
  */
 const loadProjects = async () => {
   loading.value = true;
-  console.log('加载项目列表: ',queryParams.value);
+  console.log('加载项目列表: ', queryParams.value);
   const res = await listGameEventProject(queryParams.value);
   projectList.value = res.rows;
   total.value = res.total;
@@ -602,10 +603,10 @@ const resetQuery = () => {
 
 /** 多选框选中数据 */
 const handleSelectionChange = (selection: GameScoreVO[]) => {
-  ids.value = selection.map(item => item.projectId); // 使用eventId作为标识
+  ids.value = selection.map((item) => item.projectId); // 使用eventId作为标识
   single.value = selection.length != 1;
   multiple.value = !selection.length;
-}
+};
 
 const navigateToEditPage = (row: GameEventProjectVO) => {
   const projectId = row.projectId;
@@ -621,8 +622,8 @@ const navigateToEditPage = (row: GameEventProjectVO) => {
 
 onMounted(() => {
   // getDefaultEventInfo().then(() => {
-    getList();
-    refreshData();
+  getList();
+  refreshData();
   // });
 });
-</script>
+</script>