当前位置: 首页 > news >正文

el-upload实现文件上传预览

本笔记仅提供el-upload附件预览的思路,不保证完全cv就可以使用。

需修改fileUploadYt.vue中后端接口返回的数据格式;

如果你是vue3项目,还需要在temp.vue中修改@vue-office的导入方式,直接打开我的注释并且删除旧的导入即可。

Vue2+element文件上传预览的功能实现https://blog.csdn.net/m0_74149462/article/details/129025238?ops_request_misc=%257B%2522request%255Fid%2522%253A%25225da3c6f21ac258714348fabc2f30021a%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=5da3c6f21ac258714348fabc2f30021a&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-3-129025238-null-null.nonecase&utm_term=%E9%A2%84%E8%A7%88&spm=1018.2226.3001.4450el-upload文件上传组件的封装https://blog.csdn.net/m0_74149462/article/details/130361411?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522c439a6f34bedbeba7f67cdadb8d2ab4d%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=c439a6f34bedbeba7f67cdadb8d2ab4d&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-130361411-null-null.nonecase&utm_term=el-upload&spm=1018.2226.3001.4450

需要用到的插件

"@vue-office/docx": "^1.6.3",
"@vue-office/excel": "^1.7.14",
"@vue-office/pdf": "^2.0.10",
"@vue-office/pptx": "^1.0.1",
// 如果是vue2项目的话还需要安装这个
"@vue/composition-api": "^1.7.2",
"vue-demi": "^0.14.10",

1. 新建/filePreviewer页面

每次点击预览都会跳到这个页面,该页面接收两个参数fileType:文件类型和fileSrc:文件地址【可以是流或者cdn链接如:192.....0/a.docx】

 {path: "/filePreviewer",component: () => import("@/components/filePreviewer/filePreviewer.vue"),hidden: true},

2. 配置filePreviewer

filePreviewer.vue

