|
|
@@ -200,84 +200,30 @@
|
|
|
</el-form-item>-->
|
|
|
<!-- 比赛图标 -->
|
|
|
<el-form-item label="比赛图标" prop="competitionIcon">
|
|
|
- <div class="upload-container">
|
|
|
- <el-upload
|
|
|
- class="upload-icon"
|
|
|
- action="#"
|
|
|
- :on-change="handleIconChange"
|
|
|
- :on-remove="handleIconRemove"
|
|
|
- :file-list="fileList"
|
|
|
- :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="handlePreviewClick">
|
|
|
- <!-- 只有当 iconPreviewUrl 或 competitionIcon 存在时才显示 img -->
|
|
|
- <img
|
|
|
- v-if="iconPreviewUrl || competitionIcon"
|
|
|
- :src="iconPreviewUrl || competitionIcon"
|
|
|
- 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="fileList.length > 0">当前已选文件:{{ fileList[0].name }}</span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
+ <div class="icon-select-container">
|
|
|
+ <el-button type="primary" @click="openIconSelectDialog('icon')" :disabled="dialog.mode === 'view'">点击选择图标</el-button>
|
|
|
+ <div v-if="form.competitionIcon" class="preview-area" @click="handlePreviewIconClick">
|
|
|
+ <img
|
|
|
+ :src="form.competitionIcon"
|
|
|
+ alt="预览图"
|
|
|
+ style="max-width: 100px; max-height: 100px; margin-top: 10px; cursor: pointer; border-radius: 4px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-else style="margin-top: 10px; color: #999">未选择图标</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
- <!-- 比赛图标 -->
|
|
|
+ <!-- 比赛背景 -->
|
|
|
<el-form-item label="比赛背景" prop="competitionBg">
|
|
|
- <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 class="icon-select-container">
|
|
|
+ <el-button type="primary" @click="openIconSelectDialog('background')" :disabled="dialog.mode === 'view'">点击选择背景</el-button>
|
|
|
+ <div v-if="form.competitionBg" class="preview-area" @click="handlePreviewBgClick">
|
|
|
+ <img
|
|
|
+ :src="form.competitionBg"
|
|
|
+ alt="预览图"
|
|
|
+ style="max-width: 100px; max-height: 100px; margin-top: 10px; cursor: pointer; border-radius: 4px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-else style="margin-top: 10px; color: #999">未选择背景</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="报名时间" prop="startTime">
|
|
|
@@ -491,13 +437,18 @@
|
|
|
<!-- 使用 component 动态加载目标组件 -->
|
|
|
<levels-index :blind-structure-id="dialogParams.blindStructureId" :name="dialogParams.name" />
|
|
|
</el-dialog>
|
|
|
- <!-- 预览弹窗 -->
|
|
|
- <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 v-model="previewDialogVisible" title="图片预览" width="50%">
|
|
|
+ <img :src="previewDialogSrc" alt="预览图片" style="max-width: 100%; max-height: 80vh" />
|
|
|
</el-dialog>
|
|
|
+ <!-- 图片库选择组件 -->
|
|
|
+ <TournamentImageSelect
|
|
|
+ v-model="imageSelectVisible"
|
|
|
+ :default-type="imageSelectType"
|
|
|
+ :default-scene="'online'"
|
|
|
+ @confirm="handleImageSelectConfirm"
|
|
|
+ @cancel="handleImageSelectCancel"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -515,7 +466,6 @@ import { TournamentsVO, TournamentsQuery, TournamentsForm } from '@/api/system/p
|
|
|
import { selectItemsSelList, selectXianXiaItemsSelList } from '@/api/system/business/items';
|
|
|
import { selectPhysicalBlingStructuresInfo } from '@/api/system/physical/blindStructures';
|
|
|
import { selectPhysicalBlindLevelsById } from '@/api/system/physical/blindLevels';
|
|
|
-import { uploadTournament } from '@/api/system/business/tournaments';
|
|
|
import { selectPhysicalLeagueTournamentSelList } from '@/api/system/physical/leagueTournament';
|
|
|
import { selectPhysicalJudgeSelList } from '@/api/system/physical/judge';
|
|
|
import { selectCompetitionZoneSelList } from '@/api/system/physical/competitionZone';
|
|
|
@@ -783,14 +733,6 @@ const getList = async () => {
|
|
|
const cancel = () => {
|
|
|
reset();
|
|
|
resetFormPrize();
|
|
|
- fileList.value = [];
|
|
|
- fileList2.value = [];
|
|
|
- // 清除预览图和临时链接
|
|
|
- iconPreviewUrl.value = '';
|
|
|
- competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
-
|
|
|
- iconPreviewUrl2.value = '';
|
|
|
- competitionBg.value = '';
|
|
|
dialog.visible = false;
|
|
|
};
|
|
|
|
|
|
@@ -831,14 +773,6 @@ const handleSelectionChange = (selection: TournamentsVO[]) => {
|
|
|
const handleAdd = () => {
|
|
|
reset();
|
|
|
resetFormPrize();
|
|
|
- fileList.value = [];
|
|
|
- fileList2.value = [];
|
|
|
- // 清除预览图和临时链接
|
|
|
- iconPreviewUrl.value = '';
|
|
|
- competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
- iconPreviewUrl2.value = '';
|
|
|
- competitionBg.value = '';
|
|
|
-
|
|
|
form.value.leagueTournamentId = queryParams.value.leagueTournamentId ? Number(queryParams.value.leagueTournamentId) : undefined;
|
|
|
dialog.visible = true;
|
|
|
dialog.title = '创建比赛';
|
|
|
@@ -860,8 +794,7 @@ const handleUpdate = async (row?: TournamentsVO, mode: 'edit' | 'view' = 'edit')
|
|
|
form.value.gameType = String(res.data.gameType); // 转为字符串
|
|
|
form.value.gameVariant = String(res.data.gameVariant); // 转为字符串
|
|
|
form.value.qualifierType = String(res.data.qualifierType);
|
|
|
- competitionIcon.value = res.data.competitionIcon;
|
|
|
- competitionBg.value = res.data.competitionBg;
|
|
|
+ // competitionIcon 和 competitionBg 已通过 Object.assign 自动赋值到 form
|
|
|
// 处理报名条件数据
|
|
|
const conditionItems = res.data.itemsConditionList || [];
|
|
|
if (conditionItems.length > 0) {
|
|
|
@@ -1196,122 +1129,46 @@ const removeReward = (index: number) => {
|
|
|
const getRewardTooltipContent = (rewards: any[]) => {
|
|
|
return rewards.map((prize) => `第${prize.ranking}名:${prize.quantity} ${prize.itemsName}`).join('\n');
|
|
|
};
|
|
|
-//预览图标需要
|
|
|
-const iconPreviewUrl = ref('');
|
|
|
-const competitionIcon = ref('');
|
|
|
-const fileList = ref([]);
|
|
|
-const dialogVisible = ref(false);
|
|
|
-const previewSrc = ref('');
|
|
|
-const handleIconChange = async (file) => {
|
|
|
- const index = fileList.value.findIndex((f) => f.uid === file.uid);
|
|
|
- fileList.value = [];
|
|
|
-
|
|
|
- if (file.raw) {
|
|
|
- iconPreviewUrl.value = URL.createObjectURL(file.raw);
|
|
|
- }
|
|
|
-
|
|
|
- if (index === -1) {
|
|
|
- // 如果文件不在列表中,则添加进去
|
|
|
- fileList.value.push(file);
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- const rawFile = file.raw;
|
|
|
- const res = await uploadTournament(rawFile);
|
|
|
- if (res.code === 200) {
|
|
|
- // 更新文件状态为成功
|
|
|
- fileList.value[index] = {
|
|
|
- ...file,
|
|
|
- status: 'success',
|
|
|
- response: res.data.url
|
|
|
- };
|
|
|
- data.form.competitionIcon = fileList.value[index].response;
|
|
|
- iconPreviewUrl.value = fileList.value[index].response;
|
|
|
- ElMessage.success('上传成功');
|
|
|
- } else {
|
|
|
- throw new Error(res.msg);
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- // 更新文件状态为失败
|
|
|
- fileList.value[index] = {
|
|
|
- ...file,
|
|
|
- status: 'fail',
|
|
|
- error: '上传失败'
|
|
|
- };
|
|
|
- ElMessage.error('上传失败,请重试');
|
|
|
- }
|
|
|
-};
|
|
|
-// 删除文件处理函数
|
|
|
-const handleIconRemove = (file, updatedFileList) => {
|
|
|
- fileList.value = updatedFileList;
|
|
|
- // 清除预览图和临时链接
|
|
|
- iconPreviewUrl.value = '';
|
|
|
- competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
+// 图片库选择相关变量
|
|
|
+const imageSelectVisible = ref(false);
|
|
|
+const imageSelectType = ref<'icon' | 'background'>('icon');
|
|
|
+const previewDialogVisible = ref(false);
|
|
|
+const previewDialogSrc = ref('');
|
|
|
+
|
|
|
+// 打开图片选择对话框
|
|
|
+const openIconSelectDialog = (type: 'icon' | 'background') => {
|
|
|
+ imageSelectType.value = type;
|
|
|
+ imageSelectVisible.value = true;
|
|
|
};
|
|
|
-// 点击预览图触发放大
|
|
|
-const handlePreviewClick = () => {
|
|
|
- const currentSrc = iconPreviewUrl.value || competitionIcon.value;
|
|
|
- if (currentSrc) {
|
|
|
- dialogVisible.value = true;
|
|
|
+
|
|
|
+// 图片选择确认回调
|
|
|
+const handleImageSelectConfirm = (url: string) => {
|
|
|
+ if (imageSelectType.value === 'icon') {
|
|
|
+ form.value.competitionIcon = url;
|
|
|
+ } else {
|
|
|
+ form.value.competitionBg = url;
|
|
|
}
|
|
|
+ imageSelectVisible.value = false;
|
|
|
};
|
|
|
-//预览图标需要
|
|
|
-const iconPreviewUrl2 = ref('');
|
|
|
-const competitionBg = ref('');
|
|
|
-const fileList2 = ref([]);
|
|
|
-const dialogVisible2 = ref(false);
|
|
|
-const previewSrc2 = ref('');
|
|
|
-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);
|
|
|
- }
|
|
|
+// 图片选择取消回调
|
|
|
+const handleImageSelectCancel = () => {
|
|
|
+ imageSelectVisible.value = false;
|
|
|
+};
|
|
|
|
|
|
- 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 handlePreviewIconClick = () => {
|
|
|
+ if (form.value.competitionIcon) {
|
|
|
+ previewDialogSrc.value = form.value.competitionIcon;
|
|
|
+ previewDialogVisible.value = true;
|
|
|
}
|
|
|
};
|
|
|
-// 删除文件处理函数
|
|
|
-const handleIconRemove2 = (file, updatedFileList) => {
|
|
|
- fileList2.value = updatedFileList;
|
|
|
- // 清除预览图和临时链接
|
|
|
- iconPreviewUrl2.value = '';
|
|
|
- competitionBg.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
|
|
|
-};
|
|
|
-// 点击预览图触发放大
|
|
|
-const handlePreviewClick2 = () => {
|
|
|
- const currentSrc = iconPreviewUrl2.value || competitionBg.value;
|
|
|
- if (currentSrc) {
|
|
|
- dialogVisible2.value = true;
|
|
|
+
|
|
|
+// 预览背景点击
|
|
|
+const handlePreviewBgClick = () => {
|
|
|
+ if (form.value.competitionBg) {
|
|
|
+ previewDialogSrc.value = form.value.competitionBg;
|
|
|
+ previewDialogVisible.value = true;
|
|
|
}
|
|
|
};
|
|
|
/** 修改按钮操作 */
|
|
|
@@ -1332,8 +1189,7 @@ const handleCopy = async (row?: TournamentsVO) => {
|
|
|
form.value.delayCardNum = res.data.delayCardNum;
|
|
|
|
|
|
form.value.gameVariant = String(res.data.gameVariant); // 转为字符串
|
|
|
- competitionIcon.value = res.data.competitionIcon;
|
|
|
- competitionBg.value = res.data.competitionBg;
|
|
|
+ // competitionIcon 和 competitionBg 已通过 Object.assign 自动赋值到 form
|
|
|
// 处理报名条件数据
|
|
|
const conditionItems = res.data.itemsConditionList || [];
|
|
|
if (conditionItems.length > 0) {
|