<template>
    <div id="image-upload">
        <el-upload
                ref="imageUpload"
                :multiple="multiple"
                :file-list="imageList"
                list-type="picture-card"
                :action="getAction()"
                :headers="headers"
                :before-upload="beforeUpload"
                :http-request="customImageUpload">
            <i class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
                <img class="el-upload-list__item-thumbnail" :src="file.url">
                <span class="el-upload-list__item-actions">
                    <!--预览按钮-->
                    <span class="el-upload-list__item-preview" @click="onPreview(file)"
                          :title="$t('components.diskimageupload.preview')"
                          v-show="showPreview">
                        <i class="el-icon-view"></i>
                    </span>
                    <!--OCR按钮-->
                    <span class="el-upload-list__item-delete" @click="onOcr(file)"
                          :title="$t('components.diskimageupload.ocrdiscern')"
                           v-show="showOcrview && (file.name.match(/^.+\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG|bmp|BMP)$/))">>
                      <i class="el-icon-camera"></i>
                    </span>
                    <!--下载按钮-->
                    <span class="el-upload-list__item-delete" @click="onDownload(file)"
                          :title="$t('components.diskimageupload.load')">
                      <i class="el-icon-download"></i>
                    </span>
                    <!--删除按钮-->
                    <span class="el-upload-list__item-delete" @click="onRemove(file)"
                          :title="$t('components.diskimageupload.delete')">
                      <i class="el-icon-delete"></i>
                    </span>
              </span>
            </div>
        </el-upload>
        <!-- 预览弹框 -->
        <el-dialog :visible.sync="dialogVisible" :modal="false">
            <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
        <!-- 自定义弹框 -->
        <div class="dialogDiv">
            <el-dialog
                    :title="dialogTitle"
                    center
                    width="70%"
                    top="5vh"
                    :visible="showDialog"
                    :close-on-click-modal="true"
                    :show-close="true"
                    :before-close="dialogClose"
                    :modal-append-to-body="false">
                <div style="height: 100%;">
                    <iframe id="fileIframe" :src="iframeUrl" frameborder="0" width="100%"></iframe>
                </div>
            </el-dialog>
        </div>
    </div>
</template>

<script lang="ts">
import {Component, Vue, Prop} from 'vue-property-decorator';
import {Message, MessageBox} from 'element-ui';
import Axios from 'axios';
import {Subscription} from 'rxjs';
import { AppServiceBase, getSessionStorage } from 'ibiz-core';
import { getCookie } from 'qx-util';

@Component({})
export default class DiskImageUplaod extends Vue {

    /**
     * 当前表单对象
     *
     * @type {*}
     * @memberof DiskImageUplaod
     */
    @Prop() public data!: any;

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

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

    /**
     * 是否多选
     *
     * @type {boolean}
     * @memberof AppFileUpload
     */
    @Prop({default: true}) public multiple?: boolean;

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

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

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

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

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

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


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


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

    /**
     * 图片列表
     *
     * @type {Array<any>}
     * @memberof DiskImageUplaod
     */
    public imageList: Array<any> = [];

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

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

    /**
     * 表单状态事件
     *
     * @type {*}
     * @memberof DiskImageUplaod
     */
    public formStateEvent: Subscription | undefined;

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

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

    /**
     * 预览弹出框显示标识，true显示，false隐藏
     *
     * @type {boolean}
     * @memberof DiskImageUplaod
     */
    public dialogVisible: boolean = false;

    /**
     * 预览弹出框中的图片地址
     *
     * @type {string}
     * @memberof DiskImageUplaod
     */
    public dialogImageUrl: string = '';

    /**
     * 存放图片的fileid,用于图片列表定位
     *
     * @type {boolean}
     * @memberof DiskImageUplaod
     */
    public imageFileids: Array<any> = [];

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

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

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

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

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

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

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

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

