ソースを参照

feat(gameEventProject): 增加项目类型动态添加功能

- 为项目名称、项目类型、裁判组、积分分值列添加宽度限制和溢出提示
- 修复裁判组判断条件,防止空引用错误
- 在项目类型选择器中添加新增按钮,支持动态添加项目类型
- 优化下拉选择器增加可筛选和清空功能
- 将"排序方式"字段更名为"排名方式"
- 引入字典数据API和ElMessageBox组件
- 实现项目类型动态添加逻辑,包括验证、排序计算和自动选中
zhou 3 週間 前
コミット
8776e96c43
1 ファイル変更81 行追加10 行削除
  1. 81 10
      src/views/system/gameEventProject/index.vue

+ 81 - 10
src/views/system/gameEventProject/index.vue

@@ -51,8 +51,8 @@
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="序号" align="center" fixed="left" type="index" />
         <el-table-column label="项目id" align="center" fixed="left" prop="projectId" v-if="columns[0].visible" />
-        <el-table-column label="项目名称" align="center" fixed="left" prop="projectName" v-if="columns[1].visible" />
-        <el-table-column label="项目类型" align="center" prop="projectType" v-if="columns[2].visible">
+        <el-table-column label="项目名称" align="center" width="180" fixed="left" prop="projectName" :show-overflow-tooltip="true" v-if="columns[1].visible" />
+        <el-table-column label="项目类型" align="center" width="180" prop="projectType" :show-overflow-tooltip="true" v-if="columns[2].visible">
           <template #default="scope">
             <dict-tag :options="game_project_type" :value="scope.row.projectType || ''" />
           </template>
@@ -78,10 +78,10 @@
             <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="裁判组" align="center" prop="refereeGroup" v-if="columns[8].visible">
+        <el-table-column label="裁判组" align="center" width="150" prop="refereeGroup" v-if="columns[8].visible">
           <template #default="scope">
             <el-button
-              v-if="scope.row.refereeGroups.size > 0"
+              v-if="scope.row.refereeGroups && scope.row.refereeGroups.size > 0"
               type="primary"
               size="small"
               @click="handleViewRefereeGroup(scope.row.refereeGroups, scope.row.projectName)"
@@ -118,7 +118,7 @@
             {{ scope.row.orderType === '0' ? '升序' : '降序' }}
           </template>
         </el-table-column>
-        <el-table-column label="积分分值" align="center" prop="scoreValue" v-if="columns[11].visible" />
+        <el-table-column label="积分分值" align="center" prop="scoreValue" :show-overflow-tooltip="true" v-if="columns[11].visible" />
         <!-- <el-table-column label="奖项" align="center" prop="award" /> -->
         <el-table-column label="比赛轮次" align="center" prop="gameRound" v-if="columns[12].visible">
           <template #default="scope">
@@ -157,9 +157,12 @@
           <el-input v-model="form.projectName" placeholder="请输入项目名称" />
         </el-form-item>
         <el-form-item label="项目类型" prop="projectType">
-          <el-select v-model="form.projectType" placeholder="请选择项目类型">
-            <el-option v-for="dict in game_project_type" :key="dict.value" :label="dict.label" :value="dict.value" />
-          </el-select>
+          <div style="display: flex; width: 100%">
+            <el-select v-model="form.projectType" filterable clearable placeholder="请选择项目类型" style="flex: 1">
+              <el-option v-for="dict in game_project_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+            <el-button link type="primary" icon="Plus" style="margin-left: 5px; font-size: 18px" @click="handleAddProjectType" />
+          </div>
         </el-form-item>
         <el-form-item label="比赛场地" prop="location">
           <el-input v-model="form.location" placeholder="请输入比赛场地" />
@@ -180,11 +183,11 @@
           </el-radio-group>
         </el-form-item>
         <el-form-item label="计算规则" prop="scoreRule">
-          <el-select v-model="form.scoreRule" placeholder="请选择计算规则" style="width: 100%">
+          <el-select v-model="form.scoreRule" filterable clearable placeholder="请选择计算规则" style="width: 100%">
             <el-option v-for="dict in game_score_type" :key="dict.value" :label="dict.label" :value="dict.value" />
           </el-select>
         </el-form-item>
-        <el-form-item label="排方式" prop="orderType">
+        <el-form-item label="排方式" prop="orderType">
           <el-radio-group v-model="form.orderType">
             <el-radio value="0">升序</el-radio>
             <el-radio value="1">降序</el-radio>
@@ -256,11 +259,13 @@ import {
   updateGameEventProject,
   BatchAddProject
 } from '@/api/system/gameEventProject';
+import { addData, listData } from '@/api/system/dict/data';
 import { listGameEventGroup } from '@/api/system/gameEventGroup';
 import { GameEventProjectVO, GameEventProjectQuery, GameEventProjectForm } from '@/api/system/gameEventProject/types';
 import RefereeGroupDialog from './RefereeGroupDialog.vue';
 import ProjectLibraryDialog from './ProjectLibraryDialog.vue';
 import StatsDetailDialog from './StatsDetailDialog.vue';
+import { ElMessageBox } from 'element-plus';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { game_score_type, game_project_type, game_project_classification, game_round, game_stage } = toRefs<any>(proxy?.useDict('game_score_type', 'game_project_type', 'game_project_classification', 'game_round', 'game_stage'));
@@ -511,6 +516,72 @@ const handleLibraryConfirm = async (projects: GameEventProjectVO[]) => {
   getList(); // 刷新列表
 };
 
+/** 添加项目类型 */
+const handleAddProjectType = () => {
+  ElMessageBox.prompt('请输入新的项目类型名称', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    inputPattern: /\S+/,
+    inputErrorMessage: '项目类型名称不能为空'
+  }).then(async ({ value }) => {
+    try {
+      // 1. 实时获取最新的字典数据,避免缓存导致的冲突
+      const res = await listData({
+        dictType: 'game_project_type',
+        pageNum: 1,
+        pageSize: 100
+      } as any);
+      
+      const latestDicts = res.rows || [];
+      
+      // 2. 计算当前最大值和排序
+      let maxSort = 0;
+      let maxValue = 0;
+      latestDicts.forEach((item: any) => {
+        const val = parseInt(item.dictValue);
+        if (!isNaN(val) && val > maxValue) {
+          maxValue = val;
+        }
+        const sort = item.dictSort;
+        if (sort !== undefined && sort !== null && sort > maxSort) {
+          maxSort = sort;
+        }
+      });
+
+      const newValue = (maxValue + 1).toString();
+      const newSort = maxSort + 1;
+
+      const newDict: any = {
+        dictLabel: value,
+        dictValue: newValue,
+        dictSort: newSort,
+        dictType: 'game_project_type',
+        status: '0'
+      };
+
+      // 3. 提交新增
+      await addData(newDict);
+      proxy?.$modal.msgSuccess('添加成功');
+
+      // 4. 更新当前页面的字典数据(用于下拉框显示)
+      game_project_type.value.push({
+        label: value,
+        value: newValue,
+        elTagType: 'default',
+        elTagClass: ''
+      });
+      
+      // 5. 自动选中新添加的项目类型
+      form.value.projectType = newValue;
+    } catch (error: any) {
+      if (error !== 'cancel') {
+        console.error('添加项目类型失败:', error);
+        proxy?.$modal.msgError(error.msg || '添加项目类型失败');
+      }
+    }
+  });
+};
+
 onMounted(() => {
   getList();
   // getGameEventGroupList();