Sfoglia il codice sorgente

feat(tournaments): 更新系统标题并添加晋级赛功能

- 将系统标题从"三湘杯后台管理系统"更新为"X-Poker Games后台管理系统"
- 在物理赛事模块中新增晋级赛相关功能
- 添加赛事类型选择下拉框,支持普通赛和晋级赛两种类型
- 实现目标锦标赛选择和晋级条件配置功能
- 新增查询联赛关联线下赛事的API接口
- 优化盲注等级加载逻辑,在表单初始化时主动触发
- 添加晋级条件类型字典和相应的条件值输入功能
- 完善晋级赛相关的数据类型定义和表单验证
fugui001 1 mese fa
parent
commit
6966622387

+ 1 - 1
.env.development

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 三湘杯后台管理系统
+VITE_APP_TITLE = X-Poker Games后台管理系统
 
 # 开发环境配置
 VITE_APP_ENV = 'development'

+ 1 - 1
.env.production

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 三湘杯后台管理系统
+VITE_APP_TITLE = X-Poker Games后台管理系统
 
 # 生产环境配置
 VITE_APP_ENV = 'production'

+ 1 - 1
index.html

@@ -6,7 +6,7 @@
     <meta name="renderer" content="webkit" />
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
     <link rel="icon" href="/favicon.ico" />
-    <title>三湘杯后台管理系统</title>
+    <title>X-Poker Games后台管理系统</title>
     <!--[if lt IE 11
       ]><script>
         window.location.href = '/html/ie.html';

+ 2 - 2
package.json

@@ -1,8 +1,8 @@
 {
   "$schema": "https://json.schemastore.org/package",
-  "name": "三湘杯后台管理系统",
+  "name": "X-Poker Games后台管理系统",
   "version": "5.4.0-2.4.0",
-  "description": "三湘杯后台管理系统",
+  "description": "X-Poker Games后台管理系统",
   "author": "LionLi",
   "license": "MIT",
   "type": "module",

+ 9 - 0
src/api/system/physical/tournaments/index.ts

@@ -61,3 +61,12 @@ export const delTournaments = (id: string | number | Array<string | number>) =>
     method: 'delete'
   });
 };
+/**
+ * 查询联赛关联的线下赛事列表(无参)
+ */
+export const selectPhysicalTournamentsLeagueId = (): AxiosPromise<TournamentsVO[]> => {
+  return request({
+    url: '/physical/tournaments/selectPhysicalTournamentsLeagueId',
+    method: 'get'
+  });
+};

+ 5 - 2
src/api/system/physical/tournaments/types.ts

