添加文件上传组件
This commit is contained in:
parent
9b6d47c9c4
commit
2a50804e35
|
|
@ -33,6 +33,7 @@
|
||||||
"splitpanes": "4.0.4",
|
"splitpanes": "4.0.4",
|
||||||
"vue": "3.5.16",
|
"vue": "3.5.16",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "1.1.1",
|
||||||
|
"vue-pdf-embed": "^2.1.3",
|
||||||
"vue-router": "4.5.1",
|
"vue-router": "4.5.1",
|
||||||
"vuedraggable": "4.1.0"
|
"vuedraggable": "4.1.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
72
src/components/FileUpload/PdfPreview.vue
Normal file
72
src/components/FileUpload/PdfPreview.vue
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
<template>
|
||||||
|
<div class="pdf-viewer">
|
||||||
|
<vue-pdf-embed :source="pdfUrl" :page="currentPage" :style="`transform: scale(${scale})`"
|
||||||
|
class="pdf-document" />
|
||||||
|
|
||||||
|
<div class="pdf-controls">
|
||||||
|
<el-button @click="prevPage" :disabled="currentPage <= 1">上一页</el-button>
|
||||||
|
<span>第 {{ currentPage }} 页 / 共 {{ pageCount }} 页</span>
|
||||||
|
<el-button @click="nextPage" :disabled="currentPage >= pageCount">下一页</el-button>
|
||||||
|
<!-- <el-button @click="zoomIn">放大</el-button>
|
||||||
|
<el-button @click="zoomOut">缩小</el-button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import VuePdfEmbed from 'vue-pdf-embed'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
pdfUrl: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
pageCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const scale = ref(1)
|
||||||
|
|
||||||
|
const prevPage = () => {
|
||||||
|
if (currentPage.value > 1) currentPage.value--
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextPage = () => {
|
||||||
|
if (currentPage.value < props.pageCount) currentPage.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoomIn = () => {
|
||||||
|
scale.value += 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoomOut = () => {
|
||||||
|
if (scale.value > 0.5) scale.value -= 0.1
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.pdf-viewer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf-document {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
281
src/components/FileUpload/multiFileUpload.vue
Normal file
281
src/components/FileUpload/multiFileUpload.vue
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<div v-for="itemFile in fileList" class="image-wrapper">
|
||||||
|
<img v-if="isImageFile(itemFile.suffix)" :src="itemFile.fileUrl" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'doc' || itemFile.suffix == 'docx'" :src="iconDoc"
|
||||||
|
class="avatar viewFile" @click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'xls' || itemFile.suffix == 'xlsx'" :src="iconXls"
|
||||||
|
class="avatar viewFile" @click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'ppt' || itemFile.suffix == 'pptx'" :src="iconPpt"
|
||||||
|
class="avatar viewFile" @click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'zip'" :src="iconZip" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'pdf'" :src="iconPdf" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'mp3'" :src="iconVideo" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'mp4'" :src="iconMove" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else-if="itemFile.suffix == 'txt'" :src="iconTxt" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<img v-else :src="iconOther" class="avatar viewFile"
|
||||||
|
@click.stop="handleCardPreview(itemFile.fileUrl, itemFile.suffix)" />
|
||||||
|
<div class="actions">
|
||||||
|
<span class="delete" @click.stop="handleRemoveImage(itemFile)">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-upload action="#" class="noFileCard" :http-request="requestUpload" list-type="picture-card"
|
||||||
|
:file-list="fileList" multiple :on-change="handleChange" :show-file-list="false"
|
||||||
|
:before-upload="beforeUpload">
|
||||||
|
<el-icon class="avatar-uploader-icon">
|
||||||
|
<Plus />
|
||||||
|
</el-icon>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 图片预览 -->
|
||||||
|
<el-dialog v-model="dialogVisible" width="1080px" class="my_dialog" align-center title="附件预览">
|
||||||
|
<img v-if="isImageFile(suffix)" :src="dialogImageUrl" class="preview-image" alt="Preview Image" />
|
||||||
|
<div v-else class="unsupported-file">
|
||||||
|
<pdf-preview :pdf-url="dialogImageUrl" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineExpose, ref } from 'vue'
|
||||||
|
import { Plus, Delete } from '@element-plus/icons-vue'
|
||||||
|
import { uploadFile } from "@/api/common"
|
||||||
|
import iconDoc from '@/assets/images/iconDoc.png'
|
||||||
|
import iconOther from '@/assets/images/iconOther.png'
|
||||||
|
import iconPdf from '@/assets/images/iconPdf.png'
|
||||||
|
import iconVideo from '@/assets/images/iconVideo.png'
|
||||||
|
import iconXls from '@/assets/images/iconXls.png'
|
||||||
|
import iconZip from '@/assets/images/iconZip.png'
|
||||||
|
import iconMove from '@/assets/images/iconMove.png'
|
||||||
|
import iconTxt from '@/assets/images/iconTxt.png'
|
||||||
|
import iconPpt from '@/assets/images/iconPpt.png'
|
||||||
|
import PdfPreview from './PdfPreview.vue'
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
const emit = defineEmits(['setFormFile'])
|
||||||
|
|
||||||
|
// 文件列表初始化
|
||||||
|
const fileList = ref([])
|
||||||
|
// 文件类型 1-营业执照 2-媒体权属 9-其它附件
|
||||||
|
const _fileType = ref('1')
|
||||||
|
const baseUrl = import.meta.env.VITE_APP_BASE_API
|
||||||
|
const dialogImageUrl = ref('')
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const suffix = ref('')
|
||||||
|
|
||||||
|
const setFileInfo = (files) => {
|
||||||
|
// 处理无后缀名情况
|
||||||
|
// if (!filePath || filePath.indexOf('.') === -1) {
|
||||||
|
// fileList.value = []
|
||||||
|
// return '';
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var suffix = filePath.split('.').pop();
|
||||||
|
// fileList.value = [{
|
||||||
|
// name: filePath,
|
||||||
|
// url: baseUrl + filePath,
|
||||||
|
// suffix: suffix
|
||||||
|
// }]
|
||||||
|
fileList.value = files
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否为图片文件
|
||||||
|
const isImageFile = (suffix) => {
|
||||||
|
console.log('是否图片', suffix, ['jpeg', 'jpg', 'png'].includes(suffix.toLowerCase()))
|
||||||
|
return ['jpeg', 'jpg', 'png'].includes(suffix.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
const handleCardPreview = (filePath, _suffix) => {
|
||||||
|
suffix.value = _suffix
|
||||||
|
dialogImageUrl.value = filePath
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除图片
|
||||||
|
const handleRemoveImage = (itemFile) => {
|
||||||
|
const index = fileList.value.findIndex(item => item.fileName === itemFile.fileName)
|
||||||
|
if (index !== -1) {
|
||||||
|
fileList.value.splice(index, 1)
|
||||||
|
emit('setFormFile', fileList.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义上传
|
||||||
|
const requestUpload = async (options) => {
|
||||||
|
console.log('自定义上传', options)
|
||||||
|
const { file } = options
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await uploadFile(formData)
|
||||||
|
if (res.code === 200) {
|
||||||
|
fileList.value.push({
|
||||||
|
id: undefined,
|
||||||
|
busSupplierId: undefined,
|
||||||
|
fileType: _fileType,
|
||||||
|
fileUrl: baseUrl + res.fileName,
|
||||||
|
fileName: res.fileName,
|
||||||
|
originalFileName: res.originalFilename,
|
||||||
|
size: res.size,
|
||||||
|
suffix: res.suffix
|
||||||
|
})
|
||||||
|
emit('setFormFile', fileList.value)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('上传失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件类型校验
|
||||||
|
const beforeUpload = (file) => {
|
||||||
|
// const validTypes = [
|
||||||
|
// // 图片类型
|
||||||
|
// "image/jpeg",
|
||||||
|
// "image/jpg",
|
||||||
|
// "image/png",
|
||||||
|
// // PDF 类型
|
||||||
|
// "application/pdf",
|
||||||
|
// "application/x-pdf",
|
||||||
|
// "application/acrobat",
|
||||||
|
// "applications/vnd.pdf",
|
||||||
|
// "text/pdf",
|
||||||
|
// "text/x-pdf"]
|
||||||
|
// const isValidType = validTypes.includes(file.type)
|
||||||
|
// // const isLt5M = file.size / 1024 / 1024 < 5
|
||||||
|
|
||||||
|
// if (!isValidType) {
|
||||||
|
// proxy.$modal.msgError("文件格式错误,请上传 JPG/JPEG/PNG/PDF 后缀的文件。");
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!isLt5M) {
|
||||||
|
// proxy.$modal.msgError("文件大小不能超过5MB");
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件变化处理
|
||||||
|
const handleChange = (file, files) => {
|
||||||
|
// 可以在这里添加文件变化时的额外处理逻辑
|
||||||
|
// 不需要清空 fileList,因为上传逻辑会处理
|
||||||
|
// fileList.value = []
|
||||||
|
}
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
setFileInfo,
|
||||||
|
_fileType
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.hasFileCard {
|
||||||
|
display: inline;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noFileCard {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewFile {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border: 1px solid #dedede;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-wrapper {
|
||||||
|
position: relative;
|
||||||
|
max-width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload--picture-card) {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.image-wrapper:hover .actions {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 5px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 70vh;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsupported-file {
|
||||||
|
padding: 0px;
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
width: 100%;
|
||||||
|
height: 70vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.myIcon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
color: #d2d2d2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -17,7 +17,7 @@ const service = axios.create({
|
||||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
// 超时
|
// 超时
|
||||||
timeout: 10000
|
timeout: 300000
|
||||||
})
|
})
|
||||||
|
|
||||||
// request拦截器
|
// request拦截器
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="业务部门" prop="yewuDept">
|
<el-form-item label="业务部门" prop="yewuDept">
|
||||||
<el-select v-model="ruleForm.yewuDept" placeholder="请选择" clearable style="min-width: 30px;">
|
<el-select v-model="ruleForm.yewuDept" placeholder="请选择" clearable style="min-width: 30px;">
|
||||||
<el-option v-for="dict in business_department" :key="dict.value" :label="dict.label"
|
<el-option v-for="item in deptList" :key="item.deptId" :label="item.deptName"
|
||||||
:value="dict.value" />
|
:value="item.deptId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -103,7 +103,8 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="人员规模" prop="renyuanSize">
|
<el-form-item label="人员规模" prop="renyuanSize">
|
||||||
<el-select v-model="ruleForm.renyuanSize" placeholder="请选择" style="min-width: 30px;" clearable>
|
<el-select v-model="ruleForm.renyuanSize" placeholder="请选择" style="min-width: 30px;"
|
||||||
|
@change="handleChangeSize" clearable>
|
||||||
<el-option v-for="dict in personnel_size" :key="dict.value" :label="dict.label"
|
<el-option v-for="dict in personnel_size" :key="dict.value" :label="dict.label"
|
||||||
:value="dict.value" />
|
:value="dict.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -280,7 +281,7 @@
|
||||||
<el-row :gutter="30" class="my_form_row">
|
<el-row :gutter="30" class="my_form_row">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="不可见权限">
|
<el-form-item label="不可见权限">
|
||||||
<el-switch v-model="ruleForm.switch" class="ml-2"
|
<el-switch v-model="ruleForm.invisibleFlag" class="ml-2" :active-value="1" :inactive-value="0"
|
||||||
style="--el-switch-on-color: #0BA200; --el-switch-off-color: #9CA4AB" />
|
style="--el-switch-on-color: #0BA200; --el-switch-off-color: #9CA4AB" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -298,108 +299,21 @@
|
||||||
<el-row :gutter="10" class="my_form_row">
|
<el-row :gutter="10" class="my_form_row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="营业执照">
|
<el-form-item label="营业执照">
|
||||||
<template v-if="docUploadList.length > 0">
|
<multiFileUpload ref="businessLicenseRef" @set-form-file="handleSetBusinessLicense" />
|
||||||
<div v-for="itemFile in docUploadList" class="image-wrapper">
|
|
||||||
<img v-if="isImageFile(itemFile.suffix)" :src="itemFile.url" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'doc' || itemFile.suffix == 'docx'" :src="iconDoc"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'xls' || itemFile.suffix == 'xlsx'" :src="iconXls"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'ppt' || itemFile.suffix == 'pptx'" :src="iconPpt"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'zip'" :src="iconZip" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'pdf'" :src="iconPdf" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp3'" :src="iconVideo" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp4'" :src="iconMove" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'txt'" :src="iconTxt" class="avatar viewFile" />
|
|
||||||
<img v-else :src="iconOther" class="avatar viewFile" />
|
|
||||||
<div class="actions">
|
|
||||||
<span class="delete" @click.stop="handleRemoveImage(itemFile)">
|
|
||||||
<el-icon>
|
|
||||||
<Delete />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-upload action="#" :http-request="requestUpload" list-type="picture-card"
|
|
||||||
:show-file-list="false">
|
|
||||||
<el-icon class="avatar-uploader-icon">
|
|
||||||
<Plus />
|
|
||||||
</el-icon>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="10" class="my_form_row">
|
<el-row :gutter="10" class="my_form_row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="其他附件">
|
<el-form-item label="其他附件">
|
||||||
<template v-if="docUploadList.length > 0">
|
<multiFileUpload ref="otherFileRef" @set-form-file="handleSetOtherFile" />
|
||||||
<div v-for="itemFile in docUploadList" class="image-wrapper">
|
|
||||||
<img v-if="isImageFile(itemFile.suffix)" :src="itemFile.url" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'doc' || itemFile.suffix == 'docx'" :src="iconDoc"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'xls' || itemFile.suffix == 'xlsx'" :src="iconXls"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'ppt' || itemFile.suffix == 'pptx'" :src="iconPpt"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'zip'" :src="iconZip" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'pdf'" :src="iconPdf" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp3'" :src="iconVideo" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp4'" :src="iconMove" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'txt'" :src="iconTxt" class="avatar viewFile" />
|
|
||||||
<img v-else :src="iconOther" class="avatar viewFile" />
|
|
||||||
<div class="actions">
|
|
||||||
<span class="delete" @click.stop="handleRemoveImage(itemFile)">
|
|
||||||
<el-icon>
|
|
||||||
<Delete />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-upload action="#" :http-request="requestUpload" list-type="picture-card"
|
|
||||||
:show-file-list="false">
|
|
||||||
<el-icon class="avatar-uploader-icon">
|
|
||||||
<Plus />
|
|
||||||
</el-icon>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="10" class="my_form_row">
|
<el-row :gutter="10" class="my_form_row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="媒体权属">
|
<el-form-item label="媒体权属">
|
||||||
<template v-if="docUploadList.length > 0">
|
<multiFileUpload ref="mediaRightsRef" @set-form-file="handleSetMediaRights" />
|
||||||
<div v-for="itemFile in docUploadList" class="image-wrapper">
|
|
||||||
<img v-if="isImageFile(itemFile.suffix)" :src="itemFile.url" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'doc' || itemFile.suffix == 'docx'" :src="iconDoc"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'xls' || itemFile.suffix == 'xlsx'" :src="iconXls"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'ppt' || itemFile.suffix == 'pptx'" :src="iconPpt"
|
|
||||||
class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'zip'" :src="iconZip" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'pdf'" :src="iconPdf" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp3'" :src="iconVideo" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'mp4'" :src="iconMove" class="avatar viewFile" />
|
|
||||||
<img v-else-if="itemFile.suffix == 'txt'" :src="iconTxt" class="avatar viewFile" />
|
|
||||||
<img v-else :src="iconOther" class="avatar viewFile" />
|
|
||||||
<div class="actions">
|
|
||||||
<span class="delete" @click.stop="handleRemoveImage(itemFile)">
|
|
||||||
<el-icon>
|
|
||||||
<Delete />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-upload action="#" :http-request="requestUpload" list-type="picture-card"
|
|
||||||
:show-file-list="false">
|
|
||||||
<el-icon class="avatar-uploader-icon">
|
|
||||||
<Plus />
|
|
||||||
</el-icon>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -410,19 +324,13 @@
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, defineEmits, ref } from 'vue'
|
import { onMounted, nextTick, defineEmits, ref } from 'vue'
|
||||||
import { Close } from '@element-plus/icons-vue'
|
import { Close } from '@element-plus/icons-vue'
|
||||||
import { sysRegionListByPid } from "@/api/system/administrativeRegion"
|
import { sysRegionListByPid } from "@/api/system/administrativeRegion"
|
||||||
import { addBusSupplier, updateBusSupplier, getBusSupplier } from "@/api/supplier"
|
import { addBusSupplier, updateBusSupplier, getBusSupplier } from "@/api/supplier"
|
||||||
import iconDoc from '@/assets/images/iconDoc.png'
|
import { listDept } from "@/api/system/dept"
|
||||||
import iconOther from '@/assets/images/iconOther.png'
|
|
||||||
import iconPdf from '@/assets/images/iconPdf.png'
|
import multiFileUpload from '../../components/FileUpload/multiFileUpload.vue'
|
||||||
import iconVideo from '@/assets/images/iconVideo.png'
|
|
||||||
import iconXls from '@/assets/images/iconXls.png'
|
|
||||||
import iconZip from '@/assets/images/iconZip.png'
|
|
||||||
import iconMove from '@/assets/images/iconMove.png'
|
|
||||||
import iconTxt from '@/assets/images/iconTxt.png'
|
|
||||||
import iconPpt from '@/assets/images/iconPpt.png'
|
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const emit = defineEmits(['handleShowList']);
|
const emit = defineEmits(['handleShowList']);
|
||||||
|
|
@ -432,6 +340,11 @@ const formTitle = ref('新建')
|
||||||
const province = ref([])
|
const province = ref([])
|
||||||
const city = ref([])
|
const city = ref([])
|
||||||
const county = ref([])
|
const county = ref([])
|
||||||
|
// 业务部门数据
|
||||||
|
const deptList = ref([])
|
||||||
|
const businessLicenseRef = ref(null)
|
||||||
|
const otherFileRef = ref(null)
|
||||||
|
const mediaRightsRef = ref(null)
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
ruleForm: {},
|
ruleForm: {},
|
||||||
|
|
@ -471,7 +384,7 @@ const data = reactive({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const { ruleForm, rules } = toRefs(data)
|
const { ruleForm, rules } = toRefs(data)
|
||||||
const { invoice_type, media_ownership, personnel_size, main_media_types, media_quality, history_cooperation, supplier_level, supplier_cooperation_degree, main_business, business_department, company_type, cooperative_procurement_amount, cooperation_discount_intensity, enterprise_bad_records } = proxy.useDict("invoice_type", "media_ownership", "personnel_size", "main_media_types", "media_quality", "history_cooperation", "supplier_level", "supplier_cooperation_degree", "main_business", "business_department", "company_type", "cooperative_procurement_amount", "cooperation_discount_intensity", "enterprise_bad_records")
|
const { invoice_type, media_ownership, personnel_size, main_media_types, media_quality, history_cooperation, supplier_level, supplier_cooperation_degree, main_business, company_type, cooperative_procurement_amount, cooperation_discount_intensity, enterprise_bad_records } = proxy.useDict("invoice_type", "media_ownership", "personnel_size", "main_media_types", "media_quality", "history_cooperation", "supplier_level", "supplier_cooperation_degree", "main_business", "company_type", "cooperative_procurement_amount", "cooperation_discount_intensity", "enterprise_bad_records")
|
||||||
|
|
||||||
|
|
||||||
// 获取省/直辖市数据
|
// 获取省/直辖市数据
|
||||||
|
|
@ -522,47 +435,47 @@ const getCountyList2 = (value) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 人员规模选择
|
||||||
// 营业执照集合
|
const handleChangeSize = (val) => {
|
||||||
const docUploadList = ref([])
|
console.log('选择', val, personnel_size.value)
|
||||||
const baseUrl = import.meta.env.VITE_APP_BASE_API
|
const curSizeInfo = personnel_size.value.filter(item => item.value == val)[0]
|
||||||
// 判断是否为图片文件
|
ruleForm.value.renyuanSize = val
|
||||||
const isImageFile = (suffix) => {
|
ruleForm.value.renyuanGuimo = curSizeInfo?.label
|
||||||
return ['jpeg', 'jpg', 'png'].includes(suffix?.toLowerCase())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义上传
|
// 获取业务部门
|
||||||
const requestUpload = (options) => {
|
const getDepList = () => {
|
||||||
const { file } = options
|
listDept({ businessFlag: 1 }).then(response => {
|
||||||
const formData = new FormData()
|
deptList.value = response.data
|
||||||
formData.append('file', file)
|
})
|
||||||
|
|
||||||
try {
|
|
||||||
// uploadFile(formData).then(res => {
|
|
||||||
// if (res.code === 200) {
|
|
||||||
// docUploadList.value.push({
|
|
||||||
// name: res.originalFilename,
|
|
||||||
// url: baseUrl + res.fileName,
|
|
||||||
// suffix: res.suffix
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('上传失败:', error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除附件
|
// 设置营业执照
|
||||||
const handleRemoveImage = (fileInfo) => {
|
const businessLicenseList = ref([])
|
||||||
docUploadList.value = docUploadList.value.filter(
|
const handleSetBusinessLicense = (_files) => {
|
||||||
item => item.name != fileInfo.name
|
businessLicenseList.value = _files
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置其他附件
|
||||||
|
const otherFileList = ref([])
|
||||||
|
const handleSetOtherFile = (_files) => {
|
||||||
|
otherFileList.value = _files
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置媒体权属附件
|
||||||
|
const mediaRightsList = ref([])
|
||||||
|
const handleSetMediaRights = (_files) => {
|
||||||
|
mediaRightsList.value = _files
|
||||||
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
proxy.$refs["ruleFormRef"].validate(valid => {
|
proxy.$refs["ruleFormRef"].validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
// 使用扩展运算符合并数组
|
||||||
|
const mergedArray = [...businessLicenseList.value, ...otherFileList.value, ...mediaRightsList.value];
|
||||||
|
console.log('营业资质', mergedArray)
|
||||||
|
ruleForm.value.busSupplierFileList = mergedArray
|
||||||
if (ruleForm.value.supplierId != undefined) {
|
if (ruleForm.value.supplierId != undefined) {
|
||||||
updateBusSupplier(ruleForm.value).then(response => {
|
updateBusSupplier(ruleForm.value).then(response => {
|
||||||
proxy.$modal.msgSuccess("修改成功")
|
proxy.$modal.msgSuccess("修改成功")
|
||||||
|
|
@ -606,71 +519,20 @@ async function handleResponse(response) {
|
||||||
const initForm = (_formTitle, _ruleForm) => {
|
const initForm = (_formTitle, _ruleForm) => {
|
||||||
formTitle.value = _formTitle
|
formTitle.value = _formTitle
|
||||||
ruleForm.value = _ruleForm
|
ruleForm.value = _ruleForm
|
||||||
|
getDepList()
|
||||||
getProvinceList()
|
getProvinceList()
|
||||||
if (ruleForm.value.supplierId) getSupplierInfo()
|
if (ruleForm.value.supplierId) getSupplierInfo()
|
||||||
|
nextTick(() => {
|
||||||
|
businessLicenseRef.value._fileType = 1
|
||||||
|
otherFileRef.value._fileType = 9
|
||||||
|
mediaRightsRef.value._fileType = 2
|
||||||
|
// businessLicenseRef.value?.setFileInfo(ruleForm.value.beforeCondition.certificatePhoto)
|
||||||
|
// otherFileRef.value?.setFileInfo(ruleForm.value.beforeCondition.qualificationForm)
|
||||||
|
// mediaRightsRef.value?.setFileInfo(ruleForm.value.beforeCondition.shFile)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// 暴露方法\属性给父组件
|
// 暴露方法\属性给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initForm
|
initForm
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang='scss'>
|
|
||||||
.el-upload--picture-card {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewFile {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border: 1px solid #dedede;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-container {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-wrapper {
|
|
||||||
position: relative;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
margin-right: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-wrapper:hover .actions {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 5px;
|
|
||||||
transition: background 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -107,6 +107,14 @@
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="业务部门">
|
||||||
|
<el-radio-group v-model="form.businessFlag">
|
||||||
|
<el-radio :value="0">否</el-radio>
|
||||||
|
<el-radio :value="1">是</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
@ -181,7 +189,8 @@ function reset() {
|
||||||
leader: undefined,
|
leader: undefined,
|
||||||
phone: undefined,
|
phone: undefined,
|
||||||
email: undefined,
|
email: undefined,
|
||||||
status: "0"
|
status: "0",
|
||||||
|
businessFlag: 0
|
||||||
}
|
}
|
||||||
proxy.resetForm("deptRef")
|
proxy.resetForm("deptRef")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user