<template>
    <div class="app-data-upload-view" element-loading-background="rgba(57, 57, 57, 0.2)">
        <input
            ref="inputUpLoad"
            type="file"
            style="display: none"
            accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            @change="fileChange"
        />
        <div class="main-content">
            <div v-if="!selectedFile" class="upload-container" @click="handleUpLoad">
                <img class="icon-import" src="@/assets/img/icon-import.svg" />
                <span class="select-file-text">{{ $t('components.appDataUploadView.selectfile') }}</span>
            </div>
            <div v-else class="data-info-container">
                <div v-if="!isUploaded" class="message-container">
                    <div class="success-list" v-if="!isUploading">
                        {{ $t('components.appDataUploadView.selectfilesucess') }}
                    </div>
                    <div class="success-list" v-if="isUploading">
                        导入过程中，请稍候
                    </div>
                </div>
                <div v-else class="message-container">
                    <div class="result-list" v-if="Object.keys(responseResult).length > 0">
                        <ul>
                            <li class="title"><span>{{ $t('components.appDataUploadView.importresult') }}</span></li>
                            <li>
                                <span>
                                    {{ $t('components.appDataUploadView.totaldata') }} {{ responseResult.total }} {{ $t('components.appDataUploadView.total') }}，{{ $t('app.commonwords.wrong') }}[{{ responseResult.error }}]，{{ $t('app.commonwords.success') }}[{{ responseResult.success }}]
                                </span>
                            </li>
                            <template
                                v-if="responseResult.errorInfos && responseResult.errorInfos.length !== 0">
                                <li class="title"><span>{{ $t('components.appDataUploadView.errorinfo') }}</span></li>
                                <li class="error-item" v-for="(item, index) in responseResult.errorInfos" :key="index">
                                    <span v-if="item.index">{{ $t('components.appDataUploadView.start') }} {{item.index}} {{ $t('components.appDataUploadView.row') }}：</span><span v-html="item.errorinfo"></span>
                                </li>
                            </template>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <el-row class="second-content">
            <el-col>
                <div class="import-template-message">{{ $t('components.appDataUploadView.datatemplatemessage') }}</div>
                <div class="import-template">
                    <img class="icon-link" src="@/assets/img/icon-link.svg" />
                    <span style="cursor: pointer" @click="downloadTemp">
                        {{ viewParams.appDeLogicName + $t('components.appDataUploadView.datatemplate') }}</span
                    >
                </div>
            </el-col>
            <div class="import-template-download-info" v-if="isUploaded && responseResult.errorfile" @click="downloadFeedbackMsg">
                {{ $t('components.appDataUploadView.downloadinfo') }}
            </div>
        </el-row>
        <el-row class="button-container">
            <el-button type="primary" @click="handleCancel">{{ $t('components.appDataUploadView.cancel') }}</el-button>
            <el-button
                :disabled="!selectedFile"
                :loading="isUploading"
                type="primary"
                class="primary-button"
                @click="uploadServer"
                >{{ $t('components.appDataUploadView.uploadserver') }}</el-button
            >
        </el-row>
    </div>
</template>

