前言:avue实现原文件上传是有格式限制的,且预览展示效果稍微差点,我使用kkfileview去写,这样不会限制文件上传格式
- <basic-container>
- <avue-crud ref="crud"
- v-model="form"
- :before-open="beforeOpen"
- :data="data"
- :option="option"
- :page.sync="page"
- :permission="permissionList"
- :table-loading="loading"
- :upload-after="uploadAfter"
- :upload-before="uploadBefore"
- :upload-delete="uploadDelete"
- :upload-preview="uploadPreview"
- @row-update="rowUpdate"
- @row-save="rowSave"
- @row-del="rowDel"
- @search-change="searchChange"
- @search-reset="searchReset"
- @selection-change="selectionChange"
- @current-change="currentChange"
- @size-change="sizeChange"
- @on-load="onLoad">
- <template slot="fileName" slot-scope="{ type, size, row }">
- <div class="download">
- <div v-for="(item, index) in row.fileLocation" :key="index">
- <el-tooltip :content="item.name" class="item" effect="dark
- placement="bottom">
- <div @click="downloadAnnex(row.fileLocation[index], item)">
- {{ item.name }}
- div>
- el-tooltip>
- div>
- div>
- avue-crud>
- <showFile ref="showFileList" :fileLocationName="fileLocationName"
- :fileUpdata="fileUpdata">showFile>
- basic-container>
- template>
-
-
- import { add, getDetail, getList, remove, update, upspecialdata } from "@/api/safety/administration/safetylicense";
- import { mapGetters } from "vuex";
- import showFile from "../../safety/showFile.vue";
- import safetydivicecloseopenshrecord from "@/views/public/safetydivicecloseopenshrecord.vue";
- import { updateFileLocation } from "@/mixins/update-file-location"
-
- export default {
- components: {
- showFile,
- },
- mixins: [updateFileLocation],
- data() {
- fileUpdata: "fileName", // 表格显示时用
- fileLocationName: "fileLocation", // 附件本字段
- form: {},
- query: {},
- loading: true,
- page: {
- pageSize: 10,
- currentPage: 1,
- total: 0,
- },
- selectionList: [],
- option: {
- height: "auto",
- calcHeight: 210,
- searchShow: true,
- searchMenuSpan: 6,
- tip: false,
- border: true,
- index: true,
- viewBtn: true,
- selection: true,
- labelWidth: 140,
- column: [
- {
- label: "许可证照上传",
- prop: "fileLocation",
- type: "upload",
- dataType: "object",
- showFileList: true,
- showColumn: false,
- multiple: true,
- drag: false,
- loadText: "附件上传中,请稍等",
- previewSrcList: false,
- propsHttp: {
- name: "originalName",
- url: "link",
- res: "data",
- // home: "domain",
- },
- props: {
- label: 'name',
- value: 'link'
- },
- action: "/api/blade-resource/oss/endpoint/put-file-attach",
- span: 24, rules: [{
- required: true,
- message: "请输入附件",
- trigger: "blur"
- }]
-
-
- },
-
- {
- label: "文件预览",
- prop: "fileName",
- display: false,
- showColumn: true,
- rules: [
- {
- required: true,
- message: "请输入文件名称",
- trigger: "blur",
- },
- ],
- },
- },
- ],
- },
- data: [],
- };
- },
-
- methods: {
- shrecordfun(row, index) {
- this.closeoropenid = row.id;
- this.shrecordVisible = true;
- },
-
- // 是否点击放大图片
- uploadPreview(file, column, done) {
- this.$nextTick(() => {
- /**
- * e:文件路径
- * k:源文件名字
- */
- this.$refs.showFileList.downloadAnnex(file.url || file.link, file.name);//调用组件方法
- });
- },
- // 预览方法
- downloadAnnex(e, k) {
- this.$nextTick(() => {
- this.$refs.showFileList.downloadAnnex(e.url || e.link, k);//调用组件方法
- });
- },
- // 上传前方法
- uploadBefore(file, done, loading, column) {
- done()
- },
- // 上传后方法
- uploadAfter(res, done, loading, column) {
- this.form[this.fileLocationName] = this.formFileLocation(res, this.fileLocationName)
- done()
- },
- // 删除前的方法
- uploadDelete(file, column) {
- this.$nextTick(() => {
- this.$refs.showFileList.frontUploadDelete(file, column); //调用组件方法
- });
- },
-
- // 新增数据调取接口
- rowSave(row, done, loading) {
- row[this.fileLocationName] = JSON.stringify(row[this.fileLocationName])
- // 结束
- add(row).then(
- () => {
- done();
- this.onLoad(this.page);
- this.$message({
- type: "success",
- message: "操作成功!",
- });
- },
- (error) => {
- window.console.log(error);
- loading();
- }
- );
- },
-
- // 编辑数据调取接口
- rowUpdate(row, index, done, loading) {
- // 修改事件
- // row[this.tableDisplay] = ""; //表格显示的字段
- row[this.fileLocationName] = JSON.stringify(row[this.fileLocationName])
- // 结束
- update(row).then(
- () => {
- done();
- this.onLoad(this.page);
- this.$message({
- type: "success",
- message: "操作成功!",
- });
- },
- (error) => {
- window.console.log(error);
- loading();
- }
- );
- },
- // 点击查看/编辑查看数据
- beforeOpen(done, type) {
- this.$nextTick(() => {
- this.$refs.showFileList.add(type);//调用组件方法
- });
- if (["edit", "view"].includes(type)) {
-
- getDetail(this.form.id).then((res) => {
- this.form[this.fileLocationName] = this.formData(res, this.fileLocationName)
- });
- }
- done();
- },
- searchReset() {
- this.query = {};
- this.onLoad(this.page);
- },
- searchChange(params, done) {
- this.query = params;
- this.page.currentPage = 1;
- this.onLoad(this.page, params);
- done();
- },
- selectionChange(list) {
- this.selectionList = list;
- },
- selectionClear() {
- this.selectionList = [];
- this.$refs.crud.toggleSelection();
- },
- currentChange(currentPage) {
- this.page.currentPage = currentPage;
- this.onLoad(this.page);
- },
- sizeChange(pageSize) {
- this.page.pageSize = pageSize;
- },
-
- // 页面初始数据加载
- onLoad(page, params = {}) {
- this.loading = true;
- params.mytype = "3";
- getList(
- page.currentPage,
- page.pageSize,
- Object.assign(params, this.query)
- ).then((res) => {
- const data = res.data.data;
- this.page.total = data.total;
- this.data = this.dataRecords(data, this.fileLocationName)
- this.loading = false;
- this.selectionClear();
- });
- },
- },
注意:
文件上传:
1)、type:'upload'
2)、
dataType
配置数据的结构string
或object,
当
dataType
配置为object
时,可以配置props
存储的数据结构
label
图片的名称value
路径地址3)、
propsHttp
配置请求接口返回的数据结构
name
图片的名称url
路径地址res
返回数据层级结构home
相对路径的主路径意思就是你配置
dataType为object,传给后台:json数据格式
eg:"[{\"name\":\"原平经济技术开发区化工园区禁限控目录.pdf\",\"link\":\"/261267-sksoft/upload/20230828/8855ad3f839c2831c2c07c9f8f645af6.pdf\"}]"
字段回显就会是中文,不需要自己在单独处理数据
4)、action:是上传文件调取的接口
5)、showfile文件是我写的公共的上文件组件 不使用原生的预览样式,自己封装的6)、rowUpdate - rowSave - beforeopen - onLoad页面中使用的方法是我封装的mixins的方法
7)、fileLocationName定义的是上传文件的给后端传接口的字段名字,因为名字不同所以写了这个来定义
3、showfile文件
- <div>
- // 不使用avue原生的预览样式
- <el-dialog title="预览与下载" :visible.sync="dialogVisible" width="60%" :fullscreen="dialogFull"
- :before-close="handleClose" :append-to-body="true" :modal-append-to-body="false">
- <template slot="title">
- <div class="avue-crud__dialog__header">
- <span class="el-dialog__title">
- <span style="
- display: inline-block;
- background-color: #3478f5;
- width: 3px;
- height: 20px;
- margin-right: 5px;
- float: left;
- margin-top: 2px;
- ">span>
- 预览与下载
- span>
- <div class="avue-crud__dialog__menu" @click="dialogFull ? (dialogFull = false) : (dialogFull = true)">
- <i class="el-icon-full-screen">i>
- div>
- div>
- template>
- <div class="dialogVisible">
- <div class="dialogVisible_left">
-
- <iframe id="frmDialog" frameborder="0" width="100%" height="750rpx" allowfullscreen="true"
- :src="pdfWord">iframe>
- div>
- div>
- <span slot="footer" class="dialog-footer">
- <el-button @click="handleClose">取 消el-button>
- <el-button type="primary" @click="dialogVisibleDow">下载el-button>
- span>
- el-dialog>
- div>
-
- <script>
- export default {
- props: {
- tableDisplay: String,
- fileUpdata: String,
- fileLocationName: String
- },
- data() {
- return {
- dialogFull: false,
- dialogVisible: false,
- pdfWord: "",
- imgurl: "",
- flieName: [],
- fileUrl: [],
- dowName: "",
- addName: [],
- annexStrList: [],
- demoDel: [],
- btnAnnexStrList: []
- };
- },
- methods: {
- // 全屏
- handleClose(done) {
- this.dialogVisible = false
- this.dialogFull = false,
- done();
- },
- // 文件预览
- downloadAnnex(e, data) {
- this.dowName = data;
- // let KKFILEIP = "线上地址";
- let KKFILEIP = "http://127.0.0.1";
- // const fileurl =""
- // if(e.indexOf(window.location.origin)>=0){
- // fileurl =e
- // }else{
- // fileurl = window.location.origin + e;
- // }
- // const fileurl = window.location.origin + e;
- // const fileurl = '地址' + e;
- const fileurl = '测试地址' + e;
- console.log(fileurl, 'fileurl');
- this.imgurl = fileurl;
- this.pdfWord =
- KKFILEIP +
- // ":10001/preview/onlinePreview?url=" +
- ":8012/onlinePreview?url=" +
- encodeURIComponent(Base64.encode(fileurl));
- this.dialogVisible = true;
- },
- // 下载图片
- dialogVisibleDow() {
- getBlob(this.imgurl).then((blob) => {
- saveAs(blob, this.dowName);
- });
- function getBlob(url) {
- return new Promise((resolve) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", url, true);
- xhr.responseType = "blob";
- xhr.onload = () => {
- if (xhr.status === 200) {
- resolve(xhr.response);
- }
- };
- xhr.send();
- });
- }
- function saveAs(blob, filename) {
- const elelink = document.createElement("a");
- elelink.style.display = "none";
- elelink.download = filename;
- elelink.href = window.URL.createObjectURL(blob);
- document.body.appendChild(elelink);
- elelink.click();
- document.body.removeChild(elelink);
- }
- },
- // 上传前方法
- frontUploadBefore(file, done, loading, column) {
- this.flieName.push(file.name);
- done();
- },
- // 上传后方法
- behindUploadAfter(res, done, loading, column) {
- if (this.annexStrList[0] == "" || this.annexStrList[0] == ",") {
- this.annexStrList = []
- }
- let a = { url: res.link, name: res.originalName }
- // // this.addName.push(res.link + "-" + res.originalName)
- this.addName.push(a)
- this.annexStrList.push(a.url)
- done();
- },
- // 删除前的方法
- frontUploadDelete(file, column) {
- this.fileUrl.push(file.url);
- this.demoDel.push(this.annexStrList[file.uid])
- this.annexStrList.splice(file.uid, 1)
- },
- //
- //打开时候要执行的东西
- add(type) {
- this.addName = [];
- this.demoDel = [];
- if (type == "add") {
- this.flieName = [];
- }
- },
- addRes(res) {
- if (res.data.data[this.tableDisplay]) {
- let filelist = JSON.parse(res.data.data[this.tableDisplay]);
- let alist = [];
- for (let i = 0; i < filelist.length; i++) {
- let b = { name: filelist[i].name, url: filelist[i].url }
- alist.push(b);
- }
- this.annexStrList = alist
- return alist;
- }
-
- },
-
- flieNameList() {
- return this.flieName
- },
- fileUrlList() {
- this.fileUrl = []
-
- },
- demoDelList() {
- return this.demoDel.toString();
-
- },
- addNameList() {
- return JSON.stringify(this.addName)
- },
- annexStrNameList() {
- return this.annexStrList.toString()
- },
- annexStrNameListView() {
- return this.annexStrList
-
- },
- //初始加载
- flieOnload(data) {
- for (let i = 0; i < data.records.length; i++) {
- let allName = [];
- if (data.records[i][this.tableDisplay]) {
- data.records[i][this.tableDisplay] = data.records[i][this.tableDisplay].split(",");
- let arr = data.records[i][this.tableDisplay];
- for (let j = 0; j < arr.length; j++) {
- let index = arr[j].indexOf("-");
- let list = arr[j].substring(index + 1, arr[j].length);
- allName.push(list.toString());
- }
- data.records[i][this.fileUpdata] = allName;
- data.records[i][this.fileLocationName] = data.records[i][this.fileLocationName].split(",");
- }
- }
- },
- },
- };
- script>
-
-
- <style scoped lang="scss">
- /* dialog*/
- .el-dialog__header {
- padding: 15px 20px 15px;
- }
-
- .el-dialog__headerbtn {
- top: 15px;
- }
-
- /*dialog header*/
- /deep/.el-dialog__header {
- background: #e3eaed;
- }
-
- /deep/.avue-crud__dialog__header {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: justify;
- -ms-flex-pack: justify;
- justify-content: space-between;
- }
-
- /deep/.el-dialog__title {
- color: rgba(0, 0, 0, 0.85);
- font-weight: 500;
- word-wrap: break-word;
- }
-
- /deep/.avue-crud__dialog__menu {
- padding-right: 20px;
- float: left;
- }
-
- /deep/.avue-crud__dialog__menu i {
- color: #909399;
- font-size: 15px;
- }
-
- /deep/.el-icon-full-screen {
- cursor: pointer;
- }
-
- /deep/.el-icon-full-screen:before {
- content: "\e719";
- }
-
- .download {
- color: rgb(50, 185, 226);
- }
-
- .dialogVisible {
- display: flex;
- }
-
- .dialogVisible_right {
- width: 50%;
- }
-
- .dialogVisible_left {
- width: 100%;
- }
-
- .imgurl {
- height: 100%;
- width: 100%;
- }
- style>
注意:这一块代码可能会有点乱,vue页面 有上传前,上传后方法就不会使用shoefile文件的方法,showfile页面的方法是针对图片上传的方法
4、updateFileLocation文件
- export const updateFileLocation = {
- methods: {
- formFileLocation(res, fileLocationName) {
- let a = [
- ...this.form[fileLocationName],
- {
- name: res.originalName,
- link: res.link,
- },
- ]
- return a
- },
- isJSON(data) {
- try {
- JSON.parse(data)
- return true
- } catch (error) {
- return false
- }
- },
- formData(res, fileLocationName) {
- let b = this.isJSON(res.data.data[fileLocationName])
- ? JSON.parse(res.data.data[fileLocationName])
- : ''
- return b
- },
- dataRecords(data, fileLocationName) {
- return data.records.map((i) => {
- const obj = this.isJSON(i[fileLocationName])
- ? JSON.parse(i[fileLocationName])
- : ''
- i[fileLocationName] = obj || null
- return i
- })
- },
- },
- }