赛事详情个人项目限制

This commit is contained in:
马梓彭 2026-05-06 22:20:13 +08:00
parent 1b512e704d
commit e284d2153c
7 changed files with 56 additions and 13 deletions

View File

@ -54,7 +54,7 @@
<el-card shadow="never"> <el-card shadow="never">
<template #header>限报配置</template> <template #header>限报配置</template>
<div v-if="localFormData.projects?.length" class="project-limit-section"> <div v-if="localFormData.projects?.length && !isOnlyIndividual" class="project-limit-section">
<div class="project-limit-section__header"> <div class="project-limit-section__header">
<div class="project-limit-section__title"> <div class="project-limit-section__title">
<span class="required-star" v-if="!readonly">*</span> <span class="required-star" v-if="!readonly">*</span>
@ -77,7 +77,7 @@
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item v-if="!readonly" <el-form-item v-if="!readonly"
:prop="`projects.${$index}.limitCount`" :prop="`projects.${$index}.limitCount`"
:rules="[{ required: true, message: '请填写项目限报数', trigger: 'change' }]" :rules="isOnlyIndividual ? [] : [{ required: true, message: '请填写项目限报数', trigger: 'change' }]"
style="margin: 0; justify-content: center;" style="margin: 0; justify-content: center;"
> >
<el-input-number v-model="row.limitCount" :min="0" :step="1" :precision="0" :controls="true" class="project-limit-input" :disabled="readonly" /> <el-input-number v-model="row.limitCount" :min="0" :step="1" :precision="0" :controls="true" class="project-limit-input" :disabled="readonly" />

View File

