lrj
13 小时以前 ae3349d2ff53767b5bc9cb30e1bf7e15f9e814ee
web/src/views/ActivityForm.vue
@@ -143,7 +143,7 @@
                </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">
@@ -396,7 +396,7 @@
          <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"
@@ -476,10 +476,10 @@
// 计算过滤后的评委列表
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())
  )
})
@@ -580,7 +580,7 @@
  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)
@@ -610,7 +610,7 @@
        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: []
      }
@@ -678,8 +678,8 @@
// 获取默认阶段名称 - 使用更灵活的命名方式,避免硬编码特定阶段名称
const getDefaultStageName = (index) => {
  // 提供一些常用的阶段名称建议,但不强制使用
  const suggestedNames = ['', '第一阶段', '第二阶段', '第三阶段', '第四阶段', '第五阶段']
  return suggestedNames[index] || `第${index}阶段`
  const suggestedNames = ['第一阶段', '第二阶段', '第三阶段', '第四阶段', '第五阶段']
  return suggestedNames[index - 1] || `第${index}阶段`
}
// 获取阶段在原始数组中的索引
@@ -794,6 +794,12 @@
// 评委管理
const addJudge = () => {
  // 检查比赛是否已保存
  if (!isEdit.value && !form.value.id) {
    ElMessage.warning('请先保存比赛信息后再添加评委')
    return
  }
  resetJudgeDialog()
  judgeDialogVisible.value = true
}
@@ -1102,6 +1108,8 @@
const handleMediaUpload = async (activityId) => {
  if (!form.value || !form.value.mediaFiles) return
  
  const failedFiles = []
  try {
    for (const mediaFile of form.value.mediaFiles) {
      // 跳过已经有 id 的媒体文件(已保存的)
@@ -1144,13 +1152,21 @@
        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 // 抛出错误让上层处理
  }
}
@@ -1164,6 +1180,11 @@
    
    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,
@@ -1174,31 +1195,50 @@
      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字段
@@ -1213,29 +1253,61 @@
    
    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
@@ -1254,7 +1326,15 @@
  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)
  }
})