utils.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import { YYYYMMDDHHmmss } from "@/constant/constants";
  2. import moment from "moment";
  3. import queryString from "query-string";
  4. import MD5 from "js-md5";
  5. export function dateFormatForAPI(date) {
  6. return moment(date).format(YYYYMMDDHHmmss);
  7. }
  8. export function timeFormatForAPI(date) {
  9. return moment(date).format("HH:mm:ss");
  10. }
  11. export function formatEmptyToNull(obj) {
  12. Object.keys(obj).forEach((key) => {
  13. obj[key] = obj[key] === "" || obj[key] === undefined ? null : obj[key];
  14. });
  15. return obj;
  16. }
  17. // 错误上报:本地打印,百度统计,阿里云日志
  18. export function errorLog(message, { stack = "", code = "" }) {
  19. console.error({ message, stack, code });
  20. window._hmt.push([
  21. "_trackEvent",
  22. "message: " + message,
  23. stack && "stack: " + stack,
  24. code && "code: " + code,
  25. ]);
  26. }
  27. const CryptoJS = require("crypto-js");
  28. export function AESString(content) {
  29. const KEY = "1234567890123456";
  30. const IV = "1234567890123456";
  31. // console.log(content);
  32. var key = CryptoJS.enc.Utf8.parse(KEY);
  33. var iv = CryptoJS.enc.Utf8.parse(IV);
  34. var encrypted = CryptoJS.AES.encrypt(content, key, { iv: iv });
  35. return encrypted.toString();
  36. }
  37. export function encodePassword(content) {
  38. return window.btoa(content);
  39. }
  40. export function object2QueryString(obj) {
  41. return queryString.stringify(obj);
  42. }
  43. function toDataURL(url) {
  44. return fetch(url)
  45. .then((response) => {
  46. return response.blob();
  47. })
  48. .then((blob) => {
  49. return URL.createObjectURL(blob);
  50. });
  51. }
  52. // 下载文件
  53. export async function downloadFileURL(url, name) {
  54. const link = document.createElement("a");
  55. link.style.display = "none";
  56. const fileName = name || url.split("/").pop().split("?")[0];
  57. link.setAttribute("download", fileName);
  58. // txt 文件会直接在浏览器里面打开,这时候只能修改服务器设置,加上 Content-Disposition: attachment
  59. if ([".txt"].some((v) => fileName.endsWith(v))) {
  60. // const urlObj = new URL(url);
  61. // link.href = await toDataURL(url.replace(urlObj.origin));
  62. link.href = await toDataURL(url);
  63. } else {
  64. link.href = url;
  65. }
  66. document.body.appendChild(link);
  67. link.click();
  68. document.body.removeChild(link);
  69. }
  70. /**
  71. * 将目标对象中有的属性值与源对象中的属性值合并
  72. * @param {Object} target 目标对象
  73. * @param {Object} sources 源对象
  74. */
  75. export function objAssign(target, sources) {
  76. let targ = { ...target };
  77. for (let k in targ) {
  78. targ[k] = Object.prototype.hasOwnProperty.call(sources, k)
  79. ? sources[k]
  80. : targ[k];
  81. }
  82. return targ;
  83. }
  84. function parseDownloadFilename(dispositionInfo) {
  85. const strs = dispositionInfo.split(";");
  86. let filename = "";
  87. strs
  88. .map((item) => item.split("="))
  89. .find((item) => {
  90. if (item[0].indexOf("filename") !== -1) {
  91. filename = decodeURI(item[1]);
  92. }
  93. });
  94. return filename;
  95. }
  96. /**
  97. * 文件流下载
  98. * @param {Function} fetchFunc 下载程序,返回promise
  99. * @param {String} fileName 保存的文件名
  100. */
  101. export async function downloadBlob(fetchFunc, fileName) {
  102. const res = await fetchFunc().catch(() => {});
  103. if (!res) return;
  104. const filename =
  105. fileName || parseDownloadFilename(res.headers["content-disposition"]);
  106. const blobUrl = URL.createObjectURL(new Blob([res.data]));
  107. let a = document.createElement("a");
  108. a.download = filename;
  109. a.href = blobUrl;
  110. document.body.appendChild(a);
  111. a.click();
  112. a.parentNode.removeChild(a);
  113. return true;
  114. }
  115. export function objTypeOf(obj) {
  116. const toString = Object.prototype.toString;
  117. const map = {
  118. "[object Boolean]": "boolean",
  119. "[object Number]": "number",
  120. "[object String]": "string",
  121. "[object Function]": "function",
  122. "[object Array]": "array",
  123. "[object Date]": "date",
  124. "[object RegExp]": "regExp",
  125. "[object Undefined]": "undefined",
  126. "[object Null]": "null",
  127. "[object Object]": "object",
  128. };
  129. return map[toString.call(obj)];
  130. }
  131. export function formatDate(format = "YYYY/MM/DD HH:mm:ss", date = new Date()) {
  132. if (objTypeOf(date) !== "date") return;
  133. const options = {
  134. "Y+": date.getFullYear(),
  135. "M+": date.getMonth() + 1,
  136. "D+": date.getDate(),
  137. "H+": date.getHours(),
  138. "m+": date.getMinutes(),
  139. "s+": date.getSeconds(),
  140. };
  141. Object.entries(options).map(([key, val]) => {
  142. if (new RegExp("(" + key + ")").test(format)) {
  143. const zeros = key === "Y+" ? "0000" : "00";
  144. const value = (zeros + val).substr(("" + val).length);
  145. format = format.replace(RegExp.$1, value);
  146. }
  147. });
  148. return format;
  149. }
  150. /**
  151. * 获取时间长度文字
  152. * @param {Number} timeNumber 时间数值,单位:毫秒
  153. */
  154. export function timeNumberToText(timeNumber) {
  155. const DAY_TIME = 24 * 60 * 60 * 1000;
  156. const HOUR_TIME = 60 * 60 * 1000;
  157. const MINUTE_TIME = 60 * 1000;
  158. const SECOND_TIME = 1000;
  159. let [day, hour, minute, second] = [0, 0, 0, 0];
  160. let residueTime = timeNumber;
  161. if (residueTime >= DAY_TIME) {
  162. day = Math.floor(residueTime / DAY_TIME);
  163. residueTime -= day * DAY_TIME;
  164. day += "天";
  165. }
  166. if (residueTime >= HOUR_TIME) {
  167. hour = Math.floor(residueTime / HOUR_TIME);
  168. residueTime -= hour * HOUR_TIME;
  169. hour += "小时";
  170. }
  171. if (residueTime >= MINUTE_TIME) {
  172. minute = Math.floor(residueTime / MINUTE_TIME);
  173. residueTime -= minute * MINUTE_TIME;
  174. minute += "分钟";
  175. }
  176. if (residueTime >= SECOND_TIME) {
  177. second = Math.round(residueTime / SECOND_TIME);
  178. second += "秒";
  179. }
  180. return [day, hour, minute, second].filter((item) => !!item).join("");
  181. }
  182. export function deepCopy(obj) {
  183. return JSON.parse(JSON.stringify(obj));
  184. }
  185. /** @param blob {Blob} File is a type of Blob */
  186. export async function getMd5FromBlob(blob) {
  187. async function blobToArray(blob) {
  188. return new Promise((resolve) => {
  189. var reader = new FileReader();
  190. reader.addEventListener("loadend", function () {
  191. // reader.result contains the contents of blob as a typed array
  192. resolve(reader.result);
  193. });
  194. reader.readAsArrayBuffer(blob);
  195. });
  196. }
  197. const ab = await blobToArray(blob);
  198. return MD5(ab);
  199. }
  200. /**
  201. * 获取随机code,默认获取16位
  202. * @param {Number} len 推荐8的倍数
  203. *
  204. */
  205. export function randomCode(len = 16) {
  206. if (len <= 0) return;
  207. let steps = Math.ceil(len / 8);
  208. let stepNums = [];
  209. for (let i = 0; i < steps; i++) {
  210. let ranNum = Math.random().toString(32).slice(-8);
  211. stepNums.push(ranNum);
  212. }
  213. return stepNums.join("");
  214. }
  215. export function snakeToHump(content) {
  216. let cont = content.toLowerCase().split("_");
  217. return cont.map((item) => item[0].toUpperCase() + item.substr(1)).join("");
  218. }
  219. /**
  220. * 计算总数
  221. * @param {Array} dataList 需要统计的数组
  222. */
  223. export function calcSum(dataList) {
  224. if (!dataList.length) return 0;
  225. return dataList.reduce(function (total, item) {
  226. return total + item;
  227. }, 0);
  228. }