request.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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 Vue from "vue";
  9. import logger from "./logger";
  10. import browser from "./browser";
  11. import { base64ToBlob } from "./file";
  12. import { checkLogin } from "@/api";
  13. import { LoginDetector } from "@/utils/starter";
  14. import { $alert, $confirm } from "@/components/shared/message";
  15. let vue = new Vue();
  16. // 空函数
  17. const noop = function() {};
  18. // 请求回调队列
  19. let postQueue = [];
  20. export const statusCode = {
  21. NEXT: -999, //继续执行
  22. SUCCESS: 0, //成功
  23. EXCEPTION: -1, //异常错误
  24. FAILURE_CODE_3002: 3002, //请至少保留一个场景。
  25. FAILURE_CODE_3003: 3003, //文件名称不允许超过50个字符
  26. FAILURE_CODE_3005: 3005, //不是该用户作品
  27. FAILURE_CODE_3006: 3006, //作品已被删除,无法编辑
  28. FAILURE_CODE_3007: 3007, //素材已被引用,无法删除。
  29. FAILURE_CODE_5003: 5003, //不支持此图片
  30. FAILURE_CODE_7005: 7005, //审核中不能编辑
  31. FAILURE_CODE_7006: 7006, //已审核不能编辑
  32. FAILURE_CODE_5001: 5001, //token失效
  33. FAILURE_CODE_5004: 5004, // 密码错误
  34. };
  35. /**
  36. * 已知错误提示集合
  37. */
  38. // const defineErrorCode = []
  39. let __showNetworkError = false;
  40. export const showLoginTips = () => {
  41. // 防止多次请求弹出
  42. if (showLoginTips.__is_show) {
  43. return;
  44. }
  45. showLoginTips.__is_show = true;
  46. return $confirm({
  47. title: "提示",
  48. content: "登录态失效,请重新登录",
  49. okText: "去登录",
  50. noText: "登录完毕,继续",
  51. okLink: "/",
  52. ok: function() {
  53. showLoginTips.__is_show = false;
  54. return false;
  55. },
  56. no: function() {
  57. checkLogin().then((response) => {
  58. if (response.code === statusCode.SUCCESS) {
  59. postQueue.length && postQueue.forEach((item) => item());
  60. postQueue = [];
  61. LoginDetector.valid();
  62. location.reload()
  63. } else if (response.code === statusCode.FAILURE_CODE_5001) {
  64. showLoginTips();
  65. }
  66. })
  67. showLoginTips.__is_show = false;
  68. },
  69. });
  70. };
  71. function getCookie(objname) {
  72. //获取指定名称的cookie的值
  73. var arrstr = document.cookie.split("; ");
  74. for (var i = 0; i < arrstr.length; i++) {
  75. var temp = arrstr[i].split("=");
  76. if (temp[0] == objname) return unescape(temp[1]);
  77. }
  78. }
  79. export function getToken() {
  80. return (
  81. browser.urlHasValue("token", true) || localStorage.getItem("token") || getCookie("fdkankantoken") || ""
  82. );
  83. }
  84. export function statusCodesHandler(result, callback) {
  85. if (result.code == statusCode.FAILURE_CODE_7005) {
  86. return $alert({
  87. content: "该VR作品待审核,不可编辑。",
  88. forceOK: true,
  89. ok: () => {
  90. let url = window.location.href
  91. window.location.href = url
  92. },
  93. });
  94. }
  95. if (result.code == statusCode.FAILURE_CODE_7006) {
  96. return $alert({
  97. content: "该VR作品已审核,不可编辑。",
  98. forceOK: true,
  99. ok: () => {
  100. window.location.reload();
  101. },
  102. });
  103. }
  104. if (result.code == statusCode.FAILURE_CODE_3007) {
  105. return $alert({ content: "素材已被引用,无法删除。" });
  106. }
  107. if (result.code == statusCode.FAILURE_CODE_3002) {
  108. return $alert({ content: "请至少保留一个场景。" });
  109. }
  110. if (result.code == statusCode.FAILURE_CODE_3006) {
  111. return $alert({ content: "作品已被删除,无法编辑" });
  112. }
  113. if (result.code == statusCode.FAILURE_CODE_3005) {
  114. return;
  115. }
  116. if (result.code == statusCode.FAILURE_CODE_3003) {
  117. return statusCode.FILE;
  118. // return $alert({ content: '文件名称不允许超过50个字符' })
  119. }
  120. if (result.code == statusCode.FAILURE_CODE_5003) {
  121. return statusCode.FILE;
  122. // return $alert({ content: '不支持此图片' })
  123. }
  124. if (result.code == statusCode.FAILURE_CODE_5004) {
  125. return vue.$msg.error("密码错误");
  126. // return vue.({ content: "密码错误" });
  127. }
  128. if (result.code == statusCode.FAILURE_CODE_5001) {
  129. callback(result.code);
  130. return showLoginTips();
  131. }
  132. if (result.code != statusCode.SUCCESS) {
  133. return $alert({ content: `${result.msg}` });
  134. }
  135. return statusCode.NEXT;
  136. }
  137. $.ajaxSetup({
  138. headers: {},
  139. beforeSend: function(xhr) {
  140. const token = getToken();
  141. if (token) {
  142. xhr.setRequestHeader("token", token);
  143. }
  144. },
  145. error: function() {
  146. // 出错时默认的处理函数
  147. if (__showNetworkError) {
  148. return;
  149. }
  150. __showNetworkError = true;
  151. $alert({
  152. content: "网络异常,请稍后再试",
  153. forceOK: true,
  154. ok: () => {
  155. __showNetworkError = false;
  156. },
  157. });
  158. return;
  159. },
  160. success: function() {},
  161. complete: function(data) {
  162. },
  163. });
  164. export const http = {
  165. statusCode,
  166. __request(xhr, method, url, data, done, fail) {
  167. if (typeof done != "function") {
  168. done = noop;
  169. }
  170. if (typeof fail != "function") {
  171. fail = noop;
  172. }
  173. xhr.done((result) => {
  174. if (typeof result.code !== "undefined") {
  175. const flag = statusCodesHandler(result, function(code) {
  176. // 需要登录的状态
  177. if (code == statusCode.FAILURE_CODE_5001) {
  178. postQueue.push(function() {
  179. http[method](url, data, done, fail);
  180. });
  181. }
  182. });
  183. if (!flag) {
  184. return;
  185. }
  186. if (flag === statusCode.FILE) { // 并没有这个值
  187. done(result);
  188. }
  189. if (flag === statusCode.NEXT) {
  190. done(result, result.code == 0);
  191. }
  192. } else {
  193. done(result);
  194. }
  195. });
  196. xhr.fail(fail);
  197. xhr.always(() => (xhr = null));
  198. return xhr;
  199. },
  200. /**
  201. * Get请求
  202. * @param {String} url 请求地址
  203. * @param {Object?} data 请求参数
  204. * @param {Function?} done 成功回调
  205. * @param {Function?} fail 失败回调
  206. */
  207. get(url, data = {}, done, fail) {
  208. if (/\.json/.test(url)) {
  209. // json文件格式自动调用getJson方法
  210. return this.getJson(url, data, done, fail);
  211. }
  212. return this.__request($.get(url, data), "get", url, data, done, fail);
  213. },
  214. /**
  215. * Get Blob请求
  216. * @param {String} url 请求地址
  217. * @param {Object?} data 请求参数
  218. * @param {Function?} done 成功回调
  219. * @param {Function?} fail 失败回调
  220. */
  221. getText(url, data = {}, done, fail) {
  222. return this.__request(
  223. $.ajax({
  224. url: url,
  225. dataType: "text",
  226. }),
  227. "getText",
  228. url,
  229. data,
  230. done,
  231. fail
  232. );
  233. },
  234. /**
  235. * GetJson请求 读取json文件数据
  236. * @param {String} url 请求地址
  237. * @param {Object?} data 请求参数
  238. * @param {Function?} done 成功回调
  239. * @param {Function?} fail 失败回调
  240. */
  241. getJson(url, data = {}, done, fail) {
  242. return this.__request($.getJSON(url, data), "get", url, data, done, fail);
  243. },
  244. /**
  245. * Get Blob请求
  246. * @param {String} url 请求地址
  247. * @param {Object?} data 请求参数
  248. * @param {Function?} done 成功回调
  249. * @param {Function?} fail 失败回调
  250. */
  251. getBlob(url, data = {}, done, fail) {
  252. return this.__request(
  253. $.ajax({
  254. url: url,
  255. dataType: "blob",
  256. }),
  257. "getBlob",
  258. url,
  259. data,
  260. done,
  261. fail
  262. );
  263. },
  264. /**
  265. * Get Arraybuffer请求
  266. * @param {String} url 请求地址
  267. * @param {Object?} data 请求参数
  268. * @param {Function?} done 成功回调
  269. * @param {Function?} fail 失败回调
  270. */
  271. getArraybuffer(url, data = {}, done, fail) {
  272. return this.__request(
  273. $.ajax({
  274. url: url,
  275. dataType: "arraybuffer",
  276. }),
  277. "getArraybuffer",
  278. url,
  279. data,
  280. done,
  281. fail
  282. );
  283. },
  284. /**
  285. * Post 请求
  286. * @param {String} url 请求地址
  287. * @param {Object?} data 请求参数
  288. * @param {Function?} done 成功回调
  289. * @param {Function?} fail 失败回调
  290. */
  291. post(url, data = {}, done, fail) {
  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. return this.__request(
  303. $.ajax({
  304. type: "POST",
  305. url: url,
  306. contentType: "application/json",
  307. data: JSON.stringify(data),
  308. }),
  309. "postJson",
  310. url,
  311. data,
  312. done,
  313. fail
  314. );
  315. },
  316. /**
  317. * Post 表单 支持文件上传
  318. * @param {String} url 请求地址
  319. * @param {FormData?} formData 请求参数
  320. * @param {Function?} done 成功回调
  321. * @param {Function?} fail 失败回调
  322. */
  323. postForm(url, formData, done, fail, onProgress) {
  324. if (typeof onProgress === "function") {
  325. return this.__request(
  326. $.ajax({
  327. type: "POST",
  328. url: url,
  329. processData: false,
  330. contentType: false,
  331. data: formData,
  332. xhr: function() {
  333. const xhr = new XMLHttpRequest();
  334. xhr.upload.addEventListener("progress", function(e) {
  335. onProgress(e.loaded / e.total);
  336. });
  337. xhr.onabort = () => {
  338. console.log('xhr aborted.');
  339. }
  340. return xhr;
  341. },
  342. // 覆盖全局配置的失败回调。因为无论是上传子集失败还是用户取消了上传,都不需要弹窗。
  343. error: function() {
  344. },
  345. }),
  346. "postForm",
  347. url,
  348. formData,
  349. done,
  350. fail
  351. );
  352. } else {
  353. return this.__request(
  354. $.ajax({
  355. type: "POST",
  356. url: url,
  357. processData: false,
  358. contentType: false,
  359. data: formData,
  360. }),
  361. "postForm",
  362. url,
  363. formData,
  364. done,
  365. fail
  366. );
  367. }
  368. },
  369. /**
  370. * 加载图片
  371. * @param {String} url 请求地址
  372. * @param {Number?} retry 重试次数,默认为3
  373. */
  374. loadImage(url, retry = 3) {
  375. const def = $.Deferred();
  376. const img = new Image();
  377. const load = () => {
  378. logger.warn("Retrying load image: " + url);
  379. this.loadImage(url, retry - 1)
  380. .done(def.resolve.bind(def))
  381. .progress(def.notify.bind(def))
  382. .fail(def.reject.bind(def));
  383. };
  384. img.onerror = function() {
  385. retry > 0
  386. ? setTimeout(() => load(), 1e3)
  387. : def.reject(`[${url}]加载失败`);
  388. };
  389. img.onload = function() {
  390. def.resolve(img);
  391. };
  392. img.crossOrigin = "anonymous";
  393. img.src = url;
  394. return def;
  395. },
  396. /**
  397. * 上传文件
  398. * @param {String} url 请求地址
  399. * @param {Object?} data 请求参数
  400. * @param {Function?} done 成功回调
  401. * @param {Function?} fail 失败回调
  402. */
  403. uploadFile(url, data = {}, done, fail, onProgress) {
  404. const form = new FormData();
  405. // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob
  406. // form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name);
  407. // } else {
  408. // form.append("file", file.file, file.name || file.file.name);
  409. // }
  410. for (let key in data) {
  411. if (key == "file") {
  412. form.append("file", data[key], data.filename || data[key].name);
  413. } else if (key != "filename") {
  414. form.append(key, data[key]);
  415. }
  416. }
  417. return this.postForm(url, form, done, fail, onProgress);
  418. },
  419. /**
  420. * 上传文件
  421. * @param {String} url 请求地址
  422. * @param {Object?} data 请求参数 {file:'base64 string',filename:'image.jpg',...}
  423. * @param {Function?} done 成功回调
  424. * @param {Function?} fail 失败回调
  425. */
  426. uploadBlobFile(url, data = {}, done, fail) {
  427. const form = new FormData();
  428. for (let key in data) {
  429. if (key === "file") {
  430. form.append("file", base64ToBlob(data.file), data.filename);
  431. } else if (key != "filename") {
  432. form.append(key, data[key]);
  433. }
  434. }
  435. return this.postForm(url, form, done, fail);
  436. },
  437. };