<script>
    jsonService = axios.create({
        method: 'post',
        timeout: 30000,
        baseURL: '/ajax/',
        headers: {'Content-Type': 'application/json;charset=UTF-8'},
    });
    downloadService = axios.create({
        method: 'post',
        timeout: 30000,
        baseURL: '',
        responseType: 'blob',
        headers: {'Content-Type': 'application/json;charset=UTF-8'},
    });
    uploadService = axios.create({
        method: 'post',
        timeout: 30000,
        baseURL: '',
        responseType: 'blob',
        headers: {'Content-Type': 'multipart/form-data'},
        onUploadProgress: function (progressEvent) {
            var complete = (progressEvent.loaded / progressEvent.total * 100 | 0) + '%'
            nav.tipShow("上传中(" + complete + ")")
        },
    });
    function handleError(status) {
        switch (status) {
            case 401:
                return {message: "未授权，请登录(401)"};
            case 403:
                return {message: "拒绝访问(403)"};
            case 404:
                return {message: "请求地址错误(404)"};
            case 408:
                return {message: "请求超时(408)"};
            case 500:
                return {message: "服务器内部错误(500)"};
            case 501:
                return {message: "服务未实现(501)"};
            default:
                return {message: "请求错误(" + error.response.status + ")"};
        }
    }
    function jsonRequest(data) {
        nav.barShow();
        nav.tipShow();
        return jsonService.request(data)
                .then(function (response) {
                    nav.tipClose();
                    if (response.data.errors) {// 确保服务器正确返回Json
                        nav.barFinish();
                    } else {
                        response.data = {errors: [{message: '服务器响应错误'}]};
                        nav.barError();
                    }
                    return Promise.resolve(response.data);
                }, function (error) {
                    nav.tipClose();
                    nav.barError();
                    const rsp = {errors: []};
                    if (!error.response) {
                        rsp.errors.push({message: error.message});
                    } else {
                        rsp.errors.push(handleError(error.response.status));
                    }
                    return Promise.reject(rsp);
                })
    }
    function upRequest(data) {
        nav.barShow();
        nav.tipShow("上传中...");
        var fd = new FormData();
        fd.append("file", data.data);
        data.data = fd;
        return uploadService.request(data)
                .then(function (response) {
                    nav.tipClose();
                    if (!response.data) {
                        nav.barError();
                        return Promise.resolve({errors: [{message: '下载错误'}]});
                    } else if ("application/json" == response.data.type) {
                        var reader = new FileReader();
                        reader.addEventListener("loadend", function () {
                            var rsp = JSON.parse(reader.result);
                            if (rsp.errors.length > 0) {
                                nav.barError();
                                nav.e(rsp.errors[0].message)
                            } else {
                                nav.barFinish();
                            }
                        });
                        reader.readAsText(response.data, "utf-8");
                        return Promise.resolve({errors: []});
                    } else {
                        nav.barFinish();
                        // 获取响应header中文件信息
                        var dis = response.headers['content-disposition'];
                        // 正则匹配文件名
                        var fileName = dis.match(/filename="(.*\..*)"/)[1];
                        // 模拟下载
                        var url = window.URL.createObjectURL(new Blob([response.data]));
                        var link = document.createElement('a')
                        link.style.display = 'none';
                        link.href = url;
                        link.setAttribute('download', decodeURIComponent(fileName))
                        document.body.appendChild(link)
                        link.click();
                        return Promise.resolve({errors: []});
                    }
                }, function (error) {
                    nav.tipClose();
                    nav.barError();
                    const rsp = {errors: []};
                    if (!error.response) {
                        rsp.errors.push({message: error.message});
                    } else {
                        rsp.errors.push(handleError(error.response.status));
                    }
                    return Promise.reject(rsp);
                })
    };
    function downRequest(data) {
        nav.barShow();
        return downloadService.request(data)
                .then(function (response) {
                    if (!response.data) {
                        nav.barError();
                        return Promise.resolve({errors: [{message: '下载错误'}]});
                    } else if ("application/json" == response.data.type) {
                        var reader = new FileReader();
                        reader.addEventListener("loadend", function () {
                            var rsp = JSON.parse(reader.result);
                            if (rsp.errors.length > 0) {
                                nav.barError();
                                nav.e(rsp.errors[0].message)
                            } else {
                                nav.barFinish();
                            }
                        });
                        reader.readAsText(response.data, "utf-8");
                        return Promise.resolve({errors: []});
                    } else {
                        nav.barFinish();
                        // 获取响应header中文件信息
                        var dis = response.headers['content-disposition'];
                        // 正则匹配文件名
                        var fileName = dis.match(/filename="(.*\..*)"/)[1];
                        // 模拟下载
                        var url = window.URL.createObjectURL(new Blob([response.data]));
                        var link = document.createElement('a')
                        link.style.display = 'none';
                        link.href = url;
                        link.setAttribute('download', decodeURIComponent(fileName))
                        document.body.appendChild(link)
                        link.click();
                        return Promise.resolve({errors: []});
                    }
                }, function (response) {
                    return Promise.resolve(handleError(response.response.status));
                })
    };
    // 定义共享异步请求对象
    Vue.prototype.$ajax = {
        login: function (data) {
            return jsonRequest({
                url: "system/Auth/login",
                data: JSON.stringify(data),
            })
        },
        upload: function (data) {
            return upRequest({
                url: "ajax/system/File/upload",
                data: data,
            })
        },
        download: function (data) {
            return downRequest({
                url: "ajax/system/File/download",
                data: JSON.stringify(data),
            })
        },
        create: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/create",
                data: JSON.stringify(data),
            })
        },
        update: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/update",
                data: JSON.stringify(data),
            })
        },
        delete: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/delete",
                data: JSON.stringify(data),
            })
        },
        find: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/find",
                data: JSON.stringify(data),
            })
        },
        get: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/get",
                data: JSON.stringify(data),
            })
        },
        load: function (module, target, data) {
            return jsonRequest({
                url: module + "/" + target + "/load",
                data: JSON.stringify(data),
            })
        },
        template: function (module, target, data) {
            return downRequest({
                url: "/ajax/" + module + "/" + target + "/template",
                data: JSON.stringify(data),
            })
        },
        imports: function (module, target, data) {
            return upRequest({
                url: "/ajax/" + module + "/" + target + "/imports",
                data: data,
            })
        },
        exports: function (module, target, data) {
            return downRequest({
                url: "/ajax/" + module + "/" + target + "/exports",
                data: data,
            })
        },
    };
    var mixin = {
        data: {
            activeIndex: 'home',
            contextPath: '${context?default("")}',
            homePath: '${home?default("")}',
            loadingTip: '',
            loadingBar: '',
            isSubmit: false,
            result: [],
            select: []
        },
        methods: {
            tipShow: function (msg) {
                var message = "<i class='el-icon-loading'></i> 正在加载 ..."
                if (msg) {
                    message = "<i class='el-icon-loading'></i> " + msg
                }
                if (!this.loadingTip) {
                    this.loadingTip = this.$message({
                        type: '',
                        duration: 0,
                        dangerouslyUseHTMLString: true,
                        message: message
                    });
                } else {
                    this.loadingTip.message = message;
                }
            },
            tipClose: function (msg) {
                if (this.loadingTip) {
                    this.loadingTip.close();
                    this.loadingTip = '';
                }
            },
            barShow: function () {
                if (!this.loadingBar) {
                    this.loadingBar = this.$message({
                        type: '',
                        duration: 0,
                        customClass: 'loading-bar',
                        dangerouslyUseHTMLString: true,
                        message: '<i class="bar" style="width: 90%"></i>'
                    });
                } else {
                    this.loadingBar.message = '<i class="bar" style="width: 90%"></i>'
                }
            },
            barFinish: function () {
                if (this.loadingBar) {
                    this.loadingBar.message = '<i class="bar" style="width: 100%"></i>'
                    setTimeout(function () {
                        if (this.loadingBar) {
                            this.loadingBar.close();
                            this.loadingBar = '';
                        }
                    }.bind(this), 500);
                }
            },
            barError: function () {
                if (this.loadingBar) {
                    this.loadingBar.message = '<i class="bar error" style="width: 100%"></i>'
                    setTimeout(function () {
                        if (this.loadingBar) {
                            this.loadingBar.close();
                            this.loadingBar = '';
                        }
                    }.bind(this), 500);
                }
            },
            i: function (message, callback) {
                this.$message({
                    type: "info",
                    showClose: true,
                    message: message,
                    duration: 1500,
                    onClose: callback
                });
            },
            e: function (message, callback) {
                this.$message({
                    type: "error",
                    showClose: true,
                    message: message,
                    duration: 1500,
                    onClose: callback
                });
            },
            w: function (message, callback) {
                this.$message({
                    type: "warning",
                    showClose: true,
                    message: message,
                    duration: 1500,
                    onClose: callback
                });
            },
            s: function (message, callback) {
                this.$message({
                    type: "success",
                    showClose: true,
                    message: message,
                    duration: 1500,
                    onClose: callback
                });
            },
            toOpen: function (url) {
                this.tipShow();
                var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
                $("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_self' style='dispaly:none;'></a>"))
                document.getElementById("wb-open").click();
                $("#wb-open").remove();
            },
            toOpenNew: function (url) {
                var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
                $("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_blank' style='dispaly:none;'></a>"))
                document.getElementById("wb-open").click();
                $("#wb-open").remove();
            },
            toHome: function () {
                this.tipShow();
                location.href = this.contextPath + "/"
            },
            /**
             * 滚动屏蔽至顶部
             */
            scrollToTop: function () {
                var distance = document.documentElement.scrollTop || document.body.scrollTop;
                var step = distance / 10;

                (function jump() {
                    if (distance > 0) {
                        distance -= step;
                        window.scrollTo(0, distance);
                        setTimeout(jump, 10)
                    }
                })();
            },
            /**
             * 控制任一目标滚动到顶部
             * select jquery对象
             */
            scrollToTop: function (select) {
                var distance = $(select).scrollTop();
                var step = distance / 10;

                (function jump() {
                    if (distance > 0) {
                        distance -= step;
                        $(select).scrollTop(distance);
                        setTimeout(jump, 10)
                    } else {
                        $(select).scrollTop(distance);
                    }
                })();
            },
            onSearch: function () {
                this.vm.pageNumber = 1;
                this.onFind();
            },
            onReset: function (form) {
                this.$refs[form].resetFields();
                this.w('重置成功');
            },
            onPageChange: function (pageNumber) {
                this.vm.pageNumber = pageNumber;
                this.onFind();
            },
            onSelectionChange: function (select) {
                this.select = select;
            },
            selectExcel: function () {
                this.$refs['excel'].dispatchEvent(new MouseEvent('click'))
            },
            onTemplate: function () {
                this.$ajax.template(this.module, this.target, {});
            },
            onImport: function (item) {
                const file = item.target.files[0];
                this.$ajax.imports(this.module, this.target, file);
                this.$refs['excel'].value = ''
            },
            onExport: function () {
                this.$ajax.exports(this.module, this.target, this.vm);
            },
            onSave: function () {
                this.$refs['form'].validate(function (valid) {
                    if (valid) {
                        if (this.form.id) {
                            this.$ajax.update(this.module, this.target, this.form).then(function (response) {
                                if (response.errors.length > 0) {
                                    nav.e(response.errors[0].message);
                                } else {
                                    this.onFind();
                                    this.form.dialog = false;
                                }
                            }.bind(this))
                        } else {
                            this.$ajax.create(this.module, this.target, this.form).then(function (response) {
                                if (response.errors.length > 0) {
                                    nav.e(response.errors[0].message);
                                } else {
                                    this.onFind();
                                    this.form.dialog = false;
                                }
                            }.bind(this))
                        }
                    } else {
                        return false;
                    }
                }.bind(this));
            },
            onFind: function () {
                this.$ajax.find(this.module, this.target, this.vm).then(function (response) {
                    if (response.errors.length > 0) {
                        this.e(response.errors[0].message);
                    } else {
                        this.result = response.result;
                        this.vm.totalCount = Number(response.totalCount);
                    }
                }.bind(this))
            },
            onDelete: function (item) {
                this.$confirm('将删除该项, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(function () {
                    this.$ajax.delete(this.module, this.target, {id: item.id}).then(function (response) {
                        if (response.errors.length > 0) {
                            this.e(response.errors[0].message);
                        } else {
                            this.s("删除成功");
                            this.onFind();
                        }
                    }.bind(this));
                }.bind(this)).catch(function (action) {

                });
            },
            onBitchDelete: function () {
                if (this.select.length == 0) {
                    this.w("至少选中一项");
                } else {
                    this.$confirm('将删除已选择的项, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(function () {
                        for (var i = 0; i < this.select.length; i++) {
                            var obj = this.select[i];
                            this.$ajax.delete(this.module, this.target, {id: obj.id}).then(function (response) {
                                if (response.errors.length > 0) {
                                    this.e(response.errors[0].message);
                                } else {
                                    for (var j = 0; j < this.select.length; j++) {
                                        if (this.select[j].id == obj.id) {
                                            this.select.splice(j, 1);
                                        }
                                    }
                                    if (this.select.length == 0) {
                                        this.s("删除成功")
                                        this.onFind();
                                    }
                                }
                            }.bind(this))
                        }
                    }.bind(this)).catch(function (action) {

                    });
                }
            },
        },
        created: function () {
        },
        mounted: function () {
        },
        filters: {},
        watch: {}
    }
    // 实例化工具
    window.nav = new Vue({
        mixins: [mixin]
    })
</script>