@@ -154,6 +154,8 @@ export interface TournamentsVO {
    * 晋级条件值:级别数或人数比例(1-100)
    */
   qualifierValue: number;
+
+  tournamentType?: number;
 }
 
 export interface TournamentsForm extends BaseEntity {
@@ -319,8 +321,8 @@ export interface TournamentsForm extends BaseEntity {
   /**
    * 晋级条件类型:0=无晋级,1=按级别晋级,2=按人数比例晋级
    */
-  qualifierType?: number;
-
+  qualifierType?: string;
+  tournamentType?: number;
   /**
    * 晋级条件值:级别数或人数比例(1-100)
    */
@@ -491,6 +493,7 @@ export interface TournamentsQuery extends PageQuery {
    * 晋级条件值:级别数或人数比例(1-100)
    */
   qualifierValue?: number;
+  tournamentType?: number;
 
   /**
    * 日期范围参数

+ 1 - 1
src/layout/components/Sidebar/Logo.vue

@@ -34,7 +34,7 @@ defineProps({
   }
 });
 
-const title = ref('三湘杯后台管理系统');
+const title = ref('X-Poker Games后台管理系统');
 const settingsStore = useSettingsStore();
 const sideTheme = computed(() => settingsStore.sideTheme);
 </script>

+ 6 - 2
src/views/system/business/tournaments/index.vue

@@ -239,8 +239,8 @@
                 <el-button link type="primary" icon="Files" @click="handleCopy(scope.row)"> 复制 </el-button>
               </el-tooltip>
 
-              <el-tooltip content="牌局复盘" placement="top" v-hasPermi="['business:tournaments:query']">
-                <el-button link type="primary" icon="DocumentChecked" @click="handleViewPublicHistory(scope.row)"> 牌局复盘 </el-button>
+              <el-tooltip content="复盘" placement="top" v-hasPermi="['business:tournaments:query']">
+                <el-button link type="primary" icon="DocumentChecked" @click="handleViewPublicHistory(scope.row)"> 复盘 </el-button>
               </el-tooltip>
 
               <el-tooltip content="领奖审核" placement="top" v-hasPermi="['business:tournaments:query']">
@@ -1371,6 +1371,10 @@ const handleUpdate = async (row?: TournamentsVO, mode: 'edit' | 'view' = 'edit')
       }
     ];
   }
+  // ✅ 主动触发盲注等级加载
+  if (form.value.blindStructureId) {
+    await handleBlindStructureChange(form.value.blindStructureId);
+  }
   dialog.visible = true;
   dialog.title = mode === 'view' ? '查看比赛' : '编辑比赛';
   dialog.mode = mode; // 设置模式

+ 132 - 6
src/views/system/physical/tournaments/index.vue

@@ -393,6 +393,87 @@
             </el-select>
           </div>
         </el-form-item>
+
+
+        <el-form-item label="赛事标识" prop="tournamentType">
+          <el-select
+            v-model="form.tournamentType"
+            placeholder="请选择"
+            :disabled="dialog.mode === 'view'"
+          >
+            <el-option
+              v-for="item in tournamentTypeOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="目标锦标赛" prop="targetTournamentId" v-if="form.tournamentType === 1">
+          <el-select
+            v-model="form.targetTournamentId"
+            placeholder="请选择比赛"
+            :disabled="dialog.mode === 'view'"
+            remote
+            :remote-method="loadTargetTournaments"
+            :loading="selectLoading"
+            clearable
+          >
+            <el-option
+              v-for="item in selectOptions"
+              :key="item.id"
+              :label="item.label"
+              :value="item.id"
+            />
+          </el-select>
+         </el-form-item>
+        <el-form-item
+          label="晋级条件类型"
+          prop="qualifierType"
+          v-if="form.tournamentType === 1"
+        >
+          <el-select
+            aria-required="true"
+            v-model="form.qualifierType"
+            placeholder="请选择"
+            :disabled="dialog.mode === 'view'"
+            @change="handleQualifierTypeChange"
+          >
+            <el-option v-for="dict in qualifier_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item
+          label="晋级条件值"
+          prop="qualifierValue"
+          v-if="form.tournamentType === 1 && form.qualifierType === '2'"
+        >
+          <el-input
+            v-model="form.qualifierValue"
+            placeholder="请输入晋级条件值"
+            :disabled="dialog.mode === 'view'"
+          />
+        </el-form-item>
+
+        <el-form-item
+          label="晋级级别"
+          prop="qualifierValue"
+          v-if="form.tournamentType === 1 && form.qualifierType === '1'"
+        >
+          <el-select
+            v-model="form.qualifierValue"
+            placeholder="选项"
+            style="width: 200px"
+            :disabled="dialog.mode === 'view'"
+          >
+            <el-option
+              v-for="item in itemOptionsStructuresLevel2"
+              :key="item.id"
+              :label="item.label"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -416,7 +497,7 @@
 </template>
 
 <script setup name="Tournaments" lang="ts">
-import { listTournaments, getTournaments, delTournaments, addTournaments, updateTournaments } from '@/api/system/physical/tournaments';
+import { listTournaments, getTournaments, delTournaments, addTournaments, updateTournaments, selectPhysicalTournamentsLeagueId } from '@/api/system/physical/tournaments';
 import { TournamentsVO, TournamentsQuery, TournamentsForm } from '@/api/system/physical/tournaments/types';
 import { selectItemsSelList, selectXianXiaItemsSelList } from '@/api/system/business/items';
 import { selectPhysicalBlingStructuresInfo } from '@/api/system/physical/blindStructures';
@@ -429,9 +510,10 @@ import LevelsIndex from '@/views/system/physical/blindLevels/index.vue';
 import { LeagueTournamentVO } from '@/api/system/physical/leagueTournament/types';
 import { JudgeVO } from '@/api/system/physical/judge/types';
 import { ElSelect } from 'element-plus';
+import { ref } from 'vue';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { game_variant_type, tournaments_time, physical_tournaments_type } = toRefs<any>(
-  proxy?.useDict('game_variant_type', 'tournaments_time', 'physical_tournaments_type')
+const { game_variant_type, tournaments_time, physical_tournaments_type , qualifier_type } = toRefs<any>(
+  proxy?.useDict('game_variant_type', 'tournaments_time', 'physical_tournaments_type', 'qualifier_type')
 );
 const tournamentsList = ref<TournamentsVO[]>([]);
 const buttonLoading = ref(false);
@@ -486,7 +568,8 @@ const initFormData: TournamentsForm = {
   actionTime: undefined,
   targetTournamentId: undefined,
   qualifierType: undefined,
-  qualifierValue: undefined
+  qualifierValue: undefined,
+  tournamentType: 0, // 👈 默认普通赛
 };
 const data = reactive<PageData<TournamentsForm, TournamentsQuery>>({
   form: { ...initFormData },
@@ -738,6 +821,7 @@ const handleUpdate = async (row?: TournamentsVO, mode: 'edit' | 'view' = 'edit')
   form.value.signTime = String(res.data.signTime);
   form.value.gameType = String(res.data.gameType); // 转为字符串
   form.value.gameVariant = String(res.data.gameVariant); // 转为字符串
+  form.value.qualifierType = String(res.data.qualifierType);
   competitionIcon.value = res.data.competitionIcon;
   competitionBg.value = res.data.competitionBg;
   // 处理报名条件数据
@@ -774,6 +858,10 @@ const handleUpdate = async (row?: TournamentsVO, mode: 'edit' | 'view' = 'edit')
       }
     ];
   }
+  // ✅ 主动触发盲注等级加载
+  if (form.value.blindStructureId) {
+    await handleBlindStructureChange(form.value.blindStructureId);
+  }
   dialog.visible = true;
   dialog.title = mode === 'view' ? '查看比赛' : '编辑比赛';
   dialog.mode = mode; // 设置模式
@@ -859,6 +947,7 @@ onMounted(() => {
   loadLeagueTournamentOptions();
   loadJudgeOptions();
   loadItemPrizeOptions();
+  loadLeagueRelatedTournaments();
 });
 const itemOptions = ref<{ id: number; label: string }[]>([]);
 // 加载报名条件选项
@@ -936,7 +1025,7 @@ const loadItemStructuresOptions = async () => {
 
 // 下拉选项数据
 const itemOptionsStructuresLevel = ref<{ id: number; label: string }[]>([]);
-
+const itemOptionsStructuresLevel2 = ref<{ id: number; label: string }[]>([]);
 // 加载报名条件选项
 const handleBlindStructureChange = async (value: number) => {
   //data.form.lateRegistrationLevel = null;
@@ -957,6 +1046,7 @@ const handleBlindStructureChange = async (value: number) => {
         }
       }
       itemOptionsStructuresLevel.value = list;
+      itemOptionsStructuresLevel2.value = list;
       // 判断当前选择的 lateRegistrationLevel 是否在新列表中
       const currentLevel = data.form.lateRegistrationLevel;
       if (currentLevel && !list.some((item) => item.id === currentLevel)) {
@@ -1293,5 +1383,41 @@ const resetFormConditions = () => {
 const getConditionTooltipContent = (conditions: any[]) => {
   return conditions.map((condition) => `${condition.itemsName} x ${condition.quantity}`).join('\n');
 };
-
+const tournamentTypeOptions = ref([
+  { value: 0, label: '普通赛' },
+  { value: 1, label: '晋级赛' }
+]);
+const selectOptions = ref<{ id: string | number; label: string }[]>([]); // 👈 类型明确:id 可能是 string/number,name 是必填字段
+const selectLoading = ref(false);
+const loadLeagueRelatedTournaments = async () => {
+  try {
+    selectLoading.value = true;
+    const res = await selectPhysicalTournamentsLeagueId();
+    const data2 = res.data as unknown as { id: number; name: string }[];
+    const list = [];
+    for (let i = 0; i < data2.length; i++) {
+      const item = data2[i];
+      list.push({
+        id: item.id,
+        label: item.name
+      });
+    }
+    selectOptions.value = list;
+  } catch (error) {
+    console.error('加载联赛关联赛事失败', error);
+    ElMessage.error('加载失败');
+  } finally {
+    selectLoading.value = false;
+  }
+};
+const loadTargetTournaments = (query: string) => {
+  if (!query.trim()) {
+    selectOptions.value = leagueRelatedTournaments.value;
+    return;
+  }
+  // 这里可加模糊搜索逻辑(如 filter)
+  selectOptions.value = leagueRelatedTournaments.value.filter(item =>
+    item.name.toLowerCase().includes(query.toLowerCase())
+  );
+};
 </script>