2 Commits 3d65650fae ... 4ec8038639

Author SHA1 Message Date
  zhou 4ec8038639 feat(gameScore): 项目表头添加跳转详情页功能 6 days ago
  zhou 19e6cf5cd2 feat(gameScore): 更新比赛项目状态显示和参赛人数统计 6 days ago
2 changed files with 186 additions and 5 deletions
  1. 75 1
      src/views/system/gameScore/gameScoreBonus.vue
  2. 111 4
      src/views/system/gameScore/index.vue

+ 75 - 1
src/views/system/gameScore/gameScoreBonus.vue

@@ -51,9 +51,17 @@
         <el-table-column 
           v-for="project in bonusProjectList" 
           :key="project.projectId" 
-          :label="project.projectName" 
           align="center" 
           width="120">
+          <template #header>
+            <el-button 
+              link 
+              type="primary" 
+              @click="goToProjectDetail(project)"
+              class="project-header-link">
+              {{ project.projectName }}
+            </el-button>
+          </template>
           <template #default="scope">
             {{ scope.row.projectScores[project.projectName] || 0 }}
           </template>
@@ -91,12 +99,14 @@
 
 <script setup name="GameScoreBonus" lang="ts">
 import { ref, onMounted, onUnmounted, getCurrentInstance, toRefs } from 'vue';
+import { useRouter } from 'vue-router';
 import { Timer } from '@element-plus/icons-vue';
 import { getBonusData, updateBonusData, exportBonusExcel } from '@/api/system/gameScore';
 import { useGameEventStore } from '@/store/modules/gameEvent';
 import type { ComponentInternalInstance } from 'vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const router = useRouter();
 
 // 默认赛事信息
 const gameEventStore = useGameEventStore();
@@ -312,6 +322,36 @@ const refreshBonusData = async () => {
   startCountdown();
 };
 
