request.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /*
  2. * @Author: Rindy
  3. * @Date: 2019-08-06 16:25:08
  4. * @LastEditors: Rindy
  5. * @LastEditTime: 2020-07-29 17:36:36
  6. * @Description: Request
  7. */
  8. import logger from './logger'
  9. import browser from './browser'
  10. import { base64ToBlob } from './file'
  11. import { checkLogin } from "@/api";
  12. import { LoginDetector } from "@/utils/starter";
  13. import { $alert, $loginTips } from '@/components/shared/message'
  14. import { $waiting } from '@/components/shared/loading'
  15. // 空函数
  16. const noop = function() {}
  17. // 请求回调队列
  18. let postQueue = []
  19. export const statusCode = {
  20. NEXT: -999, //继续执行
  21. SUCCESS: 0, //成功
  22. EXCEPTION: -1, //异常错误
  23. EXCEPTION_FUWU: 1, //服务异常
  24. FAILURE_CODE_3001: 3001, //模型重复
  25. FAILURE_CODE_3002: 3002, //户型重复
  26. FAILURE_CODE_7007: 7007, //房源不存在
  27. FAILURE_CODE_7008: 7008, //有关联场景使用此场景,不能删除
  28. FAILURE_CODE_7005: 7005, //审核中不能编辑
  29. FAILURE_CODE_7006: 7006, //已审核不能编辑
  30. FAILURE_CODE_5001: 5001, //token失效
  31. FAILURE_CODE_60001: 60001 //场景名称不能为空
  32. }
  33. /**
  34. * 已知错误提示集合
  35. */
  36. // const defineErrorCode = []
  37. let __showNetworkError = false
  38. let __showNoHouseError = false
  39. const showLoginTips = () => {
  40. // 防止多次请求弹出
  41. if (showLoginTips.__is_show) {
  42. return
  43. }
  44. showLoginTips.__is_show = true
  45. return $loginTips({
  46. title: '提示',
  47. okText: '去登录',
  48. noText: '登录完毕,继续',
  49. content: '您没有登录,请登录后再编辑',
  50. okLink: '/evergrande/#/login',
  51. ok: function() {
  52. showLoginTips.__is_show = false
  53. return false
  54. },
  55. no: function() {
  56. checkLogin().then(response => {
  57. if (response.code === statusCode.SUCCESS) {
  58. postQueue.length && postQueue.forEach(item => item())
  59. postQueue = []
  60. LoginDetector.valid();
  61. } else if (response.code === statusCode.FAILURE_CODE_5001) {
  62. showLoginTips()
  63. }
  64. })
  65. showLoginTips.__is_show = false
  66. }
  67. })
  68. }
  69. export function getToken() {
  70. return browser.urlHasValue('token', true) || localStorage.getItem('token') || ''
  71. }
  72. export function statusCodesHandler(result, callback) {
  73. if (result.code == statusCode.FAILURE_CODE_7005) {
  74. return $alert({
  75. content: '该VR项目待审核,不可编辑。',
  76. forceOK:true,
  77. ok:()=>{
  78. window.location.reload()
  79. }})
  80. }
  81. if (result.code == statusCode.FAILURE_CODE_60001) {
  82. return $alert({
  83. content: '场景名称不能为空'})
  84. }
  85. if (result.code == statusCode.FAILURE_CODE_3001) {
  86. return $alert({
  87. content: 'VR模型已存在,不能重复添加'})
  88. }
  89. if (result.code == statusCode.FAILURE_CODE_3002) {
  90. return $alert({
  91. content: '户型已存在,不能重复添加'})
  92. }
  93. if (result.code == statusCode.FAILURE_CODE_7006) {
  94. return $alert({
  95. content: '该VR项目已审核,不可编辑。',
  96. forceOK:true,
  97. ok:()=>{
  98. window.location.reload()
  99. }})
  100. }
  101. if (result.code == statusCode.FAILURE_CODE_7008) {
  102. if (__showNoHouseError) {
  103. return
  104. }
  105. __showNoHouseError = true
  106. return $alert({
  107. content: `此场景有被热点关联,不能删除`,
  108. forceOK:true,
  109. ok:()=>{
  110. __showNoHouseError = false
  111. $waiting.hide()
  112. }})
  113. }
  114. if (result.code == statusCode.FAILURE_CODE_7007) {
  115. if (__showNoHouseError) {
  116. return
  117. }
  118. __showNoHouseError = true
  119. return $alert({
  120. content: `房源不存在`,
  121. forceOK:true,
  122. ok:()=>{
  123. __showNoHouseError = false
  124. $waiting.hide()
  125. }})
  126. }
  127. if (result.code == statusCode.EXCEPTION||result.code == statusCode.EXCEPTION_FUWU) {
  128. if (__showNoHouseError) {
  129. return
  130. }
  131. __showNoHouseError = true
  132. return $alert({
  133. content: `${result.msg}`,
  134. forceOK:true,
  135. ok:()=>{
  136. __showNoHouseError = false
  137. $waiting.hide()
  138. }})
  139. }
  140. if (result.code == statusCode.FAILURE_CODE_5001) {
  141. callback(result.code)
  142. return showLoginTips()
  143. }
  144. return statusCode.NEXT
  145. }
  146. $.ajaxSetup({
  147. headers: {},
  148. beforeSend: function(xhr) {
  149. const token = getToken()
  150. if (token) {
  151. xhr.setRequestHeader("token", token)
  152. }
  153. },
  154. error: function() { // 出错时默认的处理函数
  155. if (__showNetworkError) {
  156. return
  157. }
  158. __showNetworkError = true
  159. $alert({content: '网络异常,请稍后再试',
  160. forceOK:true,
  161. ok:()=>{
  162. __showNetworkError = false
  163. }})
  164. return
  165. },
  166. success: function() {
  167. },
  168. complete: function(data) {
  169. // Post类型请求无论成功或失败都关闭等待提示
  170. if (this.type === 'POST'&& this.url.indexOf('pano/scene/uploadPano') == -1) {
  171. let isLongpolling = ''
  172. try {
  173. isLongpolling = JSON.parse(this.data).islongpolling
  174. } catch (error) {
  175. error
  176. }
  177. (http.__loading && !isLongpolling) && $waiting.hide()
  178. }
  179. http.__loading = true
  180. }
  181. });
  182. export const http = {
  183. statusCode,
  184. __loading: true,
  185. __request(xhr, method, url, data, done, fail) {
  186. if (typeof done != 'function') {
  187. done = noop
  188. }
  189. if (typeof fail != 'function') {
  190. fail = noop
  191. }
  192. xhr.done(result => {
  193. if (typeof result.code !== 'undefined') {
  194. const flag = statusCodesHandler(result, function(code) {
  195. // 需要登录的状态
  196. if (code == statusCode.FAILURE_CODE_5001) {
  197. postQueue.push(function() {
  198. http[method](url, data, done, fail)
  199. })
  200. // if (url.indexOf('isLogin') == -1) {
  201. // postQueue.push(function() {
  202. // http[method](url, data, done, fail)
  203. // })
  204. // }
  205. }
  206. })
  207. if (flag === statusCode.NEXT) {
  208. done(result, result.code == 0)
  209. }
  210. } else {
  211. done(result)
  212. }
  213. })
  214. xhr.fail(fail)
  215. xhr.always(() => xhr = null)
  216. return xhr
  217. },
  218. /**
  219. * Get请求
  220. * @param {String} url 请求地址
  221. * @param {Object?} data 请求参数
  222. * @param {Function?} done 成功回调
  223. * @param {Function?} fail 失败回调
  224. */
  225. get(url, data = {}, done, fail) {
  226. if (/\.json/.test(url)) {
  227. // json文件格式自动调用getJson方法
  228. return this.getJson(url, data, done, fail)
  229. }
  230. return this.__request($.get(url, data), 'get', url, data, done, fail)
  231. },
  232. /**
  233. * Get Blob请求
  234. * @param {String} url 请求地址
  235. * @param {Object?} data 请求参数
  236. * @param {Function?} done 成功回调
  237. * @param {Function?} fail 失败回调
  238. */
  239. getText(url, data = {}, done, fail) {
  240. return this.__request($.ajax({
  241. url: url,
  242. dataType: "text",
  243. }), 'getText', url, data, done, fail)
  244. },
  245. /**
  246. * GetJson请求 读取json文件数据
  247. * @param {String} url 请求地址
  248. * @param {Object?} data 请求参数
  249. * @param {Function?} done 成功回调
  250. * @param {Function?} fail 失败回调
  251. */
  252. getJson(url, data = {}, done, fail) {
  253. return this.__request($.getJSON(url, data), 'get', url, data, done, fail)
  254. },
  255. /**
  256. * Get Blob请求
  257. * @param {String} url 请求地址
  258. * @param {Object?} data 请求参数
  259. * @param {Function?} done 成功回调
  260. * @param {Function?} fail 失败回调
  261. */
  262. getBlob(url, data = {}, done, fail) {
  263. return this.__request($.ajax({
  264. url: url,
  265. dataType: "blob",
  266. }), 'getBlob', url, data, done, fail)
  267. },
  268. /**
  269. * Get Arraybuffer请求
  270. * @param {String} url 请求地址
  271. * @param {Object?} data 请求参数
  272. * @param {Function?} done 成功回调
  273. * @param {Function?} fail 失败回调
  274. */
  275. getArraybuffer(url, data = {}, done, fail) {
  276. return this.__request($.ajax({
  277. url: url,
  278. dataType: "arraybuffer",
  279. }), 'getArraybuffer', url, data, done, fail)
  280. },
  281. /**
  282. * Post 请求
  283. * @param {String} url 请求地址
  284. * @param {Object?} data 请求参数
  285. * @param {Function?} done 成功回调
  286. * @param {Function?} fail 失败回调
  287. */
  288. post(url, data = {}, done, fail) {
  289. if (url.indexOf('isLogin') == -1) {
  290. http.__loading && $waiting.show()
  291. }
  292. return this.__request($.post(url, data), 'post', url, data, done, fail)
  293. },
  294. /**
  295. * PostJson 请求
  296. * @param {String} url 请求地址
  297. * @param {Object?} data 请求参数
  298. * @param {Function?} done 成功回调
  299. * @param {Function?} fail 失败回调
  300. */
  301. postJson(url, data = {}, done, fail) {
  302. (http.__loading && !data.islongpolling) && $waiting.show()
  303. return this.__request($.ajax({
  304. type: "POST",
  305. url: url,
  306. contentType: 'application/json',
  307. data: JSON.stringify(data)
  308. }), 'postJson', url, data, done, fail)
  309. },
  310. /**
  311. * Post 表单 支持文件上传
  312. * @param {String} url 请求地址
  313. * @param {FormData?} formData 请求参数
  314. * @param {Function?} done 成功回调
  315. * @param {Function?} fail 失败回调
  316. */
  317. postForm(url, formData, done, fail, onProgress) {
  318. if (typeof onProgress === "function") {
  319. return this.__request($.ajax({
  320. type: "POST",
  321. url: url,
  322. processData: false,
  323. contentType: false,
  324. data: formData,
  325. xhr: function() {
  326. const xhr = new XMLHttpRequest();
  327. xhr.upload.addEventListener('progress', function(e) {
  328. onProgress((e.loaded / e.total) * 100 + '%')
  329. })
  330. return xhr;
  331. },
  332. }), 'postForm', url, formData, done, fail)
  333. } else {
  334. http.__loading && $waiting.show()
  335. return this.__request($.ajax({
  336. type: "POST",
  337. url: url,
  338. processData: false,
  339. contentType: false,
  340. data: formData
  341. }), 'postForm', url, formData, done, fail)
  342. }
  343. },
  344. /**
  345. * 加载图片
  346. * @param {String} url 请求地址
  347. * @param {Number?} retry 重试次数,默认为3
  348. */
  349. loadImage(url, retry = 3) {
  350. const def = $.Deferred();
  351. const img = new Image;
  352. const load = () => {
  353. logger.warn("Retrying load image: " + url);
  354. this.loadImage(url, retry - 1).done(def.resolve.bind(def)).progress(def.notify.bind(def)).fail(def.reject.bind(def));
  355. }
  356. img.onerror = function() {
  357. retry > 0 ? setTimeout(() => load(), 1e3) : def.reject(`[${url}]加载失败`)
  358. }
  359. img.onload = function() {
  360. def.resolve(img)
  361. }
  362. img.crossOrigin = "anonymous";
  363. img.src = url;
  364. return def;
  365. },
  366. /**
  367. * 上传文件
  368. * @param {String} url 请求地址
  369. * @param {Object?} data 请求参数
  370. * @param {Function?} done 成功回调
  371. * @param {Function?} fail 失败回调
  372. */
  373. uploadFile(url, data = {}, done, fail, onProgress) {
  374. const form = new FormData()
  375. // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob
  376. // form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name);
  377. // } else {
  378. // form.append("file", file.file, file.name || file.file.name);
  379. // }
  380. for (let key in data) {
  381. if (key == 'file') {
  382. form.append("file", data[key], data.filename || data[key].name);
  383. } else if (key != 'filename') {
  384. form.append(key, data[key])
  385. }
  386. }
  387. return this.postForm(url, form, done, fail, onProgress)
  388. },
  389. /**
  390. * 上传文件
  391. * @param {String} url 请求地址
  392. * @param {Object?} data 请求参数 {file:'base64 string',filename:'image.jpg',...}
  393. * @param {Function?} done 成功回调
  394. * @param {Function?} fail 失败回调
  395. */
  396. uploadBlobFile(url, data = {}, done, fail) {
  397. const form = new FormData()
  398. for (let key in data) {
  399. if (key === 'file') {
  400. form.append("file", base64ToBlob(data.file), data.filename);
  401. } else if (key != 'filename') {
  402. form.append(key, data[key])
  403. }
  404. }
  405. return this.postForm(url, form, done, fail)
  406. }
  407. }