From c4938f6f4e839890b032c75c7a57333a6a9157a9 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期四, 06 十一月 2025 17:06:10 +0800
Subject: [PATCH] 添加新闻功能
---
web/src/views/ActivityForm.vue | 550 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 397 insertions(+), 153 deletions(-)
diff --git a/web/src/views/ActivityForm.vue b/web/src/views/ActivityForm.vue
index 7d972bd..931fa32 100644
--- a/web/src/views/ActivityForm.vue
+++ b/web/src/views/ActivityForm.vue
@@ -65,19 +65,9 @@
</el-col>
</el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="姣旇禌鍦板潃" prop="address">
- <el-input v-model="form.address" placeholder="璇疯緭鍏ユ瘮璧涘湴鍧�" />
- </el-form-item>
- </el-col>
-
- <el-col :span="12">
- <el-form-item label="浜烘暟" prop="playerMax">
- <el-input-number v-model="form.playerMax" :min="1" :max="9999" style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
+ <el-form-item label="姣旇禌鍦板潃" prop="address">
+ <el-input v-model="form.address" placeholder="璇疯緭鍏ユ瘮璧涘湴鍧�" />
+ </el-form-item>
<el-form-item label="姣旇禌鎻忚堪" prop="description">
<el-input
@@ -89,7 +79,10 @@
</el-form-item>
<!-- 鍥剧墖/瑙嗛涓婁紶 -->
- <el-divider content-position="left">鍥剧墖/瑙嗛</el-divider>
+ <el-divider content-position="left">
+ 鍥剧墖/瑙嗛
+ <span class="media-description">鏀寔jpg/png/mp4锛屾渶澶�3涓枃浠�</span>
+ </el-divider>
<el-form-item label="濯掍綋鏂囦欢">
<div class="media-upload-section">
@@ -119,7 +112,7 @@
<!-- 娣诲姞鎸夐挳 -->
<el-upload
v-if="form.mediaFiles.length < 3"
- class="media-uploader"
+ class="media-uploader media-uploader-left"
:show-file-list="false"
:before-upload="beforeMediaUpload"
action="#"
@@ -130,7 +123,6 @@
<div class="upload-placeholder">
<el-icon class="upload-icon"><Plus /></el-icon>
<div class="upload-text">娣诲姞鍥剧墖/瑙嗛</div>
- <div class="upload-tip">鏀寔jpg/png/mp4锛屾渶澶�3涓枃浠�</div>
</div>
</el-upload>
</div>
@@ -146,35 +138,33 @@
<el-tab-pane label="姣旇禌闃舵" name="stages">
<div class="stages-header">
<span>姣旇禌闃舵</span>
- <el-button size="small" type="primary" @click="addStage">娣诲姞闃舵</el-button>
+ <div class="stages-controls">
+ <el-button size="small" type="primary" @click="addStage">娣诲姞闃舵</el-button>
+ </div>
</div>
- <div v-if="form.stages && form.stages.length > 0" class="stages-list">
- <div v-for="(stage, index) in form.stages" :key="index" class="stage-item">
+ <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-name">{{ stage.name || '鏈懡鍚嶉樁娈�' }}</div>
+ <div class="stage-header">
+ <span class="stage-order">{{ stage.sortOrder || '-' }}</span>
+ <span class="stage-name">{{ stage.name || '鏈懡鍚嶉樁娈�' }}</span>
+ </div>
<div class="stage-details">
<span class="detail-item">
<el-icon><Clock /></el-icon>
{{ formatDateTime(stage.matchTime) }}
</span>
- <span class="detail-item">
- <el-icon><User /></el-icon>
- {{ stage.playerMax || 0 }} 浜�
- </span>
- <span class="detail-item">
- <el-icon><UserFilled /></el-icon>
- 瀹為檯: {{ stage.actualPlayerCount || 0 }} 浜�
- </span>
+
<el-tag :type="stage.state === 1 ? 'success' : 'info'" size="small">
{{ stage.state === 1 ? '杩涜涓�' : '鏈紑濮�' }}
</el-tag>
</div>
</div>
<div class="stage-actions">
- <el-button size="small" @click="editStage(stage, index)">缂栬緫</el-button>
+ <el-button size="small" @click="editStage(stage, getOriginalStageIndex(stage))">缂栬緫</el-button>
<el-button size="small" @click="closeStage(stage)" v-if="stage.state === 1">鍏抽棴</el-button>
- <el-button size="small" type="danger" @click="removeStage(index)">鍒犻櫎</el-button>
+ <el-button size="small" type="danger" @click="removeStage(getOriginalStageIndex(stage))">鍒犻櫎</el-button>
</div>
</div>
</div>
@@ -189,7 +179,7 @@
<el-button size="small" type="primary" @click="addJudge">鏂板璇勫</el-button>
</div>
- <el-table :data="form.judges" style="width: 100%" border>
+ <el-table :data="form.judges" style="width: 100%" border v-loading="judgeLoading">
<el-table-column label="鍚嶇О" prop="name" />
<el-table-column label="姣旇禌闃舵" width="200">
<template #default="{ row }">
@@ -203,9 +193,8 @@
</el-tag>
</template>
</el-table-column>
- <el-table-column label="鎿嶄綔" width="150" align="center">
+ <el-table-column label="鎿嶄綔" width="100" align="center">
<template #default="{ row, $index }">
- <el-button size="small" @click="editJudge(row, $index)">缂栬緫</el-button>
<el-button size="small" type="danger" @click="removeJudge($index)">鍒犻櫎</el-button>
</template>
</el-table-column>
@@ -214,37 +203,7 @@
<el-empty v-if="!form.judges || form.judges.length === 0" description="鏆傛棤璇勫" />
</el-tab-pane>
- <!-- 瀛﹀憳鍒楄〃 -->
- <el-tab-pane label="瀛﹀憳鍒楄〃" name="students">
- <div class="students-header">
- <span>瀛﹀憳鍒楄〃</span>
- </div>
-
- <el-table :data="form.students" style="width: 100%" border>
- <el-table-column label="瀛﹀憳鍚嶇О" prop="name" />
- <el-table-column label="鏈�鍚庡弬涓庣殑姣旇禌闃舵" width="200">
- <template #default="{ row }">
- {{ getLastStage(row) }}
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="250" align="center">
- <template #default="{ row, $index }">
- <el-button size="small" @click="viewStudent(row, $index)">鏌ョ湅</el-button>
- <el-button size="small" type="primary" @click="rateStudent(row, $index)">璇勫垎</el-button>
- <el-button size="small" @click="commentStudent(row, $index)">鐐硅瘎</el-button>
- <el-button
- size="small"
- :type="row.isAdvanced ? 'success' : 'warning'"
- @click="toggleAdvancement(row, $index)"
- >
- {{ row.isAdvanced ? '宸叉檵绾�' : '鏅嬬骇' }}
- </el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <el-empty v-if="!form.students || form.students.length === 0" description="鏆傛棤瀛﹀憳" />
- </el-tab-pane>
+
</el-tabs>
</div>
@@ -274,6 +233,26 @@
<el-input v-model="currentStage.name" placeholder="璇疯緭鍏ラ樁娈靛悕绉�" maxlength="30" />
</el-form-item>
+ <el-form-item label="姣旇禌闃舵椤哄簭" prop="sortOrder">
+ <el-select v-model="currentStage.sortOrder" placeholder="璇烽�夋嫨闃舵椤哄簭" style="width: 100%">
+ <el-option label="1" :value="1" />
+ <el-option label="2" :value="2" />
+ <el-option label="3" :value="3" />
+ <el-option label="4" :value="4" />
+ <el-option label="5" :value="5" />
+ </el-select>
+ </el-form-item>
+
+ <el-form-item label="瀛﹀憳浜烘暟" prop="playerMax">
+ <el-input-number
+ v-model="currentStage.playerMax"
+ :min="1"
+ :max="1000"
+ placeholder="璇疯緭鍏ュ鍛樹汉鏁�"
+ style="width: 100%"
+ />
+ </el-form-item>
+
<el-form-item label="璇勫垎妯℃澘">
<el-select v-model="currentStage.ratingSchemeId" placeholder="缁ф壙姣旇禌妯℃澘" style="width: 100%">
<el-option label="缁ф壙姣旇禌妯℃澘" :value="null" />
@@ -299,10 +278,6 @@
<el-form-item label="闃舵鍦板潃">
<el-input v-model="currentStage.address" placeholder="璇疯緭鍏ラ樁娈靛湴鍧�" />
- </el-form-item>
-
- <el-form-item label="浜烘暟">
- <el-input-number v-model="currentStage.playerMax" :min="1" :max="9999" style="width: 100%" />
</el-form-item>
<el-form-item label="闃舵鎻忚堪">
@@ -347,14 +322,16 @@
<!-- 闃舵閫夋嫨 -->
<div style="margin-bottom: 16px;">
- <el-form-item label="娣诲姞鍒伴樁娈碉細" label-width="100px">
- <el-select v-model="selectedStageOption" style="width: 100%;" @change="handleStageChange">
- <el-option label="鎵�鏈夐樁娈�" value="all" />
+ <el-form-item label="璐熻矗闃舵锛�" label-width="100px">
+ <!-- 璋冭瘯淇℃伅 -->
+
+ <el-select v-model="selectedStageOptions" multiple style="width: 100%;" placeholder="璇烽�夋嫨璐熻矗鐨勯樁娈�">
+ <!-- 浣跨敤璁$畻灞炴�� -->
<el-option
- v-for="stage in form.stages"
- :key="stage.id"
- :label="stage.name"
- :value="stage.id ? stage.id.toString() : ''"
+ v-for="option in stageOptions"
+ :key="option.value"
+ :label="option.label"
+ :value="option.value"
/>
</el-select>
</el-form-item>
@@ -419,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.stages"
+ v-for="stage in (form?.stages || [])"
:key="stage.id"
:label="stage.name"
:value="stage.id"
@@ -439,7 +416,7 @@
</template>
<script setup>
-import { ref, onMounted, computed } from 'vue'
+import { ref, onMounted, computed, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, VideoPlay, Clock, User, UserFilled, Search } from '@element-plus/icons-vue'
@@ -462,6 +439,9 @@
// Tab鐩稿叧
const activeTab = ref('stages')
+// 闃舵鏁伴噺閫夋嫨
+const selectedStageCount = ref(1)
+
// 闃舵缂栬緫寮圭獥鐩稿叧
const stageDialogVisible = ref(false)
const currentStageIndex = ref(-1)
@@ -472,7 +452,6 @@
matchTime: '',
address: '',
ratingSchemeId: null,
- playerMax: null,
state: 1,
actualPlayerCount: 0
})
@@ -490,17 +469,17 @@
// 璇勫閫夋嫨鐩稿叧
const allJudges = ref([])
const judgeSearchText = ref('')
-const selectedStageOption = ref('all')
+const selectedStageOptions = ref([])
const selectedJudges = ref([])
const judgeLoading = ref(false)
// 璁$畻杩囨护鍚庣殑璇勫鍒楄〃
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())
)
})
@@ -524,7 +503,7 @@
matchTime: '',
address: '',
ratingSchemeId: null,
- playerMax: 100,
+ playerMax: null,
state: 1,
stages: [],
judges: [],
@@ -534,6 +513,31 @@
// 璁$畻灞炴��
const isEdit = computed(() => !!route.params.id)
+
+// 鎸塻ortOrder鎺掑簭鐨勯樁娈靛垪琛�
+const sortedFormStages = computed(() => {
+ if (!form.value.stages) return []
+ return [...form.value.stages].sort((a, b) => {
+ const orderA = a.sortOrder || 999
+ const orderB = b.sortOrder || 999
+ return orderA - orderB
+ })
+})
+
+// 鐢ㄤ簬涓嬫媺妗嗙殑闃舵閫夐」
+const stageOptions = computed(() => {
+ if (!form.value?.stages) {
+ return []
+ }
+
+ return form.value.stages
+ .filter(stage => stage && stage.id != null)
+ .map(stage => ({
+ label: stage.name,
+ value: stage.id.toString(),
+ stage: stage
+ }))
+})
// 琛ㄥ崟楠岃瘉瑙勫垯
const rules = {
@@ -553,6 +557,10 @@
name: [
{ required: true, message: '璇疯緭鍏ラ樁娈靛悕绉�', trigger: 'blur' },
{ max: 30, message: '闃舵鍚嶇О涓嶈兘瓒呰繃30涓瓧绗�', trigger: 'blur' }
+ ],
+ playerMax: [
+ { required: true, message: '璇疯緭鍏ュ鍛樹汉鏁�', trigger: 'blur' },
+ { type: 'number', min: 1, max: 1000, message: '瀛﹀憳浜烘暟蹇呴』鍦�1-1000涔嬮棿', trigger: 'blur' }
]
}
@@ -572,8 +580,7 @@
try {
judgeLoading.value = true
const judges = await getAllJudges()
- allJudges.value = judges || []
- console.log('鍔犺浇璇勫鍒楄〃鎴愬姛:', allJudges.value.length, '涓瘎濮�')
+ allJudges.value = (judges || []).filter(judge => judge && judge.id && judge.name)
} catch (error) {
console.error('鍔犺浇璇勫鍒楄〃澶辫触:', error)
ElMessage.error('鍔犺浇璇勫鍒楄〃澶辫触: ' + error.message)
@@ -590,6 +597,7 @@
try {
loading.value = true
const activity = await getActivity(route.params.id)
+
if (activity) {
form.value = {
id: activity.id,
@@ -599,22 +607,18 @@
matchTime: activity.matchTime || '',
address: activity.address || '',
ratingSchemeId: activity.ratingSchemeId,
- playerMax: activity.playerMax || 100,
+ 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: []
}
// 鍔犺浇骞跺洖濉凡涓婁紶濯掍綋锛歵argetType=2 鍋囪涓衡�滄椿鍔ㄢ�濓紝濡備笉鍚岃璋冩暣
try {
const medias = await getMediasByTarget(MediaTargetType.ACTIVITY, parseInt(activity.id))
- console.log('=== 鍔犺浇娲诲姩濯掍綋璋冭瘯淇℃伅 ===')
- console.log('娲诲姩ID:', activity.id)
- console.log('鑾峰彇鍒扮殑濯掍綋鏁版嵁:', medias)
form.value.mediaFiles = (medias || []).map(m => {
- console.log('澶勭悊濯掍綋鏂囦欢:', m)
const isImage = (m.mediaType === 1) || (m.fileExt && ['jpg','jpeg','png','gif','webp'].includes(m.fileExt.toLowerCase()))
const isVideo = (m.mediaType === 2) || (m.fileExt && ['mp4','mov','m4v','avi','mkv'].includes(m.fileExt.toLowerCase()))
const mediaItem = {
@@ -625,13 +629,14 @@
uploaded: true, // 鏍囪涓哄凡涓婁紶锛屼笉闇�瑕侀噸鏂颁笂浼�
file: null // 宸蹭繚瀛樼殑鏂囦欢娌℃湁file瀵硅薄
}
- console.log('杞崲鍚庣殑濯掍綋椤�:', mediaItem)
return mediaItem
})
- console.log('鏈�缁堢殑mediaFiles:', form.value.mediaFiles)
} catch (e) {
console.error('鍔犺浇娲诲姩濯掍綋澶辫触:', e)
}
+
+ // 璁剧疆闃舵鏁伴噺閫夋嫨鍣ㄧ殑鍊�
+ selectedStageCount.value = (form.value && form.value.stages) ? form.value.stages.length || 1 : 1
}
} catch (error) {
console.error('鍔犺浇姣旇禌鏁版嵁澶辫触:', error)
@@ -642,6 +647,47 @@
}
// 闃舵绠$悊
+// 闃舵鏁伴噺鍙樺寲澶勭悊
+const onStageCountChange = (count) => {
+ if (!count || !form.value || !form.value.stages) return
+
+ // 濡傛灉褰撳墠闃舵鏁伴噺灏戜簬閫夋嫨鐨勬暟閲忥紝鑷姩娣诲姞闃舵
+ while (form.value.stages.length < count) {
+ const stageIndex = form.value.stages.length + 1
+ form.value.stages.push({
+ id: null,
+ name: getDefaultStageName(stageIndex),
+ description: '',
+ matchTime: '',
+ address: form.value.address || '',
+ ratingSchemeId: form.value.ratingSchemeId,
+ sortOrder: stageIndex,
+ state: 1,
+ actualPlayerCount: 0
+ })
+ }
+
+ // 濡傛灉褰撳墠闃舵鏁伴噺澶氫簬閫夋嫨鐨勬暟閲忥紝鍒犻櫎澶氫綑鐨勯樁娈�
+ if (form.value.stages.length > count) {
+ form.value.stages = form.value.stages.slice(0, count)
+ }
+
+ ElMessage.success(`宸茶缃负${count}涓樁娈礰)
+}
+
+// 鑾峰彇榛樿闃舵鍚嶇О - 浣跨敤鏇寸伒娲荤殑鍛藉悕鏂瑰紡锛岄伩鍏嶇‖缂栫爜鐗瑰畾闃舵鍚嶇О
+const getDefaultStageName = (index) => {
+ // 鎻愪緵涓�浜涘父鐢ㄧ殑闃舵鍚嶇О寤鸿锛屼絾涓嶅己鍒朵娇鐢�
+ const suggestedNames = ['绗竴闃舵', '绗簩闃舵', '绗笁闃舵', '绗洓闃舵', '绗簲闃舵']
+ return suggestedNames[index - 1] || `绗�${index}闃舵`
+}
+
+// 鑾峰彇闃舵鍦ㄥ師濮嬫暟缁勪腑鐨勭储寮�
+const getOriginalStageIndex = (stage) => {
+ if (!form.value || !form.value.stages) return -1
+ return form.value.stages.findIndex(s => s === stage)
+}
+
const addStage = () => {
currentStageIndex.value = -1
resetStageForm()
@@ -655,6 +701,8 @@
}
const removeStage = async (index) => {
+ if (!form.value || !form.value.stages) return
+
try {
await ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓樁娈靛悧锛�', '鎻愮ず', {
confirmButtonText: '纭畾',
@@ -662,6 +710,15 @@
type: 'warning'
})
form.value.stages.splice(index, 1)
+
+ // 閲嶆柊鎺掑簭sortOrder
+ form.value.stages.forEach((stage, idx) => {
+ stage.sortOrder = idx + 1
+ })
+
+ // 鏇存柊閫夋嫨鐨勯樁娈垫暟閲�
+ selectedStageCount.value = form.value.stages.length
+
ElMessage.success('鍒犻櫎鎴愬姛')
} catch {
// 鐢ㄦ埛鍙栨秷鍒犻櫎
@@ -683,12 +740,16 @@
}
const saveStage = async () => {
+ if (!form.value || !form.value.stages) return
+
try {
await stageFormRef.value.validate()
if (currentStageIndex.value === -1) {
- // 鏂板闃舵
- form.value.stages.push({ ...currentStage.value })
+ // 鏂板闃舵 - 璁剧疆姝g‘鐨剆ortOrder
+ const newStage = { ...currentStage.value }
+ newStage.sortOrder = form.value.stages.length + 1
+ form.value.stages.push(newStage)
} else {
// 缂栬緫闃舵
form.value.stages[currentStageIndex.value] = { ...currentStage.value }
@@ -710,6 +771,7 @@
address: '',
ratingSchemeId: null,
playerMax: null,
+ sortOrder: null, // 灏嗗湪saveStage涓缃纭殑鍊�
state: 1,
actualPlayerCount: 0
}
@@ -732,6 +794,12 @@
// 璇勫绠$悊
const addJudge = () => {
+ // 妫�鏌ユ瘮璧涙槸鍚﹀凡淇濆瓨
+ if (!isEdit.value && !form.value.id) {
+ ElMessage.warning('璇峰厛淇濆瓨姣旇禌淇℃伅鍚庡啀娣诲姞璇勫')
+ return
+ }
+
resetJudgeDialog()
judgeDialogVisible.value = true
}
@@ -742,6 +810,11 @@
}
const removeJudge = async (index) => {
+ if (!form.value || !form.value.judges) {
+ ElMessage.error('琛ㄥ崟鏁版嵁鏈垵濮嬪寲')
+ return
+ }
+
try {
await ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓瘎濮斿悧锛�', '鎻愮ず', {
confirmButtonText: '纭畾',
@@ -756,26 +829,40 @@
}
const getJudgeStages = (judge) => {
- if (!judge.stageIds || !form.value.stages) return []
- return form.value.stages.filter(stage => judge.stageIds.includes(stage.id))
+ if (!judge.stageIds || !form.value || !form.value.stages) return []
+
+ const stages = []
+
+ // 妫�鏌ユ瘮璧涢樁娈�
+ judge.stageIds.forEach(stageId => {
+ // 澶勭悊瀹為檯闃舵ID
+ const stage = form.value.stages.find(s => s.id === stageId)
+ if (stage) {
+ stages.push({
+ id: stage.id,
+ name: stage.name
+ })
+ }
+ })
+
+ return stages
}
const resetJudgeDialog = () => {
judgeSearchText.value = ''
- selectedStageOption.value = 'all'
+ // 娓呯┖闃舵閫夋嫨
+ selectedStageOptions.value = []
selectedJudges.value = []
}
const handleJudgeSearch = (value) => {
- console.log('鎼滅储璇勫:', value)
+ // 鎼滅储璇勫
}
-const handleStageChange = (value) => {
- console.log('閫夋嫨闃舵:', value)
-}
+
const handleJudgeSelectionChange = (value) => {
- console.log('閫夋嫨璇勫:', value)
+ // 閫夋嫨璇勫
}
const toggleSelectAll = () => {
@@ -797,6 +884,17 @@
return
}
+ if (!form.value || !form.value.judges) {
+ ElMessage.error('琛ㄥ崟鏁版嵁鏈垵濮嬪寲')
+ return
+ }
+
+ // 濡傛灉鏈夐樁娈典絾娌℃湁閫夋嫨闃舵锛屽垯鎻愮ず
+ if (form.value && form.value.stages && form.value.stages.length > 0 && selectedStageOptions.value.length === 0) {
+ ElMessage.warning('璇烽�夋嫨鑷冲皯涓�涓礋璐i樁娈�')
+ return
+ }
+
let addedCount = 0
selectedJudges.value.forEach(judgeId => {
@@ -805,29 +903,35 @@
// 妫�鏌ユ槸鍚﹀凡缁忓瓨鍦�
const existingJudge = form.value.judges.find(j => j.id === judgeId)
if (existingJudge) {
- // 鏇存柊鐜版湁璇勫鐨勯樁娈�
- if (selectedStageOption.value === 'all') {
- existingJudge.stageIds = form.value.stages.map(s => s.id).filter(id => id != null)
- } else {
- const stageId = parseInt(selectedStageOption.value)
- if (!existingJudge.stageIds.includes(stageId)) {
- existingJudge.stageIds.push(stageId)
- }
+ // 鏇存柊鐜版湁璇勫鐨勯樁娈碉紝鍚堝苟鏂伴�夋嫨鐨勯樁娈�
+ if (selectedStageOptions.value.length > 0) {
+ selectedStageOptions.value.forEach(stageId => {
+ const stageIdInt = parseInt(stageId)
+ if (!existingJudge.stageIds.includes(stageIdInt)) {
+ existingJudge.stageIds.push(stageIdInt)
+ }
+ })
}
} else {
- // 娣诲姞鏂拌瘎濮�
+ // 娣诲姞鏂拌瘎濮旓紝鍖呭惈鎵�鏈夐�夋嫨鐨勯樁娈�
+ const stageIds = selectedStageOptions.value.length > 0
+ ? selectedStageOptions.value.map(id => parseInt(id))
+ : []
+
const newJudge = {
id: judge.id,
name: judge.name,
- stageIds: selectedStageOption.value === 'all'
- ? form.value.stages.map(s => s.id).filter(id => id != null)
- : [parseInt(selectedStageOption.value)]
+ stageIds: stageIds
}
form.value.judges.push(newJudge)
addedCount++
}
}
})
+
+ // 娓呯┖閫夋嫨
+ selectedJudges.value = []
+ selectedStageOptions.value = []
judgeDialogVisible.value = false
ElMessage.success(`鎴愬姛娣诲姞 ${addedCount} 涓瘎濮擿)
@@ -882,7 +986,7 @@
}
const getLastStage = (student) => {
- if (!student.lastStageId || !form.value.stages) return '鏃�'
+ if (!student.lastStageId || !form.value || !form.value.stages) return '鏃�'
const stage = form.value.stages.find(s => s.id === student.lastStageId)
return stage ? stage.name : '鏃�'
}
@@ -927,13 +1031,17 @@
uploaded: false // 鏍囪涓烘湭涓婁紶
}
- form.value.mediaFiles.push(mediaFile)
- ElMessage.success('鏂囦欢宸查�夋嫨锛岀偣鍑绘洿鏂版寜閽椂灏嗕笂浼�')
+ if (form.value && form.value.mediaFiles) {
+ form.value.mediaFiles.push(mediaFile)
+ ElMessage.success('鏂囦欢宸查�夋嫨锛岀偣鍑绘洿鏂版寜閽椂灏嗕笂浼�')
+ }
return false // 闃绘el-upload鐨勯粯璁や笂浼�
}
const beforeMediaUpload = (file) => {
+ if (!form.value || !form.value.mediaFiles) return false
+
if (form.value.mediaFiles.length >= 3) {
ElMessage.error('鏈�澶氬彧鑳戒笂浼�3涓枃浠�!')
return false
@@ -998,6 +1106,10 @@
// 澶勭悊濯掍綋鏂囦欢涓婁紶
const handleMediaUpload = async (activityId) => {
+ if (!form.value || !form.value.mediaFiles) return
+
+ const failedFiles = []
+
try {
for (const mediaFile of form.value.mediaFiles) {
// 璺宠繃宸茬粡鏈� id 鐨勫獟浣撴枃浠讹紙宸蹭繚瀛樼殑锛�
@@ -1016,10 +1128,8 @@
}
try {
- console.log('寮�濮嬩笂浼犳枃浠�:', mediaFile.name)
// 1. 涓婁紶鏂囦欢鍒版湇鍔″櫒
const uploadResult = await uploadFile(mediaFile.file)
- console.log('鏂囦欢涓婁紶鎴愬姛:', uploadResult)
// 2. 淇濆瓨濯掍綋淇℃伅鍒版暟鎹簱
const mediaInput = {
@@ -1031,11 +1141,7 @@
targetType: MediaTargetType.ACTIVITY, // 娲诲姩
targetId: parseInt(activityId) // 杞崲涓烘暟瀛楃被鍨�
}
-
- console.log('鍑嗗淇濆瓨濯掍綋淇℃伅:', mediaInput)
- console.log('娲诲姩ID:', activityId)
const savedMedia = await saveMedia(mediaInput)
- console.log(`濯掍綋鏂囦欢 ${mediaFile.name} 涓婁紶骞朵繚瀛樻垚鍔�:`, savedMedia)
// 鏇存柊濯掍綋鏂囦欢淇℃伅
mediaFile.id = savedMedia.id
@@ -1046,28 +1152,41 @@
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 // 鎶涘嚭閿欒璁╀笂灞傚鐞�
}
}
// 鎻愪氦琛ㄥ崟
const handleSubmit = async () => {
if (submitting.value) return
+ if (!form.value) return
+
try {
await formRef.value.validate()
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 = {
- id: form.value.id,
- pid: form.value.pid || 0,
name: form.value.name,
description: form.value.description,
signupDeadline: form.value.signupDeadline,
@@ -1076,24 +1195,70 @@
ratingSchemeId: form.value.ratingSchemeId,
playerMax: form.value.playerMax,
state: form.value.state || 1,
- stages: form.value.stages ? form.value.stages.map(stage => ({
- id: stage.id,
- name: stage.name,
- description: stage.description,
- matchTime: stage.matchTime,
- address: stage.address,
- ratingSchemeId: stage.ratingSchemeId,
- playerMax: stage.playerMax,
- state: stage.state || 1
- })) : [],
- judges: form.value.judges ? form.value.judges.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('杩囨护鍚巗tages:', 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
+ }
+ // 鍙湪鏈夋湁鏁圛D鏃舵墠娣诲姞id瀛楁
+ if (stage.id) {
+ stageData.id = stage.id
+ }
+ // 鍙湪鏈夋湁鏁坮atingSchemeId鏃舵墠娣诲姞璇ュ瓧娈�
+ if (stage.ratingSchemeId) {
+ stageData.ratingSchemeId = stage.ratingSchemeId
+ }
+ console.log(`澶勭悊鍚巗tage ${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('杩囨护鍚巎udges:', filteredJudges)
+ return filteredJudges.map((judge, index) => {
+ console.log(`澶勭悊judge ${index}:`, judge)
+ const judgeData = {
+ judgeId: judge.id,
+ judgeName: judge.name,
+ stageIds: judge.stageIds || []
+ }
+ console.log(`澶勭悊鍚巎udge ${index}:`, judgeData)
+ return judgeData
+ })
+ })() : []
+ }
+
+ // 濡傛灉鏄紪杈戞ā寮忥紝娣诲姞id瀛楁
+ if (isEdit.value && form.value.id) {
+ saveData.id = form.value.id
+ }
+
+ // 濡傛灉鏈塸id锛屾坊鍔爌id瀛楁
+ if (form.value.pid) {
+ saveData.pid = form.value.pid
}
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鐨刬d
if (!isEdit.value && result && result.id) {
@@ -1101,23 +1266,48 @@
}
// 澶勭悊濯掍綋鏂囦欢涓婁紶鍜屼繚瀛�
+ let mediaUploadSuccess = true
if (form.value.mediaFiles && form.value.mediaFiles.length > 0) {
- const activityId = result.id || form.value.id
+ // 淇activityId鑾峰彇閫昏緫锛氫紭鍏堜娇鐢╮esult.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('鏈�缁坅ctivityId:', 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
@@ -1134,6 +1324,19 @@
await loadRatingSchemes()
await loadAllJudges()
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)
+ }
})
</script>
@@ -1169,7 +1372,7 @@
.stage-header {
display: flex;
- justify-content: space-between;
+ justify-content: flex-start;
align-items: center;
}
@@ -1271,11 +1474,32 @@
flex: 1;
}
+.stage-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 8px;
+}
+
+.stage-order {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ background-color: #409eff;
+ color: white;
+ border-radius: 50%;
+ font-size: 12px;
+ font-weight: 600;
+ flex-shrink: 0;
+}
+
.stage-name {
font-size: 16px;
font-weight: 500;
color: #303133;
- margin-bottom: 8px;
+ margin: 0;
+ margin-left: 4px;
}
.stage-details {
@@ -1487,4 +1711,24 @@
flex: 1;
padding-left: 8px;
}
+
+/* 濯掍綋鎻忚堪鏂囨湰鏍峰紡 */
+.media-description {
+ font-size: 12px;
+ color: #909399;
+ font-weight: normal;
+ margin-left: 8px;
+}
+
+/* 濯掍綋涓婁紶鎸夐挳 */
+.media-uploader-left {
+ margin-left: 16px;
+}
+
+.media-container {
+ display: flex;
+ align-items: flex-start;
+ gap: 16px;
+ flex-wrap: wrap;
+}
</style>
\ No newline at end of file
--
Gitblit v1.8.0