+// 跳转到项目详情页
+const goToProjectDetail = (project: any) => {
+  const event = gameEventStore.defaultEventInfo;
+  const eventId = event?.eventId;
+  
+  if (!eventId) {
+    proxy?.$modal.msgWarning('未指定赛事,无法跳转');
+    return;
+  }
+  
+  if (!project.projectId) {
+    proxy?.$modal.msgWarning('项目信息不完整,无法跳转');
+    return;
+  }
+  
+  // 构建路由参数
+  const routeParams = {
+    projectId: project.projectId,
+    projectName: project.projectName || '未知项目',
+    projectType: project.projectType || '0',
+    eventId: eventId,
+    classification: project.projectClassification || '0' // 默认为个人项目
+  };
+  
+  // 跳转到项目详情页
+  router.push({
+    path: `/system/gameScore/edit/${routeParams.projectId}/${routeParams.projectName}/${routeParams.projectType}/${routeParams.eventId}/${routeParams.classification}`
+  });
+};
+
 onUnmounted(() => {
   if (autoRefreshInterval.value) {
     clearInterval(autoRefreshInterval.value);
@@ -389,6 +429,40 @@ onMounted(async () => {
   text-align: center;
 } */
 
+/* 项目表头链接样式 */
+.project-header-link {
+  padding: 4px 8px !important;
+  height: auto !important;
+  font-size: 14px;
+  font-weight: 600;
+  color: #409eff !important;
+  text-decoration: none;
+  border: none !important;
+  background: none !important;
+  box-shadow: none !important;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+
+.project-header-link:hover {
+  color: #66b1ff !important;
+  background: rgba(64, 158, 255, 0.1) !important;
+  transform: translateY(-1px);
+}
+
+.project-header-link:focus {
+  outline: none;
+  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important;
+}
+
+/* 表头样式增强 */
+.el-table .el-table__header .project-header-link {
+  font-weight: 600;
+  text-align: center;
+  display: inline-block;
+  min-width: 80px;
+}
+
 /* 响应式设计 */
 @media (max-width: 1200px) {
   .countdown-info {

+ 111 - 4
src/views/system/gameScore/index.vue

@@ -82,10 +82,24 @@
 
         <el-table-column label="状态" align="center" prop="status" v-if="columns[4].visible">
           <template #default="scope">
-            <el-select v-model="scope.row.status" placeholder="请选择状态">
-              <el-option label="进行中" value="0"></el-option>
-              <el-option label="完赛" value="1"></el-option>
-            </el-select>
+            <el-tag :type="getStatusType(scope.row)">
+              {{ getStatusText(scope.row) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="参赛总人/队数" align="center" prop="totalParticipants" v-if="columns[7].visible">
+          <template #default="scope">
+            {{ scope.row.totalParticipants || 0 }}
+          </template>
+        </el-table-column>
+        <el-table-column label="完赛人/队数" align="center" prop="completedParticipants" v-if="columns[8].visible">
+          <template #default="scope">
+            {{ scope.row.completedParticipants || 0 }}
+          </template>
+        </el-table-column>
+        <el-table-column label="未完赛人/队数" align="center" prop="incompleteParticipants" v-if="columns[9].visible">
+          <template #default="scope">
+            {{ scope.row.incompleteParticipants || 0 }}
           </template>
         </el-table-column>
         <el-table-column label="比赛时间" align="center" prop="startTime" v-if="columns[5].visible" />
@@ -155,6 +169,9 @@ const columns = ref<FieldOption[]>([
   { key: 4, label: '状态', visible: true },
   { key: 5, label: '比赛时间', visible: true },
   { key: 6, label: '更新时间', visible: true },
+  { key: 7, label: '参赛总人数', visible: true },
+  { key: 8, label: '完赛人数', visible: true },
+  { key: 9, label: '未完赛人数', visible: true },
 ]);
 
 // 下拉框数据
@@ -710,6 +727,38 @@ const getProjectTypeName = (type: string) => {
   return typeItem ? typeItem.label : '未知';
 };
 
+/**
+ * 获取状态文本
+ */
+const getStatusText = (row: any) => {
+  const totalParticipants = row.totalParticipants || 0;
+  const completedParticipants = row.completedParticipants || 0;
+  
+  // 如果完赛人/队数等于参赛总人/队数,显示完赛
+  if (totalParticipants > 0 && completedParticipants === totalParticipants) {
+    return '完赛';
+  }
+  
+  // 否则显示进行中
+  return '进行中';
+};
+
+/**
+ * 获取状态标签类型
+ */
+const getStatusType = (row: any) => {
+  const totalParticipants = row.totalParticipants || 0;
+  const completedParticipants = row.completedParticipants || 0;
+  
+  // 如果完赛人/队数等于参赛总人/队数,显示成功状态
+  if (totalParticipants > 0 && completedParticipants === totalParticipants) {
+    return 'success';
+  }
+  
+  // 否则显示警告状态
+  return 'warning';
+};
+
 const exportScoresNames = () => {
   // 获取默认赛事ID
   const event = gameEventStore.defaultEventInfo;
@@ -740,6 +789,9 @@ const loadProjects = async () => {
     const res = await listGameEventProject(queryParams.value);
     projectList.value = res.rows;
     total.value = res.total;
+    
+    // 为每个项目计算参赛人数
+    await calculateParticipantCounts();
   } catch (error) {
     console.error('加载项目列表失败:', error);
     proxy?.$modal.msgError('加载项目列表失败');
@@ -748,6 +800,61 @@ const loadProjects = async () => {
   }
 };
 
+/**
+ * 计算每个项目的参赛人数
+ */
+const calculateParticipantCounts = async () => {
+  for (const project of projectList.value) {
+    try {
+      // 获取该项目的成绩数据
+      const scoreRes = await getProjectScoreData({
+        eventId: project.eventId,
+        projectId: project.projectId,
+        classification: project.classification,
+        pageNum: 1,
+        pageSize: 1000
+      });
+      
+      const scores = scoreRes.rows || [];
+      
+      // 计算参赛总人数(去重后的队伍或运动员数量)
+      const uniqueParticipants = new Set();
+      scores.forEach(score => {
+        if (project.classification === '0') {
+          // 个人项目:按运动员ID去重
+          if (score.athleteId) {
+            uniqueParticipants.add(score.athleteId);
+          }
+        } else {
+          // 团体项目:按队伍ID去重
+          if (score.teamId) {
+            uniqueParticipants.add(score.teamId);
+          }
+        }
+      });
+      
+      // 使用类型断言添加新属性
+      (project as any).totalParticipants = uniqueParticipants.size;
+      
+      // 计算完赛人数(有成绩记录的)
+      const completedScores = scores.filter(score => 
+        score.individualPerformance || score.teamPerformance
+      );
+      (project as any).completedParticipants = completedScores.length;
+      
+      // 计算未完赛人数
+      (project as any).incompleteParticipants = (project as any).totalParticipants - (project as any).completedParticipants;
+      
+    } catch (error) {
+      console.error(`计算项目 ${project.projectName} 参赛人数失败:`, error);
+      // 设置默认值
+      (project as any).totalParticipants = 0;
+      (project as any).completedParticipants = 0;
+      (project as any).incompleteParticipants = 0;
+    }
+  }
+};
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.value.pageNum = 1;