@ -163,7 +163,8 @@ import { merchantPageGet } from '/@/api/match/merchant';
const props = defineProps({ const props = defineProps({
modelValue: { type: Object, required: true }, modelValue: { type: Object, required: true },
readonly: { type: Boolean, default: false } readonly: { type: Boolean, default: false },
projects: { type: Array, default: () => [] }
}); });
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);
@ -220,8 +221,8 @@ const syncMerchantInfo = () => {
}; };
watch( watch(
() => props.modelValue, [() => props.modelValue, () => props.projects],
(v) => { ([v, externalProjects]) => {
if (!v) return; if (!v) return;
// 直接复制所有属性,强制覆盖 // 直接复制所有属性,强制覆盖
@ -233,7 +234,8 @@ watch(
localFormData.value.bankName = v.bankName ?? ''; localFormData.value.bankName = v.bankName ?? '';
localFormData.value.accountNumber = v.accountNumber ?? ''; localFormData.value.accountNumber = v.accountNumber ?? '';
localFormData.value.businessLicenseUrl = v.businessLicenseUrl ?? ''; localFormData.value.businessLicenseUrl = v.businessLicenseUrl ?? '';
localFormData.value.projects = v.projects ?? []; // 优先使用外部传入的 projects,如果没有则使用 modelValue 中的
localFormData.value.projects = (externalProjects && externalProjects.length > 0) ? externalProjects : (v.projects ?? []);
// 如果已经初始化完成,调用 syncMerchantInfo // 如果已经初始化完成,调用 syncMerchantInfo
if (isInitialized.value) { if (isInitialized.value) {

View File

@ -6,7 +6,7 @@
<div style="height:50px;"></div> <div style="height:50px;"></div>
<Step2Units v-model:modelValue="formData.units" :readonly="true" /> <Step2Units v-model:modelValue="formData.units" :readonly="true" />
<div style="height:50px;"></div> <div style="height:50px;"></div>
<Step3ProjectConfig v-model:modelValue="formData.projectConfig" :readonly="true" /> <Step3ProjectConfig v-model:modelValue="projectConfigWithRegistrationType" :readonly="true" />
<div style="height:50px;"></div> <div style="height:50px;"></div>
<Step4FeeConfig v-model:modelValue="formData.feeConfig" :readonly="true" :projects="formData.projectConfig.projects" /> <Step4FeeConfig v-model:modelValue="formData.feeConfig" :readonly="true" :projects="formData.projectConfig.projects" />
<div style="height:100px;"></div> <div style="height:100px;"></div>
@ -404,6 +404,12 @@ const formData = ref({
projectPrices: {}, projectPrices: {},
}, },
}); });
// 合并 registrationType 的项目配置
const projectConfigWithRegistrationType = computed(() => ({
...formData.value.projectConfig,
registrationType: formData.value.basicInfo.registrationType,
}));
// 打开弹窗 // 打开弹窗
const openDialog = async (id) => { const openDialog = async (id) => {
// 先设置 eventId,再显示对话框 // 先设置 eventId,再显示对话框

View File

@ -140,8 +140,10 @@
<!-- 性别 --> <!-- 性别 -->
<el-form-item label="性别" prop="gender"> <el-form-item label="性别" prop="gender">
<el-tag :type="formData.gender === 0 ? '' : 'success'"> <el-tag v-if="formData.gender !== ''" :type="formData.gender === 0 ? '' : 'success'">
{{ formData.gender === 0 ? '男' : '女' }}</el-tag> {{ formData.gender === 0 ? '男' : '女' }}
</el-tag>
<span v-else style="color: #909399;">请选择性别</span>
</el-form-item> </el-form-item>
<el-form-item v-if="ocrType === 'idcard'" label="身份证号" prop="idCardNumber"> <el-form-item v-if="ocrType === 'idcard'" label="身份证号" prop="idCardNumber">
@ -198,7 +200,7 @@ const getDefaultFormData = () => ({
id: undefined, id: undefined,
name: '', name: '',
idCardNumber: '', idCardNumber: '',
gender: 0, gender: '',
idCardImageUrl: '', idCardImageUrl: '',
birthDate: '', birthDate: '',
mobile: '', mobile: '',

View File

@ -86,7 +86,7 @@ const getDefaultFormData = () => ({
id: undefined, id: undefined,
name: '', name: '',
age: '', age: '',
gender: 0, gender: '',
mobile: '', mobile: '',
}); });

View File

@ -265,7 +265,7 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="isShowViewChangeMembersDialog = false">关闭</el-button> <el-button @click="isShowViewChangeMembersDialog = false">关闭</el-button>
<el-button type="primary" @click="openChangeMembersDialog">更换参赛队员</el-button> <el-button type="primary" @click="openChangeMembersDialog" :disabled="isChangeMemberDisabled">更换参赛队员</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -868,6 +868,33 @@ const isCancelDisabledByRow = (row) => {
return !(payStatus === 1); return !(payStatus === 1);
}; };
// 检查当前查看/更换队员弹窗中是否可以更换队员
const isChangeMemberDisabled = computed(() => {
if (!viewChangeMembersData.value) return true;
// 检查是否已超过赛事报名截止时间
if (viewChangeMembersData.value.registrationEndTime) {
try {
const endTime = new Date(viewChangeMembersData.value.registrationEndTime);
const currentTime = new Date();
if (currentTime > endTime) {
// 已超过报名截止时间,禁用更换队员
return true;
}
} catch {
// 日期解析失败,继续检查其他条件
}
}
// 检查赛事状态,如果不是报名中(1)则禁用
const eventStatus = normalizeToNumber(viewChangeMembersData.value.eventStatus);
if (eventStatus !== 1) {
return true;
}
return false;
});
// 格式化组别的年龄段(出生日期范围) // 格式化组别的年龄段(出生日期范围)
const formatGroupDate = (item) => { const formatGroupDate = (item) => {
const start = item?.birthDateStart; const start = item?.birthDateStart;

View File

@ -63,7 +63,7 @@
<div style="height:50px;"></div> <div style="height:50px;"></div>
<Step2Units v-model:modelValue="formData.units" :readonly="true" /> <Step2Units v-model:modelValue="formData.units" :readonly="true" />
<div style="height:50px;"></div> <div style="height:50px;"></div>
<Step3ProjectConfig v-model:modelValue="formData.projectConfig" :readonly="true" /> <Step3ProjectConfig v-model:modelValue="projectConfigWithRegistrationType" :readonly="true" />
<div style="height:50px;"></div> <div style="height:50px;"></div>
<UserStep4FeeConfig v-model:modelValue="formData.feeConfig" :readonly="true" /> <UserStep4FeeConfig v-model:modelValue="formData.feeConfig" :readonly="true" />
<div style="height:100px;"></div> <div style="height:100px;"></div>
@ -680,6 +680,12 @@ const formData = ref({
}, },
}); });
// 合并 registrationType 的项目配置
const projectConfigWithRegistrationType = computed(() => ({
...formData.value.projectConfig,
registrationType: formData.value.basicInfo.registrationType,
}));
const clearDetailState = () => { const clearDetailState = () => {
detailLoading.value = false; detailLoading.value = false;
detailData.value = null; detailData.value = null;