/* * @Author: Rindy * @Date: 2019-08-06 16:25:08 * @LastEditors: Rindy * @LastEditTime: 2020-07-29 17:36:36 * @Description: Request */ import logger from './logger' import browser from './browser' import { base64ToBlob } from './file' import { checkLogin } from "@/api"; import { LoginDetector } from "@/utils/starter"; import { $alert, $loginTips } from '@/components/shared/message' import { $waiting } from '@/components/shared/loading' // 空函数 const noop = function() {} // 请求回调队列 let postQueue = [] export const statusCode = { NEXT: -999, //继续执行 SUCCESS: 0, //成功 EXCEPTION: -1, //异常错误 EXCEPTION_FUWU: 1, //服务异常 FAILURE_CODE_3001: 3001, //模型重复 FAILURE_CODE_3002: 3002, //户型重复 FAILURE_CODE_7007: 7007, //房源不存在 FAILURE_CODE_7008: 7008, //有关联场景使用此场景,不能删除 FAILURE_CODE_7005: 7005, //审核中不能编辑 FAILURE_CODE_7006: 7006, //已审核不能编辑 FAILURE_CODE_5001: 5001, //token失效 FAILURE_CODE_60001: 60001 //场景名称不能为空 } /** * 已知错误提示集合 */ // const defineErrorCode = [] let __showNetworkError = false let __showNoHouseError = false const showLoginTips = () => { // 防止多次请求弹出 if (showLoginTips.__is_show) { return } showLoginTips.__is_show = true return $loginTips({ title: '提示', okText: '去登录', noText: '登录完毕,继续', content: '您没有登录,请登录后再编辑', okLink: '/evergrande/#/login', ok: function() { showLoginTips.__is_show = false return false }, no: function() { checkLogin().then(response => { if (response.code === statusCode.SUCCESS) { postQueue.length && postQueue.forEach(item => item()) postQueue = [] LoginDetector.valid(); } else if (response.code === statusCode.FAILURE_CODE_5001) { showLoginTips() } }) showLoginTips.__is_show = false } }) } export function getToken() { return browser.urlHasValue('token', true) || localStorage.getItem('token') || '' } export function statusCodesHandler(result, callback) { if (result.code == statusCode.FAILURE_CODE_7005) { return $alert({ content: '该VR项目待审核,不可编辑。', forceOK:true, ok:()=>{ window.location.reload() }}) } if (result.code == statusCode.FAILURE_CODE_60001) { return $alert({ content: '场景名称不能为空'}) } if (result.code == statusCode.FAILURE_CODE_3001) { return $alert({ content: 'VR模型已存在,不能重复添加'}) } if (result.code == statusCode.FAILURE_CODE_3002) { return $alert({ content: '户型已存在,不能重复添加'}) } if (result.code == statusCode.FAILURE_CODE_7006) { return $alert({ content: '该VR项目已审核,不可编辑。', forceOK:true, ok:()=>{ window.location.reload() }}) } if (result.code == statusCode.FAILURE_CODE_7008) { if (__showNoHouseError) { return } __showNoHouseError = true return $alert({ content: `此场景有被热点关联,不能删除`, forceOK:true, ok:()=>{ __showNoHouseError = false $waiting.hide() }}) } if (result.code == statusCode.FAILURE_CODE_7007) { if (__showNoHouseError) { return } __showNoHouseError = true return $alert({ content: `房源不存在`, forceOK:true, ok:()=>{ __showNoHouseError = false $waiting.hide() }}) } if (result.code == statusCode.EXCEPTION||result.code == statusCode.EXCEPTION_FUWU) { if (__showNoHouseError) { return } __showNoHouseError = true return $alert({ content: `${result.msg}`, forceOK:true, ok:()=>{ __showNoHouseError = false $waiting.hide() }}) } if (result.code == statusCode.FAILURE_CODE_5001) { callback(result.code) return showLoginTips() } return statusCode.NEXT } $.ajaxSetup({ headers: {}, beforeSend: function(xhr) { const token = getToken() if (token) { xhr.setRequestHeader("token", token) } }, error: function() { // 出错时默认的处理函数 if (__showNetworkError) { return } __showNetworkError = true $alert({content: '网络异常,请稍后再试', forceOK:true, ok:()=>{ __showNetworkError = false }}) return }, success: function() { }, complete: function(data) { // Post类型请求无论成功或失败都关闭等待提示 if (this.type === 'POST'&& this.url.indexOf('pano/scene/uploadPano') == -1) { let isLongpolling = '' try { isLongpolling = JSON.parse(this.data).islongpolling } catch (error) { error } (http.__loading && !isLongpolling) && $waiting.hide() } http.__loading = true } }); export const http = { statusCode, __loading: true, __request(xhr, method, url, data, done, fail) { if (typeof done != 'function') { done = noop } if (typeof fail != 'function') { fail = noop } xhr.done(result => { if (typeof result.code !== 'undefined') { const flag = statusCodesHandler(result, function(code) { // 需要登录的状态 if (code == statusCode.FAILURE_CODE_5001) { postQueue.push(function() { http[method](url, data, done, fail) }) // if (url.indexOf('isLogin') == -1) { // postQueue.push(function() { // http[method](url, data, done, fail) // }) // } } }) if (flag === statusCode.NEXT) { done(result, result.code == 0) } } else { done(result) } }) xhr.fail(fail) xhr.always(() => xhr = null) return xhr }, /** * Get请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ get(url, data = {}, done, fail) { if (/\.json/.test(url)) { // json文件格式自动调用getJson方法 return this.getJson(url, data, done, fail) } return this.__request($.get(url, data), 'get', url, data, done, fail) }, /** * Get Blob请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ getText(url, data = {}, done, fail) { return this.__request($.ajax({ url: url, dataType: "text", }), 'getText', url, data, done, fail) }, /** * GetJson请求 读取json文件数据 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ getJson(url, data = {}, done, fail) { return this.__request($.getJSON(url, data), 'get', url, data, done, fail) }, /** * Get Blob请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ getBlob(url, data = {}, done, fail) { return this.__request($.ajax({ url: url, dataType: "blob", }), 'getBlob', url, data, done, fail) }, /** * Get Arraybuffer请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ getArraybuffer(url, data = {}, done, fail) { return this.__request($.ajax({ url: url, dataType: "arraybuffer", }), 'getArraybuffer', url, data, done, fail) }, /** * Post 请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ post(url, data = {}, done, fail) { if (url.indexOf('isLogin') == -1) { http.__loading && $waiting.show() } return this.__request($.post(url, data), 'post', url, data, done, fail) }, /** * PostJson 请求 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ postJson(url, data = {}, done, fail) { (http.__loading && !data.islongpolling) && $waiting.show() return this.__request($.ajax({ type: "POST", url: url, contentType: 'application/json', data: JSON.stringify(data) }), 'postJson', url, data, done, fail) }, /** * Post 表单 支持文件上传 * @param {String} url 请求地址 * @param {FormData?} formData 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ postForm(url, formData, done, fail, onProgress) { if (typeof onProgress === "function") { return this.__request($.ajax({ type: "POST", url: url, processData: false, contentType: false, data: formData, xhr: function() { const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', function(e) { onProgress((e.loaded / e.total) * 100 + '%') }) return xhr; }, }), 'postForm', url, formData, done, fail) } else { http.__loading && $waiting.show() return this.__request($.ajax({ type: "POST", url: url, processData: false, contentType: false, data: formData }), 'postForm', url, formData, done, fail) } }, /** * 加载图片 * @param {String} url 请求地址 * @param {Number?} retry 重试次数,默认为3 */ loadImage(url, retry = 3) { const def = $.Deferred(); const img = new Image; const load = () => { logger.warn("Retrying load image: " + url); this.loadImage(url, retry - 1).done(def.resolve.bind(def)).progress(def.notify.bind(def)).fail(def.reject.bind(def)); } img.onerror = function() { retry > 0 ? setTimeout(() => load(), 1e3) : def.reject(`[${url}]加载失败`) } img.onload = function() { def.resolve(img) } img.crossOrigin = "anonymous"; img.src = url; return def; }, /** * 上传文件 * @param {String} url 请求地址 * @param {Object?} data 请求参数 * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ uploadFile(url, data = {}, done, fail, onProgress) { const form = new FormData() // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob // form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name); // } else { // form.append("file", file.file, file.name || file.file.name); // } for (let key in data) { if (key == 'file') { form.append("file", data[key], data.filename || data[key].name); } else if (key != 'filename') { form.append(key, data[key]) } } return this.postForm(url, form, done, fail, onProgress) }, /** * 上传文件 * @param {String} url 请求地址 * @param {Object?} data 请求参数 {file:'base64 string',filename:'image.jpg',...} * @param {Function?} done 成功回调 * @param {Function?} fail 失败回调 */ uploadBlobFile(url, data = {}, done, fail) { const form = new FormData() for (let key in data) { if (key === 'file') { form.append("file", base64ToBlob(data.file), data.filename); } else if (key != 'filename') { form.append(key, data[key]) } } return this.postForm(url, form, done, fail) } }