czr-util.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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 YM = (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. return format ? `${Y}年${M}月` : `${Y}-${M}`;
  86. }
  87. export const M = (date: any, format = false) => {
  88. const _date = new Date(date)
  89. const M = `${_date.getMonth() + 1 < 10 ? `0${_date.getMonth() + 1}` : _date.getMonth() + 1}`;
  90. return format ? `${M}月` : `${M}`;
  91. }
  92. export const YMD = (date: any, format = false) => {
  93. const _date = new Date(date)
  94. const Y = `${_date.getFullYear()}`;
  95. const M = `${_date.getMonth() + 1 < 10 ? `0${_date.getMonth() + 1}` : _date.getMonth() + 1}`;
  96. const D = `${_date.getDate() < 10 ? `0${_date.getDate()}` : _date.getDate()}`;
  97. return format ? `${Y}年${M}月${D}日` : `${Y}-${M}-${D}`;
  98. }
  99. export const Hms = (date: any, format = false) => {
  100. const _date = new Date(date)
  101. const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
  102. const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
  103. const s = _date.getSeconds() < 10 ? `0${_date.getSeconds()}` : _date.getSeconds();
  104. return format ? `${H}时${m}分${s}秒` : `${H}:${m}:${s}`;
  105. }
  106. //防抖
  107. export const debounce = function (cb: any, ms = 0) {
  108. let timer: any = null
  109. return function () {
  110. if (timer) clearTimeout(timer)
  111. timer = setTimeout(() => {
  112. // @ts-ignore
  113. cb.apply(this, arguments)
  114. timer = null
  115. }, ms)
  116. }
  117. }
  118. export const comTime = (time: any, format = false) => {
  119. const sAll = time
  120. const d = Math.floor(sAll / (1000 * 60 * 60 * 24))
  121. const h = Math.floor((sAll - d * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  122. const m = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60)) / (1000 * 60))
  123. const s = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60) - m * (1000 * 60)) / 1000)
  124. let result: any = {d, h, m ,s}
  125. if (format) {
  126. result = ''
  127. if (d > 0) {
  128. result += d + '天'
  129. }
  130. if (d > 0 || h > 0) {
  131. result += h + '时'
  132. }
  133. if (d > 0 || h > 0 || m > 0) {
  134. result += m + '分'
  135. }
  136. result += s + '秒'
  137. }
  138. return result
  139. }
  140. export const comTimeByArea = (start: any, end: any, format = false, _D = '天', _H = '时', _M = '分', _S = '秒') => {
  141. const sAll = new Date(end).getTime() - new Date(start).getTime()
  142. const d = Math.floor(sAll / (1000 * 60 * 60 * 24))
  143. const h = Math.floor((sAll - d * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  144. const m = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60)) / (1000 * 60))
  145. const s = Math.floor((sAll - d * (1000 * 60 * 60 * 24) - h * (1000 * 60 * 60) - m * (1000 * 60)) / 1000)
  146. let result: any = {d, h, m ,s}
  147. if (format) {
  148. result = ''
  149. if (d > 0) {
  150. result += d + _D
  151. }
  152. if (d > 0 || h > 0) {
  153. result += h + _H
  154. }
  155. if (d > 0 || h > 0 || m > 0) {
  156. result += m + _M
  157. }
  158. result += s + _S
  159. }
  160. return result
  161. }
  162. export const deepAssign = (...obj: any) => {
  163. const result = Object.assign({}, ...obj)
  164. for (let item of obj) {
  165. for (let [idx, val] of Object.entries(item)) {
  166. if (val instanceof Array) {
  167. result[idx] = val
  168. } else if (val instanceof Object) {
  169. result[idx] = deepAssign(result[idx], val)
  170. }
  171. }
  172. }
  173. return result
  174. }
  175. export const copy = (value: any) => {
  176. const str = document.createElement('input')
  177. str.setAttribute('value', value)
  178. document.body.appendChild(str)
  179. str.select()
  180. document.execCommand('copy')
  181. document.body.removeChild(str)
  182. console.log(value)
  183. }
  184. /**
  185. *
  186. * @param precision 精度 1、0.1 、0.01……
  187. * @param colorArr
  188. * [
  189. * [20.1, '#111111'],
  190. * [20.3, '#dddddd'],
  191. * [20.7, '#eeeeee'],
  192. * ]
  193. * @return colorMap
  194. * new Map([
  195. * [20.1, '#111111']
  196. * ……
  197. * [20.3, '#dddddd']
  198. * ……
  199. * [20.7, '#eeeeee']
  200. * ])
  201. */
  202. export const getGradientColorArray = (precision: any, colorArr: any) => {
  203. // 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
  204. const colorRgb = (sColor: any) => {
  205. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  206. let _sColor = sColor.toLowerCase();
  207. if (_sColor && reg.test(_sColor)) {
  208. if (_sColor.length === 4) {
  209. let sColorNew = "#";
  210. for (let i = 1; i < 4; i += 1) {
  211. sColorNew += _sColor.slice(i, i + 1).concat(_sColor.slice(i, i + 1));
  212. }
  213. _sColor = sColorNew;
  214. }
  215. //处理六位的颜色值
  216. const sColorChange = [];
  217. for (let i = 1; i < 7; i += 2) {
  218. // @ts-ignore
  219. sColorChange.push(parseInt("0x" + _sColor.slice(i, i + 2)));
  220. }
  221. return sColorChange;
  222. } else {
  223. return _sColor;
  224. }
  225. };
  226. // 将rgb表示方式转换为hex表示方式
  227. const colorHex = (rgb: any) => {
  228. const _this = rgb;
  229. const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  230. if (/^(rgb|RGB)/.test(_this)) {
  231. const aColor = _this.replace(/(?:(|)|rgb|RGB)*/g, "").split(",");
  232. let strHex = "#";
  233. for (let i = 0; i < aColor.length; i++) {
  234. let hex = Number(aColor[i]).toString(16);
  235. hex = Number(hex) < 10 ? 0 + '' + hex : hex;// 保证每个rgb的值为2位
  236. if (hex === "0") {
  237. hex += hex;
  238. }
  239. strHex += hex;
  240. }
  241. if (strHex.length !== 7) {
  242. strHex = _this;
  243. }
  244. return strHex;
  245. } else if (reg.test(_this)) {
  246. const aNum = _this.replace(/#/, "").split("");
  247. if (aNum.length === 6) {
  248. return _this;
  249. } else if (aNum.length === 3) {
  250. let numHex = "#";
  251. for (let i = 0; i < aNum.length; i += 1) {
  252. numHex += (aNum[i] + aNum[i]);
  253. }
  254. return numHex;
  255. }
  256. } else {
  257. return _this;
  258. }
  259. }
  260. const rgb2hex = (sRGB: any) => {
  261. const reg = /^(RGB|rgb)\((\d+),\s*(\d+),\s*(\d+)\)$/
  262. if (!reg.test(sRGB)) return sRGB
  263. const rgbArr = sRGB.match(/\d+/g)
  264. const resultRgbArr = rgbArr.map((v: any) => {
  265. if (+v > 16) return (+v).toString(16)
  266. return '0' + (+v).toString(16)
  267. })
  268. return '#' + resultRgbArr.join('')
  269. }
  270. const gradientColor = (startColor: any, endColor: any, step: any) => {
  271. const startRGB = colorRgb(startColor);//转换为rgb数组模式
  272. const startR = startRGB[0];
  273. const startG = startRGB[1];
  274. const startB = startRGB[2];
  275. const endRGB = colorRgb(endColor);
  276. const endR = endRGB[0];
  277. const endG = endRGB[1];
  278. const endB = endRGB[2];
  279. const sR = (endR - startR) / step;//总差值
  280. const sG = (endG - startG) / step;
  281. const sB = (endB - startB) / step;
  282. const colorArr = [];
  283. for (let i = 0; i <= step; i++) {
  284. //计算每一步的hex值
  285. const hex = colorHex('rgb(' + parseInt((sR * i + startR)) + ',' + parseInt((sG * i + startG)) + ',' + parseInt((sB * i + startB)) + ')');
  286. // @ts-ignore
  287. colorArr.push(rgb2hex(hex));
  288. }
  289. return colorArr;
  290. }
  291. const colorMap = new Map()
  292. colorArr.forEach((v: any, i: number) => {
  293. if (i < colorArr.length - 1) {
  294. const _arr = gradientColor(v[1], colorArr[i + 1][1], (Number(colorArr[i + 1][0]) - Number(v[0])) / precision)
  295. _arr.forEach((cV, cI) => {
  296. colorMap.set((Number(v[0]) + cI * precision).toFixed(String(precision).split('').filter(p => p === '0').length), cV)
  297. })
  298. } else {
  299. colorMap.set(Number(v[0]).toFixed(String(precision).split('').filter(p => p === '0').length), v[1])
  300. }
  301. })
  302. return colorMap
  303. }
  304. // 根据部门名称 寻找上级所有父节点名称
  305. //data:要遍历的数据, target:查找目标, result用于装查找结果的数组
  306. export const findParent = (data: any, target: any, result: any) => {
  307. for (let item of data) {
  308. if (item.deptName === target) {
  309. //将查找到的目标数据加入结果数组中
  310. //可根据需求unshift(ConditionItem.id)或unshift(ConditionItem)
  311. result.unshift(item.deptName);
  312. return true;
  313. }
  314. if (item.children && item.children.length > 0) {
  315. let isFind = findParent(item.children, target, result);
  316. if (isFind) {
  317. result.unshift(item.deptName);
  318. return true;
  319. }
  320. }
  321. }
  322. return false;
  323. };
  324. // 涉及到跨域问题,需要配nginx代理的url地址处理
  325. export const proxyNginxUrl = (url: string) => {
  326. if (url) {
  327. // @ts-ignore
  328. const apiMapper = window.czrConfig?.nginxApiMapper || new Map()
  329. let newUrl = url
  330. apiMapper.forEach((v: any, k: any) => {
  331. if (url.includes(k)) {
  332. newUrl = v + url.substring(url.indexOf(k) + k.length, url.length)
  333. }
  334. })
  335. return newUrl
  336. }
  337. return url
  338. };
  339. // 后端接口拦截 < > 内的文本,正反向格式化为 /《/ /》/ res = true 为接收返回值进行格式化
  340. export const formatInputHtmlInterceptor = (html: string, res = true) => {
  341. if (html) {
  342. const map = new Map()
  343. map.set('<', '_《_')
  344. map.set('>', '_》_')
  345. let nHtml = html.toString()
  346. map.forEach((v, k) => {
  347. if (res) {
  348. nHtml = nHtml.replace(eval(`/${v}/g`), k)
  349. } else {
  350. nHtml = nHtml.replace(eval(`/${k}/g`), v)
  351. }
  352. })
  353. return nHtml
  354. }
  355. return html
  356. }
  357. //生成从minNum到maxNum的随机数
  358. // export const randomNum = (minNum: number,maxNum: number) => {
  359. // return parseInt(String(Math.random() * (maxNum - minNum + 1) + minNum),10);
  360. // }
  361. export const randomNum = (min = 0, max = 0, decimal=0) => {
  362. // 获取数值的小数部分
  363. const getDecimalNum = (data: number) => {
  364. return Number(data.toString().split('.')[1]);
  365. }
  366. let min_z = Math.trunc(min); // 最小值的整数部分
  367. let max_z = Math.trunc(max); // 最大值的整数部分
  368. // 判断是否存在小数部分,不存在的话为0
  369. let min_x = isNaN(getDecimalNum(min)) ? 0 : getDecimalNum(min); // 最小值的小数部分
  370. let max_x = isNaN(getDecimalNum(max)) ? 0 : getDecimalNum(max); // 最大值的小数部分
  371. // 区分有小数和没小数的情况
  372. if (min_x > 0 || max_x > 0 || decimal > 0) {
  373. // 整数部分随机数
  374. let z = parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  375. // 小数部分随机数
  376. let x = 0;
  377. // 小数部分随机数最大位数
  378. let max_decimal = min_x.toString().length > max_x.toString().length ? min_x.toString().length : max_x.toString().length;
  379. max_decimal = decimal > max_decimal ? decimal : max_decimal;
  380. // 判断随机出的整数部分,是否等于最小值或者最大值
  381. if(z == min_z || z == max_z){
  382. if(z == min_z){
  383. // 整数部分随机数等于最小值,那么应该从最小值的小数部分开始,到小数位数的最大值随机就可以
  384. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal) - min_x) + min_x), 10);
  385. }else{
  386. // 整数部分随机数等于最大值,那么应该从0开始,到最大值小数部分
  387. x = parseInt(String(Math.random() * (max_x + 1)), 10);
  388. }
  389. }else{
  390. // 整数部分在最大最小值区间的,就从0到小数位数的最大值随机就可以
  391. x = parseInt(String(Math.random() * (Math.pow(10, max_decimal))), 10);
  392. }
  393. return Number(`${z}.${x}`);
  394. } else {
  395. return parseInt(String(Math.random() * (max_z - min_z + 1) + min_z), 10);
  396. }
  397. }
  398. /**
  399. *
  400. * @param val 处理的数值
  401. * @param unit 单位,默认空字符
  402. * @param digits 小数,默认1
  403. */
  404. export const formatNumberUnit = (val, unit = '', digits = 1) => {
  405. let num = ''
  406. let str = ''
  407. if (String(val).length < 5) {
  408. num = val
  409. str = unit
  410. } else if (String(val).length < 9) {
  411. num = Number((Number(val) / 10000).toFixed(digits)) / 1 + ''
  412. str = '万' + unit
  413. } else if (String(val).length < 13) {
  414. num = Number((Number(val) / 10000 / 10000).toFixed(digits)) / 1 + ''
  415. str = '亿' + unit
  416. }
  417. return {
  418. num: num, unit: str
  419. }
  420. }
  421. /**
  422. * 将一串数字str按指定间隔n填充指定字符char
  423. * @param str
  424. * @param n
  425. * @param char
  426. */
  427. export const numberJoinChar = (str, n = 3, char = ',') => {
  428. const _str = String(str)
  429. let result = '';
  430. for (let i = _str.length - 1; i >= 0; i--) {
  431. result = _str[i] + result;
  432. if ((_str.length - i) % n === 0 && i !== 0) {
  433. result = char + result;
  434. }
  435. }
  436. return result;
  437. }
  438. // 根据起始周几获取本周第一天日期
  439. export const getFirstDateOfWeek = (fDate, firstDayOfWeek) => {
  440. const day = fDate.getDay();
  441. const diff = (day < firstDayOfWeek ? 7 : 0) + day - firstDayOfWeek;
  442. const firstDate = new Date(fDate.getFullYear(), fDate.getMonth(), fDate.getDate() - diff);
  443. return firstDate;
  444. }
  445. // 根据起始周几获取本周最后一天日期
  446. export const getLastDateOfWeek = (lDate, lastDayOfWeek) => {
  447. const day = lDate.getDay();
  448. const diff = (day < lastDayOfWeek ? 7 : 0) + day - lastDayOfWeek;
  449. const lastDate = new Date(lDate.getFullYear(), lDate.getMonth(), lDate.getDate() + (6 - diff));
  450. return lastDate;
  451. }
  452. export const oneDayTime = 1000 * 60 * 60 * 24
  453. // 根据当天时间、起始周几、选的月,获取整月日期
  454. export const getMonthCalendarData = (d, fD, selectMonth = null) => {
  455. const getYMDTime = (date) => {
  456. const _date = new Date(date)
  457. const Y = _date.getFullYear()
  458. const M = _date.getMonth() + 1
  459. const D = _date.getDate()
  460. return new Date(`${Y}-${M}-${D}`).getTime()
  461. }
  462. const _date = selectMonth ? new Date(selectMonth) : new Date(d)
  463. // d的月份有几天
  464. const monthDaysTotal = new Date(_date.getFullYear(), _date.getMonth() + 1, 0).getDate()
  465. // d的月份的第一天
  466. const monthFirstDate = new Date(_date.getFullYear(), _date.getMonth(), 1)
  467. // 日历第一天
  468. const wholeFirstDay = getFirstDateOfWeek(monthFirstDate, fD)
  469. // d的月份的最后一天
  470. const monthLastDate = new Date(_date.getFullYear(), _date.getMonth(), monthDaysTotal)
  471. // 日历最后一天
  472. const wholeLastDay = getLastDateOfWeek(monthLastDate, fD)
  473. const arr: any = []
  474. let w: any = []
  475. for (let i = wholeFirstDay.getTime(); i <= wholeLastDay.getTime(); i += oneDayTime) {
  476. const t = new Date(i)
  477. const obj: any = {
  478. date: t,
  479. dateStr: YMD(t),
  480. dayStr: t.getDate(),
  481. tom: getYMDTime(t) > getYMDTime(d)
  482. }
  483. if (getYMDTime(t) < monthFirstDate.getTime()) {
  484. obj.last = true // 是补全的日历过去时间
  485. } else if (getYMDTime(t) > monthLastDate.getTime()) {
  486. obj.will = true // 是补全的日历未来时间
  487. } else if (getYMDTime(t) === getYMDTime(d)) {
  488. obj.today = true // 是传入的当前日期
  489. }
  490. w.push(obj)
  491. if (w.length === 7) {
  492. const wObj: any = {
  493. calendar: w
  494. }
  495. arr.push(wObj)
  496. w = []
  497. }
  498. }
  499. return arr
  500. }
  501. // 根据起始周几获取一周的数组
  502. export const getWeekCN = (xq) => {
  503. const m = new Map([
  504. [0, '日'],
  505. [1, '一'],
  506. [2, '二'],
  507. [3, '三'],
  508. [4, '四'],
  509. [5, '五'],
  510. [6, '六'],
  511. ])
  512. const weekArray: any = [];
  513. for (let i = 0; i < 7; i++) {
  514. const index = (xq + i) % 7;
  515. weekArray.push(m.get(index));
  516. }
  517. return weekArray
  518. }
  519. export const resetRgbaOpacity = (polyColor, opacity) => {
  520. // 使用正则表达式匹配rgba颜色中的透明度部分
  521. const rgbaRegex = /rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)/;
  522. const matches = polyColor.match(rgbaRegex);
  523. if (!matches) {
  524. throw new Error('Invalid rgba string');
  525. }
  526. // 提取原来的透明度值,并将其乘以给定因子
  527. const oldOpacity = parseFloat(matches[4]);
  528. const newOpacity = Math.min(Math.max(oldOpacity * opacity, 0), 1); // 确保透明度值在0到1之间
  529. // 重新组合rgba字符串
  530. const newRgbaStr = `rgba(${matches[1]}, ${matches[2]}, ${matches[3]}, ${newOpacity})`;
  531. return newRgbaStr;
  532. }
  533. export const randomColor = (opacity) => `rgba(${randomNum(0, 255)}, ${randomNum(0, 255)}, ${randomNum(0, 255)}, ${opacity ? opacity : randomNum(0.5, 1, 1)})`
  534. //判断是否覆盖24小时
  535. export const covers24Hours = (arr) =>{
  536. if (arr.length == 0) return false;
  537. let result = 0;
  538. for (const item of arr) {
  539. //获取时间
  540. if (item.length == 0) return;
  541. let start = item[0]?.split(":");
  542. let end = item[1]?.split(":");
  543. //把时间全部转化为秒
  544. start = Number(start[0]) * 3600 + Number(start[1]) * 60 + Number(start[2]);
  545. end = Number(end[0]) * 3600 + Number( end[1]) * 60 + Number(end[2]);
  546. if (start > end) {
  547. end = end + 86400;
  548. }
  549. result += Math.abs(end - start);
  550. }
  551. return result === 86400 || result === 86399;
  552. }
  553. export const toPhone = (phone) => {
  554. let a: any = document.createElement('a')
  555. a.style = {opacity: 0}
  556. a.href = 'tel:' + phone
  557. a.click()
  558. document.removeChild(a)
  559. }
  560. export const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
  561. export const hexToRgb = (hex) => {
  562. // 移除可能存在的 '#' 符号
  563. const cleanHex = hex.replace('#', '');
  564. // 确保长度为 6 位
  565. if (cleanHex.length !== 6) {
  566. throw new Error('Invalid hex color format');
  567. }
  568. // 解析 R, G, B 值
  569. const r = parseInt(cleanHex.substring(0, 2), 16);
  570. const g = parseInt(cleanHex.substring(2, 4), 16);
  571. const b = parseInt(cleanHex.substring(4, 6), 16);
  572. // 返回 RGB 字符串
  573. return `rgb(${r}, ${g}, ${b})`;
  574. }
  575. export const hexToOpaqueHex = (hex, opacity) => {
  576. // 解析 16 进制颜色
  577. const match = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
  578. if (!match) {
  579. throw new Error('Invalid hex color format');
  580. }
  581. // 提取 RGB 值
  582. const r = parseInt(match[1], 16);
  583. const g = parseInt(match[2], 16);
  584. const b = parseInt(match[3], 16);
  585. // 计算不透明的 RGB 值
  586. const oneMinusOpacity = 1 - opacity;
  587. const finalR = Math.round(r * opacity + 255 * oneMinusOpacity);
  588. const finalG = Math.round(g * opacity + 255 * oneMinusOpacity);
  589. const finalB = Math.round(b * opacity + 255 * oneMinusOpacity);
  590. // 将 RGB 值转换为 16 进制颜色
  591. return `#${finalR.toString(16).padStart(2, '0')}${finalG.toString(16).padStart(2, '0')}${finalB.toString(16).padStart(2, '0')}`;
  592. }
  593. export const extractRgbFromRgba = (rgbaString) => {
  594. const match = rgbaString.match(/^rgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})(?:,\s*[\d.]+)?\)$/);
  595. if (match) {
  596. return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10)];
  597. }
  598. return [46, 129, 255];
  599. }
  600. export const _console = (p) => console.log(p)
  601. export const domRootHasAttr = (dom, attr) => {
  602. if (!dom) {
  603. return false
  604. }
  605. if (dom.getAttribute(attr)) {
  606. return true
  607. }
  608. return domRootHasAttr(dom.parentElement, attr)
  609. }