Ver Fonte

feat(gameEventProject): 新增参赛性别和组别字段功能

- 在 GameEventProject 类型定义中新增 gender 和 groups 字段
- 在表单界面添加参赛性别选择下拉框和参赛组别多选框
- 集成排名分组相关API接口,支持动态添加组别
- 将成绩类型字段从下拉选择改为单选按钮组
- 实现 groups 字段在表单显示时字符串与数组之间的转换逻辑
- 添加新增组别的弹窗确认功能
zhou há 3 semanas atrás
pai
commit
19f056863b

+ 20 - 0
src/api/system/gameEventProject/types.ts

@@ -113,6 +113,16 @@ export interface GameEventProjectVO {
    */
   remark: string;
 
+  /**
+   * 参赛性别
+   */
+  gender: string;
+
+  /**
+   * 参赛组别
+   */
+  groups: string;
+
   /**
    * 参赛人数
    */
@@ -237,6 +247,16 @@ export interface GameEventProjectForm extends BaseEntity {
    * 备注
    */
   remark?: string;
+
+  /**
+   * 参赛性别
+   */
+  gender?: string;
+
+  /**
+   * 参赛组别(多选用数组,提交前转字符串)
+   */
+  groups?: string | string[];
 }
 
 export interface GameEventProjectQuery extends PageQuery {

+ 71 - 8
src/views/system/gameEventProject/index.vue

@@ -164,6 +164,19 @@
             <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="gender">
+          <el-select v-model="form.gender" placeholder="请选择参赛性别" clearable style="width: 100%">
+            <el-option v-for="dict in sys_group_sex" :key="dict.value" :label="dict.label" :value="dict.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="参赛组别" prop="groups">
+          <div style="display: flex; width: 100%; align-items: center">
+            <el-select v-model="form.groups" multiple collapse-tags filterable placeholder="请选择参赛组别" style="flex: 1">
+              <el-option v-for="item in rankGroupOptions" :key="item.rgId" :label="item.rgName" :value="item.rgId.toString()" />
+            </el-select>
+            <el-button link type="primary" icon="Plus" style="margin-left: 5px; font-size: 18px" @click="handleAddRankGroup" />
+          </div>
+        </el-form-item>
         <el-form-item label="比赛场地" prop="location">
           <el-input v-model="form.location" placeholder="请输入比赛场地" />
         </el-form-item>
@@ -182,10 +195,10 @@
             <el-radio v-for="dict in game_round" :key="dict.value" :label="dict.label" :value="dict.value" />
           </el-radio-group>
         </el-form-item>
-        <el-form-item label="计算规则" prop="scoreRule">
-          <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 label="成绩类型" prop="scoreRule">
+          <el-radio-group v-model="form.scoreRule" style="width: 100%">
+            <el-radio v-for="dict in game_score_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+          </el-radio-group>
         </el-form-item>
         <el-form-item label="排名方式" prop="orderType">
           <el-radio-group v-model="form.orderType">
@@ -260,6 +273,7 @@ import {
   BatchAddProject
 } from '@/api/system/gameEventProject';
 import { addData, listData } from '@/api/system/dict/data';
+import { listRankGroup, addRankGroup } from '@/api/system/rankGroup';
 import { listGameEventGroup } from '@/api/system/gameEventGroup';
 import { GameEventProjectVO, GameEventProjectQuery, GameEventProjectForm } from '@/api/system/gameEventProject/types';
 import RefereeGroupDialog from './RefereeGroupDialog.vue';
@@ -268,11 +282,12 @@ 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'));
+const { game_score_type, game_project_type, game_project_classification, game_round, game_stage, sys_group_sex } = toRefs<any>(proxy?.useDict('game_score_type', 'game_project_type', 'game_project_classification', 'game_round', 'game_stage', 'sys_group_sex'));
 
 const gameEventGroupList = ref<any[]>([]); // ���·����б�
 
 const gameEventProjectList = ref<GameEventProjectVO[]>([]);
+const rankGroupOptions = ref<any[]>([]);
 const buttonLoading = ref(false);
 const loading = ref(true);
 const showSearch = ref(true);
@@ -343,6 +358,8 @@ const initFormData: GameEventProjectForm = {
   award: undefined,
   gameRound: undefined,
   gameStage: undefined,
+  gender: undefined,
+  groups: [],
   status: '0',
   remark: undefined
 };
@@ -374,6 +391,12 @@ const getList = async () => {
   loading.value = false;
 };
 
+/** 查询排名分组列表 */
+const getRankGroupOptions = async () => {
+  const res = await listRankGroup();
+  rankGroupOptions.value = res.rows;
+};
+
 /** 查询赛事分组列表 */
 const getGameEventGroupList = async () => {
   const res = await listGameEventGroup({
@@ -429,6 +452,12 @@ const handleUpdate = (row?: GameEventProjectVO) => {
   const projectId = row?.projectId || ids.value.at(0);
   getGameEventProject(projectId).then(response => {
     Object.assign(form.value, response.data);
+    // 将 groups 字符串转为数组以便多选回显
+    if (typeof form.value.groups === 'string' && form.value.groups) {
+      form.value.groups = form.value.groups.split(',');
+    } else {
+      form.value.groups = [];
+    }
     dialog.visible = true;
     dialog.title = '修改赛事项目';
   });
@@ -439,8 +468,14 @@ const submitForm = (isContinue = false) => {
   gameEventProjectFormRef.value?.validate(valid => {
     if (valid) {
       buttonLoading.value = true;
-      if (form.value.projectId !== undefined) {
-        updateGameEventProject(form.value).then(response => {
+      const submitData = { ...form.value };
+      // 提交前将 groups 数组转为逗号分隔字符串
+      if (Array.isArray(submitData.groups)) {
+        submitData.groups = submitData.groups.join(',');
+      }
+      
+      if (submitData.projectId !== undefined) {
+        updateGameEventProject(submitData).then(response => {
           proxy?.$modal.msgSuccess('修改成功');
           dialog.visible = false;
           getList();
@@ -448,7 +483,7 @@ const submitForm = (isContinue = false) => {
           buttonLoading.value = false;
         });
       } else {
-        addGameEventProject(form.value).then(response => {
+        addGameEventProject(submitData).then(response => {
           proxy?.$modal.msgSuccess('新增成功');
           if (isContinue) {
             // 保存并继续:不关闭弹窗,并确保 projectId 为空
@@ -582,8 +617,36 @@ const handleAddProjectType = () => {
   });
 };
 
+/** 添加排名分组 */
+const handleAddRankGroup = () => {
+  ElMessageBox.prompt('请输入新的组别名称', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    inputPattern: /\S+/,
+    inputErrorMessage: '组别名称不能为空'
+  }).then(async ({ value }) => {
+    try {
+      const newGroup: any = {
+        rgName: value,
+        parentId: 0,
+        sortNum: 0,
+        status: '0'
+      };
+      await addRankGroup(newGroup);
+      proxy?.$modal.msgSuccess('添加组别成功');
+      // 刷新组别列表
+      await getRankGroupOptions();
+    } catch (error: any) {
+      if (error !== 'cancel') {
+        proxy?.$modal.msgError(error.msg || '添加组别失败');
+      }
+    }
+  });
+};
+
 onMounted(() => {
   getList();
+  getRankGroupOptions();
   // getGameEventGroupList();
 });