feat: 初始化
This commit is contained in:
554
src/components/AttachmentUpload.vue
Normal file
554
src/components/AttachmentUpload.vue
Normal file
@@ -0,0 +1,554 @@
|
||||
<template>
|
||||
<el-form :model="formData" ref="applyForm" :rules="rules" :label-position="labelPosition" style="margin-left: 5px">
|
||||
<el-row>
|
||||
<!-- <el-col :span="24">-->
|
||||
<!-- <el-form-item :label="label" prop="attachment" >-->
|
||||
<!-- <template v-if="preview">-->
|
||||
<!-- <file-upload @getFile="getAttachment" :multiple="false"-->
|
||||
<!-- :disabled="singleFileArray?.length>0?true:false" title="如需修改需求申请书附件,请先删除文件再上传!"/>-->
|
||||
<!-- <fvTable style="width: 100%;max-height: 80px;" height="80" v-if="singleFileArray?.length>0"-->
|
||||
<!-- :tableConfig="editSingleTableConfig"-->
|
||||
<!-- :data="singleFileArray" :isSettingCol="false" :pagination="false">-->
|
||||
<!-- </fvTable>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-else-if="!preview">-->
|
||||
<!-- <file-upload @getFile="getAttachment" :multiple="false"-->
|
||||
<!-- :disabled="isSingleFile"/>-->
|
||||
<!-- <fvTable style="width: 100%;max-height: 80px;" v-if="showSingleTable" height="80"-->
|
||||
<!-- :tableConfig="singleTableConfig"-->
|
||||
<!-- :data="_singleFileValue" :isSettingCol="false" :pagination="false">-->
|
||||
<!-- </fvTable>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="24">
|
||||
<el-form-item :label="label" prop="" required>
|
||||
<file-upload @getFile="getOtherFile"/>
|
||||
<el-button color="#DED0B2" v-if="templateDownloadBtnShow" @click="handleImportTemplateDownload"
|
||||
style="margin-left: 10px">模板下载
|
||||
</el-button>
|
||||
<fvTable style="width: 100%;max-height: 160px;" v-if="showTable" height="160" :tableConfig="tableConfig"
|
||||
:data="allFileList" :isSettingCol="false" :pagination="false">
|
||||
<template #empty>
|
||||
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
|
||||
</template>
|
||||
</fvTable>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<file-preview ref="filePreviewRef" v-if="filePreviewShow" :fileName="filePreviewParam.fileName"
|
||||
:fileUrl="filePreviewParam.fileUrl"
|
||||
:fileType="filePreviewParam.fileType"/>
|
||||
</template>
|
||||
|
||||
<script setup lang="jsx">
|
||||
import FileUpload from '@/components/FileUpload.vue'
|
||||
import {deleteFile, downloadFile, downloadTemplate, downloadTemplateZip} from "@/api/project-demand";
|
||||
import {ElMessageBox, ElNotification} from "element-plus";
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
showFileList: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: '项目附件'
|
||||
},
|
||||
showTable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showSingleTable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
preview: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否显示模板下载按钮
|
||||
templateDownloadBtnShow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//模板下载时的文件名
|
||||
templateName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
singleList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
otherFileList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
labelPosition: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(["getAttachment", "getOtherFile", "update:singleList"])
|
||||
|
||||
const baseTableConf = reactive(
|
||||
[
|
||||
{
|
||||
prop: 'index',
|
||||
type: 'index',
|
||||
label: '序号',
|
||||
align: 'center',
|
||||
width: '80',
|
||||
},
|
||||
{
|
||||
prop: 'originalFileName',
|
||||
label: '文件名',
|
||||
align: 'center',
|
||||
width: 400,
|
||||
currentRender: ({row, index}) => (
|
||||
<div style="color: #2a99ff;cursor: pointer;"
|
||||
onClick={() => clickToPreview(row)}>{row.originalFileName}</div>)
|
||||
},
|
||||
{
|
||||
prop: 'tag',
|
||||
label: '标签',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'size',
|
||||
label: '文件大小',
|
||||
align: 'center',
|
||||
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
|
||||
},
|
||||
]
|
||||
)
|
||||
const tableConfig = reactive({
|
||||
columns: [
|
||||
...baseTableConf,
|
||||
{
|
||||
prop: 'oper',
|
||||
label: '操作',
|
||||
align: 'center',
|
||||
showOverflowTooltip: false,
|
||||
currentRender: ({row, index}) => {
|
||||
let btn = []
|
||||
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
|
||||
// if (row.newFile) {
|
||||
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
|
||||
// }
|
||||
return (
|
||||
<div style={{width: '100%'}}>
|
||||
{
|
||||
btn.map(item => (
|
||||
<el-button
|
||||
type={item.type}
|
||||
onClick={() => item.func()}
|
||||
link
|
||||
>
|
||||
{item.label}
|
||||
</el-button>
|
||||
))
|
||||
}
|
||||
{
|
||||
row.newFile || props.preview || !props.preview ?
|
||||
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
|
||||
// perm={['']}
|
||||
onDelete={() => handleDelete(row)}/>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
const singleTableConfig = reactive({
|
||||
columns: [
|
||||
...baseTableConf,
|
||||
{
|
||||
prop: 'oper',
|
||||
label: '操作',
|
||||
align: 'center',
|
||||
showOverflowTooltip: false,
|
||||
currentRender: ({row, index}) => {
|
||||
let btn = []
|
||||
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
|
||||
// if (row.newFile) {
|
||||
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
|
||||
// }
|
||||
return (
|
||||
<div style={{width: '100%'}}>
|
||||
{
|
||||
btn.map(item => (
|
||||
<el-button
|
||||
type={item.type}
|
||||
onClick={() => item.func()}
|
||||
link
|
||||
>
|
||||
{item.label}
|
||||
</el-button>
|
||||
))
|
||||
}
|
||||
{
|
||||
row.newFile || props.preview || !props.preview ?
|
||||
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
|
||||
// perm={['']}
|
||||
onDelete={() => handleSingleDelete(row)}/>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
const editSingleTableConfig = reactive({
|
||||
columns: [
|
||||
...baseTableConf,
|
||||
{
|
||||
prop: 'oper',
|
||||
label: '操作',
|
||||
align: 'center',
|
||||
showOverflowTooltip: false,
|
||||
currentRender: ({row, index}) => {
|
||||
let btn = []
|
||||
btn.push({label: '下载', func: () => handleDownload(row), type: 'primary'})
|
||||
// if (row.newFile) {
|
||||
// btn.push({label: '删除', func: () => handleDelete(row), type: 'primary'})
|
||||
// }
|
||||
return (
|
||||
<div style={{width: '100%'}}>
|
||||
{
|
||||
btn.map(item => (
|
||||
<el-button
|
||||
type={item.type}
|
||||
onClick={() => item.func()}
|
||||
link
|
||||
>
|
||||
{item.label}
|
||||
</el-button>
|
||||
))
|
||||
}
|
||||
{
|
||||
row.newFile || props.preview || !props.preview ?
|
||||
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
|
||||
// perm={['']}
|
||||
onDelete={() => deleteSingleFile(row, 1)}/>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
const singleFileArray = ref([])
|
||||
const rules = reactive({
|
||||
// attachment: [{required: true, message: '请上传附件', trigger: ['blur', 'change']}],
|
||||
})
|
||||
const applyForm = ref()
|
||||
const singleFile = ref({})
|
||||
const isSingleFile = ref(false)
|
||||
const isHaveOneFile = ref(false)
|
||||
const allFileList = ref([])
|
||||
if (localStorage.getItem('singleFile')) {
|
||||
singleFileArray.value.push(JSON.parse(localStorage.getItem('singleFile')))
|
||||
singleFile.value = JSON.parse(localStorage.getItem('singleFile'))
|
||||
}
|
||||
|
||||
const filePreviewParam = ref({
|
||||
fileUrl: '',
|
||||
fileName: '',
|
||||
fileType: 'pdf'
|
||||
})
|
||||
const filePreviewRef = ref()
|
||||
const filePreviewShow = ref(false)
|
||||
|
||||
const _singleFileValue = computed({
|
||||
get() {
|
||||
return props.singleList;
|
||||
},
|
||||
set(value) {
|
||||
emit('update:singleList', value)
|
||||
}
|
||||
})
|
||||
const _otherFileListValue = computed({
|
||||
get() {
|
||||
return props.otherFileList;
|
||||
},
|
||||
set(value) {
|
||||
emit('update:otherFileList', value)
|
||||
}
|
||||
})
|
||||
if (_otherFileListValue.value && _otherFileListValue.value.length > 0) {
|
||||
isHaveOneFile.value = true
|
||||
_otherFileListValue.value.forEach(item => {
|
||||
allFileList.value.push(item)
|
||||
})
|
||||
}
|
||||
// watch(() => props.showSingleTable, (newVal) => {
|
||||
// props.showSingleTable = newVal
|
||||
// }, {deep: true})
|
||||
watch(() => props.formData.fileList, (newVal) => {
|
||||
if (props.preview) {
|
||||
newVal?.forEach(item => {
|
||||
isHaveOneFile.value = true
|
||||
allFileList.value.push(item)
|
||||
})
|
||||
}
|
||||
}, {immediate: true})
|
||||
|
||||
watch(() => props.formData.singleFile, (newVal) => {
|
||||
props.formData.singleFile = newVal
|
||||
if (newVal != null) {
|
||||
singleFileArray.value.push(newVal)
|
||||
} else {
|
||||
singleFileArray.value = []
|
||||
}
|
||||
singleFile.value = newVal
|
||||
}, {immediate: true})
|
||||
|
||||
|
||||
// watch(() => props.otherFileList, (newVal) => {
|
||||
// props.otherFileList=newVal
|
||||
// if (props.preview) {
|
||||
// console.log('newotherFileList', newVal,props.preview,props.formData.fileList)
|
||||
// if (props.formData.fileList === null || props.formData.fileList?.length === 0) {
|
||||
// allFileList.value = newVal
|
||||
// } else {
|
||||
// console.log('props.otherFileList',props.otherFileList)
|
||||
// // props.otherFileList?.forEach(item => {
|
||||
// // allFileList.value.push(item)
|
||||
// // })
|
||||
// }
|
||||
// } else {
|
||||
// allFileList.value = newVal
|
||||
// }
|
||||
// }, {deep: true})
|
||||
watch(() => props.showTable, (newVal) => {
|
||||
props.showTable = newVal
|
||||
}, {deep: true})
|
||||
// watch(() => props.singleList, (newVal) => {
|
||||
// console.log('singleFile', newVal)
|
||||
// singleFileList.value = newVal
|
||||
// }, {deep: true})
|
||||
|
||||
watch(() => isSingleFile.value, (newVal) => {
|
||||
isSingleFile.value = newVal
|
||||
}, {deep: true})
|
||||
watch(() => isHaveOneFile.value, (newVal) => {
|
||||
isHaveOneFile.value = newVal
|
||||
}, {deep: true})
|
||||
// watch(() => singleFile.value, (newVal) => {
|
||||
// singleFile.value = newVal
|
||||
// }, {deep: true})
|
||||
|
||||
|
||||
const handleImportTemplateDownload = async () => {
|
||||
console.info("🚀 ~method:handleImportTemplateDownload -----", props.tag)
|
||||
let templateType = ''
|
||||
let templateTypeList = ''
|
||||
let isZip = false
|
||||
if (props.tag === '需求上报') {
|
||||
templateType = '2'
|
||||
isZip = false
|
||||
} else if (props.tag === '项目立项') {
|
||||
templateTypeList = '5,6'
|
||||
isZip = true
|
||||
} else if (props.tag === '项目验收') {
|
||||
templateType = '7'
|
||||
isZip = false
|
||||
} else if (props.tag === '阶段变更') {
|
||||
templateTypeList = '8,9'
|
||||
isZip = true
|
||||
}
|
||||
let res = ''
|
||||
if (isZip) {
|
||||
res = await downloadTemplateZip(templateTypeList)
|
||||
let fileName = props.templateName +'.zip'
|
||||
const blob = new Blob([res.data])
|
||||
let a = document.createElement('a')
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.download = fileName
|
||||
a.click()
|
||||
} else {
|
||||
res = await downloadTemplate(templateType)
|
||||
const blob = new Blob([res])
|
||||
let a = document.createElement('a')
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.download = props.templateName + ".docx"
|
||||
a.click()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const clickToPreview = (row) => {
|
||||
filePreviewShow.value = false
|
||||
console.log('clickToPreview', row, row.fileType)
|
||||
filePreviewParam.value = {
|
||||
fileUrl: row.url,
|
||||
fileName: row.originalFileName,
|
||||
fileType: row.fileType
|
||||
}
|
||||
nextTick(() => {
|
||||
filePreviewShow.value = true
|
||||
})
|
||||
// filePreviewRef.value.show()
|
||||
}
|
||||
|
||||
|
||||
const handleDelete = (row, type) => {
|
||||
deleteFile(row.fileId).then(res => {
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: res.msg,
|
||||
type: res.code === 1000 ? 'success' : 'error'
|
||||
})
|
||||
if (res.code === 1000) {
|
||||
if (type === 'single') {
|
||||
_singleFileValue.value.splice(_singleFileValue.value.findIndex((item) => item.fileId === row.fileId), 1);
|
||||
isSingleFile.value = false
|
||||
} else {
|
||||
allFileList.value.splice(allFileList.value.findIndex((item) => item.fileId === row.fileId), 1);
|
||||
if (allFileList.value && allFileList.value?.length == 0) {
|
||||
isHaveOneFile.value = false
|
||||
} else {
|
||||
isHaveOneFile.value = true
|
||||
}
|
||||
if (localStorage.getItem('collectData')) {
|
||||
let collectData = JSON.parse(localStorage.getItem('collectData'))
|
||||
collectData.fileList = allFileList.value
|
||||
localStorage.setItem('collectData', JSON.stringify(collectData))
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const handleSingleDelete = (row) => {
|
||||
handleDelete(row, 'single')
|
||||
}
|
||||
const getAttachment = (val) => {
|
||||
isSingleFile.value = true
|
||||
emit('getAttachment', val)
|
||||
}
|
||||
const compositeParam = (item) => {
|
||||
return {
|
||||
fileId: item.id,
|
||||
size: item.size,
|
||||
originalFileName: item.originalFilename,
|
||||
fileType: item.fileType,
|
||||
url: item.url,
|
||||
newFile: true,
|
||||
tag: props.tag
|
||||
}
|
||||
}
|
||||
const getOtherFile = (val) => {
|
||||
if (props.preview) {
|
||||
allFileList.value.push(compositeParam(val))
|
||||
} else {
|
||||
allFileList.value = _otherFileListValue.value
|
||||
}
|
||||
isHaveOneFile.value = true
|
||||
emit('getOtherFile', val)
|
||||
}
|
||||
const deleteAttachment = (val) => {
|
||||
deleteFile(val).then(res => {
|
||||
if (res.code === 1000) {
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: "删除成功",
|
||||
type: 'success'
|
||||
})
|
||||
isSingleFile.value = false
|
||||
singleFile.value = null
|
||||
singleFileArray.value = []
|
||||
}
|
||||
});
|
||||
}
|
||||
const deleteSingleFile = (row, type) => {
|
||||
ElMessageBox.confirm(`确认删除名称为${row.originalFileName}的文件吗?`, '系统提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteFile(row.fileId).then(res => {
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: res.msg,
|
||||
type: res.code === 1000 ? 'success' : 'error'
|
||||
})
|
||||
if (res.code === 1000) {
|
||||
isSingleFile.value = false
|
||||
if (type === 1) {
|
||||
singleFile.value = null
|
||||
singleFileArray.value = []
|
||||
} else {
|
||||
props.otherFileList.splice(props.otherFileList.findIndex((item) => item.fileId === row.fileId), 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}).catch(() => {
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: "用户取消删除! ",
|
||||
type: 'warning'
|
||||
})
|
||||
})
|
||||
}
|
||||
const handleDownload = (row) => {
|
||||
downloadFile(row.fileId).then(res => {
|
||||
const blob = new Blob([res])
|
||||
let a = document.createElement('a')
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.download = row.originalFileName
|
||||
a.click()
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
validate() {
|
||||
return applyForm.value.validate()
|
||||
},
|
||||
clearValidate() {
|
||||
return applyForm.value.clearValidate()
|
||||
},
|
||||
allFileList,
|
||||
singleFile,
|
||||
isSingleFile,
|
||||
isHaveOneFile,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.el-table--fit ) {
|
||||
height: 300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-table__header) {
|
||||
.is-leaf:first-child {
|
||||
.cell {
|
||||
margin-left: -22px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body) {
|
||||
.el-table__cell:first-child {
|
||||
.cell {
|
||||
margin-left: -11px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user