fix bugs
This commit is contained in:
136
src/api/martial/attachment.js
Normal file
136
src/api/martial/attachment.js
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import request from '@/axios';
|
||||||
|
|
||||||
|
// ==================== 赛事附件管理接口 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件详情
|
||||||
|
* @param {Number} id - 附件ID
|
||||||
|
*/
|
||||||
|
export const getAttachmentDetail = (id) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/detail',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件列表查询(分页)
|
||||||
|
* @param {Number} current - 当前页
|
||||||
|
* @param {Number} size - 每页条数
|
||||||
|
* @param {Object} params - 查询参数
|
||||||
|
*/
|
||||||
|
export const getAttachmentList = (current, size, params) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/list',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
current,
|
||||||
|
size,
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据赛事ID和类型获取附件列表
|
||||||
|
* @param {Number} competitionId - 赛事ID
|
||||||
|
* @param {String} attachmentType - 附件类型:info-赛事发布, rules-赛事规程, schedule-活动日程, results-成绩, medals-奖牌榜, photos-图片直播
|
||||||
|
*/
|
||||||
|
export const getAttachmentsByType = (competitionId, attachmentType) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/getByType',
|
||||||
|
method: 'get',
|
||||||
|
params: { competitionId, attachmentType }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据赛事ID获取所有附件
|
||||||
|
* @param {Number} competitionId - 赛事ID
|
||||||
|
*/
|
||||||
|
export const getAttachmentsByCompetition = (competitionId) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/getByCompetition',
|
||||||
|
method: 'get',
|
||||||
|
params: { competitionId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改附件
|
||||||
|
* @param {Object} data - 附件数据
|
||||||
|
* @param {Number} data.id - ID(修改时必传)
|
||||||
|
* @param {Number} data.competitionId - 赛事ID
|
||||||
|
* @param {String} data.attachmentType - 附件类型
|
||||||
|
* @param {String} data.fileName - 文件名称
|
||||||
|
* @param {String} data.fileUrl - 文件URL
|
||||||
|
* @param {Number} data.fileSize - 文件大小(字节)
|
||||||
|
* @param {String} data.fileType - 文件类型(扩展名)
|
||||||
|
* @param {Number} data.orderNum - 排序序号
|
||||||
|
* @param {Number} data.status - 状态(1-启用 0-禁用)
|
||||||
|
*/
|
||||||
|
export const submitAttachment = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/submit',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存附件
|
||||||
|
* @param {Array} attachments - 附件列表
|
||||||
|
*/
|
||||||
|
export const batchSubmitAttachments = (attachments) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/batchSubmit',
|
||||||
|
method: 'post',
|
||||||
|
data: attachments
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除附件
|
||||||
|
* @param {String} ids - 附件ID,多个用逗号分隔
|
||||||
|
*/
|
||||||
|
export const removeAttachment = (ids) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/remove',
|
||||||
|
method: 'post',
|
||||||
|
params: { ids }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除赛事的指定类型附件
|
||||||
|
* @param {Number} competitionId - 赛事ID
|
||||||
|
* @param {String} attachmentType - 附件类型
|
||||||
|
*/
|
||||||
|
export const removeAttachmentByType = (competitionId, attachmentType) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/martial/competition/attachment/removeByType',
|
||||||
|
method: 'post',
|
||||||
|
params: { competitionId, attachmentType }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 附件类型常量
|
||||||
|
export const ATTACHMENT_TYPES = {
|
||||||
|
INFO: 'info', // 赛事发布
|
||||||
|
RULES: 'rules', // 赛事规程
|
||||||
|
SCHEDULE: 'schedule', // 活动日程
|
||||||
|
RESULTS: 'results', // 成绩
|
||||||
|
MEDALS: 'medals', // 奖牌榜
|
||||||
|
PHOTOS: 'photos' // 图片直播
|
||||||
|
}
|
||||||
|
|
||||||
|
// 附件类型标签映射
|
||||||
|
export const ATTACHMENT_TYPE_LABELS = {
|
||||||
|
info: '赛事发布',
|
||||||
|
rules: '赛事规程',
|
||||||
|
schedule: '活动日程',
|
||||||
|
results: '成绩',
|
||||||
|
medals: '奖牌榜',
|
||||||
|
photos: '图片直播'
|
||||||
|
}
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 活动日程 -->
|
<!-- 活动日程 -->
|
||||||
<div class="form-section">
|
<!-- <div class="form-section">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<i class="el-icon-date"></i>
|
<i class="el-icon-date"></i>
|
||||||
活动日程
|
活动日程
|
||||||
@@ -290,7 +290,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- 项目列表 -->
|
<!-- 项目列表 -->
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
|
|||||||
@@ -370,8 +370,134 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 活动日程 -->
|
<!-- 附件管理 -->
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
|
<div class="section-title">
|
||||||
|
<i class="el-icon-folder-opened"></i>
|
||||||
|
附件管理
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 附件类型选项卡 -->
|
||||||
|
<el-tabs v-model="activeAttachmentTab" type="card">
|
||||||
|
<el-tab-pane
|
||||||
|
v-for="tab in attachmentTabs"
|
||||||
|
:key="tab.type"
|
||||||
|
:label="tab.label"
|
||||||
|
:name="tab.type"
|
||||||
|
>
|
||||||
|
<div class="attachment-section">
|
||||||
|
<!-- 上传按钮 -->
|
||||||
|
<div class="attachment-upload" v-if="currentView !== 'view'">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-upload"
|
||||||
|
size="small"
|
||||||
|
@click="handleOpenAttachmentUpload(tab.type)"
|
||||||
|
>
|
||||||
|
上传{{ tab.label }}附件
|
||||||
|
</el-button>
|
||||||
|
<span class="upload-tip">支持 PDF、Word、Excel、图片等格式,单个文件不超过 50MB</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 附件列表 -->
|
||||||
|
<el-table
|
||||||
|
:data="formData.attachments[tab.type] || []"
|
||||||
|
border
|
||||||
|
style="width: 100%; margin-top: 15px;"
|
||||||
|
v-if="(formData.attachments[tab.type] || []).length > 0"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
label="文件名"
|
||||||
|
min-width="200"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="file-name-cell">
|
||||||
|
<i :class="getFileIcon(scope.row.fileType)" class="file-icon"></i>
|
||||||
|
<span>{{ scope.row.fileName }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="文件大小"
|
||||||
|
width="120"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatFileSize(scope.row.fileSize) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="上传时间"
|
||||||
|
width="180"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.createTime || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="排序"
|
||||||
|
width="100"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input-number
|
||||||
|
v-if="currentView !== 'view'"
|
||||||
|
v-model="scope.row.orderNum"
|
||||||
|
:min="0"
|
||||||
|
:max="999"
|
||||||
|
size="small"
|
||||||
|
style="width: 80px"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ scope.row.orderNum }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="操作"
|
||||||
|
width="150"
|
||||||
|
align="center"
|
||||||
|
fixed="right"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handlePreviewAttachment(scope.row)"
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="currentView !== 'view'"
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleDeleteAttachment(tab.type, scope.$index)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<div class="empty-attachment" v-else>
|
||||||
|
<i class="el-icon-folder-opened"></i>
|
||||||
|
<p>暂无{{ tab.label }}附件</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 活动日程 -->
|
||||||
|
<!-- <div class="form-section">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<i class="el-icon-date"></i>
|
<i class="el-icon-date"></i>
|
||||||
活动日程
|
活动日程
|
||||||
@@ -512,7 +638,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- 项目列表 -->
|
<!-- 项目列表 -->
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
@@ -781,6 +907,22 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 附件上传对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
title="上传附件"
|
||||||
|
v-model="attachmentUploadDialogVisible"
|
||||||
|
width="555px"
|
||||||
|
append-to-body
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<avue-form
|
||||||
|
ref="attachmentUploadForm"
|
||||||
|
:option="attachmentUploadOption"
|
||||||
|
v-model="attachmentUploadForm"
|
||||||
|
:upload-after="attachmentUploadAfter"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -806,6 +948,14 @@ import {
|
|||||||
removeVenue,
|
removeVenue,
|
||||||
getVenuesByCompetition
|
getVenuesByCompetition
|
||||||
} from '@/api/martial/venue'
|
} from '@/api/martial/venue'
|
||||||
|
import {
|
||||||
|
getAttachmentsByCompetition,
|
||||||
|
submitAttachment,
|
||||||
|
removeAttachment,
|
||||||
|
batchSubmitAttachments,
|
||||||
|
ATTACHMENT_TYPES,
|
||||||
|
ATTACHMENT_TYPE_LABELS
|
||||||
|
} from '@/api/martial/attachment'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CompetitionManagement',
|
name: 'CompetitionManagement',
|
||||||
@@ -820,6 +970,39 @@ export default {
|
|||||||
size: 10,
|
size: 10,
|
||||||
total: 0
|
total: 0
|
||||||
},
|
},
|
||||||
|
// 附件相关数据
|
||||||
|
activeAttachmentTab: 'info',
|
||||||
|
attachmentTabs: [
|
||||||
|
{ type: 'info', label: '赛事发布' },
|
||||||
|
{ type: 'rules', label: '赛事规程' },
|
||||||
|
{ type: 'schedule', label: '活动日程' },
|
||||||
|
{ type: 'results', label: '成绩' },
|
||||||
|
{ type: 'medals', label: '奖牌榜' },
|
||||||
|
{ type: 'photos', label: '图片直播' }
|
||||||
|
],
|
||||||
|
attachmentUploadDialogVisible: false,
|
||||||
|
currentAttachmentType: '',
|
||||||
|
attachmentUploadForm: {},
|
||||||
|
attachmentUploadOption: {
|
||||||
|
submitBtn: false,
|
||||||
|
emptyBtn: false,
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '附件上传',
|
||||||
|
prop: 'attachmentFile',
|
||||||
|
type: 'upload',
|
||||||
|
drag: true,
|
||||||
|
loadText: '文件上传中,请稍等',
|
||||||
|
span: 24,
|
||||||
|
accept: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png,.gif,.zip,.rar',
|
||||||
|
tip: '支持 PDF、Word、Excel、PPT、图片、压缩包等格式,单个文件不超过 50MB',
|
||||||
|
propsHttp: {
|
||||||
|
res: 'data',
|
||||||
|
},
|
||||||
|
action: '/blade-resource/oss/endpoint/put-file'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
formData: {
|
formData: {
|
||||||
competitionName: '',
|
competitionName: '',
|
||||||
competitionCode: '', // 比赛编码
|
competitionCode: '', // 比赛编码
|
||||||
@@ -840,7 +1023,15 @@ export default {
|
|||||||
awards: '',
|
awards: '',
|
||||||
schedule: [],
|
schedule: [],
|
||||||
projects: [],
|
projects: [],
|
||||||
venues: []
|
venues: [],
|
||||||
|
attachments: {
|
||||||
|
info: [],
|
||||||
|
rules: [],
|
||||||
|
schedule: [],
|
||||||
|
results: [],
|
||||||
|
medals: [],
|
||||||
|
photos: []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
formRules: {
|
formRules: {
|
||||||
competitionName: [
|
competitionName: [
|
||||||
@@ -988,10 +1179,11 @@ export default {
|
|||||||
try {
|
try {
|
||||||
this.formData = this.formatBackendData(detailData);
|
this.formData = this.formatBackendData(detailData);
|
||||||
console.log('格式化后的表单数据:', this.formData);
|
console.log('格式化后的表单数据:', this.formData);
|
||||||
// 加载关联数据:活动日程、项目列表、场地配置
|
// 加载关联数据:活动日程、项目列表、场地配置、附件
|
||||||
this.loadActivitySchedules();
|
this.loadActivitySchedules();
|
||||||
this.loadProjects();
|
this.loadProjects();
|
||||||
this.loadVenues();
|
this.loadVenues();
|
||||||
|
this.loadAttachments();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('格式化数据时出错:', error);
|
console.error('格式化数据时出错:', error);
|
||||||
this.$message.error('数据格式化失败: ' + error.message);
|
this.$message.error('数据格式化失败: ' + error.message);
|
||||||
@@ -1154,6 +1346,212 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 加载附件列表
|
||||||
|
loadAttachments() {
|
||||||
|
if (!this.competitionId) {
|
||||||
|
console.warn('loadAttachments: competitionId 为空,跳过加载');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('开始加载附件列表,competitionId:', this.competitionId);
|
||||||
|
getAttachmentsByCompetition(this.competitionId)
|
||||||
|
.then(res => {
|
||||||
|
console.log('附件列表返回数据:', res);
|
||||||
|
const responseData = res.data?.data;
|
||||||
|
|
||||||
|
// 初始化附件对象
|
||||||
|
const attachments = {
|
||||||
|
info: [],
|
||||||
|
rules: [],
|
||||||
|
schedule: [],
|
||||||
|
results: [],
|
||||||
|
medals: [],
|
||||||
|
photos: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (responseData && Array.isArray(responseData)) {
|
||||||
|
// 按类型分组
|
||||||
|
responseData.forEach(item => {
|
||||||
|
const type = item.attachmentType;
|
||||||
|
if (attachments[type]) {
|
||||||
|
attachments[type].push({
|
||||||
|
id: item.id,
|
||||||
|
fileName: item.fileName,
|
||||||
|
fileUrl: item.fileUrl,
|
||||||
|
fileSize: item.fileSize,
|
||||||
|
fileType: item.fileType,
|
||||||
|
orderNum: item.orderNum || 0,
|
||||||
|
createTime: item.createTime
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('✅ 加载的附件列表:', attachments);
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ 附件列表为空');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.formData.attachments = attachments;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('❌ 加载附件列表失败:', err);
|
||||||
|
// 不显示错误消息,因为可能是新建赛事还没有附件
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 打开附件上传对话框
|
||||||
|
handleOpenAttachmentUpload(type) {
|
||||||
|
this.currentAttachmentType = type;
|
||||||
|
this.attachmentUploadForm = {};
|
||||||
|
this.attachmentUploadDialogVisible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 附件上传成功回调
|
||||||
|
attachmentUploadAfter(res, done, loading, column) {
|
||||||
|
console.log('附件上传响应:', res);
|
||||||
|
|
||||||
|
if (res && (res.link || res.url)) {
|
||||||
|
const fileUrl = res.link || res.url;
|
||||||
|
const fileName = res.originalName || res.name || this.getFileNameFromUrl(fileUrl);
|
||||||
|
const fileType = this.getFileExtension(fileName);
|
||||||
|
const fileSize = res.size || 0;
|
||||||
|
|
||||||
|
// 添加到对应类型的附件列表
|
||||||
|
if (!this.formData.attachments[this.currentAttachmentType]) {
|
||||||
|
this.formData.attachments[this.currentAttachmentType] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.formData.attachments[this.currentAttachmentType].push({
|
||||||
|
fileName: fileName,
|
||||||
|
fileUrl: fileUrl,
|
||||||
|
fileSize: fileSize,
|
||||||
|
fileType: fileType,
|
||||||
|
orderNum: this.formData.attachments[this.currentAttachmentType].length,
|
||||||
|
isNew: true // 标记为新上传的附件
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$message.success('附件上传成功');
|
||||||
|
this.attachmentUploadDialogVisible = false;
|
||||||
|
} else {
|
||||||
|
this.$message.error('上传失败,未获取到文件地址');
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 预览附件
|
||||||
|
handlePreviewAttachment(attachment) {
|
||||||
|
if (!attachment.fileUrl) {
|
||||||
|
this.$message.warning('文件地址不存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.open(attachment.fileUrl, '_blank');
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除附件
|
||||||
|
handleDeleteAttachment(type, index) {
|
||||||
|
this.$confirm('确定要删除该附件吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const attachment = this.formData.attachments[type][index];
|
||||||
|
|
||||||
|
// 如果是已保存的附件,需要调用后端删除
|
||||||
|
if (attachment.id) {
|
||||||
|
removeAttachment(attachment.id.toString())
|
||||||
|
.then(() => {
|
||||||
|
this.formData.attachments[type].splice(index, 1);
|
||||||
|
this.$message.success('删除成功');
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('删除附件失败:', err);
|
||||||
|
this.$message.error('删除失败');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 新上传的附件直接从列表中移除
|
||||||
|
this.formData.attachments[type].splice(index, 1);
|
||||||
|
this.$message.success('删除成功');
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取文件图标
|
||||||
|
getFileIcon(fileType) {
|
||||||
|
const iconMap = {
|
||||||
|
'pdf': 'el-icon-document',
|
||||||
|
'doc': 'el-icon-document',
|
||||||
|
'docx': 'el-icon-document',
|
||||||
|
'xls': 'el-icon-document',
|
||||||
|
'xlsx': 'el-icon-document',
|
||||||
|
'ppt': 'el-icon-document',
|
||||||
|
'pptx': 'el-icon-document',
|
||||||
|
'jpg': 'el-icon-picture',
|
||||||
|
'jpeg': 'el-icon-picture',
|
||||||
|
'png': 'el-icon-picture',
|
||||||
|
'gif': 'el-icon-picture',
|
||||||
|
'zip': 'el-icon-folder',
|
||||||
|
'rar': 'el-icon-folder'
|
||||||
|
};
|
||||||
|
return iconMap[fileType?.toLowerCase()] || 'el-icon-document';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化文件大小
|
||||||
|
formatFileSize(bytes) {
|
||||||
|
if (!bytes || bytes === 0) return '0 B';
|
||||||
|
if (typeof bytes === 'string') return bytes;
|
||||||
|
|
||||||
|
const k = 1024;
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
return (bytes / Math.pow(k, i)).toFixed(1) + ' ' + sizes[i];
|
||||||
|
},
|
||||||
|
|
||||||
|
// 从URL获取文件名
|
||||||
|
getFileNameFromUrl(url) {
|
||||||
|
if (!url) return 'unknown';
|
||||||
|
const parts = url.split('/');
|
||||||
|
return parts[parts.length - 1] || 'unknown';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取文件扩展名
|
||||||
|
getFileExtension(fileName) {
|
||||||
|
if (!fileName) return '';
|
||||||
|
const parts = fileName.split('.');
|
||||||
|
return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// 保存附件
|
||||||
|
async saveAttachments(competitionId) {
|
||||||
|
const allAttachments = [];
|
||||||
|
|
||||||
|
// 收集所有需要保存的附件
|
||||||
|
for (const type of Object.keys(this.formData.attachments)) {
|
||||||
|
const attachments = this.formData.attachments[type] || [];
|
||||||
|
for (const attachment of attachments) {
|
||||||
|
// 只保存新上传的附件或已修改的附件
|
||||||
|
if (attachment.isNew || attachment.isModified) {
|
||||||
|
allAttachments.push({
|
||||||
|
id: attachment.id || null,
|
||||||
|
competitionId: competitionId,
|
||||||
|
attachmentType: type,
|
||||||
|
fileName: attachment.fileName,
|
||||||
|
fileUrl: attachment.fileUrl,
|
||||||
|
fileSize: attachment.fileSize,
|
||||||
|
fileType: attachment.fileType,
|
||||||
|
orderNum: attachment.orderNum || 0,
|
||||||
|
status: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allAttachments.length === 0) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('准备保存的附件:', allAttachments);
|
||||||
|
return batchSubmitAttachments(allAttachments);
|
||||||
|
},
|
||||||
|
|
||||||
getStatusText(status) {
|
getStatusText(status) {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
1: '未开始',
|
1: '未开始',
|
||||||
@@ -1311,6 +1709,9 @@ export default {
|
|||||||
savePromises.push(this.saveVenues(savedCompetitionId));
|
savePromises.push(this.saveVenues(savedCompetitionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. 保存附件
|
||||||
|
savePromises.push(this.saveAttachments(savedCompetitionId));
|
||||||
|
|
||||||
// 等待所有保存操作完成
|
// 等待所有保存操作完成
|
||||||
if (savePromises.length > 0) {
|
if (savePromises.length > 0) {
|
||||||
Promise.all(savePromises)
|
Promise.all(savePromises)
|
||||||
@@ -1498,7 +1899,15 @@ export default {
|
|||||||
awards: '',
|
awards: '',
|
||||||
schedule: [],
|
schedule: [],
|
||||||
projects: [],
|
projects: [],
|
||||||
venues: []
|
venues: [],
|
||||||
|
attachments: {
|
||||||
|
info: [],
|
||||||
|
rules: [],
|
||||||
|
schedule: [],
|
||||||
|
results: [],
|
||||||
|
medals: [],
|
||||||
|
photos: []
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1789,4 +2198,55 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 附件管理样式
|
||||||
|
.attachment-section {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-upload {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
|
||||||
|
.upload-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.file-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-attachment {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 40px 0;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__content) {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 活动日程 -->
|
<!-- 活动日程 -->
|
||||||
<div class="form-section">
|
<!-- <div class="form-section">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<i class="el-icon-date"></i>
|
<i class="el-icon-date"></i>
|
||||||
活动日程
|
活动日程
|
||||||
@@ -386,7 +386,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div> -->
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
|
|||||||
Reference in New Issue
Block a user