| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="form.value && form.value.stages && form.value.stages.length > 0" class="stages-list"> |
| | | <div v-if="form && form.stages && form.stages.length > 0" class="stages-list"> |
| | | <div v-for="(stage, index) in sortedFormStages" :key="index" class="stage-item"> |
| | | <div class="stage-info"> |
| | | <div class="stage-header"> |
| | |
| | | <el-select v-model="currentStudent.lastStageId" placeholder="请选择阶段" style="width: 100%"> |
| | | <el-option label="无" :value="null" /> |
| | | <el-option |
| | | v-for="stage in (form.value?.stages || [])" |
| | | v-for="stage in (form?.stages || [])" |
| | | :key="stage.id" |
| | | :label="stage.name" |
| | | :value="stage.id" |
| | |
| | | // 计算过滤后的评委列表 |
| | | const filteredJudges = computed(() => { |
| | | if (!judgeSearchText.value.trim()) { |
| | | return allJudges.value |
| | | return allJudges.value.filter(judge => judge && judge.id && judge.name) |
| | | } |
| | | return allJudges.value.filter(judge => |
| | | judge.name.toLowerCase().includes(judgeSearchText.value.toLowerCase()) |
| | | judge && judge.name && judge.name.toLowerCase().includes(judgeSearchText.value.toLowerCase()) |
| | | ) |
| | | }) |
| | | |
| | |
| | | try { |
| | | judgeLoading.value = true |
| | | const judges = await getAllJudges() |
| | | allJudges.value = judges || [] |
| | | allJudges.value = (judges || []).filter(judge => judge && judge.id && judge.name) |
| | | } catch (error) { |
| | | console.error('加载评委列表失败:', error) |
| | | ElMessage.error('加载评委列表失败: ' + error.message) |
| | |
| | | playerMax: activity.playerMax, |
| | | state: activity.state, |
| | | stages: activity.stages || [], |
| | | judges: activity.judges || [], |
| | | judges: (activity.judges || []).filter(judge => judge && judge.id && judge.name), |
| | | students: activity.students || [], |
| | | mediaFiles: [] |
| | | } |
| | |
| | | // 获取默认阶段名称 - 使用更灵活的命名方式,避免硬编码特定阶段名称 |
| | | const getDefaultStageName = (index) => { |
| | | // 提供一些常用的阶段名称建议,但不强制使用 |
| | | const suggestedNames = ['', '第一阶段', '第二阶段', '第三阶段', '第四阶段', '第五阶段'] |
| | | return suggestedNames[index] || `第${index}阶段` |
| | | const suggestedNames = ['第一阶段', '第二阶段', '第三阶段', '第四阶段', '第五阶段'] |
| | | return suggestedNames[index - 1] || `第${index}阶段` |
| | | } |
| | | |
| | | // 获取阶段在原始数组中的索引 |
| | |
| | | |
| | | // 评委管理 |
| | | const addJudge = () => { |
| | | // 检查比赛是否已保存 |
| | | if (!isEdit.value && !form.value.id) { |
| | | ElMessage.warning('请先保存比赛信息后再添加评委') |
| | | return |
| | | } |
| | | |
| | | resetJudgeDialog() |
| | | judgeDialogVisible.value = true |
| | | } |
| | |
| | | const handleMediaUpload = async (activityId) => { |
| | | if (!form.value || !form.value.mediaFiles) return |
| | | |
| | | const failedFiles = [] |
| | | |
| | | try { |
| | | for (const mediaFile of form.value.mediaFiles) { |
| | | // 跳过已经有 id 的媒体文件(已保存的) |
| | |
| | | mediaFile.uploadResult = uploadResult |
| | | } catch (error) { |
| | | console.error(`媒体文件 ${mediaFile.name} 处理失败:`, error) |
| | | ElMessage.error(`文件 ${mediaFile.name} 上传失败: ${error.message}`) |
| | | // 不抛出错误,继续处理其他文件 |
| | | failedFiles.push({ |
| | | name: mediaFile.name, |
| | | error: error.message |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 如果有文件上传失败,抛出错误 |
| | | if (failedFiles.length > 0) { |
| | | const failedNames = failedFiles.map(f => f.name).join(', ') |
| | | throw new Error(`以下文件上传失败: ${failedNames}`) |
| | | } |
| | | } catch (error) { |
| | | console.error('媒体文件处理失败:', error) |
| | | // 不影响主流程,只记录错误 |
| | | throw error // 抛出错误让上层处理 |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | submitting.value = true |
| | | |
| | | console.log('=== 开始保存比赛 ===') |
| | | console.log('form.value:', form.value) |
| | | console.log('form.value.stages:', form.value.stages) |
| | | console.log('form.value.judges:', form.value.judges) |
| | | |
| | | // 准备保存数据,只包含后端支持的字段 |
| | | const saveData = { |
| | | name: form.value.name, |
| | |
| | | ratingSchemeId: form.value.ratingSchemeId, |
| | | playerMax: form.value.playerMax, |
| | | state: form.value.state || 1, |
| | | stages: form.value.stages ? form.value.stages.map(stage => { |
| | | const stageData = { |
| | | name: stage.name, |
| | | description: stage.description, |
| | | matchTime: stage.matchTime, |
| | | address: stage.address, |
| | | playerMax: stage.playerMax, |
| | | sortOrder: stage.sortOrder, |
| | | state: stage.state || 1 |
| | | } |
| | | // 只在有有效ID时才添加id字段 |
| | | if (stage.id) { |
| | | stageData.id = stage.id |
| | | } |
| | | // 只在有有效ratingSchemeId时才添加该字段 |
| | | if (stage.ratingSchemeId) { |
| | | stageData.ratingSchemeId = stage.ratingSchemeId |
| | | } |
| | | return stageData |
| | | }) : [], |
| | | judges: form.value.judges ? form.value.judges.filter(judge => judge.id && judge.name).map(judge => ({ |
| | | judgeId: judge.id, |
| | | judgeName: judge.name, |
| | | stageIds: judge.stageIds || [] |
| | | })) : [] |
| | | stages: form.value.stages ? (() => { |
| | | console.log('=== 处理stages ===') |
| | | console.log('原始stages:', form.value.stages) |
| | | const filteredStages = form.value.stages.filter(stage => stage) |
| | | console.log('过滤后stages:', filteredStages) |
| | | return filteredStages.map((stage, index) => { |
| | | console.log(`处理stage ${index}:`, stage) |
| | | const stageData = { |
| | | name: stage.name, |
| | | description: stage.description, |
| | | matchTime: stage.matchTime, |
| | | address: stage.address, |
| | | playerMax: stage.playerMax, |
| | | sortOrder: stage.sortOrder, |
| | | state: stage.state || 1 |
| | | } |
| | | // 只在有有效ID时才添加id字段 |
| | | if (stage.id) { |
| | | stageData.id = stage.id |
| | | } |
| | | // 只在有有效ratingSchemeId时才添加该字段 |
| | | if (stage.ratingSchemeId) { |
| | | stageData.ratingSchemeId = stage.ratingSchemeId |
| | | } |
| | | console.log(`处理后stage ${index}:`, stageData) |
| | | return stageData |
| | | }) |
| | | })() : [], |
| | | judges: form.value.judges ? (() => { |
| | | console.log('=== 处理judges ===') |
| | | console.log('原始judges:', form.value.judges) |
| | | const filteredJudges = form.value.judges.filter(judge => judge && judge.id && judge.name) |
| | | console.log('过滤后judges:', filteredJudges) |
| | | return filteredJudges.map((judge, index) => { |
| | | console.log(`处理judge ${index}:`, judge) |
| | | const judgeData = { |
| | | judgeId: judge.id, |
| | | judgeName: judge.name, |
| | | stageIds: judge.stageIds || [] |
| | | } |
| | | console.log(`处理后judge ${index}:`, judgeData) |
| | | return judgeData |
| | | }) |
| | | })() : [] |
| | | } |
| | | |
| | | // 如果是编辑模式,添加id字段 |
| | |
| | | |
| | | const result = await saveActivity(saveData) |
| | | |
| | | console.log('=== 保存结果 ===') |
| | | console.log('result:', result) |
| | | console.log('result type:', typeof result) |
| | | console.log('result.id:', result?.id) |
| | | console.log('result.id type:', typeof result?.id) |
| | | console.log('JSON.stringify(result):', JSON.stringify(result, null, 2)) |
| | | |
| | | // 如果是新增,更新form的id |
| | | if (!isEdit.value && result && result.id) { |
| | | form.value.id = result.id |
| | | } |
| | | |
| | | // 处理媒体文件上传和保存 |
| | | let mediaUploadSuccess = true |
| | | if (form.value.mediaFiles && form.value.mediaFiles.length > 0) { |
| | | const activityId = result.id || form.value.id |
| | | // 修复activityId获取逻辑:优先使用result.id(新增时),其次使用form.value.id(编辑时) |
| | | const activityId = result?.id || form.value.id |
| | | console.log('=== 媒体文件上传 ===') |
| | | console.log('result:', result) |
| | | console.log('form.value.id:', form.value.id) |
| | | console.log('最终activityId:', activityId) |
| | | |
| | | if (activityId) { |
| | | await handleMediaUpload(activityId) |
| | | try { |
| | | await handleMediaUpload(activityId) |
| | | console.log('媒体文件上传成功') |
| | | } catch (mediaError) { |
| | | console.error('媒体文件上传失败:', mediaError) |
| | | mediaUploadSuccess = false |
| | | ElMessage.warning('比赛保存成功,但部分媒体文件上传失败,请稍后重新编辑添加') |
| | | } |
| | | } else { |
| | | console.error('无法获取activityId,跳过媒体文件上传') |
| | | mediaUploadSuccess = false |
| | | ElMessage.warning('比赛保存成功,但无法获取比赛ID,媒体文件上传失败') |
| | | } |
| | | } |
| | | |
| | | ElMessage.success(isEdit.value ? '更新成功' : '创建成功') |
| | | |
| | | // 如果是新增,不自动返回,让用户可以继续添加评委和学员 |
| | | if (isEdit.value) { |
| | | goBack() |
| | | if (mediaUploadSuccess) { |
| | | ElMessage.success(isEdit.value ? '更新成功' : '创建成功') |
| | | } |
| | | |
| | | // 保存成功后返回列表页面 |
| | | goBack() |
| | | } catch (error) { |
| | | console.error('=== 保存比赛失败 ===') |
| | | console.error('错误对象:', error) |
| | | console.error('错误消息:', error.message) |
| | | console.error('错误堆栈:', error.stack) |
| | | console.error('当前form.value:', form.value) |
| | | |
| | | if (error.message) { |
| | | console.error('保存比赛失败:', error) |
| | | ElMessage.error('保存失败: ' + error.message) |
| | | } else { |
| | | ElMessage.error('保存失败: 未知错误') |
| | | } |
| | | } finally { |
| | | submitting.value = false |
| | |
| | | await loadActivity() |
| | | |
| | | // 如果是新建模式且没有阶段,自动创建一个阶段 |
| | | console.log('检查默认阶段创建条件:', { |
| | | isEdit: isEdit.value, |
| | | hasForm: !!form.value, |
| | | hasStages: !!(form.value && form.value.stages), |
| | | stagesLength: form.value && form.value.stages ? form.value.stages.length : 'undefined' |
| | | }) |
| | | |
| | | if (!isEdit.value && form.value && form.value.stages && form.value.stages.length === 0) { |
| | | console.log('创建默认阶段') |
| | | onStageCountChange(1) |
| | | } |
| | | }) |