123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <!--
- * @Description: 对上传文件组件进行封装
- * @Author: kcz
- * @Date: 2020-03-17 12:53:50
- * @LastEditors: kcz
- * @LastEditTime: 2021-05-05 12:12:30
- -->
- <template>
- <div :style="{ width: record.options.width }">
- <a-upload
- v-if="!record.options.drag"
- :disabled="record.options.disabled || parentDisabled"
- :name="config.uploadFileName || record.options.fileName"
- :headers="config.uploadFileHeaders || record.options.headers"
- :data="config.uploadFileData || optionsData"
- :action="config.uploadFile || record.options.action"
- :multiple="record.options.multiple"
- :fileList="fileList"
- @preview="handlePreview"
- @change="handleChange"
- :remove="remove"
- :beforeUpload="beforeUpload"
- >
- <a-button
- v-if="fileList.length < record.options.limit"
- :disabled="record.options.disabled || parentDisabled"
- >
- <a-icon type="upload" /> {{ record.options.placeholder }}
- </a-button>
- </a-upload>
- <a-upload-dragger
- v-else
- :class="{ 'hide-upload-drag': !(fileList.length < record.options.limit) }"
- :disabled="record.options.disabled || parentDisabled"
- :name="config.uploadFileName || record.options.fileName"
- :headers="config.uploadFileHeaders || record.options.headers"
- :data="config.uploadFileData || optionsData"
- :action="config.uploadFile || record.options.action"
- :multiple="record.options.multiple"
- :fileList="fileList"
- @preview="handlePreview"
- @change="handleChange"
- :remove="remove"
- :beforeUpload="beforeUpload"
- >
- <p class="ant-upload-drag-icon">
- <a-icon type="cloud-upload" />
- </p>
- <p class="ant-upload-text">单击或拖动文件到此区域</p>
- </a-upload-dragger>
- </div>
- </template>
- <script>
- /*
- * author kcz
- * date 2019-12-31
- * description 上传文件组件
- */
- export default {
- name: "KUploadFile",
- // eslint-disable-next-line vue/require-prop-types
- props: ["record", "value", "config", "parentDisabled", "dynamicData"],
- data() {
- return {
- fileList: []
- };
- },
- watch: {
- value: {
- // value 需要深度监听及默认先执行handler函数
- handler(val) {
- if (val) {
- this.setFileList();
- }
- },
- immediate: true,
- deep: true
- }
- },
- computed: {
- optionsData() {
- try {
- return JSON.parse(this.record.options.data);
- } catch (err) {
- console.error(err);
- return {};
- }
- }
- },
- methods: {
- setFileList() {
- // 当传入value改变时,fileList也要改变
- // 如果传入的值为字符串,则转成json
- if (typeof this.value === "string") {
- this.fileList = JSON.parse(this.value);
- // 将转好的json覆盖组件默认值的字符串
- this.handleSelectChange();
- } else {
- this.fileList = this.value;
- }
- },
- handleSelectChange() {
- setTimeout(() => {
- const arr = this.fileList.map(item => {
- if (typeof item.response !== "undefined") {
- const res = item.response;
- return {
- type: "file",
- name: item.name,
- status: item.status,
- uid: res.data.fileId || Date.now(),
- url: res.data.url || ""
- };
- } else {
- return {
- type: "file",
- name: item.name,
- status: item.status,
- uid: item.uid,
- url: item.url || ""
- };
- }
- });
- this.$emit("change", arr);
- this.$emit("input", arr);
- }, 10);
- },
- handlePreview(file) {
- // 下载文件
- const downloadWay = this.record.options.downloadWay;
- const dynamicFun = this.record.options.dynamicFun;
- if (downloadWay === "a") {
- // 使用a标签下载
- const a = document.createElement("a");
- a.href = file.url || file.thumbUrl;
- a.download = file.name;
- a.click();
- } else if (downloadWay === "ajax") {
- // 使用ajax获取文件blob,并保持到本地
- this.getBlob(file.url || file.thumbUrl).then(blob => {
- this.saveAs(blob, file.name);
- });
- } else if (downloadWay === "dynamic") {
- // 触发动态函数
- this.dynamicData[dynamicFun](file);
- }
- },
- /**
- * 获取 blob
- * url 目标文件地址
- */
- 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();
- });
- },
- /**
- * 保存 blob
- * filename 想要保存的文件名称
- */
- saveAs(blob, filename) {
- if (window.navigator.msSaveOrOpenBlob) {
- navigator.msSaveBlob(blob, filename);
- } else {
- const link = document.createElement("a");
- const body = document.querySelector("body");
- link.href = window.URL.createObjectURL(blob);
- link.download = filename;
- // fix Firefox
- link.style.display = "none";
- body.appendChild(link);
- link.click();
- body.removeChild(link);
- window.URL.revokeObjectURL(link.href);
- }
- },
- remove() {
- this.handleSelectChange();
- },
- beforeUpload(e, files) {
- if (files.length + this.fileList.length > this.record.options.limit) {
- this.$message.warning(`最大上传数量为${this.record.options.limit}`);
- files.splice(this.record.options.limit - this.fileList.length);
- }
- },
- handleChange(info) {
- this.fileList = info.fileList;
- if (info.file.status === "done") {
- const res = info.file.response;
- if (res.code === 0) {
- this.handleSelectChange();
- } else {
- this.fileList.pop();
- this.$message.error(`文件上传失败`);
- }
- } else if (info.file.status === "error") {
- this.$message.error(`文件上传失败`);
- }
- }
- }
- };
- </script>
|