<template>
    <div class="app-ey-upload">
        <el-row>
            <el-col v-for="(item,index) in uploadFileList" :key="'preview' + index" class="app-ey-upload__item app-ey-upload__preview">
                <span class="file-title" @click="onDownload(item)">
                    <span>{{item.name}}</span>
                </span>
                <span class="file-version">
                    <span>文件版本号:v1.0</span>
                </span>
                <span class="file-size">
                    <span>文件大小:{{getFileSize(item.size)}}</span>
                </span>
                <span class="file-owner">
                    <span>文件上传人:Na Na Zhang</span>
                </span>
                <span class="file-time">
                    <span>文件上传时间:2022/10/31 18:49:12</span>
                </span>
                <div class="file-icon" v-if="!previewMode">
                    <!-- <img v-if="!buttonCount" src="assets/img/ey_switch.svg" @click="onRemove(item,index, true)"> -->
                    <img src="assets/img/remove_circle.svg" @click="onRemove(item,index)">
                </div>
            </el-col>
            <el-col v-if="!previewMode" v-for="count in buttonCount" :key="'button' + count" class="app-ey-upload__item">
                <el-upload
                        ref="upload"
                        list-type="text"
                        :disabled="disabled"
                        :action="getAction()"
                        :headers="myHeaders"
                        :file-list="uploadFileList"
                        :show-file-list="false"
                        :http-request="customUploadFile">
                    <el-button size="small" :disabled="disabled">
                        <img src="assets/img/ey_upload.svg">
                        文件上传
                    </el-button>
                </el-upload>
                <div class="app-ey-upload__buttons">
                    <img v-if="count === buttonCount" src="assets/img/ic_add_circle.svg" @click="buttonCount++">
                    <img v-else src="assets/img/remove_circle.svg" @click="buttonCount--">
                </div>
            </el-col>
        </el-row>
    </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from "vue-property-decorator";
import { Button, Row, Col, Link, Icon, Upload, Message, MessageBox } from "element-ui";
import Axios from "axios";
import { Subject, Unsubscribable } from "rxjs";

@Component({})
export default class AppEYUpload extends Vue {
    /**
     * 当前表单对象
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    @Prop() public data!: any;

    /**
     * 当前属性名
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    @Prop() public formItemName!: string;

    /**
     * 当前属性值
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    @Prop() public value!: string;

    /**
     * 当前表单状态
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    @Prop() public formState!: any;

    /**
     * 默认为当前实体名称,有指定则按表单参数
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    @Prop() public folder!: string;

    /**
     * 默认为当前实体主键id,有指定则按表单参数
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    @Prop() public ownerid!: string;

    /**
     * 默认为当前属性名,有指定则按表单参数
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    @Prop() public ownertype!: string;

    /**
     * 持久化
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public persistence?: boolean;

    /**
     * 是否启用
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public disabled?: boolean;

    /**
     * 是否显示拖拽区域
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public showDrag?: boolean;

    /**
     * 是否显示预览按钮
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public showPreview?: boolean;

    /**
     * 是否显示在线编辑按钮
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public showEdit?: boolean;

    /**
     * 是否显示OCR按钮
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public showOcrview?: boolean;

    /**
     * 是否显示预览按钮
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    @Prop({ default: false }) public previewMode?: boolean;

    /**
     * 表单是否处于编辑状态(有真实主键,srfuf='1';srfuf='0'时处于新建未保存)
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    public srfuf: string = "0";

    /**
     * 文件列表
     *
     * @type {Array<any>}
     * @memberof AppEYUpload
     */
    public uploadFileList: Array<any> = [];

    /**
     * 当前登陆人的token
     *
     * @type {string}
     * @memberof AppEYUpload
     */
    public token: string = "Bearer " + localStorage.getItem("token");

    /**
     * 上传文件请求头
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    public myHeaders: any = { Authorization: this.token };

    /**
     * 表单状态事件
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    public formStateEvent: any | Unsubscribable | undefined;

    /**
     * 批量更新标识,false为不更新,true才可以更新
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    public isUpdateBatch: boolean = true;

    /**
     * 新建状态标识,true为新建,false为编辑
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    public isCreate: boolean = true;

    /**
     * 自定义弹框标题
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    public dialogTitle: any = "";

    /**
     * 是否显示自定义弹框
     *
     * @type {boolean}
     * @memberof AppEYUpload
     */
    public showDialog: boolean = false;

    /**
     * 嵌入自定义弹框中iframe的url
     *
     * @type {*}
     * @memberof AppEYUpload
     */
    public iframeUrl: any = "";

    /**
     * 按钮数量
     *
     * @type {number}
     * @memberof AppEYUpload
     */
    public buttonCount: number = 1;

    /**
     * 关闭自定义弹框
     *
     * @memberof AppEYUpload
     */
    public dialogClose() {
        this.dialogTitle = "";
        this.showDialog = false;
        this.iframeUrl = "";
        let iframe: any = document.getElementById("fileIframe");
        iframe.parentNode.removeChild("fileIframe");
    }

