提交 9b69af4a 编写于 作者: laizhilong's avatar laizhilong

表单自定义上传附件组件:

1.持久化:新建表单保存时批量更新文件表,编辑表单保存时不批量更新;
2.删除文件走后台统一接口
上级 d16b955c
...@@ -8,14 +8,12 @@ ...@@ -8,14 +8,12 @@
drag drag
multiple multiple
list-type="text" list-type="text"
:action="action" :action="getAction"
:headers="myHeaders" :headers="myHeaders"
:file-list="uploadFileList" :file-list="uploadFileList"
:show-file-list="false" :show-file-list="false"
:limit="limit" :limit="limit"
:before-upload="beforeUpload" :http-request="customUploadFile">
:on-success="uploadSuccess"
:on-error="uploadError">
<div> <div>
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div> <div>
...@@ -32,13 +30,12 @@ ...@@ -32,13 +30,12 @@
ref="upload" ref="upload"
multiple multiple
list-type="text" list-type="text"
:action="action" :action="getAction"
:headers="myHeaders"
:file-list="uploadFileList" :file-list="uploadFileList"
:show-file-list="false" :show-file-list="false"
:limit="limit" :limit="limit"
:http-request="uploadFile" :http-request="customUploadFile">
:on-success="uploadSuccess"
:on-error="uploadError">
<el-button type="primary" size="small" icon="el-icon-upload">点击上传</el-button> <el-button type="primary" size="small" icon="el-icon-upload">点击上传</el-button>
<div slot="tip" class="el-upload__tip">{{uploadTip}}</div> <div slot="tip" class="el-upload__tip">{{uploadTip}}</div>
</el-upload> </el-upload>
...@@ -54,11 +51,11 @@ ...@@ -54,11 +51,11 @@
<el-link type="warning" icon="el-icon-view" v-show="showPreview" @click="onPreview(item)">预览 <el-link type="warning" icon="el-icon-view" v-show="showPreview" @click="onPreview(item)">预览
</el-link> </el-link>
<el-link type="primary" icon="el-icon-edit" <el-link type="primary" icon="el-icon-edit"
v-show="showEdit && (item.name.toString().match(/^.+\.(doc|DOC|docx|DOCX|wps|WPS|xls|XLS|xlsx|XLSX|ppt|PPT|et|ET)$/))" v-show="showEdit && (item.name.match(/^.+\.(doc|DOC|docx|DOCX|wps|WPS|xls|XLS|xlsx|XLSX|ppt|PPT|et|ET)$/))"
@click="onEdit(item)">编辑 @click="onEdit(item)">编辑
</el-link> </el-link>
<el-link icon="el-icon-camera" <el-link icon="el-icon-camera"
v-show="showOcrview && (item.name.toString().match(/^.+\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG|bmp|BMP|pdf|PDF)$/))" v-show="showOcrview && (item.name.match(/^.+\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG|bmp|BMP|pdf|PDF)$/))"
@click="onOcr(item)">OCR @click="onOcr(item)">OCR
</el-link> </el-link>
<el-link type="danger" icon="el-icon-delete" @click="onRemove(item,index)">删除</el-link> <el-link type="danger" icon="el-icon-delete" @click="onRemove(item,index)">删除</el-link>
...@@ -71,9 +68,11 @@ ...@@ -71,9 +68,11 @@
<script> <script>
import {Button, Row, Col, Link, Icon, Upload, Message, MessageBox} from 'element-ui'; import {Button, Row, Col, Link, Icon, Upload, Message, MessageBox} from 'element-ui';
import Axios from 'axios'; import Axios from 'axios';
import Qs from 'qs'; import {Subject, Unsubscribable} from 'rxjs';
// 当前登录人token
var token = "Bearer " + localStorage.getItem('token');
var token ="Bearer " +localStorage.getItem('token');
export default { export default {
name: "ibiz-file-upload", name: "ibiz-file-upload",
components: { components: {
...@@ -85,18 +84,22 @@ ...@@ -85,18 +84,22 @@
'el-upload': Upload, 'el-upload': Upload,
}, },
props: { props: {
// 当前表单对象 // 当前表单对象
data: { data: {
type: Object, type: Object,
}, },
// 当前属性名 // 当前属性名
name: { formItemName: {
type: String, type: String,
}, },
// 当前属性值 // 当前属性值
value: { value: {
type: String, type: String,
}, },
// 订阅表单状态
formState: {
type: Subject
},
// 默认为当前实体名称,有指定则按表单参数 // 默认为当前实体名称,有指定则按表单参数
folder: { folder: {
type: String, type: String,
...@@ -147,211 +150,208 @@ ...@@ -147,211 +150,208 @@
}, },
data() { data() {
return { return {
// 表单是否处于编辑状态(有真实主键,srfuf='1';srfuf='0'时处于新建未保存)
srfuf: '0',
// 上传提示语 // 上传提示语
uploadTip: `单个文件大小不超过${this.size}M,文件不超过${this.limit}个`, uploadTip: `单个文件大小不超过${this.size}M,文件不超过${this.limit}个`,
// 文件列表 // 文件列表
uploadFileList: [], uploadFileList: [],
// 临时文件列表
tempFileList: [],
// 移除的文件列表
removeFileList: [],
// headers // headers
myHeaders: {Authorization: token}, myHeaders: {Authorization: token},
// 表单状态事件
formStateEvent: Unsubscribable | undefined,
// 批量更新标识,false为不更新,true才可以更新
isUpdateBatch: true,
// 新建状态标识,true为新建,false为编辑
isCreate: true,
} }
}, },
computed: { computed: {
action() { /**
* return action
*/
getAction() {
const uploadUrl = '../net-disk/upload/' + this.getFolder + '?ownertype=' + this.getOwnertype + '&ownerid=' + this.getOwnerid;
return uploadUrl;
},
/**
* return folder
*/
getFolder() {
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
return folder;
},
/**
* return ownertype
*/
getOwnertype() {
const ownertype = typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype); const ownertype = typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype);
return ownertype;
},
/**
* return ownerid
*/
getOwnerid() {
const ownerid = typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid); const ownerid = typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid);
const uploadUrl = '../net-disk/upload/sysopenaccesses?ownertype=' + ownertype + '&ownerid=' + ownerid; return ownerid;
// const uploadUrl = '../ibizutil/upload';
return uploadUrl;
} }
}, },
watch: { watch: {},
data: { created() {
handler(newVal, oldVal) { this.formStateEvent = this.formState.subscribe(($event) => {
if (newVal) { // 表单加载完成
// 解析表单数据 if (Object.is($event.type, 'load')) {
const data = JSON.parse(JSON.stringify(newVal)); const data = JSON.parse(JSON.stringify($event.data));
if (data.srfkey) { // 编辑表单,保存时不进行批量更新
this.ownerid = data.srfkey; if (data.srfuf == '1') {
this.isCreate = false;
this.isUpdateBatch = false;
} }
// 当persistence = true时,直接从表单的data数据里获取当前属性的值 // 当persistence = true时
if (this.persistence == true && data[this.name]) { if (this.persistence == true) {
const files = data[this.name]; // 直接从表单的data数据里获取当前属性的值
if (files) this.uploadFileList = files; if (data[this.formItemName] && this.uploadFileList.length == 0) {
const files = JSON.parse(data[this.formItemName]);
for (let i = 0; i < files.length; i++) {
this.uploadFileList.push(files[i]);
} }
} }
},
immediate: false,
deep: true
},
ownerid: {
handler(newVal, oldVal) {
if (newVal) {
// 当persistence = false并且表单保存后,有主键ownerid了,调用接口批量更新下文件表里的fileid
if (this.persistence == false) {
this.updateFileBatch();
} else { } else {
// this.getFiles(); // 发送get请求获取文件列表
this.getFiles();
} }
} }
}, // 表单保存完成
immediate: false, if (Object.is($event.type, 'save')) {
deep: true // 批量更新文件表中的ownerid
if (this.isUpdateBatch == true && this.uploadFileList.length > 0) {
this.updateFileBatch(this.uploadFileList, 'update');
} }
}
});
}, },
mounted() { mounted() {
/*
* 1.当persistence = true时,直接从表单的data数据里获取当前属性的值
* 2.当persistence = false时,判断ownerid是否有值
* ownerid有值,表单data数据里并没有这个值,这时需要get请求获取文件列表
* ownerid无值,给一个空数组
* 3.默认情况下给一个空数组
*/
if (this.persistence == true) {
const files = JSON.parse(JSON.stringify(this.value));
if (files) this.uploadFileList = files;
} else if (this.persistence == false) {
if (this.ownerid) {
this.getFiles();
} else {
this.uploadFileList = [];
}
} else {
this.uploadFileList = [];
}
}, },
methods: { methods: {
/** /**
* 获取文件列表 * 获取文件列表
*/ */
getFiles() { getFiles() {
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); // 拼接url
const ownertype = typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype); const getUrl = 'net-disk/files/' + this.getFolder;
const ownerid = typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid); // 发送get请求
const getUrl = `net-disk/files/${folder}`;
Axios.get(getUrl, { Axios.get(getUrl, {
params: { params: {
ownertype: ownertype, ownertype: this.getOwnertype,
ownerid: ownerid, ownerid: this.getOwnerid,
}, },
}).then(response => { }).then(response => {
if (!response || response.status != 200) { if (!response || response.status != 200) {
Message.error("请求当前控件的值发生错误!"); Message.error("获取文件列表失败!");
return; return;
} }
// 返回的是一个jsonArray
if (response.data) { if (response.data) {
const files = JSON.parse(JSON.stringify(response.data)); const files = JSON.parse(JSON.stringify(response.data));
this.uploadFileList = files; if (this.uploadFileList.length == 0) {
this.uploadFileList.push.apply(this.uploadFileList, files);
}
} }
}).catch(error => { }).catch(error => {
Message.error("请求当前控件的值发生错误:" + error); Message.error("获取文件列表失败:" + error);
}); });
}, },
/** /**
* 上传之前 * 自定义上传文件
*/ */
beforeUpload(file) { customUploadFile(param) {
const isSize = file.size / 1024 / 1024 < this.size;
if (!isSize) {
Message.error(`上传失败,单个文件不得超过${this.size}M!`);
return false;
}
},
/**
* 自定义的文件上传行为
* @param param
*/
uploadFile(param) {
console.log("uploadFile run");
return;
// 上传的文件 // 上传的文件
let file = param.file; let file = param.file;
// 文件大小
const isSize = file.size / 1024 / 1024 < this.size; const isSize = file.size / 1024 / 1024 < this.size;
if (!isSize) { if (!isSize) {
Message.error(`上传失败,单个文件不得超过${this.size}M!`); Message.error(`上传失败,单个文件不得超过${this.size}M!`);
return; return;
} }
// url及参数 // formData传参
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
const ownertype = typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype);
const ownerid = typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid);
const uploadUrl = 'net-disk/upload/sysopenaccesses?ownertype=' + ownertype + '&ownerid=' + ownerid;
let formData = new FormData(); let formData = new FormData();
formData.append('file', file); formData.append('file', file);
formData.append('ownertype', ownertype); // 拼接url
formData.append('ownerid', ownerid); const uploadUrl = this.getAction;
// post请求 // 发送post请求
Axios.post(uploadUrl, formData, {timeout: 2000}).then(res => { Axios.post(uploadUrl, formData, {timeout: 2000}).then(response => {
// 成功回调->uploadSuccess if (!response || response.status != 200) {
param.onSuccess(res); Message.error('上传文件失败!');
}).catch(err => { }
// 失败回调->uploadError // 返回的是一个jsonobject
param.onError(err);
});
},
/**
* 上传成功的回调
* @param response
* @param file
* @param fileList
*/
uploadSuccess(response, file, fileList) {
if (response.data) { if (response.data) {
// 后端返回的是一个jsonObject // 新建表单上传,后续需要批量更新操作
const data = response.data; if (this.isCreate == true) {
// 刷新上传文件列表 this.isUpdateBatch = true;
this.uploadFileList.push(data);
// 需要持久化表单属性到数据库
if (this.persistence == true) {
// json转字符串给父组件表单对象指定属性
this.$emit('formitemvaluechange', {
name: this.name,
value: JSON.stringify(this.uploadFileList)
});
} }
} else { // 保存到文件列表进行显示
// 刷新上传文件列表 this.uploadFileList.push(response.data);
let files = fileList; // persistence=true时需要持久化表单属性
this.uploadFileList = files; if (this.persistence == true && this.uploadFileList.length > 0) {
// 需要持久化表单属性到数据库 const value = JSON.stringify(this.uploadFileList);
if (this.persistence == true) { this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
// json转字符串给父组件表单对象指定属性
this.$emit('formitemvaluechange', {
name: this.name,
value: JSON.stringify(this.uploadFileList)
});
} }
} }
}, }).catch(err => {
/** Message.error('上传文件失败:' + err);
* 上传失败的回调 });
* @param err
* @param file
* @param fileList
*/
uploadError(err, file, fileList) {
Message.error('文件上传失败,' + err);
}, },
/** /**
* 下载文件 * 下载文件
* @param item * @param item
*/ */
onDownload(item) { onDownload(item) {
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); // 拼接url
const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id); const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name); const name = typeof item.name == "string" ? item.name : JSON.stringify(item.filename);
const downloadUrl = `net-disk/download/${folder}/${id}/${name}`; const downloadUrl = 'net-disk/download/' + this.getFolder + '/' + id + '/' + name;
// 发送get请求
Axios.get(downloadUrl, { Axios.get(downloadUrl, {
headers: { headers: {
authcode: item.authcode 'authcode': item.authcode
}, },
responseType: 'arraybuffer',
}).then(response => { }).then(response => {
if (!response || response.status != 200) { if (!response || response.status != 200) {
Message.error("请求当前文件发生错误!"); Message.error("下载文件失败!");
return; return;
} }
// 请求成功,后台返回的是一个文件流
if (response.data) {
// 获取文件名
const disposition = response.headers['content-disposition'];
const filename = disposition.split('filename=')[1];
// 用blob对象获取文件流
var blob = new Blob([response.data], {type: response.headers['content-type']});
// 创建下载链接
var href = URL.createObjectURL(blob);
// 创建一个a元素并设置相关属性
var a = document.createElement('a');
a.href = href;
a.download = filename;
// 添加a元素到当前网页
document.body.appendChild(a);
// 触发a元素的点击事件,实现下载
a.click();
// 从当前网页移除a元素
document.body.removeChild(a);
// 释放blob对象
URL.revokeObjectURL(href);
} else {
Message.error('下载文件失败,未获取到文件!');
}
}).catch(error => { }).catch(error => {
Message.error("请求当前文件发生错误!" + error); Message.error("下载文件失败:" + error);
}); });
}, },
/** /**
...@@ -359,66 +359,37 @@ ...@@ -359,66 +359,37 @@
* @param item * @param item
*/ */
onPreview(item) { onPreview(item) {
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); // 拼接url
const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id); const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name); const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
const previewUrl = `net-disk/preview/${folder}/${id}/${name}`; const previewUrl = 'net-disk/preview/' + this.getFolder + '/' + id + '/' + name + '?authcode=' + item.authcode;
Axios.get(previewUrl, { // 新窗口打开url
headers: { window.open(previewUrl);
authcode: item.authcode
},
}).then(response => {
if (!response || response.status != 200) {
Message.error("请求当前文件发生错误!");
return;
}
}).catch(error => {
Message.error("请求当前文件发生错误!" + error);
});
}, },
/** /**
* 编辑文件 * 编辑文件
* @param item * @param item
*/ */
onEdit(item) { onEdit(item) {
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); // 拼接url
const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id); const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name); const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
const editUrl = `net-disk/edit/${folder}/${id}/${name}`; const editUrl = 'net-disk/edit/' + this.getFolder + '/' + id + '/' + name + '?authcode=' + item.authcode;
Axios.get(editUrl, { // 新窗口打开url
headers: { window.open(editUrl);
authcode: item.authcode
},
}).then(response => {
if (!response || response.status != 200) {
Message.error("请求当前文件发生错误!");
return;
}
}).catch(error => {
Message.error("请求当前文件发生错误!" + error);
});
}, },
/** /**
* ocr识别 * ocr识别
* @param item * @param item
*/ */
onOcr(item) { onOcr(item) {
// 拼接url
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id); const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name); const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
const ocrviewUrl = `net-disk/ocrview/${folder}/${id}/${name}`; const ocrUrl = 'net-disk/ocrview/' + this.getFolder + '/' + id + '/' + name + '?authcode=' + item.authcode;
Axios.get(ocrviewUrl, { // 新窗口打开url
headers: { window.open(ocrUrl);
authcode: item.authcode
},
}).then(response => {
if (!response || response.status != 200) {
Message.error("请求当前文件发生错误!");
return;
}
}).catch(error => {
Message.error("请求当前文件发生错误!" + error);
});
}, },
/** /**
* 删除文件 * 删除文件
...@@ -432,51 +403,54 @@ ...@@ -432,51 +403,54 @@
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
// 拼接url
const deleteUrl = 'net-disk/files/' + item.id;
// 发送delete请求
Axios.delete(deleteUrl).then(response => {
if (!response || response.status != 200) {
Message.error("删除文件失败!");
}
// 从文件列表中删除 // 从文件列表中删除
this.uploadFileList.splice(index, 1); const removeArray = this.uploadFileList.splice(index, 1);
// 需要持久化表单属性到数据库 // 将删除的文件合并到删除列表
this.removeFileList.push.apply(this.removeFileList, removeArray);
// persistence=true时需要持久化表单属性
if (this.persistence == true) { if (this.persistence == true) {
// json转字符串给父组件表单对象指定属性 const value = JSON.stringify(this.uploadFileList);
this.$emit('formitemvaluechange', { this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
name: this.name,
value: JSON.stringify(this.uploadFileList)
});
} }
// 提示删除成功 }).catch(error => {
Message({ // 提示删除失败
type: 'success', Message.error("删除文件失败:" + error);
message: '删除成功!'
});
}).catch(() => {
Message({
type: 'info',
message: '已取消删除'
}); });
}); });
} }
}, },
/** /**
* 批量更新文件表的fileid * 批量更新文件表的ownerid
*/ */
updateFileBatch() { updateFileBatch(files, opt) {
// 当persistence = false时,新建表单保存之后会拿到主键id // 拼接url
if (this.persistence == false && this.ownerid) { const updateUrl = 'net-disk/files/' + this.getFolder + '?ownertype=' + this.getOwnertype + "&ownerid=" + this.getOwnerid;
const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder); // requestBody参数
const ownertype = typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype); let requestBody = [];
const ownerid = typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid); if (files) {
const url = `net-disk/files/${folder}?ownertype=${ownertype}&ownerid=${ownerid}`; requestBody = files;
let requestbody = this.uploadFileList; }
Axios.post(url, requestbody, { // 发送post请求
timeout: 2000, Axios.post(updateUrl, requestBody, {
}).then(res => { headers: {
if (!res || res.status != 200) { "Content-Type": "application/json;charset=UTF-8"
},
timeout: 2000
}).then(response => {
if (!response || response.status != 200) {
Message.error("批量更新文件失败!"); Message.error("批量更新文件失败!");
return; return;
} }
}).catch(error => { }).catch(error => {
Message.error("批量更新文件失败!" + error); Message.error("批量更新文件失败:" + error);
}); });
}
}, },
} }
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册