app-data-upload.vue 10.5 KB
<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">
                        当前已经传输{{ uploadedProgress }}%,如文件过大,可关闭当前视图到系统消息中心查看进度。
                    </div>
                </div>
                <div v-else class="message-container">
                    <div class="result-list" v-if="responseResult.length > 0">
                        <ul>
                            <li
                                :class="item.errorInfo ? 'error-item' : 'success-item'"
                                v-for="(item, index) in responseResult"
                                :key="index"
                            >
                                {{ item.errorInfo ? item.errorInfo : item.successInfo }}
                            </li>
                        </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">
                        {{ this.viewparams.appDeLogicName + $t('components.appdatauploadview.datatemplate') }}</span
                    >
                </div>
            </el-col>
        </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 axios from 'axios';
import { Util } from 'ibiz-core';
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';

@Component({})
export default class AppDataUploadView extends Vue {
    /**
     * 传入视图参数
     *
     * @type {string}
     * @memberof AppDataUploadView
     */
    @Prop() protected dynamicProps!: string;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof AppDataUploadView
     */
    protected viewparams: any = {};

    /**
     * 视图上下文
     *
     * @type {*}
     * @memberof AppDataUploadView
     */
    protected viewdata: any = {};

    /**
     * 是否忽略错误
     *
     * @type {boolean}
     * @memberof AppDataUploadView
     */
    protected ignoreError: boolean = false;

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

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

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

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

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

    /**
     * 视图参数变化
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof AppDataUploadView
     */
    @Watch('dynamicProps', { immediate: true, deep: true })
    onParamData(newVal: any, oldVal: any) {
        if (newVal) {
            this.viewparams = eval('(' + newVal.viewparam + ')');
            this.viewdata = eval('(' + newVal.viewdata + ')');
            this.ignoreError = this.viewparams?.ignoreError;
        }
    }

    /**
     * 选择文件
     *
     * @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?.[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.viewdata.srfparentkey && this.viewdata.srfparentdename && this.viewdata.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 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)}/importdata`;
            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;
                        if (this.ignoreError) {
                            if (
                                data &&
                                Object.prototype.toString.call(data) === '[object Object]' &&
                                Object.keys(data).length > 0
                            ) {
                                Object.keys(data).forEach((key: string) => {
                                    if (data[key]['errorInfo']) {
                                        result.push({
                                            errorInfo: `第${Number(key) + 1}行:${data[key]['errorInfo']}`,
                                        });
                                    }
                                    if (data[key]['successInfo']) {
                                        result.push({
                                            successInfo: `第${Number(key) + 1}行:${data[key]['successInfo']}`,
                                        });
                                    }
                                });
                            }
                        } else {
                            result.push({ successInfo: `导入数据完成` });
                        }
                    }
                    this.setUIState(0, false, true, result);
                })
                .catch((error: any) => {
                    const errorResult: any[] = [];
                    if (error && error.status && error.status !== 200) {
                        errorResult.push({ errorInfo: error.data?.message });
                    }
                    this.setUIState(0, false, true, errorResult);
                });
        } catch (error: any) {
            this.setUIState(0, false, true, [{ errorInfo: error.data }]);
        }
    }
}
</script>

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