<template><div class="file-previewer"><!--    <div class="file-previewer-header">--><!--      <el-page-header @back="goBack">--><!--        <template #content>--><!--          <span class="text-large font-600 mr-3"> {{ title }} </span>--><!--        </template>--><!--        <div class="mt-4 text-sm font-bold"></div>--><!--      </el-page-header>--><!--    </div>--><div class="file-previewer-content"><Tempref="tempRef":fileType="fileType":fileSrc="fileSrc"v-bind="$attrs"/></div></div>
</template><script>
import Temp from "@/components/filePreviewer/temp.vue";
import { getToken } from "@/utils/auth";
import axios from "axios";
import sysCode from "@/utils/sysCode";
import { blobValidate } from "@/utils/publicFun";
import NewMessage from "@/utils/rewriteElMessage";export default {name: "FilePreviewer",components: {Temp},props: {title: {type: String,required: false},pageType: {type: Number,default: 2}},data() {return {fileType: "",fileSrc: "",fileKey: null,interfaceParams: {} // 接口参数};},methods: {goBack() {this.pageType = 1;this.$emit("close");},async getFileBlob(obj) {const { interfaceUrl, key } = obj;try {const response = await axios.post(interfaceUrl,{...this.interfaceParams},{headers: {Authorization: getToken(),"Token-Code-Header": sysCode.trading},responseType: "blob"});const isLogin = await blobValidate(response.data);if (!isLogin) {const resText = await new Response(response.data).text();const rspObj = JSON.parse(resText);const errMsg = rspObj.message || "文件获取失败";NewMessage.error({message: errMsg,type: "error",duration: 5 * 1000});return null;}this.fileSrc = response.data;this.fileType = "docx";console.log("文件预览设置成功", {fileSrc: this.fileSrc,blobSize: response.data.size,blobType: response.data.type});return response.data;} catch (error) {console.error("获取文件流失败:", error);NewMessage.error({message: "获取文件出现错误,请联系管理员!",type: "error",duration: 5 * 1000});return null;}},async getFile(obj) {const { interfaceUrl, fetchType, key } = obj;const url = interfaceUrl;const header = {authorization: getToken(),"token-code-header": "system"};try {if (fetchType === "get") {const response = await fetch(url, {method: "GET",headers: header});if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const blob = await response.blob();// 注意:这里需要根据实际情况调整,Vue2中可能需要使用其他方式存储// this.docx = await blob.arrayBuffer();this.fileSrc = await blob.arrayBuffer();} else if (fetchType === "post") {await this.getFileBlob(obj);}} catch (error) {console.error("获取文档失败:", error);this.loading = false;this.errorHandler();}}},mounted() {const obj = this.$route.query;this.$nextTick(() => {/* 通过接口获取文件流 */if (obj.key) {this.fileKey = obj.key;this.interfaceParams = JSON.parse(localStorage.getItem(obj.key) || "{}");localStorage.setItem(obj.key, JSON.stringify(this.interfaceParams));this.getFile(obj);return;}/* 直接获取文件地址 */this.fileType = obj.fileType;this.fileSrc = obj.fileSrc;});},destroyed() {if (this.fileKey) {localStorage.removeItem(this.fileKey);}}
};
</script><style lang="scss" scoped>
.file-previewer {width: 100%;//height: calc(100vh - 100px);height: 100vh;display: flex;flex-direction: column;justify-content: space-between;&-header {padding: 20px 0;height: 40px;}&-content {height: 100%;//height: calc(100% - 70px);}::v-deep .el-page-header__back {&:hover {color: var(--el-color-primary);}}
}
</style>

temp.vue

<template><div class="temp" v-loading="loading"><vue-office-docxclass="temp"v-if="fileType === 'docx'":src="fileSrc"@rendered="renderedHandler"@error="errorHandler"/><vue-office-excelclass="temp"v-if="fileType === 'excel'":src="fileSrc":options="excelOptions"@rendered="renderedHandler"@error="errorHandler"/><vue-office-pdfclass="temp"v-if="fileType === 'pdf'":src="fileSrc"@rendered="renderedHandler"@error="errorHandler"/><vue-office-pptxclass="temp"v-if="fileType === 'pptx'":src="fileSrc"@rendered="renderedHandler"@error="errorHandler"/></div>
</template><script>
import VueOfficeDocx from "@vue-office/docx";
// import VueOfficeDocx from "@vue-office/docx/lib/v3/vue-office-docx.mjs";
import "@vue-office/docx/lib/index.css";
// import "@vue-office/docx/lib/v3/index.css";import VueOfficeExcel from "@vue-office/excel";
// import VueOfficeExcel from "@vue-office/excel/lib/v3/vue-office-excel.mjs";
import "@vue-office/excel/lib/index.css";
// import "@vue-office/excel/lib/v3/index.css";import VueOfficePdf from "@vue-office/pdf";
// import VueOfficePdf from "@vue-office/pdf/lib/v3/vue-office-pdf.mjs";import VueOfficePptx from "@vue-office/pptx";
// import VueOfficePptx from "@vue-office/pptx/lib/v3/vue-office-pptx.mjs";export default {name: "OfficeViewer",components: {VueOfficeDocx,VueOfficeExcel,VueOfficePdf,VueOfficePptx},props: {fileType: {type: String,required: true,validator: value => ["docx", "excel", "pdf", "pptx"].includes(value)},fileSrc: {type: [String, Blob, ArrayBuffer],required: true},excelOptions: {type: Object,default: () => {return {xls: false,minColLength: 0,minRowLength: 0,widthOffset: 10,heightOffset: 10,beforeTransformData: workbookData => {return workbookData;},transformData: workbookData => {return workbookData;}};}}},data() {return {loading: true};},methods: {renderedHandler() {this.loading = false;this.$emit("rendered");console.log("渲染完成");},errorHandler() {this.loading = false;this.$emit("error");console.log("渲染失败");},/*** @Event 方法* @description: 通过流地址预览 Demo* @author: mhf* @time: 2025-07-21 17:06:57**/async viewByBlob() {const url = "/reservoirRealData/reservoirReport/export?id=313";const header = {authorization:"eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbktleSI6IjY1Yjk4NWZhMWY2NzQyZGU5N2Q5NmQyZjI4MTU2YzQxIiwiZGVwdElkIjoxMDEsInVzZXJOYW1lIjoiYWRtaW4iLCJ1c2VySWQiOjEwfQ.p2AVdvAZtFVfhK_YTkG1dr9jfJKR-qD_8JJ6bv4Vw4k","token-code-header": "system"};try {const response = await fetch(url, {method: "GET",headers: header});if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const blob = await response.blob();// 注意:这里需要根据实际情况调整,Vue2中可能需要使用其他方式存储// this.docx = await blob.arrayBuffer();} catch (error) {console.error("获取文档失败:", error);this.loading = false;this.errorHandler();}}},mounted() {this.loading = true;}
};
</script><style scoped lang="scss">
.temp {width: 100%;height: 100%;overflow: auto;
}
</style>

3. 文件上传组件封装fileUploadYt.vue

<!--* @Description: 文件上传通用 组件 页面* @Author: mhf* @Date: 2023-04-24 18:32:39* @Desc: 具体使用请参考 attachConfigDialog.vue 页面* @Warning: 弹窗中使用该组件时,需设置 v-if="dialogVisible" 否则将会存在文件缓存
-->
<template><div class=""><el-uploadclass="upload-demo"ref="uploadFile":disabled="utilsObj.isDisabled":action="actionUrl":headers="headerObj":file-list="utilsObj.fileList":limit="utilsObj.limitNum":http-request="handleUpload":multiple="utilsObj.isMultiple":on-preview="handlePreview":on-success="handleSuccess":on-remove="handleRemove":before-upload="handBeforeUpload":on-exceed="handleExceed"><!-- 上传按钮样式选择 --><div v-if="utilsObj.typeStyle === 0"><!-- 按钮样式 --><el-button:disabled="utilsObj.isDisabled"size="small"icon="iconfont if-biaodancaozuo-xinzeng"class="">{{ utilsObj.content || "附件" }}</el-button></div><!-- el-icon样式 --><div v-if="utilsObj.typeStyle === 1"><div v-if="!utilsObj.isDisabled" class="fileBox"><i class="iconfont if-daochu" /><div>{{ utilsObj.content || "点击上传" }}</div><div class="tips"><div class="red"><i class="el-icon-remove"></i>涉密工作及涉密信息请勿上传</div><div class="yellow"><i class="el-icon-warning yellow"></i>重要文件请修改好文件名称再上传</div></div></div></div><!--  若自定义样式,请使用插槽:<slot></slot>  --><div v-if="utilsObj.typeStyle === 2"><slot name="customBtn" /></div><el-progressv-if="singlePartFileProgress > 0 && singlePartFileProgress < 100"class="progress":percentage="singlePartFileProgress"/><!-- 上传按钮样式选择 --><div slot="file" slot-scope="{ file }" class="file-slot"><div class="file-slot-content"><i class="el-icon-upload-success el-icon-circle-check"></i><div class="file-slot-content-name">{{ file.name }}</div><el-buttonv-if="isPreviewable(file)"type="text"class="file-slot-content-preview"icon="el-icon-document"@click="filePreview(file)">预览</el-button><el-buttontype="text"class="file-slot-content-preview"icon="el-icon-download"@click="handlePreview(file)">下载</el-button><el-buttonv-if="!utilsObj.isDisabled"type="text"class="file-slot-content-remove"icon="el-icon-delete"@click="handleRemove(file)">删除</el-button></div></div></el-upload></div>
</template><script>
import { getToken } from "@/utils/auth";
import { upLoad, upLoadChunk } from "@/api/system/config";
export default {name: "Index",components: {},props: {/* 注意: 如果props里面的对象有默认参数时,必须用函数return一个对象 */utilsObj: {type: Object,default: () => ({isDisabled: false, // 是否禁用fileList: [], // 附件列表limitNum: 3, // 限制上传的文件数量 (个)fileSize: 50, // 单文件上传大小(MB)typeStyle: 0, // 文件上传的样式控制isMultiple: false, // 是否支持同时选择多个文件content: null // 上传按钮展示的文字内容})}, // 附件上传的配置项headerObj: {type: Object,default: function () {return {Authorization: getToken(),"Token-Code-Header": this.$tokenCodeHeader};}}, // 文件上传请求头参数 --- tokenurl: {type: String,default: "/annexAction/upload"},chunkSize: {type: Number, //分块大小default: 10}},data() {return {resFileArr: [], // 最终需要的文件数据chunkFile: {}, //分片上传文件信息singlePartFileProgress: 0, //文件上传进度processTimer: null //文件上传定时器};},computed: {// 附件上传的配置项actionUrl() {return process.env.VUE_APP_BASE_API + this.url;}},created() {},mounted() {setTimeout(() => {if (this.utilsObj.fileList) {this.resFileArr = this.utilsObj.fileList;}}, 500);},methods: {/*** @Event 方法 文件切片* @description: 将文件切割成多块* */sliceFile(file, chunkSize) {const chunks = [];let offset = 0;while (offset < file.size) {const chunk = file.slice(offset, offset + chunkSize);chunks.push(chunk);offset += chunkSize;}return chunks;},// 分片上传文件async uploadFileChunks(file, chunkSize) {console.log("file", file, this.chunkFile);const chunks = this.sliceFile(file, chunkSize);console.log(chunks);let exeCount = 1;for (let i = 0; i < chunks.length; i++) {const formData = new FormData();formData.append("file", chunks[i]);formData.append("fileName", this.chunkFile.file.name);formData.append("fileUid", this.chunkFile.file.uid);formData.append("partIndex", i + 1);formData.append("partTotalNum", chunks.length);try {if (this.processTimer) {clearInterval(this.processTimer);}this.processTimer = setInterval(() => {if (this.singlePartFileProgress +Math.floor(100 / chunks.length / 10) <Math.floor((100 / chunks.length) * exeCount)) {let process =Math.floor(100 / chunks.length / 10) <= 0? 1: Math.floor(100 / chunks.length / 10);this.singlePartFileProgress =this.singlePartFileProgress + process;}}, 500);const res = await upLoadChunk(formData);console.log(res);if (res.code === 1) {this.singlePartFileProgress = Math.floor((100 / chunks.length) * exeCount);exeCount++;if (this.processTimer) {clearInterval(this.processTimer);}if (i + 1 == chunks.length) {this.singlePartFileProgress = 100;this.handleSuccess(res);}} else {this.$message.error(res.msg);}} catch (error) {if (this.processTimer) {clearInterval(this.processTimer);}this.singlePartFileProgress = 0;// console.log(this.utilsObj.fileList);this.removeFailUpload();break;}}},/*** @Event 方法 当文件上传失败时,删除失败的文件* @description:  文件上传失败,依旧会在界面显示失败的一个文件,会造成上传成功的假象* */removeFailUpload() {let uid = this.chunkFile.file.uid; // 关键作用代码,去除文件列表失败文件let idx = this.$refs.uploadFile.uploadFiles.findIndex(item => item.uid === uid); // 关键作用代码,去除文件列表失败文件(uploadFiles为el-upload中的ref值)this.$refs.uploadFile.uploadFiles.splice(idx, 1); // 关键作用代码,去除文件列表失败文件},/*** @Event 方法 实现文件上传逻辑,包括文件分片处理* @description:  覆盖默认的上传行为,可以自定义上传的实现* */handleUpload(file) {this.chunkFile = file;//判断当前文件是否需要分块上传 默认 10mb以上if (file.file.size > this.chunkSize * 1024 * 1024) {this.uploadFileChunks(file.file, this.chunkSize * 1024 * 1024);} else {const formData = new FormData();formData.append("file", file.file);if (this.processTimer) {clearInterval(this.processTimer);}this.processTimer = setInterval(() => {if (this.singlePartFileProgress + 10 < 100) {this.singlePartFileProgress = this.singlePartFileProgress + 10;} //定时器,显示一个上传进度}, 500);upLoad(formData).then(res => {this.handleSuccess(res);}).catch(err => {this.removeFailUpload();}).finally(() => {if (this.processTimer) {this.singlePartFileProgress = 0;clearInterval(this.processTimer);}});}},/*** @Event 方法* @description: 点击文件列表中已上传的文件时的钩子* */handlePreview(file) {let fileType = file?.suffix || file?.response?.data?.suffix;if (file.response) {// 上传文件的时候 查看window.open(file.response.data.url,fileType === ".pdf" ? "_blank" : "_self");} else {// 文件上传成功之后返回值 查看window.open(file.url, fileType === ".pdf" ? "_blank" : "_self");}},/*** @Event 方法* @description: 文件上传成功时的钩子* */handleSuccess(file) {this.singlePartFileProgress = 0;console.log("文件上传成功时的钩子", file);if (file.code === 1) {this.resFileArr.push(file.data);this.$emit("getFileUploadYt", this.resFileArr);} else {this.$message.warning(file.message);}},/*** @Event 方法* @description: 文件列表移除文件时的钩子* */handleRemove(file) {if (file.response) {this.resFileArr.map((item, index) => {if (item === file.response.data ||item.url === file.response.data.url) {this.resFileArr.splice(index, 1);this.$emit("getFileUploadYt", this.resFileArr);}});} else {this.resFileArr.map((item, index) => {if (item === file || item.url === file.url) {this.resFileArr.splice(index, 1);this.$emit("getFileUploadYt", this.resFileArr);}});}},/*** @Event 方法* @description: 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。* */handBeforeUpload(file) {if (["application/vnd.android.package-archive","application/x-zip-compressed","text/plain","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"].indexOf(file.type) === -1) {this.$message.error("请上传后缀名为 apk、zip、pdf、txt、doc、docx、xls、xlsx的文件");return false;}if (file.size > this.utilsObj.fileSize * 1024 * 1024) {this.$message.error(`文件大小不能超过 ${this.utilsObj.fileSize}MB`);return false;}},/*** @Event 方法* @description: 文件超出个数限制时的钩子* */handleExceed(files, fileList) {this.$message.warning(`当前限制选择 ${this.utilsObj.limitNum} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);},isPreviewable(file) {const fileType = file.suffix;const previewableTypes = [".xls",".xlsx",".XLS",".XLSX",".doc",".docx",".DOC",".DOCX",".ppt",".pptx",".pdf",".PPT",".PPTX",".PDF"];let fileView = false;if (file && file.url) {fileView = previewableTypes.includes(fileType);}return fileView;},filePreview(file) {const suffix = file.suffix;const typeMapper = {docx: [".doc", ".docx", ".DOC", ".DOCX"],excel: [".xls", ".xlsx", ".XLS", ".XLSX"],pptx: [".ppt", ".pptx", ".PPT", ".PPTX"],pdf: [".pdf", ".PDF"]};const fileType = Object.keys(typeMapper).find(key =>typeMapper[key].includes(suffix));window.open("/filePreviewer?fileSrc=" + file.url + "&fileType=" + fileType);}}
};
</script><style lang="scss" scoped>
::v-deep .fileBox {height: 36px;background: rgba(255, 255, 255, 0);border-radius: 4px;display: flex;align-items: center;color: #1492ff !important;font-weight: bold;font-size: 16px;i {margin-right: 5px;}
}.disabledClass {margin-top: -35px;
}.file-slot {padding: 2px 10px;&-content {display: flex;flex-direction: row;align-items: center;&-name {margin-left: 10px;}&-preview {padding: 0 !important;border: none;margin-left: 10px;}&-remove {padding: 0 !important;border: none;color: #fc5c5c !important;}}
}::v-deep .el-upload {display: block !important;text-align: left !important;
}
.tips {font-size: 14px;margin-left: 8px;display: flex;.red {color: #fc5c5c;}.yellow {margin-left: 8px;color: #f1924e;}
}
</style>

4. 使用示例

<template><el-dialogv-dialog-outwidth="700px":title="title":visible.sync="dialogVisible":before-close="hideDialog":close-on-click-modal="false"><div class="dialog-body"><el-formref="form":model="formData":rules="formRules"label-width="5.5rem"><el-form-item label="考核标题 : " prop="title"><el-input:disabled="['详情'].includes(title)"v-model="formData.title"placeholder=""/></el-form-item><!-- 1 区县 2 乡镇 --><el-form-item label="区域类型 : " prop="areaType"><el-selectv-model="formData.areaType"filterableplaceholder="":disabled="['详情'].includes(title)"@change="changeAreaType"><el-optionv-for="item in dict.type.situation_area_type":key="item.value":label="item.label":value="parseInt(item.value)"/></el-select></el-form-item><el-form-item label="考核区域 : " prop="areaNames"><el-inputv-model="formData.areaNames"placeholder=""readonly:disabled="['详情'].includes(title)"><template slot="append"><div class="choose-class" @click="chooseDialogs"><i class="iconfont if-sousuo" /><span style="margin-left: 10px">{{title === "详情" ? "查看" : "选择"}}</span></div></template></el-input></el-form-item><el-form-item label="考核周期 : " prop="period"><el-selectv-model="formData.period"filterableplaceholder="":disabled="['详情'].includes(title)"><el-optionv-for="item in quarterList":key="item.value":label="item.label":value="item.value"/></el-select></el-form-item><!-- <el-form-item label="考核类型 : " prop="checkType"><el-input:disabled="['详情'].includes(title)"v-model="formData.checkType"/></el-form-item> --><el-form-item label="备注 : " prop="remark"><el-inputv-model="formData.remark"placeholder="":disabled="['详情'].includes(title)"type="textarea":rows="3"maxlength="200"show-word-limit></el-input></el-form-item><el-form-item label="附件 : " prop="attachment"><fileUploadYtv-if="dialogVisible"ref="fileUploadYt"@getFileUploadYt="getAnnexUrl":utilsObj="fileUploadUtils"/></el-form-item></el-form></div><lineH v-if="!['详情'].includes(title)" /><div class="dialog-footer" v-if="!['详情'].includes(title)"><el-button @click="hideDialog">取 消</el-button><el-button type="primary" @click="validateForm">确 定</el-button></div></el-dialog>
</template><script>
import {areaAssessInsert,areaAssessGetInfo,areaAssessUpdate
} from "@/api/assessEvaluate/assessArea";
import { listByPage } from "@/api/system/dept";
import { areaList } from "@/api/system/deptArea";
import { generateQuarterList } from "@/utils/index";
export default {name: "countyEvaluationDialog",components: {},props: {},dicts: ["situation_area_type"],provide() {return {requestName: areaList};},data() {return {defaultParams: {// areaType 1 区县 2 乡镇   nodeType 0 省市级 1 区县级 2公司/部门 3 乡镇// nodeType: "1"},formLabel: [{label: "区域名称",value: "areaName"}],tableDataColumn: [{label: "区域名称",prop: "areaName"},{label: "创建时间",prop: "createTime"}// {//   label: "管理单位",//   prop: "deptName"// }],dialogVisible: false,title: "",formData: {},formRules: {title: [{ required: true, message: "请输入模版标题", trigger: "blur" }],areaType: [{ required: true, message: "请选择区域类型", trigger: "blur" }],areaNames: [{ required: true, message: "请选择考核区域", trigger: "blur" }],period: [{ required: true, message: "请选择考核周期", trigger: "blur" }]},fileUploadUtils: {isDisabled: false,fileList: [],limitNum: 4,typeStyle: 1,content: "考核文件"},selectList: [],quarterList: generateQuarterList()};},methods: {changeAreaType(e) {// areaType 1 区县 2 乡镇   nodeType 0 省市级 1 区县级 2公司/部门 3 乡镇console.log("e", e);this.defaultParams.areaType = e == 1 ? "1" : "3";this.selectList = [];this.$set(this.formData, "areaNames", "");this.$set(this.formData, "areaIds", "");},getAnnexUrl(data) {console.log(data);this.$set(this.formData, "attachment", JSON.stringify(data));},chooseDialogs() {if (!this.formData.areaType) {this.$message.warning("请选择区域类型");return;}let passData = {data: this.selectList,title: "选择考核区域"};this.$refs.chooseDialogs.showDialog(passData);},getListByDialog(data) {this.$set(this.formData,"areaNames",data.map(i => i.areaName).join(","));this.$set(this.formData,"areaIdList",data.map(i => i.id));this.selectList = JSON.parse(JSON.stringify(data));},showDialog(data) {console.log("data", data);// areaType 1 区县 2 乡镇   nodeType 0 省市级 1 区县级 2公司/部门 3 乡镇this.$set(this.defaultParams, "areaType", 1);this.dialogVisible = true;this.title = data.type;if (data.data) {this.getDetail(data.data.id);}if (data.type === "详情") {this.fileUploadUtils.isDisabled = true;}},hideDialog() {this.dialogVisible = false;// this.isDisable = false;// this.$refs.form.resetFields();this.formData = {};this.fileUploadUtils.fileList = [];this.fileUploadUtils.isDisabled = false;this.selectList = [];this.$parent.getTableData();},getDetail(id) {areaAssessGetInfo({ id }).then(res => {if (res.code === 1) {this.formData = {...res.data,period: `${res.data.year}-${res.data.quarter}`};this.defaultParams.areaType = res.data.areaType == 1 ? "1" : "3";this.selectList = res.data.areaIdList.map((id, index) => ({id: id,areaName: res.data.areaNames.split(",")[index]?.trim() || "未知区域"}));try {if (this.formData.attachment) {this.fileUploadUtils.fileList = JSON.parse(this.formData.attachment);} else {this.fileUploadUtils.fileList = [];}} catch (error) {this.fileUploadUtils.fileList = [];}}});},async validateForm() {try {if (await this.$refs.form.validate()) this.submitForm();} catch (e) {}},submitForm() {if (this.title === "新增") {areaAssessInsert({...this.formData,year: this.formData.period.split("-")[0],quarter: this.formData.period.split("-")[1]}).then(res => {if (res.code === 1) {this.$message.success("新增成功");this.hideDialog();}});} else if (this.title === "编辑") {areaAssessUpdate({...this.formData,year: this.formData.period.split("-")[0],quarter: this.formData.period.split("-")[1]}).then(res => {if (res.code === 1) {this.$message.success("编辑成功");this.hideDialog();}});}}},created() {},mounted() {}
};
</script><style lang="scss" scoped>
::v-deep .el-dialog__body {padding: 20px 0 0 !important;
}.dialog-body {padding: 0 20px;max-height: 65vh;overflow-y: auto;
}.dialog-footer {text-align: center;padding: 10px 0 18px;
}
</style>

http://www.dtcms.com/a/582612.html

相关文章:

  • 嵌入式Linux C语言程序设计九
  • Git 分支流程(合并分支)
  • idea可以做网站吗最好的网站代运营公司
  • BSS供应商:电信与金融领域的幕后支撑者
  • 精通网站开发书籍wordpress 很占内存
  • 找个男做那个视频网站好东营网站建设哪家更好
  • Linux/Windows 安装miniforge
  • 近3年时政与综合类结构化真题汇总与备考策略
  • 设备资产管理都有哪些具体业务
  • 从一到无穷大 #55 提升Lakehouse查询性能:数据层面
  • 交互设计专业学什么seo常用工具网站
  • 如何让百度快速大量收录 如何增加百度收录量的方法有哪些
  • APP上架到应用商店的完整流程解析
  • 莆田网站建设维护网站制作的分割线怎么做
  • Python 字典推导式入门:一行构建键值对映射
  • 怎么让自己的网址被百度收录(网站如何被百度收录进去)
  • 简易静态网站制作流程图室内设计师工资
  • 爬虫导致IP被封号了如何解封?
  • 网站平台建设公司邮箱或企业邮箱
  • 临沂网站制作加速企业发展用什么软件制作网站
  • C++:类和对象---进阶篇
  • 深圳市南山区住房和建设局网站官网淘宝客怎么做网站导购
  • e网科技网站石家庄seo网站优化公司
  • 合肥响应式网站开发方案网站建设新得体会
  • 手绘教学网站网络规划与设计专业
  • 网站做多语言wordpress 仿虎嗅
  • 打工人日报#20251107
  • 网站常用颜色wordpress 替换编辑器
  • 数据治理咨询项目方案建议书
  • SSE实时推送订单状态