    /**
     * 获取文件大小
     *
     * @memberof AppEYUpload
     */
    public getFileSize(size: number) {
        if (size < 1024) {
            return `${size}Byte`;
        } else if (size < 1024 * 1024) {
            return `${(size / 1024).toFixed(2)}KB`;
        } else {
            return `${(size / 1024 / 1024).toFixed(2)}MB`;
        }
    }

    /**
     * 拼接上传路径
     *
     * @memberof AppEYUpload
     */
    public getAction() {
        return "/net-disk/upload/" + this.getFolder() + "?ownertype=" + this.getOwnertype() + "&ownerid=" + this.getOwnerid();
    }

    /**
     * return folder
     *
     * @memberof AppEYUpload
     */
    public getFolder() {
        return typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
    }

    /**
     * return ownertype
     *
     * @memberof AppEYUpload
     */
    public getOwnertype() {
        return typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype);
    }

    /**
     * return ownerid
     *
     * @memberof AppEYUpload
     */
    public getOwnerid() {
        return typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid);
    }

    /**
     * vue创建
     *
     * @memberof AppEYUpload
     */
    public created() {
        this.formStateEvent = this.formState.subscribe(($event: any) => {
            // 表单加载完成
            if (Object.is($event.type, "load")) {
                const data = JSON.parse(JSON.stringify($event.data));
                // 编辑表单,保存时不进行批量更新
                if (data.srfuf == "1") {
                    this.isCreate = false;
                    this.isUpdateBatch = false;
                }
                // 当persistence = true时
                if (this.persistence == true) {
                    // 直接从表单的data数据里获取当前属性的值
                    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]);
                        }
                    }
                } else {
                    // 发送get请求获取文件列表
                    this.getFiles();
                }
            }
            // 表单保存完成
            if (Object.is($event.type, "save")) {
                // 批量更新文件表中的ownerid
                if (this.isUpdateBatch == true && this.uploadFileList.length > 0) {
                    this.updateFileBatch(this.uploadFileList);
                }
            }
        });
    }

    /**
     * 获取文件列表
     *
     * @memberof AppEYUpload
     */
    public getFiles() {
        // 拼接url
        let _this: any = this;
        const getUrl = "/net-disk/files/" + this.getFolder();
        // 发送get请求
        Axios.get(getUrl, {
            params: {
                ownertype: this.getOwnertype(),
                ownerid: this.getOwnerid(),
            },
        })
            .then((response: any) => {
                if (!response || response.status != 200) {
                    Message.error(_this.$t("components.diskFileUpload.getFileFailure") + "!");
                    return;
                }
                // 返回的是一个jsonArray
                if (response.data) {
                    const files = JSON.parse(JSON.stringify(response.data));
                    if (this.uploadFileList.length == 0) {
                        this.uploadFileList.push.apply(this.uploadFileList, files);
                    }
                }
            })
            .catch((error: any) => {
                Message.error(_this.$t("components.diskFileUpload.getFileFailure") + ":" + error);
            });
    }

    /**
     * 自定义上传文件
     *
     * @param 上传文件
     * @memberof AppEYUpload
     */
    public customUploadFile(param: any) {
        // 上传的文件
        let _this: any = this;
        let file = param.file;
        // formData传参
        let formData = new FormData();
        formData.append("file", file);
        // 拼接url
        const uploadUrl = this.getAction();
        // 发送post请求
        Axios.post(uploadUrl, formData)
            .then((response: any) => {
                if (!response || response.status != 200) {
                    Message.error(_this.$t("components.diskFileUpload.loadFailure") + "!");
                }
                // 返回的是一个jsonobject
                if (response.data) {
                    // 新建表单上传,后续需要批量更新操作
                    if (this.isCreate == true) {
                        this.isUpdateBatch = true;
                    }
                    if (this.buttonCount > 1) {
                        this.buttonCount--;
                    }
                    // 保存到文件列表进行显示
                    this.uploadFileList.push(response.data);
                    console.log(this.uploadFileList);
                    
                    // persistence=true时需要持久化表单属性
                    if (this.persistence == true && this.uploadFileList.length > 0) {
                        const value = JSON.stringify(this.uploadFileList);
                        this.$emit("formitemvaluechange", { name: this.formItemName, value: value });
                    }
                }
            })
            .catch((error: any) => {
                Message.error(_this.$t("components.diskFileUpload.loadFailure") + ":" + error);
            });
    }

    /**
     * 下载文件
     *
     * @param item 下载文件
     * @memberof AppEYUpload
     */
    public onDownload(item: any) {
        // 拼接url
        let _this: any = this;
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.filename);
        const downloadUrl = "/net-disk/download/" + this.getFolder() + "/" + id + "/" + name;
        // 发送get请求
        Axios.get(downloadUrl, {
            headers: {
                authcode: item.authcode,
            },
            responseType: "arraybuffer",
        })
            .then((response: any) => {
                if (!response || response.status != 200) {
                    Message.error(_this.$t("components.diskFileUpload.downloadFile") + "!");
                    return;
                }
                // 请求成功,后台返回的是一个文件流
                if (response.data) {
                    // 获取文件名
                    const disposition = response.headers["content-disposition"];
                    const filename = disposition.split("filename=")[1];
                    // 用blob对象获取文件流
                    let blob = new Blob([response.data], { type: response.headers["content-type"] });
                    // 通过文件流创建下载链接
                    var href = URL.createObjectURL(blob);
                    // 创建一个a元素并设置相关属性
                    let a = document.createElement("a");
                    a.href = href;
                    if (name) {
                        a.download = name;
                    } else {
                        a.download = filename;
                    }
                    // 添加a元素到当前网页
                    document.body.appendChild(a);
                    // 触发a元素的点击事件,实现下载
                    a.click();
                    // 从当前网页移除a元素
                    document.body.removeChild(a);
                    // 释放blob对象
                    URL.revokeObjectURL(href);
                } else {
                    Message.error(_this.$t("components.diskFileUpload.downloadFile1"));
                }
            })
            .catch((error: any) => {
                Message.error(_this.$t("components.diskFileUpload.downloadFile") + ":" + error);
            });
    }

    /**
     * 预览文件
     *
     * @param item 预览文件
     * @memberof AppEYUpload
     */
    public onPreview(item: any) {
        // 拼接url
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
        let previewUrl = "/net-disk/preview/" + this.getFolder() + "/" + id + "/" + name + "?authcode=" + item.authcode;
        Axios.get(previewUrl)
            .then((response: any) => {
                if (!response || response.status != 200) {
                    return;
                }
                // 返回一个url,通过自定义弹框打开
                if (response.data) {
                    this.dialogTitle = name;
                    this.showDialog = true;
                    this.iframeUrl = response.data;
                }
            })
            .catch((error: any) => {
                Message.error(error);
            });
    }

    /**
     * 编辑文件
     *
     * @param item
     * @memberof AppEYUpload
     */
    public onEdit(item: any) {
        // 拼接url
        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 editUrl = "/net-disk/editview/" + this.getFolder() + "/" + id + "/" + name + "?authcode=" + item.authcode;
        // TODO:暂时用window.open
        window.open(editUrl);
    }

    /**
     * ocr识别
     * @param item
     * @memberof AppEYUpload
     */
    public onOcr(item: any) {
        // 拼接url
        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 name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
        const ocrUrl = "/net-disk/ocrview/" + this.getFolder() + "/" + id + "/" + name + "?authcode=" + item.authcode;
        Axios.get(ocrUrl)
            .then((response: any) => {
                if (!response || response.status != 200) {
                    return;
                }
                // 返回一个url,通过自定义弹框打开
                if (response.data) {
                    this.dialogTitle = name;
                    this.showDialog = true;
                    this.iframeUrl = response.data;
                }
            })
            .catch((error: any) => {
                Message.error(error);
            });
    }

    /**
     * 删除文件
     *
     * @param item
     * @param index
     * @memberof AppEYUpload
     */
    public onRemove(item: any, index: number) {
        let _this: any = this;
        if (item) {
            MessageBox.confirm(_this.$t("components.diskFileUpload.deleteFile"), _this.$t("components.diskFileUpload.deleteFilePrompt"), {
                confirmButtonText: _this.$t("components.diskFileUpload.true"),
                cancelButtonText: _this.$t("components.diskFileUpload.false"),
                type: "warning",
            }).then(() => {
                // 拼接url
                const deleteUrl = "/net-disk/files/" + item.id;
                // 发送delete请求
                Axios.delete(deleteUrl)
                    .then((response: any) => {
                        if (!response || response.status != 200) {
                            Message.error(_this.$t("components.diskFileUpload.deleteFileFailure") + "!");
                        }
                        // 从文件列表中删除
                        this.uploadFileList.splice(index, 1);
                        // persistence=true时需要持久化表单属性
                        if (this.persistence == true) {
                            const value = JSON.stringify(this.uploadFileList);
                            this.$emit("formitemvaluechange", { name: this.formItemName, value: value });
                        }
                    })
                    .catch((error: any) => {
                        // 提示删除失败
                        Message.error(_this.$t("components.diskFileUpload.deleteFileFailure") + ":" + error);
                    });
            });
        }
    }

    /**
     * 批量更新文件表的ownerid
     *
     * @memberof AppEYUpload
     */
    public updateFileBatch(files: any) {
        let _this: any = this;
        // 拼接url
        const updateUrl = "/net-disk/files/" + this.getFolder() + "?ownertype=" + this.getOwnertype() + "&ownerid=" + this.getOwnerid();
        // requestBody参数
        let requestBody = [];
        if (files) {
            requestBody = files;
        }
        // 发送post请求
        Axios.post(updateUrl, requestBody, {
            headers: {
                "Content-Type": "application/json;charset=UTF-8",
            },
            timeout: 2000,
        })
            .then((response: any) => {
                if (!response || response.status != 200) {
                    Message.error(_this.$t("components.diskFileUpload.updateFailure") + "!");
                    return;
                }
            })
            .catch((error: any) => {
                Message.error(_this.$t("components.diskFileUpload.updateFailure") + ":" + error);
            });
    }
}
</script>
<style lang="scss">
@import "./app-ey-upload.scss";
</style>