utils.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /**
  2. * @说明:工具集
  3. * @作者:陈万照
  4. * @公司:山东标梵互动技术有限公司
  5. * @官网:http://biaofun.com/
  6. * @版本:v1.0.0
  7. * @时间:2020年4月28日11:28:13
  8. */
  9. export default {
  10. /**
  11. * 同步 try catch 的进一步封装处理
  12. * 使用方法:
  13. * let [err, res] = await this.$utils.asyncTasks(Promise函数);
  14. * if(res) 成功
  15. * if(err) 失败
  16. */
  17. asyncTasks(promise) {
  18. return promise.then(data => {
  19. return [null, data];
  20. }).catch(err => [err]);
  21. },
  22. /**
  23. * 精确判断数据是否是 Object 类型
  24. * @param {Any} val 要判断的数据
  25. * @returns {Boolean} true:是;false:不是;
  26. */
  27. isObject(val) {
  28. return Object.prototype.toString.call(val) === '[object Object]' && val !== null && val !== undefined;
  29. },
  30. /**
  31. * 判断数据是否是 Array 类型
  32. * @param {Any} val 要判断的数据
  33. * @returns {Boolean} true:是;false:不是;
  34. */
  35. isArray(val) {
  36. return Object.prototype.toString.call(val) === '[object Array]';
  37. },
  38. /**
  39. * 判断数据是否是 String 类型
  40. * @param {Any} val 要判断的数据
  41. * @returns {Boolean} true:是;false:不是;
  42. */
  43. isString(val) {
  44. return Object.prototype.toString.call(val) === '[object String]';
  45. },
  46. /**
  47. * 精确判断数据是否是 Date 类型
  48. * @param {Any} val 要判断的数据
  49. * @returns {Boolean} true:是;false:不是;
  50. */
  51. isDate(val) {
  52. return Object.prototype.toString.call(val) === '[object Date]';
  53. },
  54. /**
  55. * 精确判断数据是否是 Function 类型
  56. * @param {Any} val 要判断的数据
  57. * @returns {Boolean} true:是;false:不是;
  58. */
  59. isFunction(val) {
  60. return Object.prototype.toString.call(val) === '[object Function]';
  61. },
  62. /**
  63. * 精确判断数据是否是 Number 类型
  64. * @param {Any} val 要判断的数据
  65. * @returns {Boolean} true:是;false:不是;
  66. */
  67. isNumber(val) {
  68. return Object.prototype.toString.call(val) === '[object Number]';
  69. },
  70. /**
  71. * 精确判断数据是否是 Boolean 类型
  72. * @param {Any} val 要判断的数据
  73. * @returns {Boolean} true:是;false:不是;
  74. */
  75. isBoolean(val) {
  76. return Object.prototype.toString.call(val) === '[object Boolean]';
  77. },
  78. /**
  79. * 判断 URL 是否是绝对 URL。
  80. * @param {String} url 要判断的 URL
  81. * @return {Boolean} true:是绝对URL;false:不是绝对URL;
  82. */
  83. isAbsoluteURL(url) {
  84. // 如果 URL 以 “<scheme>://” 或 “//”(协议相对URL)开头,则认为它是绝对的
  85. // RFC 3986 将方案名称定义为以字母开头的字符序列,然后是字母,数字,加号,句点或连字符的任意组合
  86. return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
  87. },
  88. /**
  89. * 合并 baseURL 和相对 URL 成一个完整的 URL
  90. * @param {String} baseURL baseURL
  91. * @param {String} relativeURL 相对 URL
  92. * @returns {String} 返回组合后的完整 URL
  93. */
  94. combineURLs(baseURL, relativeURL) {
  95. return relativeURL && this.isString(relativeURL) && this.isString(baseURL) ? baseURL.replace(/\/+$/, '') + '/' +
  96. relativeURL.replace(/^\/+/, '') : baseURL;
  97. },
  98. /**
  99. * 深度合并对象,只支持合并两个对象,该方法不会改变原有的对象
  100. * @param {Object} FirstOBJ 第一个对象
  101. * @param {Object} SecondOBJ 第二个对象
  102. * @return {Object} 返回深度合并后的对象
  103. */
  104. deepMargeObject(FirstOBJ, SecondOBJ) {
  105. let ResultOBJ = {};
  106. for (let key in FirstOBJ) {
  107. ResultOBJ[key] = ResultOBJ[key] && ResultOBJ[key].toString() === "[object Object]" ? this.deepMargeObject(ResultOBJ[
  108. key], FirstOBJ[key]) : ResultOBJ[key] = FirstOBJ[key];
  109. }
  110. for (let key in SecondOBJ) {
  111. ResultOBJ[key] = ResultOBJ[key] && ResultOBJ[key].toString() === "[object Object]" ? this.deepMargeObject(ResultOBJ[
  112. key], SecondOBJ[key]) : ResultOBJ[key] = SecondOBJ[key];
  113. }
  114. return ResultOBJ;
  115. },
  116. /**
  117. * 生成指定长度的随机字符串
  118. * @param {Number} min 最小程度
  119. * @param {Number} max 最大长度
  120. * @return {String} 返回生成的字符串
  121. */
  122. randomString(min, max) {
  123. let returnStr = "",
  124. range = (max ? Math.round(Math.random() * (max - min)) + min : min),
  125. arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
  126. 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  127. 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
  128. ];
  129. for (let i = 0; i < range; i++) {
  130. let index = Math.round(Math.random() * (arr.length - 1));
  131. returnStr += arr[index];
  132. }
  133. return returnStr;
  134. },
  135. /**
  136. * 格式化日期
  137. * @param {Date|String} date 日期或日期字符串
  138. */
  139. formatDate(date) {
  140. let YYYY = null;
  141. let M = null;
  142. let MM = null;
  143. let D = null;
  144. let DD = null;
  145. let h = null;
  146. let hh = null;
  147. let m = null;
  148. let mm = null;
  149. let s = null;
  150. let ss = null;
  151. let ms = null;
  152. let ms2 = null;
  153. let ms3 = null;
  154. let ms4 = null;
  155. let dt = null;
  156. // 如果 date 是 String 类型
  157. if (date && this.isString(date)) {
  158. // 真机运行时,如果直接用 new Date('YYYY-MM-DD hh:mm:ss') 会报 Invalid Date 错误,所以采用下面的方式创建日期
  159. let dtArr = date.replace(/\//g, '.').replace(/-/g, '.').replace(/:/g, '.').replace(/T/g, ' ').replace(' ', '.').replace(
  160. 'Z', '').split('.');
  161. let year = 2020;
  162. let month = 12;
  163. let day = 18;
  164. let hour = 0;
  165. let minute = 0;
  166. let second = 0;
  167. let millisecond = 0;
  168. // 年
  169. if (dtArr.length > 0 && !isNaN(dtArr[0])) {
  170. year = parseInt(dtArr[0]);
  171. }
  172. // 月
  173. if (dtArr.length > 1 && !isNaN(dtArr[1])) {
  174. month = parseInt(dtArr[1]);
  175. }
  176. // 日
  177. if (dtArr.length > 2 && !isNaN(dtArr[2])) {
  178. day = parseInt(dtArr[2]);
  179. }
  180. // 时
  181. if (dtArr.length > 3 && !isNaN(dtArr[3])) {
  182. hour = parseInt(dtArr[3]);
  183. }
  184. // 分
  185. if (dtArr.length > 4 && !isNaN(dtArr[4])) {
  186. minute = parseInt(dtArr[4]);
  187. }
  188. // 秒
  189. if (dtArr.length > 5 && !isNaN(dtArr[5])) {
  190. second = parseInt(dtArr[5]);
  191. }
  192. // 毫秒
  193. if (dtArr.length > 6 && !isNaN(dtArr[6])) {
  194. millisecond = parseInt(dtArr[6]);
  195. }
  196. date = new Date(year, month - 1, day, hour, minute, second, millisecond);
  197. }
  198. // 如果 date 是 Date 类型
  199. if (date && this.isDate(date)) {
  200. YYYY = date.getFullYear();
  201. M = date.getMonth() + 1;
  202. MM = M >= 10 ? M : '0' + M;
  203. D = date.getDate();
  204. DD = D >= 10 ? D : '0' + D;
  205. h = date.getHours();
  206. hh = h >= 10 ? h : '0' + h;
  207. m = date.getMinutes();
  208. mm = m >= 10 ? m : '0' + m;
  209. s = date.getSeconds();
  210. ss = s >= 10 ? s : '0' + s;
  211. ms = date.getMilliseconds();
  212. ms2 = ms;
  213. ms3 = ms;
  214. ms4 = ms;
  215. if (ms < 10) {
  216. ms2 = '0' + ms;
  217. ms3 = '00' + ms;
  218. ms4 = '000' + ms;
  219. } else if (ms < 100) {
  220. ms3 = '0' + ms;
  221. ms4 = '00' + ms;
  222. } else {
  223. ms4 = '0' + ms;
  224. }
  225. }
  226. // 返回的数据对象
  227. let result = {
  228. YYYY: YYYY,
  229. MM: MM,
  230. M: M,
  231. DD: DD,
  232. D: D,
  233. hh: hh,
  234. h: h,
  235. mm: mm,
  236. m: m,
  237. ss: ss,
  238. s: s,
  239. ms: ms,
  240. ms2: ms2,
  241. ms3: ms3,
  242. ms4: ms4,
  243. dt: date,
  244. f1: `${YYYY}-${MM}-${DD}`,
  245. f2: `${YYYY}年${M}月${D}日`,
  246. f3: `${YYYY}-${M}-${D} ${hh}:${mm}`,
  247. f4: `${h}:${m}:${s}`,
  248. f5: `${MM}-${DD}`,
  249. f6: `${YYYY}-${MM}`,
  250. f7: `${YYYY}年${M}月`,
  251. f8: `${h}:${m}`,
  252. f9: `${M}月${D}日`,
  253. notes: 'YYYY(年),MM(月,补0),M(月,不补0),DD(日,补0),D(日,不补0),hh(时,补0),h(时,不补0),mm(分,补0),m(分,不补0),ss(秒,补0),s(秒,不补0),ms(毫秒,不补0),ms2(毫秒,补0到2位),ms3(毫秒,补0到3位),ms4(毫秒,补0到4位),其余的f1,f2,... 看格式就知道了!'
  254. };
  255. return result;
  256. },
  257. /**
  258. * 数字转中文
  259. * @param {Number} num 数字
  260. */
  261. numberToChinese(num) {
  262. if (!/^\d*(\.\d*)?$/.test(num)) return "Number is wrong!";
  263. let AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
  264. let BB = new Array("", "十", "百", "千", "万", "亿", "点", "");
  265. let a = ("" + num).replace(/(^0*)/g, "").split("."),
  266. k = 0,
  267. re = "";
  268. for (let i = a[0].length - 1; i >= 0; i--) {
  269. switch (k) {
  270. case 0:
  271. re = BB[7] + re;
  272. break;
  273. case 4:
  274. if (!new RegExp("0{4}\\d{" + (a[0].length - i - 1) + "}$").test(a[0]))
  275. re = BB[4] + re;
  276. break;
  277. case 8:
  278. re = BB[5] + re;
  279. BB[7] = BB[5];
  280. k = 0;
  281. break;
  282. }
  283. if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = AA[0] + re;
  284. if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re;
  285. k++;
  286. }
  287. if (a.length > 1) //加上小数部分(如果有小数部分)
  288. {
  289. re += BB[6];
  290. for (let i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
  291. }
  292. return re;
  293. },
  294. /**
  295. * 计算两个经纬度点之间的距离
  296. * @param {Number} lng1 第一个点的经度
  297. * @param {Number} lat1 第一个点的纬度
  298. * @param {Number} lng2 第二个点的经度
  299. * @param {Number} lat2 第二个点的纬度
  300. */
  301. calcDistance(lng1, lat1, lng2, lat2) {
  302. var radLat1 = lat1 * Math.PI / 180.0;
  303. var radLat2 = lat2 * Math.PI / 180.0;
  304. var a = radLat1 - radLat2;
  305. var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
  306. var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
  307. Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
  308. s = s * 6378.137; // EARTH_RADIUS;
  309. s = Math.round(s * 10000) / 10000;
  310. return s;
  311. },
  312. /**
  313. * 获取数组最小值的下标
  314. * @param {Array} arr 数组
  315. */
  316. getArrayMixValueIndex(arrar) {
  317. let min = arrar[0];
  318. let index = 0;
  319. for (let i = 0; i < arrar.length; i++) {
  320. if (min > arrar[i]) {
  321. min = arrar[i];
  322. index = i;
  323. }
  324. }
  325. return index;
  326. }
  327. }