util.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. export const isValue = (val: any) => {
  2. if (val === null || val === undefined || (typeof val === 'string' && val.trim() === '') || (typeof val === 'object' && val?.length === 0)) {
  3. return false
  4. }
  5. return true
  6. }
  7. export const structureParams = (array: Array<any>, attribute: string) => {
  8. const endArray: any[] = []
  9. array.forEach(v => {
  10. endArray.push(v[attribute])
  11. })
  12. return endArray
  13. }
  14. export const replaceParams = (array: Array<any>, reArray: Array<any>, attribute: string, reAttribute: string) => {
  15. const endArray: any[] = []
  16. const endAllArray: any[] = []
  17. array.forEach(v => {
  18. reArray.forEach(rv => {
  19. if (v === rv[attribute]) {
  20. endArray.push(rv[reAttribute])
  21. endAllArray.push(rv)
  22. }
  23. })
  24. })
  25. return {
  26. replace: endArray,
  27. all: endAllArray
  28. }
  29. }
  30. export const copyObject = (ob: Object) => {
  31. return JSON.parse(JSON.stringify(ob))
  32. }
  33. export const arrayToMap = (array: Array<any>, key: any) => {
  34. const map = new Map()
  35. array.forEach((v: any) => {
  36. map.set(v[key], v)
  37. })
  38. return map
  39. }
  40. /**
  41. * 通过某个字段在一个多级数组中查找数据
  42. * @param data 目标数组,不能包含函数
  43. * @param current 目标数据
  44. * @param key 查找的字段
  45. * @param children 子集集合字段
  46. */
  47. export const findInListData = (data: Array<any>, current:any, key = "id", children = 'children') => {
  48. for(let item of data){
  49. if(item[key] && JSON.parse(JSON.stringify(item[key])) == JSON.parse(JSON.stringify(current))) return item
  50. if(!!item[children] && Array.isArray(item[children]) && item[children].length > 0){
  51. const findChildData: any = findInListData(item[children], current, key, children)
  52. if(findChildData) return findChildData
  53. }
  54. }
  55. return null
  56. }
  57. export const formatGetParam = (params: any) => {
  58. let paramUrl = ''
  59. Object.keys(params).forEach((v, i) => {
  60. paramUrl += i === 0 ? `${v}=${encodeURIComponent(params[v])}` : `&${v}=${encodeURIComponent(params[v])}`
  61. })
  62. return paramUrl
  63. }
  64. export const formatTableHeadFilters = (arr: Array<any>, text = 'dictLabel', value = 'dictValue') => {
  65. return arr.map(v => {
  66. v.value = v[value]
  67. v.text = v[text]
  68. return v
  69. })
  70. }
  71. export const YMDHms = (date: any) => {
  72. const _date = new Date(date)
  73. const Y = `${_date.getFullYear()}`;
  74. const M = `${_date.getMonth() + 1 < 10 ? `0${_date.getMonth() + 1}` : _date.getMonth() + 1}`;
  75. const D = `${_date.getDate() < 10 ? `0${_date.getDate()}` : _date.getDate()}`;
  76. const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
  77. const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
  78. const s = _date.getSeconds() < 10 ? `0${_date.getSeconds()}` : _date.getSeconds();
  79. return `${Y}-${M}-${D} ${H}:${m}:${s}`;
  80. }
  81. export const YMD = (date: any, format = false) => {
  82. const _date = new Date(date)
  83. const Y = `${_date.getFullYear()}`;
  84. const M = `${_date.getMonth() + 1 < 10 ? `0${_date.getMonth() + 1}` : _date.getMonth() + 1}`;
  85. const D = `${_date.getDate() < 10 ? `0${_date.getDate()}` : _date.getDate()}`;
  86. return format ? `${Y}年${M}月${D}日` : `${Y}-${M}-${D}`;
  87. }
  88. export const YM = (date: any, format = false) => {
  89. const _date = new Date(date)
  90. const Y = `${_date.getFullYear()}`;
  91. const M = `${_date.getMonth() + 1 < 10 ? `0${_date.getMonth() + 1}` : _date.getMonth() + 1}`;
  92. return format ? `${Y}年${M}月` : `${Y}-${M}`;
  93. }
  94. export const Hms = (date: any, format = false) => {
  95. const _date = new Date(date)
  96. const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
  97. const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
  98. const s = _date.getSeconds() < 10 ? `0${_date.getSeconds()}` : _date.getSeconds();
  99. return format ? `${H}时${m}分${s}秒` : `${H}:${m}:${s}`;
  100. }
  101. export const Hm = (date: any, format = false) => {
  102. const _date = new Date(date)
  103. const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
  104. const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
  105. return format ? `${H}时${m}分` : `${H}:${m}`;
  106. }
  107. //防抖
  108. export const debounce = function (cb: any, ms = 0) {
  109. let timer: any = null
  110. return function () {
  111. if (timer) clearTimeout(timer)
  112. timer = setTimeout(() => {
  113. // @ts-ignore
  114. cb.apply(this, arguments)
  115. timer = null
  116. }, ms)
  117. }
  118. }
  119. export const comTime = (time: any) => {
  120. const sAll = time
  121. const d = Math.floor(sAll / (1000 * 60 * 60 * 24))
  122. const h = Math.floor((sAll - d * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  123. const m = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60)) / (1000 * 60))
  124. const s = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60) - m * (1000 * 60)) / 1000)
  125. return{
  126. d, h, m ,s
  127. }
  128. }
  129. export const comTimeByArea = (start: any, end: any) => {
  130. const sAll = new Date(end).getTime() - new Date(start).getTime()
  131. const d = Math.floor(sAll / (1000 * 60 * 60 * 24))
  132. const h = Math.floor((sAll - d * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  133. const m = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60)) / (1000 * 60))
  134. const s = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60) - m * (1000 * 60)) / 1000)
  135. return{
  136. d, h, m ,s
  137. }
  138. }
  139. export const deepAssign = (...obj: any) => {
  140. const result = Object.assign({}, ...obj)
  141. for (let item of obj) {
  142. for (let [idx, val] of Object.entries(item)) {
  143. if (val instanceof Array) {
  144. result[idx] = val
  145. } else if (val instanceof Object) {
  146. result[idx] = deepAssign(result[idx], val)
  147. }
  148. }
  149. }
  150. return result
  151. }
  152. export const copy = (value: any) => {
  153. const str = document.createElement('input')
  154. str.setAttribute('value', value)
  155. document.body.appendChild(str)
  156. str.select()
  157. document.execCommand('copy')
  158. document.body.removeChild(str)
  159. console.log(value)
  160. }
  161. /**
  162. *
  163. * @param precision 精度 1、0.1 、0.01……
  164. * @param colorArr
  165. * [
  166. * [20.1, '#111111'],
  167. * [20.3, '#dddddd'],
  168. * [20.7, '#eeeeee'],
  169. * ]
  170. * @return colorMap
  171. * new Map([
  172. * [20.1, '#111111']
  173. * ……
  174. * [20.3, '#dddddd']
  175. * ……
  176. * [20.7, '#eeeeee']
  177. * ])
  178. */
  179. export const getGradientColorArray = (precision: any, colorArr: any) => {
  180. // 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
  181. const colorRgb = (sColor: any) => {
  182. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  183. let _sColor = sColor.toLowerCase();
  184. if (_sColor && reg.test(_sColor)) {
  185. if (_sColor.length === 4) {
  186. let sColorNew = "#";
  187. for (let i = 1; i < 4; i += 1) {
  188. sColorNew += _sColor.slice(i, i + 1).concat(_sColor.slice(i, i + 1));
  189. }
  190. _sColor = sColorNew;
  191. }
  192. //处理六位的颜色值
  193. const sColorChange: any = [];
  194. for (let i = 1; i < 7; i += 2) {
  195. sColorChange.push(parseInt("0x" + _sColor.slice(i, i + 2)));
  196. }
  197. return sColorChange;
  198. } else {
  199. return _sColor;
  200. }
  201. };
  202. // 将rgb表示方式转换为hex表示方式
  203. const colorHex = (rgb: any) => {
  204. const _this = rgb;
  205. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  206. if (/^(rgb|RGB)/.test(_this)) {
  207. const aColor = _this.replace(/(?:(|)|rgb|RGB)*/g, "").split(",");
  208. let strHex = "#";
  209. for (let i = 0; i < aColor.length; i++) {
  210. let hex = Number(aColor[i]).toString(16);
  211. hex = Number(hex) < 10 ? 0 + '' + hex : hex;// 保证每个rgb的值为2位
  212. if (hex === "0") {
  213. hex += hex;
  214. }
  215. strHex += hex;
  216. }
  217. if (strHex.length !== 7) {
  218. strHex = _this;
  219. }
  220. return strHex;
  221. } else if (reg.test(_this)) {
  222. const aNum = _this.replace(/#/, "").split("");
  223. if (aNum.length === 6) {
  224. return _this;
  225. } else if (aNum.length === 3) {
  226. let numHex = "#";
  227. for (let i = 0; i < aNum.length; i += 1) {
  228. numHex += (aNum[i] + aNum[i]);
  229. }
  230. return numHex;
  231. }
  232. } else {
  233. return _this;
  234. }
  235. }
  236. const rgb2hex = (sRGB: any) => {
  237. const reg = /^(RGB|rgb)\((\d+),\s*(\d+),\s*(\d+)\)$/
  238. if (!reg.test(sRGB)) return sRGB
  239. const rgbArr = sRGB.match(/\d+/g)
  240. const resultRgbArr = rgbArr.map((v: any) => {
  241. if (+v > 16) return (+v).toString(16)
  242. return '0' + (+v).toString(16)
  243. })
  244. return '#' + resultRgbArr.join('')
  245. }
  246. const gradientColor = (startColor: any, endColor: any, step: any) => {
  247. const startRGB = colorRgb(startColor);//转换为rgb数组模式
  248. const startR = startRGB[0];
  249. const startG = startRGB[1];
  250. const startB = startRGB[2];
  251. const endRGB = colorRgb(endColor);
  252. const endR = endRGB[0];
  253. const endG = endRGB[1];
  254. const endB = endRGB[2];
  255. const sR = (endR - startR) / step;//总差值
  256. const sG = (endG - startG) / step;
  257. const sB = (endB - startB) / step;
  258. const colorArr: any = [];
  259. for (let i = 0; i <= step; i++) {
  260. //计算每一步的hex值
  261. const hex = colorHex('rgb(' + parseInt((sR * i + startR)) + ',' + parseInt((sG * i + startG)) + ',' + parseInt((sB * i + startB)) + ')');
  262. colorArr.push(rgb2hex(hex));
  263. }
  264. return colorArr;
  265. }
  266. const colorMap = new Map()
  267. colorArr.forEach((v: any, i: number) => {
  268. if (i < colorArr.length - 1) {
  269. const _arr = gradientColor(v[1], colorArr[i + 1][1], (Number(colorArr[i + 1][0]) - Number(v[0])) / precision)
  270. _arr.forEach((cV, cI) => {
  271. colorMap.set((Number(v[0]) + cI * precision).toFixed(String(precision).split('').filter(p => p === '0').length), cV)
  272. })
  273. } else {
  274. colorMap.set(Number(v[0]).toFixed(String(precision).split('').filter(p => p === '0').length), v[1])
  275. }
  276. })
  277. return colorMap
  278. }
  279. // 根据部门名称 寻找上级所有父节点名称
  280. //data:要遍历的数据, target:查找目标, result用于装查找结果的数组
  281. export const findParent = (data: any, target: any, result: any) => {
  282. for (let item of data) {
  283. if (item.deptName === target) {
  284. //将查找到的目标数据加入结果数组中
  285. //可根据需求unshift(item.id)或unshift(item)
  286. result.unshift(item.deptName);
  287. return true;
  288. }
  289. if (item.children && item.children.length > 0) {
  290. let isFind = findParent(item.children, target, result);
  291. if (isFind) {
  292. result.unshift(item.deptName);
  293. return true;
  294. }
  295. }
  296. }
  297. return false;
  298. };
  299. // 涉及到跨域问题,需要配nginx代理的url地址处理
  300. export const proxyNginxUrl = (url: string) => {
  301. if (url) {
  302. // @ts-ignore
  303. const apiMapper = window.cusConfig?.nginxApiMapper || new Map()
  304. let newUrl = url
  305. apiMapper.forEach((v: any, k: any) => {
  306. if (url.includes(k)) {
  307. newUrl = v + url.substring(url.indexOf(k) + k.length, url.length)
  308. }
  309. })
  310. return newUrl
  311. }
  312. return url
  313. };
  314. // 后端接口拦截 < > 内的文本,正反向格式化为 /《/ /》/ res = true 为接收返回值进行格式化
  315. export const formatInputHtmlInterceptor = (html: string, res = true) => {
  316. if (html) {
  317. const map = new Map()
  318. map.set('<', '_《_')
  319. map.set('>', '_》_')
  320. let nHtml = html.toString()
  321. map.forEach((v, k) => {
  322. if (res) {
  323. nHtml = nHtml.replace(eval(`/${v}/g`), k)
  324. } else {
  325. nHtml = nHtml.replace(eval(`/${k}/g`), v)
  326. }
  327. })
  328. return nHtml
  329. }
  330. return html
  331. }
  332. //生成从minNum到maxNum的随机数
  333. // export const randomNum = (minNum: number,maxNum: number) => {
  334. // return parseInt(String(Math.random() * (maxNum - minNum + 1) + minNum),10);
  335. // }
  336. export const randomNum = (min = 0, max = 0, decimal=0) => {
  337. // 获取数值的小数部分
  338. const getDecimalNum = (data: number) => {
  339. return Number(data.toString().split('.')[1]);
  340. }
  341. let min_z = Math.trunc(min); // 最小值的整数部分
  342. let max_z = Math.trunc(max); // 最大值的整数部分
  343. // 判断是否存在小数部分,不存在的话为0
  344. let min_x = isNaN(getDecimalNum(min)) ? 0 : getDecimalNum(min); // 最小值的小数部分
  345. let max_x = isNaN(getDecimalNum(max)) ? 0 : getDecimalNum(max); // 最大值的小数部分
  346. // 区分有小数和没小数的情况
  347. if (min_x > 0 || max_x > 0 || decimal > 0) {
  348. // 整数部分随机数
  349. let z = parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  350. // 小数部分随机数
  351. let x = 0;
  352. // 小数部分随机数最大位数
  353. let max_decimal = min_x.toString().length > max_x.toString().length ? min_x.toString().length : max_x.toString().length;
  354. max_decimal = decimal > max_decimal ? decimal : max_decimal;
  355. // 判断随机出的整数部分,是否等于最小值或者最大值
  356. if(z == min_z || z == max_z){
  357. if(z == min_z){
  358. // 整数部分随机数等于最小值,那么应该从最小值的小数部分开始,到小数位数的最大值随机就可以
  359. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal) - min_x) + min_x), 10);
  360. }else{
  361. // 整数部分随机数等于最大值,那么应该从0开始,到最大值小数部分
  362. x = parseInt(String(Math.random() * (max_x + 1)), 10);
  363. }
  364. }else{
  365. // 整数部分在最大最小值区间的,就从0到小数位数的最大值随机就可以
  366. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal))), 10);
  367. }
  368. return Number(`${z}.${x}`);
  369. } else {
  370. return parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  371. }
  372. }
  373. export const downloadFile = ({ data, headers }: any, fName: string = '') => {
  374. let fileName = /.*filename=(.*)/i.exec(headers["content-disposition"])?.[1] || '下载';
  375. if (fName) {
  376. fileName = `${fName}${fileName.substring(fileName.indexOf('.'), fileName.length)}`
  377. }
  378. const a = document.createElement("a");
  379. a.style.display = "none";
  380. const url = (window.URL || window.webkitURL).createObjectURL(
  381. new Blob([data], {
  382. type: headers["content-type"]
  383. })
  384. );
  385. a.href = url
  386. a.download = decodeURIComponent((fileName));
  387. a.dispatchEvent(new MouseEvent("click"));
  388. (window.URL || window.webkitURL).revokeObjectURL(url);
  389. }
  390. /**
  391. *
  392. * @param val 处理的数值
  393. * @param unit 单位,默认空字符
  394. * @param digits 小数,默认1
  395. */
  396. export const formatNumberUnit = (val, unit = '', digits = 1) => {
  397. let num = ''
  398. let str = ''
  399. if (String(val).length < 5) {
  400. num = val
  401. str = unit
  402. } else if (String(val).length < 9) {
  403. num = Number((Number(val) / 10000).toFixed(digits)) / 1 + ''
  404. str = '万' + unit
  405. } else if (String(val).length < 13) {
  406. num = Number((Number(val) / 10000 / 10000).toFixed(digits)) / 1 + ''
  407. str = '亿' + unit
  408. }
  409. return {
  410. num: num, unit: str
  411. }
  412. }