util.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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 Hms = (date: any, format = false) => {
  89. const _date = new Date(date)
  90. const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
  91. const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
  92. const s = _date.getSeconds() < 10 ? `0${_date.getSeconds()}` : _date.getSeconds();
  93. return format ? `${H}时${m}分${s}秒` : `${H}:${m}:${s}`;
  94. }
  95. //防抖
  96. export const debounce = function (cb: any, ms = 0) {
  97. let timer: any = null
  98. return function () {
  99. if (timer) clearTimeout(timer)
  100. timer = setTimeout(() => {
  101. // @ts-ignore
  102. cb.apply(this, arguments)
  103. timer = null
  104. }, ms)
  105. }
  106. }
  107. export const comTime = (time: any, format = false) => {
  108. const sAll = time
  109. const d = Math.floor(sAll / (1000 * 60 * 60 * 24))
  110. const h = Math.floor((sAll - d * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  111. const m = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60)) / (1000 * 60))
  112. const s = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60) - m * (1000 * 60)) / 1000)
  113. let result: any = {d, h, m ,s}
  114. if (format) {
  115. result = ''
  116. if (d > 0) {
  117. result += d + '天'
  118. }
  119. if (d > 0 || h > 0) {
  120. result += h + '时'
  121. }
  122. if (d > 0 || h > 0 || m > 0) {
  123. result += m + '分'
  124. }
  125. result += s + '秒'
  126. }
  127. return result
  128. }
  129. export const comTimeByArea = (start: any, end: any, format = false) => {
  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. let result: any = {d, h, m ,s}
  136. if (format) {
  137. result = ''
  138. if (d > 0) {
  139. result += d + '天'
  140. }
  141. if (d > 0 || h > 0) {
  142. result += h + '时'
  143. }
  144. if (d > 0 || h > 0 || m > 0) {
  145. result += m + '分'
  146. }
  147. result += s + '秒'
  148. }
  149. return result
  150. }
  151. export const deepAssign = (...obj: any) => {
  152. const result = Object.assign({}, ...obj)
  153. for (let item of obj) {
  154. for (let [idx, val] of Object.entries(item)) {
  155. if (val instanceof Array) {
  156. result[idx] = val
  157. } else if (val instanceof Object) {
  158. result[idx] = deepAssign(result[idx], val)
  159. }
  160. }
  161. }
  162. return result
  163. }
  164. export const copy = (value: any) => {
  165. const str = document.createElement('input')
  166. str.setAttribute('value', value)
  167. document.body.appendChild(str)
  168. str.select()
  169. document.execCommand('copy')
  170. document.body.removeChild(str)
  171. console.log(value)
  172. }
  173. /**
  174. *
  175. * @param precision 精度 1、0.1 、0.01……
  176. * @param colorArr
  177. * [
  178. * [20.1, '#111111'],
  179. * [20.3, '#dddddd'],
  180. * [20.7, '#eeeeee'],
  181. * ]
  182. * @return colorMap
  183. * new Map([
  184. * [20.1, '#111111']
  185. * ……
  186. * [20.3, '#dddddd']
  187. * ……
  188. * [20.7, '#eeeeee']
  189. * ])
  190. */
  191. export const getGradientColorArray = (precision: any, colorArr: any) => {
  192. // 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
  193. const colorRgb = (sColor: any) => {
  194. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  195. let _sColor = sColor.toLowerCase();
  196. if (_sColor && reg.test(_sColor)) {
  197. if (_sColor.length === 4) {
  198. let sColorNew = "#";
  199. for (let i = 1; i < 4; i += 1) {
  200. sColorNew += _sColor.slice(i, i + 1).concat(_sColor.slice(i, i + 1));
  201. }
  202. _sColor = sColorNew;
  203. }
  204. //处理六位的颜色值
  205. const sColorChange = [];
  206. for (let i = 1; i < 7; i += 2) {
  207. // @ts-ignore
  208. sColorChange.push(parseInt("0x" + _sColor.slice(i, i + 2)));
  209. }
  210. return sColorChange;
  211. } else {
  212. return _sColor;
  213. }
  214. };
  215. // 将rgb表示方式转换为hex表示方式
  216. const colorHex = (rgb: any) => {
  217. const _this = rgb;
  218. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  219. if (/^(rgb|RGB)/.test(_this)) {
  220. const aColor = _this.replace(/(?:(|)|rgb|RGB)*/g, "").split(",");
  221. let strHex = "#";
  222. for (let i = 0; i < aColor.length; i++) {
  223. let hex = Number(aColor[i]).toString(16);
  224. hex = Number(hex) < 10 ? 0 + '' + hex : hex;// 保证每个rgb的值为2位
  225. if (hex === "0") {
  226. hex += hex;
  227. }
  228. strHex += hex;
  229. }
  230. if (strHex.length !== 7) {
  231. strHex = _this;
  232. }
  233. return strHex;
  234. } else if (reg.test(_this)) {
  235. const aNum = _this.replace(/#/, "").split("");
  236. if (aNum.length === 6) {
  237. return _this;
  238. } else if (aNum.length === 3) {
  239. let numHex = "#";
  240. for (let i = 0; i < aNum.length; i += 1) {
  241. numHex += (aNum[i] + aNum[i]);
  242. }
  243. return numHex;
  244. }
  245. } else {
  246. return _this;
  247. }
  248. }
  249. const rgb2hex = (sRGB: any) => {
  250. const reg = /^(RGB|rgb)\((\d+),\s*(\d+),\s*(\d+)\)$/
  251. if (!reg.test(sRGB)) return sRGB
  252. const rgbArr = sRGB.match(/\d+/g)
  253. const resultRgbArr = rgbArr.map((v: any) => {
  254. if (+v > 16) return (+v).toString(16)
  255. return '0' + (+v).toString(16)
  256. })
  257. return '#' + resultRgbArr.join('')
  258. }
  259. const gradientColor = (startColor: any, endColor: any, step: any) => {
  260. const startRGB = colorRgb(startColor);//转换为rgb数组模式
  261. const startR = startRGB[0];
  262. const startG = startRGB[1];
  263. const startB = startRGB[2];
  264. const endRGB = colorRgb(endColor);
  265. const endR = endRGB[0];
  266. const endG = endRGB[1];
  267. const endB = endRGB[2];
  268. const sR = (endR - startR) / step;//总差值
  269. const sG = (endG - startG) / step;
  270. const sB = (endB - startB) / step;
  271. const colorArr = [];
  272. for (let i = 0; i <= step; i++) {
  273. //计算每一步的hex值
  274. const hex = colorHex('rgb(' + parseInt((sR * i + startR)) + ',' + parseInt((sG * i + startG)) + ',' + parseInt((sB * i + startB)) + ')');
  275. // @ts-ignore
  276. colorArr.push(rgb2hex(hex));
  277. }
  278. return colorArr;
  279. }
  280. const colorMap = new Map()
  281. colorArr.forEach((v: any, i: number) => {
  282. if (i < colorArr.length - 1) {
  283. const _arr = gradientColor(v[1], colorArr[i + 1][1], (Number(colorArr[i + 1][0]) - Number(v[0])) / precision)
  284. _arr.forEach((cV, cI) => {
  285. colorMap.set((Number(v[0]) + cI * precision).toFixed(String(precision).split('').filter(p => p === '0').length), cV)
  286. })
  287. } else {
  288. colorMap.set(Number(v[0]).toFixed(String(precision).split('').filter(p => p === '0').length), v[1])
  289. }
  290. })
  291. return colorMap
  292. }
  293. // 根据部门名称 寻找上级所有父节点名称
  294. //data:要遍历的数据, target:查找目标, result用于装查找结果的数组
  295. export const findParent = (data: any, target: any, result: any) => {
  296. for (let item of data) {
  297. if (item.deptName === target) {
  298. //将查找到的目标数据加入结果数组中
  299. //可根据需求unshift(item.id)或unshift(item)
  300. result.unshift(item.deptName);
  301. return true;
  302. }
  303. if (item.children && item.children.length > 0) {
  304. let isFind = findParent(item.children, target, result);
  305. if (isFind) {
  306. result.unshift(item.deptName);
  307. return true;
  308. }
  309. }
  310. }
  311. return false;
  312. };
  313. // 涉及到跨域问题,需要配nginx代理的url地址处理
  314. export const proxyNginxUrl = (url: string) => {
  315. if (url) {
  316. // @ts-ignore
  317. const apiMapper = window.cusConfig?.nginxApiMapper || new Map()
  318. let newUrl = url
  319. apiMapper.forEach((v: any, k: any) => {
  320. if (url.includes(k)) {
  321. newUrl = v + url.substring(url.indexOf(k) + k.length, url.length)
  322. }
  323. })
  324. return newUrl
  325. }
  326. return url
  327. };
  328. // 后端接口拦截 < > 内的文本,正反向格式化为 /《/ /》/ res = true 为接收返回值进行格式化
  329. export const formatInputHtmlInterceptor = (html: string, res = true) => {
  330. if (html) {
  331. const map = new Map()
  332. map.set('<', '_《_')
  333. map.set('>', '_》_')
  334. let nHtml = html.toString()
  335. map.forEach((v, k) => {
  336. if (res) {
  337. nHtml = nHtml.replace(eval(`/${v}/g`), k)
  338. } else {
  339. nHtml = nHtml.replace(eval(`/${k}/g`), v)
  340. }
  341. })
  342. return nHtml
  343. }
  344. return html
  345. }
  346. //生成从minNum到maxNum的随机数
  347. // export const randomNum = (minNum: number,maxNum: number) => {
  348. // return parseInt(String(Math.random() * (maxNum - minNum + 1) + minNum),10);
  349. // }
  350. export const randomNum = (min = 0, max = 0, decimal=0) => {
  351. // 获取数值的小数部分
  352. const getDecimalNum = (data: number) => {
  353. return Number(data.toString().split('.')[1]);
  354. }
  355. let min_z = Math.trunc(min); // 最小值的整数部分
  356. let max_z = Math.trunc(max); // 最大值的整数部分
  357. // 判断是否存在小数部分,不存在的话为0
  358. let min_x = isNaN(getDecimalNum(min)) ? 0 : getDecimalNum(min); // 最小值的小数部分
  359. let max_x = isNaN(getDecimalNum(max)) ? 0 : getDecimalNum(max); // 最大值的小数部分
  360. // 区分有小数和没小数的情况
  361. if (min_x > 0 || max_x > 0 || decimal > 0) {
  362. // 整数部分随机数
  363. let z = parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  364. // 小数部分随机数
  365. let x = 0;
  366. // 小数部分随机数最大位数
  367. let max_decimal = min_x.toString().length > max_x.toString().length ? min_x.toString().length : max_x.toString().length;
  368. max_decimal = decimal > max_decimal ? decimal : max_decimal;
  369. // 判断随机出的整数部分,是否等于最小值或者最大值
  370. if(z == min_z || z == max_z){
  371. if(z == min_z){
  372. // 整数部分随机数等于最小值,那么应该从最小值的小数部分开始,到小数位数的最大值随机就可以
  373. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal) - min_x) + min_x), 10);
  374. }else{
  375. // 整数部分随机数等于最大值,那么应该从0开始,到最大值小数部分
  376. x = parseInt(String(Math.random() * (max_x + 1)), 10);
  377. }
  378. }else{
  379. // 整数部分在最大最小值区间的,就从0到小数位数的最大值随机就可以
  380. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal))), 10);
  381. }
  382. return Number(`${z}.${x}`);
  383. } else {
  384. return parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  385. }
  386. }
  387. /**
  388. *
  389. * @param val 处理的数值
  390. * @param unit 单位,默认空字符
  391. * @param digits 小数,默认1
  392. */
  393. export const formatNumberUnit = (val, unit = '', digits = 1) => {
  394. let num = ''
  395. let str = ''
  396. if (String(val).length < 5) {
  397. num = val
  398. str = unit
  399. } else if (String(val).length < 9) {
  400. num = Number((Number(val) / 10000).toFixed(digits)) / 1 + ''
  401. str = '万' + unit
  402. } else if (String(val).length < 13) {
  403. num = Number((Number(val) / 10000 / 10000).toFixed(digits)) / 1 + ''
  404. str = '亿' + unit
  405. }
  406. return {
  407. num: num, unit: str
  408. }
  409. }