    /**
     * vue创建
     *
     * @memberof DiskImageUplaod
     */
    public created() {
        this.setHeaders();
        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.imageList.length == 0) {
                        const files = JSON.parse(data[this.formItemName]);
                        files.forEach((item: any, i: number) => {
                            // 图片列表显示缩略图需要获取真实的图片信息
                            if (item.id && item.name) {
                                this.getRealImageData(item);
                            }
                        });
                    }
                } else {
                    // 发送get请求获取图片列表
                    this.getFiles();
                }
            }
            // 表单保存完成
            if (Object.is($event.type, 'save')) {
                // 批量更新文件表中的ownerid
                if (this.isUpdateBatch == true && this.imageList.length > 0) {
                    this.updateFileBatch(this.imageList);
                }
            }
        });
    }

    /**
     * @description: 组件销毁
     * 
     * @return {*}
     */    
    destroyed(){
        if(this.formStateEvent){
            this.formStateEvent.unsubscribe();
        }
    }

    /**
     * 设置请求头
     * 
     * @memberof AppFileUpload
     */
    public setHeaders(){
       if (AppServiceBase.getInstance().getAppEnvironment().SaaSMode) {
            let activeOrgData = getSessionStorage('activeOrgData');
            this.headers['srforgid'] = activeOrgData?.orgid;
            this.headers['srfsystemid'] = activeOrgData?.systemid;
            if(getSessionStorage("srfdynaorgid")){
                this.headers['srfdynaorgid'] = getSessionStorage("srfdynaorgid");
            }
        } else {
            if(getSessionStorage("srfdynaorgid")){
                this.headers['srfdynaorgid'] = getSessionStorage("srfdynaorgid");
            }
        }
         if (getCookie('ibzuaa-token')) {
            this.headers['Authorization'] = `Bearer ${getCookie('ibzuaa-token')}`;
        } else {
            // 第三方应用打开免登
            if (sessionStorage.getItem("srftoken")) {
                const token = sessionStorage.getItem('srftoken');
                this.headers['Authorization'] = `Bearer ${token}`;
            }
        }
    }

    /**
     * 获取图片列表
     *
     * @memberof DiskImageUplaod
     */
    public getFiles() {
        // 拼接url
        let _this: any = this;
        const getUrl = '/net-disk/files/' + this.getFolder();
        // 发送get请求
        this.$http.get(getUrl, {
                ownertype: this.getOwnertype(),
                ownerid: this.getOwnerid(),
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.getimagefailure') + "!",'getFiles');
                return;
            }
            // 返回的是一个jsonArray
            if (response.data) {
                const files = JSON.parse(JSON.stringify(response.data));
                if (this.imageList.length == 0) {
                    files.forEach((item: any, i: number) => {
                        // 图片列表显示缩略图需要获取真实的图片信息
                        if (item.id && item.name) {
                            this.getRealImageData(item);
                        }
                    });
                }
            }
        }).catch((error: any) => {
            this.$throw(error,'getFiles');
        });
    }

    /**
     * 获取真实的图片信息
     * @param file
     * @memberof DiskImageUplaod
     */
    public getRealImageData(file: any) {
        let fileData = file;
        let _this: any = this;
        // 拼接url，与下载一致
        const downloadUrl = '/net-disk/download/' + this.getFolder() + '/' + fileData.id + '/' + fileData.name;
        // 发送get请求
        this.$http.get(downloadUrl, {
                'authcode': fileData.authcode,
            responseType: 'blob',
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.loadimagefailure') + "!",'getRealImageData');
                return;
            }
            // 请求成功，后台返回的是一个文件流
            if (response.data) {
                // 用blob对象获取文件流
                var blob = new Blob([response.data], {type: response.headers['content-type']});
                // 通过文件流创建下载链接
                var href = URL.createObjectURL(blob);
                // 将下载链接保存到图片中
                fileData.url = href;
                // 保存图片fileid
                if (fileData.fileid) {
                    this.imageFileids.push(fileData.fileid);
                } else if (fileData.id) {
                    this.imageFileids.push(fileData.id);
                } else {
                    this.$throw(_this.$t('components.diskimageupload.imageidnone') + "!",'getRealImageData');
                    return;
                }
                // 保存图片到图片列表进行显示
                this.imageList.push(fileData);
            } else {
                this.$throw(_this.$t('components.diskimageupload.loadimagefailure1') + "!",'getRealImageData');
            }
        }).catch((error: any) => {
            this.$throw(error,'getRealImageData');
        });
    }

    /**
     * 上传之前
     * @param file
     * @memberof DiskImageUplaod
     */
    public beforeUpload(file: any) {
        // 支持上传的图片格式
        let _this: any = this;
        if (!file.name.match(/^.+\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG|bmp|BMP)$/)) {
            this.$throw(_this.$t('components.diskimageupload.uploadimagefailure1') + "!",'beforeUpload');
            return false;
        }
    }

    /**
     * 自定义图片上传
     * @param param
     * @memberof DiskImageUplaod
     */
    public customImageUpload(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请求
        this.$http.post(uploadUrl, formData, {timeout: 2000}).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.uploadimagefailure') + "!",'customImageUpload');
            }
            //返回的是一个jsonobject
            if (response.data) {
                let returnData = response.data;
                // 拼接缩略图下载url
                const downloadUrl = '/net-disk/download/' + this.getFolder() + '/' + returnData.id + '/' + returnData.name;
                // 发送get请求
                this.$http.get(downloadUrl, {
                        'authcode': returnData.authcode,
                    responseType: 'blob',
                }).then((response2: any) => {
                    if (!response2 || response2.status != 200) {
                        this.$throw(_this.$t('components.diskimageupload.loadimagefailure') + "!",'customImageUpload');
                        return;
                    }
                    // 请求成功，后台返回的是一个文件流
                    if (response2.data) {
                        // 用blob对象获取文件流
                        var blob = new Blob([response2.data], {type: response2.headers['content-type']});
                        // 通过文件流创建下载链接
                        var href = URL.createObjectURL(blob);
                        // 将下载链接保存到本次上传成功后返回的jsonobject中
                        returnData.url = href;
                        // 保存jsonobject中的图片fileid
                        if (returnData.fileid) {
                            this.imageFileids.push(returnData.fileid);
                        } else if (returnData.id) {
                            this.imageFileids.push(returnData.id);
                        } else {
                            this.$throw(_this.$t('components.diskimageupload.imageidnone') + "!",'customImageUpload');
                            return;
                        }
                        // 保存jsonobject到图片列表进行显示
                        this.imageList.push(returnData);
                        // 新建表单上传时，后续需要批量更新操作
                        if (this.isCreate == true) {
                            this.isUpdateBatch = true;
                        }
                        // persistence=true时，需要持久化表单属性
                        if (this.persistence == true && this.imageList.length > 0) {
                            const value = JSON.stringify(this.imageList);
                            this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
                        }
                    } else {
                        this.$throw(_this.$t('components.diskimageupload.loadimagefailure1') + "!",'customImageUpload');
                    }
                }).catch((error2: any) => {
                    this.$throw(error2,'customImageUpload');
                });
            }
        }).catch((error: any) => {
            this.$throw(error,'customImageUpload');
        });
    }


    /**
     *　预览
        * @param file
        * @memberof DiskImageUplaod
        */
    public onPreview(file: any) {
        let _this: any = this;
        if (file.url) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        } else {
            this.$throw(_this.$t('components.diskimageupload.notimageurl') + "!",'onPreview');
        }
    }

    /**
     * Ocr识别
     * @param file
     * @memberof DiskImageUplaod
     */
    public onOcr(file: any) {
        // 拼接url
        const id = typeof file.id == "string" ? file.id : JSON.stringify(file.id);
        const name = typeof file.name == "string" ? file.name : JSON.stringify(file.name);
        const ocrUrl = '/net-disk/ocrview/' + this.getFolder() + '/' + id + '/' + name + '?authcode=' + file.authcode;
        this.$http.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) => {
            this.$throw(error,'onOcr');
        });
    }

    /**
     * 下载
     * @param file
     * @memberof DiskImageUplaod
     */
    public onDownload(file: any) {
        // 拼接url
        let _this: any = this;
        const id = typeof file.id == "string" ? file.id : JSON.stringify(file.id);
        const name = typeof file.name == "string" ? file.name : JSON.stringify(file.filename);
        const downloadUrl = '/net-disk/download/' + this.getFolder() + '/' + id + '/' + name;
        // 发送get请求
        this.$http.get(downloadUrl, {
                'authcode': file.authcode,
            responseType: 'blob',
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.loadimagefailure2') + "!",'onDownload');
                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;
                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 {
                this.$throw(_this.$t('components.diskimageupload.loadimagefailure3') + "!",'onDownload');
            }
        }).catch((error: any) => {
            this.$throw(error,'onDownload');
        });
    }


    /**
     * 删除
     * @param file
     * @memberof DiskImageUplaod
     */
    public onRemove(file: any) {
        let _this: any = this;
        if (file) {
            MessageBox.confirm(_this.$t('components.diskimageupload.deletefile'), _this.$t('components.diskimageupload.deletefileprompt'), {
                confirmButtonText: _this.$t('components.diskimageupload.true'),
                cancelButtonText: _this.$t('components.diskimageupload.false'),
                type: 'warning'
            }).then(() => {
                if (this.imageFileids.indexOf(file.id) != -1) {
                    // 要删除的图片在图片列表中的下标
                    const index = this.imageFileids.indexOf(file.id);
                    //　拼接url
                    const deleteUrl = '/net-disk/files/' + file.id;
                    // 发送delete请求
                    this.$http.delete(deleteUrl).then((response: any) => {
                        if (!response || response.status != 200) {
                            this.$throw(_this.$t('components.diskimageupload.deleteimagefailure') + "!",'onRemove');
                        }
                        // 从fileid数组中删除
                        this.imageFileids.splice(index, 1);
                        // 从图片列表中删除
                        this.imageList.splice(index, 1);
                        // persistence=true,时需要持久化表单属性
                        if (this.persistence == true) {
                            const value = JSON.stringify(this.imageList);
                            this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
                        }
                    }).catch((error: any) => {
                        // 提示删除失败
                        this.$throw(error,'onRemove');
                    });
                }
            });
        }
    }


    /**
     * 批量更新文件表的ownerid
     * @param files
     * @memberof DiskImageUplaod
     */
    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",
                ...this.headers,
            },
            timeout: 2000
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.updatefailure') + "!",'updateFileBatch');
                return;
            }
        }).catch((error: any) => {
            this.$throw(error,'updateFileBatch');
        });
    }


}
</script>

<style lang="less">
    // el-dialog头部
    .el-dialog__header {
        height: 40px;
    }

    // el-dialog面板
    .el-dialog__wrapper {
        height: 90vh;
        overflow: visible;
    }

    // el-dialog
    .el-dialog {
        height: 76vh;
    }

    // el-dailog内容
    .el-dialog__body {
        height: inherit;
    }

    // iframe
    #fileIframe {
        height: calc(100% - 40px);
    }
</style>