赛事报名限制提示
This commit is contained in:
parent
ef5116566e
commit
f25644a6ca
@ -300,18 +300,6 @@
|
||||
|
||||
<!-- 验证提示区域 -->
|
||||
<div class="validation-notes-section">
|
||||
<!-- 参赛人数错误提示 -->
|
||||
<template v-if="showCompletionCountErrors && hasAnyCompletionCountError()">
|
||||
<el-alert
|
||||
v-for="error in getCompletionCountErrors()"
|
||||
:key="error.groupId"
|
||||
:title="error.message"
|
||||
type="error"
|
||||
:closable="false"
|
||||
style="margin-bottom: 12px;"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 年龄性别不符合要求提示 -->
|
||||
<el-alert
|
||||
v-if="hasAnyValidationErrors()"
|
||||
@ -322,13 +310,16 @@
|
||||
/>
|
||||
|
||||
<!-- 限报提示 -->
|
||||
<el-alert
|
||||
v-if="hasAnyRegistrationLimit()"
|
||||
title="此队员已达到报名限制"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
style="margin-bottom: 12px;"
|
||||
/>
|
||||
<template v-if="hasAnyRegistrationLimit()">
|
||||
<el-alert
|
||||
v-for="(detail, index) in (registrationLimitCheckResult?.limitDetails ?? [])"
|
||||
:key="index"
|
||||
:title="detail?.limitMessage ?? '报名限制'"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
style="margin-bottom: 12px;"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
@ -350,7 +341,7 @@
|
||||
type="primary"
|
||||
@click="handleStep2Next"
|
||||
:loading="submitDraftLoading"
|
||||
:disabled="hasAnyValidationErrors() || hasAnyRegistrationLimit() || hasAnyCompletionCountError()"
|
||||
:disabled="hasAnyValidationErrors() || hasAnyRegistrationLimit()"
|
||||
>
|
||||
下一步
|
||||
</el-button>
|
||||
@ -943,8 +934,6 @@ const memberRegistrationLimitMap = ref({}); // { memberId: { isLimited: boolean,
|
||||
const registrationLimitCheckResult = ref(null); // 报名限制检查结果
|
||||
const validationLoading = ref(false); // 验证加载状态
|
||||
let validationDebounceTimer = null; // 防抖定时器
|
||||
// 参赛人数错误提示显示控制
|
||||
const showCompletionCountErrors = ref(false);
|
||||
|
||||
// Step2: 团队相关
|
||||
const teamList = ref([]);
|
||||
@ -1014,7 +1003,6 @@ const clearRegisterState = () => {
|
||||
memberRegistrationLimitMap.value = {};
|
||||
registrationLimitCheckResult.value = null;
|
||||
validationLoading.value = false;
|
||||
showCompletionCountErrors.value = false;
|
||||
if (validationDebounceTimer) {
|
||||
clearTimeout(validationDebounceTimer);
|
||||
validationDebounceTimer = null;
|
||||
@ -1062,7 +1050,6 @@ const resetStep2AndBeyond = () => {
|
||||
// 验证相关状态重置
|
||||
memberValidationMap.value = {};
|
||||
registrationLimitCheckResult.value = null;
|
||||
showCompletionCountErrors.value = false;
|
||||
};
|
||||
|
||||
const openRegistrationDialog = async (row) => {
|
||||
@ -1293,71 +1280,6 @@ const hasAnyRegistrationLimit = () => {
|
||||
return registrationLimitCheckResult.value?.hasLimit ?? false;
|
||||
};
|
||||
|
||||
// ==================== 参赛人数验证相关 ====================
|
||||
// 获取某个组别的当前分配人数(考虑多团队模式)
|
||||
const getGroupAssignedCount = (groupId) => {
|
||||
const group = selectedGroupItems.value.find(g => g.id === groupId);
|
||||
if (!group) return 0;
|
||||
|
||||
// 检查是否为团队项目且启用了多团队模式
|
||||
const isMultiTeamMode = isTeamProject(group) && groupTeamsMap.value[groupId] &&
|
||||
(groupTeamsMap.value[groupId].length > 1 || getGroupMaxTeams(groupId) > 1);
|
||||
|
||||
if (isMultiTeamMode) {
|
||||
// 多团队模式:统计所有团队的队员数
|
||||
return groupTeamsMap.value[groupId].reduce((total, team) => {
|
||||
return total + (team.members?.length ?? 0);
|
||||
}, 0);
|
||||
} else {
|
||||
// 单团队模式
|
||||
return groupMemberMap.value[groupId]?.length ?? 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 检查某个组别的参赛人数是否符合要求
|
||||
const checkGroupCompletionCount = (group) => {
|
||||
const requiredCount = group.projectCompletionCount ?? 0;
|
||||
if (requiredCount <= 0) return { isValid: true, message: '' };
|
||||
|
||||
const currentCount = getGroupAssignedCount(group.id);
|
||||
|
||||
if (currentCount !== requiredCount) {
|
||||
let message;
|
||||
if (currentCount < requiredCount) {
|
||||
message = `${group.projectName}参赛人数错误(少${requiredCount - currentCount}人)`;
|
||||
} else {
|
||||
message = `${group.projectName}参赛人数错误(多${currentCount - requiredCount}人)`;
|
||||
}
|
||||
return { isValid: false, message };
|
||||
}
|
||||
|
||||
return { isValid: true, message: '' };
|
||||
};
|
||||
|
||||
// 获取所有参赛人数错误信息
|
||||
const getCompletionCountErrors = () => {
|
||||
const errors = [];
|
||||
for (const group of selectedGroupItems.value) {
|
||||
const result = checkGroupCompletionCount(group);
|
||||
if (!result.isValid) {
|
||||
errors.push({
|
||||
groupId: group.id,
|
||||
projectName: group.projectName,
|
||||
groupName: group.groupName ?? group.name,
|
||||
message: result.message
|
||||
});
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
|
||||
// 检查是否有任何参赛人数错误
|
||||
const hasAnyCompletionCountError = () => {
|
||||
return getCompletionCountErrors().length > 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 判断组别是否已达到队伍数量限制
|
||||
const isGroupAtTeamLimit = (groupId) => {
|
||||
const limit = groupTeamLimitMap.value[groupId];
|
||||
@ -1400,8 +1322,6 @@ const assignMemberToActiveGroup = async (member) => {
|
||||
}
|
||||
|
||||
groupMemberMap.value[gId].push({ ...member, teamId: member.teamId });
|
||||
// 显示参赛人数错误提示
|
||||
showCompletionCountErrors.value = true;
|
||||
// 触发实时验证(包含报名限制检查)
|
||||
debounceValidateAllMembers();
|
||||
};
|
||||
@ -1422,8 +1342,6 @@ const removeMemberFromGroup = (groupId, memberId) => {
|
||||
usedTeamId.value = null;
|
||||
}
|
||||
|
||||
// 显示参赛人数错误提示
|
||||
showCompletionCountErrors.value = true;
|
||||
// 触发实时验证
|
||||
debounceValidateAllMembers();
|
||||
};
|
||||
@ -1624,8 +1542,6 @@ const assignMemberToActiveTeam = async (member) => {
|
||||
}
|
||||
|
||||
team.members.push({ ...member, teamId: member.teamId });
|
||||
// 显示参赛人数错误提示
|
||||
showCompletionCountErrors.value = true;
|
||||
// 触发实时验证(包含报名限制检查)
|
||||
debounceValidateAllMembers();
|
||||
};
|
||||
@ -1649,8 +1565,6 @@ const removeMemberFromTeam = (groupId, teamIndex, memberId) => {
|
||||
usedTeamId.value = null;
|
||||
}
|
||||
|
||||
// 显示参赛人数错误提示
|
||||
showCompletionCountErrors.value = true;
|
||||
// 触发实时验证
|
||||
debounceValidateAllMembers();
|
||||
};
|
||||
@ -1815,10 +1729,41 @@ const checkRegistrationLimit = async () => {
|
||||
teamId: usedTeamId.value ?? selectedTeamId.value,
|
||||
});
|
||||
if (succeeded) {
|
||||
// 添加错误边界处理,确保数据格式正确
|
||||
if (data && typeof data === 'object') {
|
||||
// 确保 limitDetails 是一个数组
|
||||
if (!Array.isArray(data.limitDetails)) {
|
||||
data.limitDetails = [];
|
||||
}
|
||||
// 确保每个 limitDetail 都有 limitMessage
|
||||
data.limitDetails = data.limitDetails.map((detail) => {
|
||||
if (detail && typeof detail === 'object') {
|
||||
return {
|
||||
...detail,
|
||||
limitMessage: detail.limitMessage ?? '报名限制'
|
||||
};
|
||||
}
|
||||
return {
|
||||
limitMessage: '报名限制'
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// 如果 data 格式异常,使用默认值
|
||||
registrationLimitCheckResult.value = {
|
||||
hasLimit: false,
|
||||
limitDetails: []
|
||||
};
|
||||
return;
|
||||
}
|
||||
registrationLimitCheckResult.value = data;
|
||||
}
|
||||
} catch {
|
||||
console.error('检查报名限制失败');
|
||||
} catch (error) {
|
||||
console.error('检查报名限制失败:', error);
|
||||
// 出错时重置结果,避免显示异常
|
||||
registrationLimitCheckResult.value = {
|
||||
hasLimit: false,
|
||||
limitDetails: []
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -1848,20 +1793,11 @@ const handleStep1Next = async () => {
|
||||
setActiveTeam(group.id, 1);
|
||||
}
|
||||
});
|
||||
// 确保在初始化后不会立即显示参赛人数错误
|
||||
showCompletionCountErrors.value = false;
|
||||
};
|
||||
|
||||
const handleStep2Next = async () => {
|
||||
if (!currentEventId.value) return;
|
||||
|
||||
// 先检查参赛人数
|
||||
if (hasAnyCompletionCountError()) {
|
||||
const errors = getCompletionCountErrors();
|
||||
ElMessage.warning(errors[0]?.message ?? '参赛人数错误,请检查后重试');
|
||||
return;
|
||||
}
|
||||
|
||||
// 先检查报名限制
|
||||
await checkRegistrationLimit();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user