|
|
@@ -59,6 +59,19 @@
|
|
|
<span v-else></span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column label="比赛背景" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-image
|
|
|
+ v-if="scope.row.competitionBg"
|
|
|
+ :src="scope.row.competitionBg"
|
|
|
+ style="width: 40px; height: 40px; border-radius: 4px; cursor: zoom-in"
|
|
|
+ :preview-src-list="[scope.row.competitionBg]"
|
|
|
+ :preview-teleported="true"
|
|
|
+ fit="cover"
|
|
|
+ />
|
|
|
+ <span v-else></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<!-- <el-table-column label="开始时间" align="center" prop="startTime" width="150" sortable="custom"> </el-table-column>
|
|
|
<el-table-column label="结束时间" align="center" prop="endTime" width="150"> </el-table-column>-->
|
|
|
<el-table-column label="报名要求" align="center">
|
|
|
@@ -167,6 +180,50 @@
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <!-- 比赛图标 -->
|
|
|
+ <el-form-item label="比赛背景" prop="icon">
|
|
|
+ <div class="upload-container">
|
|
|
+ <el-upload
|
|
|
+ class="upload-icon"
|
|
|
+ action="#"
|
|
|
+ :on-change="handleIconChange2"
|
|
|
+ :on-remove="handleIconRemove2"
|
|
|
+ :file-list="fileList2"
|
|
|
+ :auto-upload="false"
|
|
|
+ :limit="1"
|
|
|
+ accept="image/*"
|
|
|
+ :disabled="dialog.mode === 'view'"
|
|
|
+ >
|
|
|
+ <template #trigger>
|
|
|
+ <el-button type="primary" :disabled="dialog.mode === 'view'">点击选择背景</el-button>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 预览图区域 -->
|
|
|
+ <template #default>
|
|
|
+ <div class="preview-area" @click="handlePreviewClick2">
|
|
|
+ <!-- 只有当 iconPreviewUrl 或 competitionIcon 存在时才显示 img -->
|
|
|
+ <img
|
|
|
+ v-if="iconPreviewUrl2 || competitionBg"
|
|
|
+ :src="iconPreviewUrl2 || competitionBg"
|
|
|
+ alt="预览图"
|
|
|
+ style="max-width: 100px; max-height: 100px; margin-top: 10px; cursor: pointer"
|
|
|
+ />
|
|
|
+ <!-- 可选:无图时显示提示文字 -->
|
|
|
+ <div v-else style="margin-top: 10px; color: #999"></div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip">
|
|
|
+ <span v-if="fileList2.length > 0">当前已选文件:{{ fileList2[0].name }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
<!-- 开始时间 -->
|
|
|
<!-- <el-form-item label="开始时间" prop="startTime">
|
|
|
<el-date-picker
|
|
|
@@ -255,7 +312,6 @@
|
|
|
<el-input v-model="form.delayCardNum" placeholder="请输入延迟卡数量" :disabled="dialog.mode === 'view'" />
|
|
|
</el-form-item>
|
|
|
|
|
|
-
|
|
|
<!-- 奖励内容 -->
|
|
|
<el-form-item label="奖励内容">
|
|
|
<div v-for="(reward, index) in formPrize.rewards" :key="index" style="display: flex; align-items: center; margin-bottom: 8px">
|
|
|
@@ -338,6 +394,11 @@
|
|
|
<el-dialog v-model="dialogVisible" title="图片预览" width="50%">
|
|
|
<img :src="previewSrc || iconPreviewUrl || competitionIcon" alt="预览图片" style="max-width: 100%; max-height: 80vh" />
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <el-dialog v-model="dialogVisible2" title="图片预览" width="50%">
|
|
|
+ <img :src="previewSrc2 || iconPreviewUrl2 || competitionBg" alt="预览图片" style="max-width: 100%; max-height: 80vh" />
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -395,10 +456,17 @@ const assignForm = reactive({
|
|
|
const dialogVisible = ref(false);
|
|
|
const previewSrc = ref('');
|
|
|
|
|
|
+const dialogVisible2 = ref(false);
|
|
|
+const previewSrc2 = ref('');
|
|
|
+
|
|
|
function openPreview(src: string) {
|
|
|
previewSrc.value = src;
|
|
|
dialogVisible.value = true;
|
|
|
}
|
|
|
+function openPreview2(src: string) {
|
|
|
+ previewSrc2.value = src;
|
|
|
+ dialogVisible2.value = true;
|
|
|
+}
|
|
|
|
|
|
// 控制 Dialog 是否显示
|
|
|
const levelsDialogVisible = ref(false);
|
|
|
@@ -533,6 +601,11 @@ const iconPreviewUrl = ref('');
|
|
|
const competitionIcon = ref('');
|
|
|
const fileList = ref([]);
|
|
|
|
|
|
+//预览图标需要
|
|
|
+const iconPreviewUrl2 = ref('');
|
|
|
+const competitionBg = ref('');
|
|
|
+const fileList2 = ref([]);
|
|
|
+
|
|
|
// 单选控制变量(用于绑定 el-radio)
|
|
|
const selectedRadio = ref<number | null>(null);
|
|
|
|
|
|
@@ -705,6 +778,9 @@ const cancel = () => {
|
|
|
// 清除预览图和临时链接
|
|
|
iconPreviewUrl.value = '';
|
|
|
competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
+
|
|
|
+ iconPreviewUrl2.value = '';
|
|
|
+ competitionBg.value = '';
|
|
|
dialog.visible = false;
|
|
|
};
|
|
|
|
|
|
@@ -741,6 +817,8 @@ const handleAdd = () => {
|
|
|
// 清除预览图和临时链接
|
|
|
iconPreviewUrl.value = '';
|
|
|
competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
+ iconPreviewUrl2.value = '';
|
|
|
+ competitionBg.value = '';
|
|
|
dialog.visible = true;
|
|
|
dialog.title = '创建自动比赛模版';
|
|
|
dialog.mode = 'edit'; // 设置模式
|
|
|
@@ -764,7 +842,7 @@ const handleUpdate = async (row?: TournamentsVO, mode: 'edit' | 'view' = 'edit')
|
|
|
Object.assign(form.value, res.data);
|
|
|
form.value.gameType = gameType; // 确保赋值正确
|
|
|
form.value.signTime = signTime;
|
|
|
-
|
|
|
+ competitionBg.value = res.data.competitionBg;
|
|
|
competitionIcon.value = res.data.competitionIcon;
|
|
|
// 处理奖励表单数据
|
|
|
const prizeItems = res.data.itemsPrizeList || [];
|
|
|
@@ -981,7 +1059,45 @@ const handleIconChange = async (file) => {
|
|
|
ElMessage.error('上传失败,请重试');
|
|
|
}
|
|
|
};
|
|
|
+const handleIconChange2 = async (file) => {
|
|
|
+ const index = fileList2.value.findIndex((f) => f.uid === file.uid);
|
|
|
+ fileList2.value = [];
|
|
|
+
|
|
|
+ if (file.raw) {
|
|
|
+ iconPreviewUrl2.value = URL.createObjectURL(file.raw);
|
|
|
+ }
|
|
|
|
|
|
+ if (index === -1) {
|
|
|
+ // 如果文件不在列表中,则添加进去
|
|
|
+ fileList2.value.push(file);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const rawFile = file.raw;
|
|
|
+ const res = await uploadTournament(rawFile);
|
|
|
+ if (res.code === 200) {
|
|
|
+ // 更新文件状态为成功
|
|
|
+ fileList2.value[index] = {
|
|
|
+ ...file,
|
|
|
+ status: 'success',
|
|
|
+ response: res.data.url
|
|
|
+ };
|
|
|
+ data.form.competitionBg = fileList2.value[index].response;
|
|
|
+ iconPreviewUrl2.value = fileList2.value[index].response;
|
|
|
+ ElMessage.success('上传成功');
|
|
|
+ } else {
|
|
|
+ throw new Error(res.msg);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ // 更新文件状态为失败
|
|
|
+ fileList2.value[index] = {
|
|
|
+ ...file,
|
|
|
+ status: 'fail',
|
|
|
+ error: '上传失败'
|
|
|
+ };
|
|
|
+ ElMessage.error('上传失败,请重试');
|
|
|
+ }
|
|
|
+};
|
|
|
const handleViewLevels = () => {
|
|
|
const blindStructureId = data.form.blindStructureId;
|
|
|
if (blindStructureId === null || blindStructureId === undefined) {
|
|
|
@@ -1007,7 +1123,21 @@ const handleIconRemove = (file, updatedFileList) => {
|
|
|
iconPreviewUrl.value = '';
|
|
|
competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
};
|
|
|
+// 点击预览图触发放大
|
|
|
+const handlePreviewClick2 = () => {
|
|
|
+ const currentSrc = iconPreviewUrl2.value || competitionBg.value;
|
|
|
+ if (currentSrc) {
|
|
|
+ dialogVisible2.value = true;
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
+// 删除文件处理函数
|
|
|
+const handleIconRemove2 = (file, updatedFileList) => {
|
|
|
+ fileList2.value = updatedFileList;
|
|
|
+ // 清除预览图和临时链接
|
|
|
+ iconPreviewUrl2.value = '';
|
|
|
+ competitionBg.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
+};
|
|
|
// 排序字段和顺序
|
|
|
const sortData = ref({
|
|
|
prop: 'startTime',
|