<script lang="ts">
import { Environment } from '@/environments/environment';
import { Util } from '@/utils';
import axios from 'axios';
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';

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

    @Prop() public viewparam: any;

    /**
     * 视图上下文
     *
     * @type {*}
     * @memberof AppDataUploadView
     */
    @Prop() public viewdata: any;

    public viewParams: any = {};

    public context: any = {};

    /**
     * 选择文件数据
     *
     * @type {*}
     * @memberof AppDataUploadView
     */
    public selectedFile: any | null = null;

    /**
     * 是否上传完成
     *
     * @type {boolean}
     * @memberof AppDataUploadView
     */
    public isUploaded: boolean = false;

    /**
     * 上传进度
     *
     * @type {number}
     * @memberof AppDataUploadView
     */
    public uploadedProgress: number = 0;

    /**
     * 是否上传过程中
     *
     * @type {boolean}
     * @memberof AppDataUploadView
     */
    public isUploading: boolean = false;

    /**
     * 导入结果集合
     *
     * @type {Array<*>}
     * @memberof AppDataUploadView
     */
    public responseResult: any = {};

    /**
     * 视图参数变化
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof AppDataUploadView
     */
    @Watch('viewparam', { immediate: true, deep: true })
    onParamData(newVal: any, oldVal: any) {
        if (newVal) {
            this.viewParams = JSON.parse(newVal);
            console.log('视图残花', this.viewParams);
        }
    }

    @Watch('viewdata', { immediate: true, deep: true })
    onViewDataChange(newVal: any, oldVal: any) {
        if (newVal) {
            this.context = JSON.parse(newVal);
            console.log('上下文', this.context);
        }
    }

    /**
     * 选择文件
     *
     * @memberof AppDataUploadView
     */
    public handleUpLoad() {
        (this.$refs.inputUpLoad as any).click();
    }

    /**
     * 取消
     *
     * @memberof AppDataUploadView
     */
    public handleCancel() {
        this.$emit('close', []);
    }

    /**
     * 文件数据变化
     *
     * @memberof AppDataUploadView
     */
    public fileChange($event: any) {
        let obj = $event.target || $event.srcElement;
        if (!obj.files) {
            return;
        }
        this.selectedFile = obj.files && obj.files.length > 0 ? obj.files[0] : {};
    }

    /**
     * 设置UI状态
     *
     * @memberof AppDataUploadView
     */
    public setUIState(uploadedProgress: number, isUploading: boolean, isUploaded: boolean, result: any = {}) {
        this.uploadedProgress = uploadedProgress;
        this.isUploading = isUploading;
        this.isUploaded = isUploaded;
        this.responseResult = result;
    }

    /**
     * 下载导入数据模板
     *
     * @memberof AppDataUploadView
     */
    public downloadTemp() {
        let requestUrl: string = '';
        if (this.viewdata && this.context.srfparentkey && this.context.srfparentdename && this.context.srfparentdename !== this.viewdata.appEntityName) {
            requestUrl += `/${Util.srfpluralize(this.viewdata.srfparentdename)}/${this.viewdata.srfparentkey}`;
        }
        requestUrl += `/${Util.srfpluralize(this.viewParams.serviceName)}/importtemplate`;
        if (this.viewParams.importId) {
            requestUrl += `?srfimporttag=${this.viewParams.importId}`;
        }
        axios({
            url: requestUrl,
            method: 'get',
            responseType: 'blob',
        }).then((response: any) => {
            if (response.status == 200) {
                let fileName = response.headers['content-disposition']
                    .split(';')
                    .find((str: string) => str.indexOf('filename=') != -1)
                    .slice(9);
                fileName = decodeURIComponent(fileName);
                let blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
                let elink = document.createElement('a');
                elink.download = fileName;
                elink.style.display = 'none';
                elink.href = URL.createObjectURL(blob);
                document.body.appendChild(elink);
                elink.click();
                URL.revokeObjectURL(elink.href); // 释放URL 对象
                document.body.removeChild(elink);
            }
        });
    }

    /**
     * 下载导入反馈信息
     *
     * @memberof AppDataUploadView
     */
     public downloadFeedbackMsg() {
        if(!this.responseResult || !this.responseResult.errorfile || !this.responseResult.errorfile.fileid){
            this.$Notice.error({ desc: this.$t('components.appDataUploadView.downloaderror') as string });
            return;
        }
        let downloadUrl: string = `${Environment.ExportFile}/${this.responseResult.errorfile.folder}/${this.responseResult.errorfile.fileid}`;
        const headers = {};
        axios({
            method: 'get',
            url: downloadUrl,
            headers: headers,
            responseType: 'blob'
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$Notice.error({ desc: this.$t('components.appDataUploadView.downloaderror') as string });
                return;
            }
            // 请求成功，后台返回的是一个文件流
            if (response.data) {
                // 获取文件名
                const filename = `导入错误${this.responseResult.errorfile.fileid}.xlsx`;
                let filetype = this.calcFilemime('xlsx');
                // 用blob对象获取文件流
                let blob = new Blob([response.data], { type: filetype });
                // 通过文件流创建下载链接
                var href = URL.createObjectURL(blob);
                // 创建一个a元素并设置相关属性
                let 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 {
                this.$Notice.error({ desc: this.$t('components.appDataUploadView.downloaderror') as string });
            }
        }).catch((error: any) => {
            console.error(error);
        });
    }

    /**
     * 计算文件mime类型
     *
     * @param filetype 文件后缀
     * @memberof AppDataUploadView
     */
     public calcFilemime(filetype: string): string {
        let mime = "application/vnd.ms-excel";
        switch (filetype) {
            case ".xlsx":
                mime = "application/vnd.ms-excel";
                break;
            case ".wps":
                mime = "application/kswps";
                break;
            case ".doc":
                mime = "application/msword";
                break;
            case ".docx":
                mime = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                break;
            case ".txt":
                mime = "text/plain";
                break;
            case ".zip":
                mime = "application/zip";
                break;
            case ".png":
                mime = "image/png";
                break;
            case ".gif":
                mime = "image/gif";
                break;
            case ".jpeg":
                mime = "image/jpeg";
                break;
            case ".jpg":
                mime = "image/jpeg";
                break;
            case ".rtf":
                mime = "application/rtf";
                break;
            case ".avi":
                mime = "video/x-msvideo";
                break;
            case ".gz":
                mime = "application/x-gzip";
                break;
            case ".tar":
                mime = "application/x-tar";
                break;
        }
        return mime;
    }

    /**
     * 上传服务器
     *
     * @memberof AppDataUploadView
     */
    public uploadServer() {
        if (!this.selectedFile) {
            return;
        }
        try {
            let requestUrl: string = '';
            this.setUIState(0, true, false);
            if (this.viewdata && this.viewdata.srfparentkey && this.viewdata.srfparentdename) {
                requestUrl += `/${Util.srfpluralize(this.viewdata.srfparentdename)}/${this.viewdata.srfparentkey}`;
            }
            requestUrl += `/${Util.srfpluralize(this.viewParams.serviceName)}/importdata2`;
            if (this.viewParams.importId) {
                requestUrl += `?srfimporttag=${this.viewParams.importId}`;
            }
            const data = new FormData();
            data.append('file', this.selectedFile);
            axios
                .post(requestUrl, data, {
                    headers: { 'Content-Type': 'multipart/form-data' },
                    onUploadProgress: (progressEvent: any) => {
                        this.uploadedProgress = Math.floor((progressEvent.loaded / progressEvent.total) * 100);
                    },
                })
                .then((res: any) => {
                    const result: any = {};
                    if (res && res.status && res.status == 200) {
                        const { data: data } = res;
                        const {errorinfo,success,total,errorfile} = data;
                        result.total = total ? Number(total) : 0;
                        result.success = success ? Number(success) : 0;
                        result.errorfile = errorfile;
                        if(errorinfo && Object.keys(errorinfo).length >0){
                            result.error =  Object.keys(errorinfo).length;
                            result.errorInfos = [];
                            Object.keys(errorinfo).forEach((item:any) =>{
                                result.errorInfos.push({index: Number(item) + 1, errorinfo: errorinfo[item].errorInfo});
                            })
                        }
                    }
                    this.setUIState(0, false, true, result);
                }).catch((error: any) => {
                    const errorResult: any = {};
                    if (error && error.status && error.status !== 200) {
                        errorResult.errorInfos = [];
                        errorResult.errorInfos.push({ errorInfo: error.data && error.data.message ? error.data.message : '' });
                    }
                    this.setUIState(0, false, true, errorResult);
                });
        } catch (error: any) {
            this.setUIState(0, false, true, { errorInfos:[{errorInfo: error.data}] });
        }
    }
}
</script>

<style lang='less'>
@import './app-data-upload.less';
</style>