|
|
@@ -368,7 +368,7 @@
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
- prop="informationType"
|
|
|
+ prop="formatRequired"
|
|
|
label="资料类型"
|
|
|
width="130"
|
|
|
align="center"
|
|
|
@@ -377,15 +377,15 @@
|
|
|
<span v-if="!scope.row.isCategoryHeader">
|
|
|
<span
|
|
|
v-if="
|
|
|
- scope.row.informationType !== null &&
|
|
|
- scope.row.informationType !== undefined
|
|
|
+ scope.row.formatRequired !== null &&
|
|
|
+ scope.row.formatRequired !== undefined
|
|
|
"
|
|
|
>
|
|
|
{{
|
|
|
getDictName(
|
|
|
- 'materialType',
|
|
|
- String(scope.row.informationType)
|
|
|
- ) || scope.row.informationType
|
|
|
+ 'formatAsk',
|
|
|
+ String(scope.row.formatRequired)
|
|
|
+ ) || scope.row.formatRequired
|
|
|
}}
|
|
|
</span>
|
|
|
<span v-else>-</span>
|
|
|
@@ -412,7 +412,7 @@
|
|
|
>
|
|
|
<template slot-scope="scope">
|
|
|
<span v-if="!scope.row.isCategoryHeader">
|
|
|
- <span v-if="scope.row.isUploaded === '1'">已上传</span>
|
|
|
+ <span v-if="scope.row.isUploaded === true">已上传</span>
|
|
|
<span v-else class="text-danger">未上传</span>
|
|
|
</span>
|
|
|
</template>
|
|
|
@@ -425,7 +425,7 @@
|
|
|
>
|
|
|
<template slot-scope="scope">
|
|
|
<template v-if="!scope.row.isCategoryHeader">
|
|
|
- <template v-if="scope.row.isUploaded === '1'">
|
|
|
+ <template v-if="scope.row.formatRequired !== '3'">
|
|
|
<el-button
|
|
|
type="text"
|
|
|
size="small"
|
|
|
@@ -441,6 +441,7 @@
|
|
|
下载
|
|
|
</el-button>
|
|
|
<el-button
|
|
|
+ v-if="scope.row.isUploaded === false"
|
|
|
type="text"
|
|
|
size="small"
|
|
|
@click="handleFileUpload(scope.row)"
|
|
|
@@ -448,32 +449,23 @@
|
|
|
上传
|
|
|
</el-button>
|
|
|
</template>
|
|
|
- <template v-else>
|
|
|
- <template
|
|
|
- v-if="
|
|
|
- getDictName(
|
|
|
- 'materialType',
|
|
|
- String(scope.row.informationType)
|
|
|
- ) === '预置模版' ||
|
|
|
- scope.row.informationType === '预置模版'
|
|
|
- "
|
|
|
+ <template v-if="scope.row.formatRequired == '3'">
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ size="small"
|
|
|
+ @click="handleTemplateDownload(scope.row)"
|
|
|
>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="small"
|
|
|
- @click="handleTemplateDownload(scope.row)"
|
|
|
- >
|
|
|
- 模版下载
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="small"
|
|
|
- @click="handleDataUpload(scope.row)"
|
|
|
- >
|
|
|
- 数据上传
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
+ 模版下载
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.isUploaded === false"
|
|
|
+ type="text"
|
|
|
+ size="small"
|
|
|
+ @click="handleDataUpload(scope.row)"
|
|
|
+ >
|
|
|
+ 数据上传
|
|
|
+ </el-button>
|
|
|
+ <!-- <template v-else>
|
|
|
<el-button
|
|
|
type="text"
|
|
|
size="small"
|
|
|
@@ -481,123 +473,12 @@
|
|
|
>
|
|
|
上传
|
|
|
</el-button>
|
|
|
- </template>
|
|
|
+ </template> -->
|
|
|
</template>
|
|
|
</template>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
-
|
|
|
- <!-- <template slot="default">
|
|
|
- <template
|
|
|
- v-if="
|
|
|
- formData.dataRequirements.categories &&
|
|
|
- formData.dataRequirements.categories.length
|
|
|
- "
|
|
|
- >
|
|
|
- <template
|
|
|
- v-for="category in formData.dataRequirements.categories"
|
|
|
- >
|
|
|
- <tr :key="`category-${category.categoryId}`">
|
|
|
- <td
|
|
|
- colspan="6"
|
|
|
- style="
|
|
|
- background-color: #f5f7fa;
|
|
|
- font-weight: 700;
|
|
|
- padding-left: 16px;
|
|
|
- "
|
|
|
- >
|
|
|
- {{ category.name }}
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- <tr
|
|
|
- v-for="(item, itemKey) in category.items"
|
|
|
- :key="`${category.categoryId}-${itemKey}`"
|
|
|
- >
|
|
|
- <td align="center">{{ item.seq }}</td>
|
|
|
- <td>{{ item.name || '-' }}</td>
|
|
|
- <td align="center">{{ item.type }}</td>
|
|
|
- <td align="center">
|
|
|
- <span
|
|
|
- :style="{
|
|
|
- color: item.required === '是' ? '#f56c6c' : '#67c23a',
|
|
|
- }"
|
|
|
- >
|
|
|
- {{ item.required }}
|
|
|
- </span>
|
|
|
- </td>
|
|
|
- <td align="center">
|
|
|
- <span
|
|
|
- :style="{
|
|
|
- color: item.uploaded ? '#67c23a' : '#909399',
|
|
|
- }"
|
|
|
- >
|
|
|
- {{ item.uploaded ? '已上传' : '未上传' }}
|
|
|
- </span>
|
|
|
- </td>
|
|
|
- <td align="center">
|
|
|
- <template v-if="item.uploaded">
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleFileView(item)"
|
|
|
- >
|
|
|
- 查看
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleFileDownload(item)"
|
|
|
- >
|
|
|
- 下载
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleFileUpload(item)"
|
|
|
- >
|
|
|
- 上传
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <template v-if="item.type === '预置模版'">
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleTemplateDownload(item)"
|
|
|
- >
|
|
|
- 模版下载
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleDataUpload(item)"
|
|
|
- >
|
|
|
- 数据上传
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- @click="handleFileUpload(item)"
|
|
|
- >
|
|
|
- 上传
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <tr>
|
|
|
- <td colspan="6" align="center" style="padding: 30px 0">
|
|
|
- 暂无报送资料要求
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </template>
|
|
|
- </template> -->
|
|
|
</el-tab-pane>
|
|
|
<!-- 成本调查表 -->
|
|
|
<el-tab-pane label="成本调查表" name="costSurvey">
|
|
|
@@ -657,10 +538,11 @@
|
|
|
<template slot-scope="scope">
|
|
|
<span
|
|
|
:style="{
|
|
|
- color: scope.row.isUploaded ? '#67c23a' : '#f56c6c',
|
|
|
+ color:
|
|
|
+ scope.row.isUploaded === true ? '#67c23a' : '#f56c6c',
|
|
|
}"
|
|
|
>
|
|
|
- {{ scope.row.isUploaded ? '已上传' : '未上传' }}
|
|
|
+ {{ scope.row.isUploaded === true ? '已上传' : '未上传' }}
|
|
|
</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -875,24 +757,54 @@
|
|
|
style="width: 100%"
|
|
|
></el-input>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="资料要求" prop="informationRequire">
|
|
|
+ <el-form-item label="资料要求:" prop="informationRequire">
|
|
|
+ <el-input
|
|
|
+ v-model="materialForm.informationRequire"
|
|
|
+ placeholder="请输入资料要求"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="格式要求:" prop="formatRequired">
|
|
|
+ <el-select
|
|
|
+ v-model="materialForm.formatRequired"
|
|
|
+ placeholder="请选择格式要求"
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in dictData['formatAsk']"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.key"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="上传附件:" prop="fileList">
|
|
|
<el-upload
|
|
|
class="upload-demo"
|
|
|
- action="#"
|
|
|
- :on-preview="handleMaterialPreview"
|
|
|
+ :action="''"
|
|
|
+ :http-request="handleMaterialUpload"
|
|
|
:on-remove="handleMaterialRemove"
|
|
|
:before-upload="beforeMaterialUpload"
|
|
|
+ :on-success="handleMaterialUploadSuccess"
|
|
|
+ :on-error="handleMaterialUploadError"
|
|
|
+ :on-progress="handleMaterialUploadProgress"
|
|
|
:file-list="materialForm.fileList"
|
|
|
multiple
|
|
|
- :limit="5"
|
|
|
+ :limit="1"
|
|
|
:on-exceed="handleMaterialExceed"
|
|
|
>
|
|
|
<el-button size="small" type="primary">选择文件</el-button>
|
|
|
- <div slot="tip" class="el-upload__tip">
|
|
|
- 最多上传5个文件,支持所有格式
|
|
|
- </div>
|
|
|
+ <!-- <div slot="tip" class="el-upload__tip">
|
|
|
+ 最多上传5个文件,支持 pdf, doc, docx, xls, xlsx, csv 格式,单个文件不超过50MB
|
|
|
+ </div> -->
|
|
|
</el-upload>
|
|
|
</el-form-item>
|
|
|
+ <!-- <el-button
|
|
|
+ type="text"
|
|
|
+ size="mini"
|
|
|
+ @click="handleMaterialUpload"
|
|
|
+ >
|
|
|
+ 上传附件
|
|
|
+ </el-button> -->
|
|
|
</el-form>
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
<el-button type="primary" @click="handleMaterialSubmit">
|
|
|
@@ -927,6 +839,7 @@
|
|
|
import { getDefaultDem, getOrgListByDemId } from '@/api/annualReviewPlan'
|
|
|
import { getAllUserList } from '@/api/uc'
|
|
|
import { dictMixin } from '@/mixins/useDict'
|
|
|
+ import { uploadFile } from '@/api/file'
|
|
|
|
|
|
export default {
|
|
|
name: 'TaskFillIn',
|
|
|
@@ -946,8 +859,9 @@
|
|
|
attributionYear: [], // 归属年度
|
|
|
projectProposal: [], // 立项来源
|
|
|
auditType: [], //监审形式
|
|
|
- materialType: [], // 资料类型
|
|
|
+ materialType: [], // 资料类别
|
|
|
materialCategory: [], // 资料类别
|
|
|
+ formatAsk: [], // 资料类型
|
|
|
},
|
|
|
// 立项依据文件列表
|
|
|
accordingFileList: [],
|
|
|
@@ -1179,7 +1093,9 @@
|
|
|
informationType: '',
|
|
|
informationName: '',
|
|
|
informationRequire: '',
|
|
|
+ formatRequired: '',
|
|
|
fileList: [],
|
|
|
+ fileUrl: '',
|
|
|
},
|
|
|
materialRules: {
|
|
|
informationType: [
|
|
|
@@ -1188,6 +1104,12 @@
|
|
|
informationName: [
|
|
|
{ required: true, message: '请输入资料名称', trigger: 'blur' },
|
|
|
],
|
|
|
+ formatRequired: [
|
|
|
+ { required: true, message: '请选择格式要求', trigger: 'change' },
|
|
|
+ ],
|
|
|
+ informationRequire: [
|
|
|
+ { required: true, message: '请输入资料要求', trigger: 'blur' },
|
|
|
+ ],
|
|
|
},
|
|
|
materialCategoryOptions: [
|
|
|
{ label: '综合性资料', value: 'comprehensive' },
|
|
|
@@ -1442,6 +1364,7 @@
|
|
|
console.log('提交成功', res)
|
|
|
if (res && res.code === 200) {
|
|
|
Message.success('提交成功')
|
|
|
+ this.handleBack()
|
|
|
} else {
|
|
|
Message.error('提交失败')
|
|
|
}
|
|
|
@@ -1501,9 +1424,98 @@
|
|
|
console.log('下载文件:', row)
|
|
|
// 实际开发中可添加文件下载逻辑(如调用后端下载接口)
|
|
|
},
|
|
|
- handleFileUpload(row) {
|
|
|
- console.log('上传文件:', row)
|
|
|
- // 实际开发中可添加文件上传逻辑(如打开上传弹窗、调用上传接口)
|
|
|
+ // 报送资料文件上传
|
|
|
+ async handleFileUpload(row) {
|
|
|
+ // 创建文件选择器
|
|
|
+ const input = document.createElement('input')
|
|
|
+ input.type = 'file'
|
|
|
+ input.accept = '.pdf,.doc,.docx,.xls,.xlsx,.csv' // 允许的文件类型
|
|
|
+
|
|
|
+ input.onchange = async (event) => {
|
|
|
+ const file = event.target.files[0]
|
|
|
+ if (!file) return
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 校验文件大小(50MB)
|
|
|
+ const maxSize = 50 * 1024 * 1024 // 50MB
|
|
|
+ if (file.size > maxSize) {
|
|
|
+ this.$message.error('文件大小不能超过50MB!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验文件格式
|
|
|
+ const allowedFormats = [
|
|
|
+ '.pdf',
|
|
|
+ '.doc',
|
|
|
+ '.docx',
|
|
|
+ '.xls',
|
|
|
+ '.xlsx',
|
|
|
+ '.csv',
|
|
|
+ ]
|
|
|
+ const fileName = file.name.toLowerCase()
|
|
|
+ const isValidFormat = allowedFormats.some((format) =>
|
|
|
+ fileName.endsWith(format)
|
|
|
+ )
|
|
|
+
|
|
|
+ if (!isValidFormat) {
|
|
|
+ this.$message.error(
|
|
|
+ '只允许上传.pdf,.doc,.docx,.xls,.xlsx,.csv格式的文件!'
|
|
|
+ )
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示上传加载提示
|
|
|
+ const loading = this.$baseLoading(1, '文件上传中...')
|
|
|
+
|
|
|
+ // 创建FormData并上传文件
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', file)
|
|
|
+
|
|
|
+ // 调用上传API
|
|
|
+ const uploadRes = await uploadFile('/api/file/v1/upload', formData)
|
|
|
+
|
|
|
+ // 检查上传结果
|
|
|
+ if (!uploadRes || uploadRes.code !== 200 || !uploadRes.value) {
|
|
|
+ loading.close()
|
|
|
+ this.$message.error('文件上传失败,请稍后重试')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件上传成功后,更新报送资料项
|
|
|
+ const fileInfo = uploadRes.value
|
|
|
+ const updateData = {
|
|
|
+ // id: row.id,
|
|
|
+ // taskId: this.taskId,
|
|
|
+ // projectId: this.projectId,
|
|
|
+ // informationType: row.informationType,
|
|
|
+ // informationName: row.informationName,
|
|
|
+ // informationRequire: row.informationRequire,
|
|
|
+ // formatRequired: row.formatRequired,
|
|
|
+ // isRequired: row.isRequired,
|
|
|
+ ...row,
|
|
|
+ fileUrl: fileInfo.savePath || fileInfo.url, // 更新文件URL
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调用更新API
|
|
|
+ const updateRes = await addOrUpdateTaskRequirement(updateData)
|
|
|
+
|
|
|
+ loading.close()
|
|
|
+
|
|
|
+ if (updateRes && updateRes.code === 200) {
|
|
|
+ this.$message.success('文件上传并更新成功!')
|
|
|
+ // 刷新报送资料列表
|
|
|
+ this.getTaskRequirementPage()
|
|
|
+ } else {
|
|
|
+ this.$message.error('文件上传成功,但更新资料失败')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('文件上传失败:', error)
|
|
|
+ this.$message.error('操作失败:' + (error.message || '未知错误'))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 触发文件选择
|
|
|
+ input.click()
|
|
|
},
|
|
|
handleTemplateDownload(row) {
|
|
|
console.log('下载预置模版:', row)
|
|
|
@@ -1563,7 +1575,9 @@
|
|
|
informationType: '',
|
|
|
informationName: '',
|
|
|
informationRequire: '',
|
|
|
+ formatRequired: '',
|
|
|
fileList: [],
|
|
|
+ fileUrl: '',
|
|
|
}
|
|
|
if (this.$refs.materialForm) {
|
|
|
this.$refs.materialForm.resetFields()
|
|
|
@@ -1582,9 +1596,30 @@
|
|
|
if (valid) {
|
|
|
// 这里可以添加提交逻辑
|
|
|
console.log('补充材料表单数据:', this.materialForm)
|
|
|
- Message.success('补充材料提交成功')
|
|
|
- this.materialDialogVisible = false
|
|
|
- this.resetMaterialForm()
|
|
|
+ addOrUpdateTaskRequirement({
|
|
|
+ taskId: this.taskId,
|
|
|
+ projectId: this.projectId,
|
|
|
+ informationType: this.materialForm.informationType,
|
|
|
+ informationName: this.materialForm.informationName,
|
|
|
+ informationRequire: this.materialForm.informationRequire,
|
|
|
+ formatRequired: this.materialForm.formatRequired,
|
|
|
+ fileUrl: this.materialForm.fileUrl,
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ console.log('补充材料提交成功', res)
|
|
|
+ if (res && res.code === 200) {
|
|
|
+ Message.success('补充材料提交成功')
|
|
|
+ this.materialDialogVisible = false
|
|
|
+ this.resetMaterialForm()
|
|
|
+ this.getTaskRequirementPage()
|
|
|
+ } else {
|
|
|
+ Message.error('补充材料提交失败')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.error('补充材料提交失败', err)
|
|
|
+ Message.error('补充材料提交失败')
|
|
|
+ })
|
|
|
} else {
|
|
|
Message.error('请完善表单信息')
|
|
|
return false
|
|
|
@@ -1592,28 +1627,245 @@
|
|
|
})
|
|
|
},
|
|
|
|
|
|
- // 文件上传相关方法
|
|
|
- handleMaterialPreview(file) {
|
|
|
- console.log('预览文件:', file)
|
|
|
- },
|
|
|
+ // 上传
|
|
|
+ // handleMaterialUpload(row, type) {
|
|
|
+ // let loading = null
|
|
|
+ // // 第一步:创建文件选择器
|
|
|
+ // const input = document.createElement('input')
|
|
|
+ // input.type = 'file'
|
|
|
+ // input.accept = '.pdf,.doc,.docx,.xls,.xlsx,.csv' // 允许的文件类型
|
|
|
|
|
|
- handleMaterialRemove(file, fileList) {
|
|
|
- console.log('移除文件:', file, fileList)
|
|
|
- this.materialForm.fileList = fileList
|
|
|
- },
|
|
|
+ // input.onchange = async (event) => {
|
|
|
+ // const file = event.target.files[0]
|
|
|
+ // if (!file) return
|
|
|
+
|
|
|
+ // try {
|
|
|
+ // // 校验文件大小(50MB)
|
|
|
+ // const maxSize = 50 * 1024 * 1024 // 50MB
|
|
|
+ // if (file.size > maxSize) {
|
|
|
+ // this.$message.error('文件大小不能超过50MB!')
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // 校验文件格式
|
|
|
+ // const allowedFormats = [
|
|
|
+ // '.pdf',
|
|
|
+ // '.doc',
|
|
|
+ // '.docx',
|
|
|
+ // '.xls',
|
|
|
+ // '.xlsx',
|
|
|
+ // 'csv',
|
|
|
+ // ]
|
|
|
+ // const fileName = file.name.toLowerCase()
|
|
|
+ // const isValidFormat = allowedFormats.some((format) =>
|
|
|
+ // fileName.endsWith(format)
|
|
|
+ // )
|
|
|
+
|
|
|
+ // if (!isValidFormat) {
|
|
|
+ // this.$message.error(
|
|
|
+ // '只允许上传.pdf,.doc,.docx,.xls,.xlsx,.csv格式的文件!'
|
|
|
+ // )
|
|
|
+ // return
|
|
|
+ // }
|
|
|
|
|
|
+ // // 显示遮罩层
|
|
|
+ // loading = this.$baseLoading(1, '文件上传中...')
|
|
|
+
|
|
|
+ // // 第三步:创建FormData并上传文件
|
|
|
+ // const formData = new FormData()
|
|
|
+ // formData.append('file', file)
|
|
|
+
|
|
|
+ // // 先调用上传API
|
|
|
+ // const uploadRes = await uploadFile('/api/file/v1/upload', formData)
|
|
|
+
|
|
|
+ // // 第四步:检查上传结果
|
|
|
+ // if (!uploadRes || !uploadRes.value) {
|
|
|
+ // // this.$message.error('文件上传失败!');
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // 第五步:文件上传成功后,再更新数据
|
|
|
+ // const fileInfo = uploadRes.value
|
|
|
+ // // 创建更新数据对象
|
|
|
+ // const updateData = {
|
|
|
+ // ...row,
|
|
|
+ // fileUrl: fileInfo?.savePath, // 更新扫描件URL
|
|
|
+ // }
|
|
|
+
|
|
|
+ // // 第六步:调用更新API
|
|
|
+ // // await updateCostProjectDocument(updateData)
|
|
|
+
|
|
|
+ // // // 第七步:更新成功,显示提示并刷新
|
|
|
+ // // this.$message.success('文件上传成功并更新数据!')
|
|
|
+ // // this.$emit('refresh', this.project.projectId) // 通知父组件刷新
|
|
|
+ // } catch (error) {
|
|
|
+ // // 错误处理
|
|
|
+ // this.$message.error('操作失败:' + (error.message || '未知错误'))
|
|
|
+ // } finally {
|
|
|
+ // // 关闭遮罩层
|
|
|
+ // loading.close()
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // // 触发文件选择
|
|
|
+ // input.click()
|
|
|
+ // },
|
|
|
+
|
|
|
+ // 文件上传前验证
|
|
|
beforeMaterialUpload(file) {
|
|
|
- // 允许所有格式的文件上传,不进行格式限制
|
|
|
+ const allowedTypes = [
|
|
|
+ 'application/pdf',
|
|
|
+ 'application/msword',
|
|
|
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
+ 'application/vnd.ms-excel',
|
|
|
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
|
+ 'text/csv',
|
|
|
+ ]
|
|
|
+
|
|
|
+ const allowedExtensions = [
|
|
|
+ '.pdf',
|
|
|
+ '.doc',
|
|
|
+ '.docx',
|
|
|
+ '.xls',
|
|
|
+ '.xlsx',
|
|
|
+ '.csv',
|
|
|
+ ]
|
|
|
+ const fileExtension = '.' + file.name.split('.').pop().toLowerCase()
|
|
|
+
|
|
|
+ // 检查文件格式
|
|
|
+ const isCorrectType = allowedTypes.includes(file.type)
|
|
|
+ const isCorrectExtension = allowedExtensions.includes(fileExtension)
|
|
|
+
|
|
|
+ if (!isCorrectType && !isCorrectExtension) {
|
|
|
+ this.$message.error(
|
|
|
+ '只允许上传 pdf, doc, docx, xls, xlsx, csv 格式的文件!'
|
|
|
+ )
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查文件大小 (50MB)
|
|
|
+ const isLt50M = file.size / 1024 / 1024 < 50
|
|
|
+ if (!isLt50M) {
|
|
|
+ this.$message.error('文件大小不能超过 50MB!')
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
return true
|
|
|
},
|
|
|
|
|
|
+ // 自定义上传方法
|
|
|
+ async handleMaterialUpload(options) {
|
|
|
+ const { file, onProgress, onSuccess, onError } = options
|
|
|
+
|
|
|
+ // 检查是否已经上传了文件
|
|
|
+ if (
|
|
|
+ this.materialForm.fileList &&
|
|
|
+ this.materialForm.fileList.length >= 1
|
|
|
+ ) {
|
|
|
+ this.$message.warning('只能上传一个文件,请先删除已上传的文件')
|
|
|
+ // 手动触发onError回调
|
|
|
+ if (onError) {
|
|
|
+ onError(new Error('只能上传一个文件'))
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', file)
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 显示上传进度
|
|
|
+ if (onProgress) {
|
|
|
+ onProgress({ percent: 0 })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调用上传API
|
|
|
+ const uploadRes = await uploadFile('/api/file/v1/upload', formData, {
|
|
|
+ onUploadProgress: (progressEvent) => {
|
|
|
+ // 计算上传进度
|
|
|
+ if (progressEvent.total) {
|
|
|
+ const percent = Math.round(
|
|
|
+ (progressEvent.loaded * 100) / progressEvent.total
|
|
|
+ )
|
|
|
+ if (onProgress) {
|
|
|
+ onProgress({ percent })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ // 检查上传结果
|
|
|
+ if (uploadRes && uploadRes.code === 200 && uploadRes.value) {
|
|
|
+ const fileInfo = uploadRes.value
|
|
|
+ // 构造文件信息对象,符合element-ui upload组件的格式
|
|
|
+ const fileObj = {
|
|
|
+ uid: file.uid,
|
|
|
+ name: file.name,
|
|
|
+ status: 'success',
|
|
|
+ size: file.size,
|
|
|
+ response: fileInfo,
|
|
|
+ url: fileInfo.savePath || fileInfo.url,
|
|
|
+ }
|
|
|
+
|
|
|
+ if (onSuccess) {
|
|
|
+ onSuccess(fileInfo, fileObj)
|
|
|
+ this.materialForm.fileUrl = fileInfo.savePath || fileInfo.url
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$message.success(`${file.name} 上传成功`)
|
|
|
+ } else {
|
|
|
+ throw new Error(uploadRes?.message || '上传失败,请稍后重试')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('文件上传失败:', error)
|
|
|
+ this.$message.error(`文件上传失败:${error.message || '未知错误'}`)
|
|
|
+ if (onError) {
|
|
|
+ onError(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传成功回调
|
|
|
+ handleMaterialUploadSuccess(response, file, fileList) {
|
|
|
+ // 更新文件列表,添加文件URL信息
|
|
|
+ this.materialForm.fileList = fileList.map((item) => {
|
|
|
+ if (item.uid === file.uid && response) {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ url: response.savePath || response.url || item.url,
|
|
|
+ response: response,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传进度回调
|
|
|
+ handleMaterialUploadProgress(event, file, fileList) {
|
|
|
+ // 可以在这里显示上传进度,element-ui 会自动处理
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传失败回调
|
|
|
+ handleMaterialUploadError(err, file, fileList) {
|
|
|
+ console.error('文件上传错误:', err)
|
|
|
+ this.$message.error(`${file.name} 上传失败`)
|
|
|
+ // 从文件列表中移除失败的文件
|
|
|
+ this.materialForm.fileList = fileList.filter(
|
|
|
+ (item) => item.uid !== file.uid
|
|
|
+ )
|
|
|
+ },
|
|
|
+
|
|
|
+ // 超出文件数量限制
|
|
|
handleMaterialExceed(files, fileList) {
|
|
|
- Message.warning(
|
|
|
- `当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
|
|
|
- files.length + fileList.length
|
|
|
- } 个文件`
|
|
|
+ this.$message.warning(
|
|
|
+ `当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${fileList.length} 个文件`
|
|
|
)
|
|
|
},
|
|
|
+
|
|
|
+ // 移除文件
|
|
|
+ handleMaterialRemove(file, fileList) {
|
|
|
+ this.materialForm.fileList = fileList
|
|
|
+ this.$message.info(`${file.name} 已移除`)
|
|
|
+ },
|
|
|
},
|
|
|
}
|
|
|
</script>
|
|
|
@@ -1706,6 +1958,7 @@
|
|
|
.ml10 {
|
|
|
margin-left: 10px;
|
|
|
}
|
|
|
+
|
|
|
.text-danger {
|
|
|
color: #d9001b;
|
|
|
}
|