You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
11 KiB

2 years ago
1 year ago
2 years ago
  1. /* eslint-disable no-param-reassign */
  2. import { Modal } from 'antd'
  3. import routes from '@/route/routes'
  4. import ErrorPage from '@/pages/public/errorPage'
  5. import { store } from '@/store'
  6. // 通用confirm方法
  7. export const commonConfirm = (title: string, cb: () => void) => {
  8. const { confirm } = Modal
  9. confirm({
  10. okText: '确定',
  11. cancelText: '取消',
  12. title,
  13. onOk() {
  14. cb()
  15. },
  16. onCancel() {}
  17. })
  18. }
  19. /**
  20. *
  21. * @param {string} phone
  22. */
  23. export const hidePhone = (phone: string) =>
  24. phone && phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
  25. /**
  26. * react router数组
  27. * @param {object[]} arr
  28. * @param {string} child
  29. */
  30. export const flattenRoutes = (arr: CommonObjectType<unknown>[]) =>
  31. arr.reduce(
  32. (prev: CommonObjectType<unknown>[], item: CommonObjectType<unknown>) => {
  33. if (Array.isArray(item.routes)) {
  34. prev.push(item)
  35. }
  36. return prev.concat(
  37. Array.isArray(item.routes) ? flattenRoutes(item.routes) : item
  38. )
  39. },
  40. []
  41. )
  42. /**
  43. * name和key
  44. * @param {string} path
  45. */
  46. export const getKeyName = (path: string = '/403') => {
  47. const truePath = path.split('?')[0];
  48. const curRoute = flattenRoutes(routes).filter(
  49. (item: { path: string | string[] }) => item.path.includes(truePath)
  50. )
  51. if (!curRoute[0])
  52. return { title: '暂无权限', tabKey: '403', component: ErrorPage }
  53. const { name, key, component } = curRoute[0]
  54. return { title: name, tabKey: key, component }
  55. }
  56. /**
  57. * Currying
  58. * @param {*} action
  59. * @param {function} cb
  60. */
  61. export const asyncAction = (action: unknown) => {
  62. const wait = new Promise((resolve) => {
  63. resolve(action)
  64. })
  65. return (cb: () => void) => {
  66. wait.then(() => setTimeout(() => cb()))
  67. }
  68. }
  69. /**
  70. *
  71. * @param {object} history history对象new新实例
  72. * @param {string} returnUrl
  73. * @param {function} cb
  74. */
  75. export const closeTabAction = (
  76. history: CommonObjectType,
  77. returnUrl: string = '/',
  78. cb?: () => void
  79. ) => {
  80. const { curTab } = store.getState().storeData
  81. const { href } = window.location
  82. const pathname = href.split('#')[1]
  83. // 删除tab
  84. const tabArr = JSON.parse(JSON.stringify(curTab))
  85. const delIndex = tabArr.findIndex((item: string) => item === pathname)
  86. tabArr.splice(delIndex, 1)
  87. // 如果要返回的页面被关闭了,再加进去
  88. if (!tabArr.includes(returnUrl)) {
  89. tabArr.push(returnUrl)
  90. }
  91. // 储存新的tabs数组
  92. const setTab = store.dispatch({
  93. type: 'SET_CURTAB',
  94. payload: tabArr
  95. })
  96. // 刷新tab
  97. const reloadTab = store.dispatch({
  98. type: 'SET_RELOADPATH',
  99. payload: returnUrl
  100. })
  101. // 停止刷新tab
  102. const stopReload = setTimeout(() => {
  103. store.dispatch({
  104. type: 'SET_RELOADPATH',
  105. payload: 'null'
  106. })
  107. }, 500)
  108. const action = () => setTab && reloadTab && stopReload
  109. // 刷新回调
  110. const callback = () => {
  111. if (cb && typeof cb === 'function') {
  112. return cb
  113. }
  114. return history.push({
  115. pathname: returnUrl
  116. })
  117. }
  118. asyncAction(action)(callback)
  119. }
  120. /**
  121. * ?
  122. */
  123. export const getQuery = (): CommonObjectType<string> => {
  124. const { href } = window.location
  125. const query = href.split('?')
  126. if (!query[1]) return {}
  127. const queryArr = decodeURI(query[1]).split('&')
  128. const queryObj = queryArr.reduce((prev, next) => {
  129. const item = next.split('=')
  130. return { ...prev, [item[0]]: item[1] }
  131. }, {})
  132. return queryObj
  133. }
  134. /**
  135. * JSON.parse(JSON.stringify()) [...]/{...}
  136. * @param {object} obj
  137. */
  138. export const deepClone = (obj: CommonObjectType) => {
  139. if (
  140. obj === null ||
  141. typeof obj !== 'object' ||
  142. obj instanceof Date ||
  143. obj instanceof Function
  144. ) {
  145. return obj
  146. }
  147. const cloneObj = Array.isArray(obj) ? [] : {}
  148. Object.keys(obj).map((key) => {
  149. cloneObj[key] = deepClone(obj[key])
  150. return cloneObj
  151. })
  152. return cloneObj
  153. }
  154. /**
  155. *
  156. * @param {*} html
  157. */
  158. export const getImgsUrl = (html?: string) => {
  159. // 匹配图片(g表示匹配所有结果i表示区分大小写)
  160. const imgReg = /<img.*?(?:>|\/>)/gi
  161. // 匹配src属性
  162. const srcReg = /src=['"]?([^'"]*)['"]?/i
  163. const arr = html.match(imgReg)
  164. if (!arr) return null
  165. // 获取图片地址
  166. const urlArr = arr.reduce((prev, next) => {
  167. const src = next.match(srcReg)
  168. return src[1] ? [...prev, src[1]] : prev
  169. }, [])
  170. return urlArr
  171. }
  172. /**
  173. *
  174. * @param {*} html
  175. */
  176. export const getVideoUrl = (html?: string) => {
  177. // 匹配图片(g表示匹配所有结果i表示区分大小写)
  178. const imgReg = /<(video|iframe).*?(?:>|\/>)/gi
  179. // 匹配src属性
  180. const srcReg = /src=['"]?([^'"]*)['"]?/i
  181. const arr = html.match(imgReg)
  182. if (!arr) return null
  183. // 获取图片地址
  184. const urlArr = arr.reduce((prev, next) => {
  185. const src = next.match(srcReg)
  186. return src[1] ? [...prev, src[1]] : prev
  187. }, [])
  188. return urlArr
  189. }
  190. /**
  191. *
  192. */
  193. export const getPermission = () => localStorage.getItem('permissions') || []
  194. /**
  195. *
  196. */
  197. export const isAuthorized = (val: string): boolean => {
  198. const permissions = getPermission();
  199. return permissions.includes(val)
  200. }
  201. /**
  202. * requestAnimationFrame替代setTimeoutsetInterval
  203. * @export
  204. * @param {*} cb
  205. * @param {*} interval
  206. */
  207. export const customizeTimer = {
  208. intervalTimer: null,
  209. timeoutTimer: null,
  210. setTimeout(cb: () => void, interval: number) {
  211. // 实现setTimeout功能
  212. const { now } = Date
  213. const stime = now()
  214. let etime = stime
  215. const loop = () => {
  216. this.timeoutTimer = requestAnimationFrame(loop)
  217. etime = now()
  218. if (etime - stime >= interval) {
  219. cb()
  220. cancelAnimationFrame(this.timeoutTimer)
  221. }
  222. }
  223. this.timeoutTimer = requestAnimationFrame(loop)
  224. return this.timeoutTimer
  225. },
  226. clearTimeout() {
  227. cancelAnimationFrame(this.timeoutTimer)
  228. },
  229. setInterval(cb: () => void, interval: number) {
  230. // 实现setInterval功能
  231. const { now } = Date
  232. let stime = now()
  233. let etime = stime
  234. const loop = () => {
  235. this.intervalTimer = requestAnimationFrame(loop)
  236. etime = now()
  237. if (etime - stime >= interval) {
  238. stime = now()
  239. etime = stime
  240. cb()
  241. }
  242. }
  243. this.intervalTimer = requestAnimationFrame(loop)
  244. return this.intervalTimer
  245. },
  246. clearInterval() {
  247. cancelAnimationFrame(this.intervalTimer)
  248. }
  249. }
  250. /**
  251. *
  252. */
  253. export const previewImg = (children: string | React.ReactNode) => {
  254. Modal.info({
  255. title: '预览',
  256. icon: false,
  257. okText: '关闭',
  258. maskClosable: true,
  259. content: children
  260. })
  261. }
  262. /**
  263. * ±
  264. * @param {string} val
  265. */
  266. export const limitDecimal = (val: string) =>
  267. val.replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
  268. /**
  269. *
  270. */
  271. export const setUserInfo = (
  272. userInfo: CommonObjectType,
  273. action: (arg0: string, arg1: unknown) => unknown,
  274. oldToken?: string
  275. ) => {
  276. const { permission, userName, token } = userInfo
  277. console.log(permission);
  278. const permissionArray = permission.reduce(
  279. (prev: CommonObjectType<string>[], next: CommonObjectType<string>) => [
  280. ...prev,
  281. next.code
  282. ],
  283. []
  284. );
  285. localStorage.setItem('permissions', permissionArray)
  286. const result = {
  287. userName,
  288. permission,
  289. token: token || oldToken
  290. }
  291. action('SET_USERINFO', result)
  292. }
  293. /**
  294. * tree结构数据
  295. * @param data
  296. * @param parentIdField
  297. */
  298. export const makeTree = (
  299. data: Array<any>,
  300. parentIdField: string = 'parentId'
  301. ): Array<any> => {
  302. const dataMap: Object = {}
  303. data.forEach((item) => {
  304. dataMap[item.id] = item
  305. })
  306. const dataTree: Array<any> = []
  307. data.forEach((item) => {
  308. const parent = dataMap[item[parentIdField]]
  309. if (parent) {
  310. if (parent.children) {
  311. parent.children.push(item)
  312. } else {
  313. parent.children = []
  314. parent.children.push(item)
  315. }
  316. } else {
  317. dataTree.push(item)
  318. }
  319. })
  320. return dataTree
  321. }
  322. /**
  323. * TreeSelect组件结构数据
  324. * @param dataTree
  325. * @param treeValueFiled
  326. * @param treeTitleFiled
  327. */
  328. export const makeTreeSelectData = (
  329. dataTree: Array<any>,
  330. treeValueFiled: string = 'value',
  331. treeTitleFiled: string = 'title'
  332. ): Array<any> => {
  333. const treeSelect: Array<any> = []
  334. dataTree.forEach((item) => {
  335. const temp = {
  336. value: item[treeValueFiled],
  337. title: item[treeTitleFiled],
  338. children: item.children || undefined
  339. }
  340. if (temp.children) {
  341. temp.children = makeTreeSelectData(
  342. temp.children,
  343. treeValueFiled,
  344. treeTitleFiled
  345. )
  346. }
  347. treeSelect.push(temp)
  348. })
  349. return treeSelect
  350. }
  351. /**
  352. * Tree组件结构数据
  353. * @param dataTree
  354. * @param treeKeyFiled
  355. * @param treeTitleFiled
  356. */
  357. export const makeTreeData = (
  358. dataTree: Array<any>,
  359. treeKeyFiled: string = 'key',
  360. treeTitleFiled: string = 'title'
  361. ): Array<any> => {
  362. const treeSelect: Array<any> = []
  363. dataTree.forEach((item) => {
  364. const temp = {
  365. key: item[treeKeyFiled],
  366. title: item[treeTitleFiled],
  367. children: item.children || undefined
  368. }
  369. if (temp.children) {
  370. temp.children = makeTreeData(
  371. temp.children,
  372. treeKeyFiled,
  373. treeTitleFiled
  374. )
  375. }
  376. treeSelect.push(temp)
  377. })
  378. return treeSelect
  379. }
  380. /**
  381. * id数组
  382. * @param tree
  383. * @param id
  384. */
  385. export const treeFindParentById = (tree: Array<any>, id: string | number): Array<number | string> => {
  386. const path = []
  387. if (tree.length === 0) return []
  388. const forFn = function (tree, id) {
  389. for (let i = 0; i < tree.length; i++) {
  390. const data = tree[i]
  391. if (data.id === id) {
  392. return path
  393. }
  394. path.push(data.id)
  395. if (data.children) {
  396. const findChildren = forFn(data.children, id);
  397. if (findChildren && findChildren.length > 0) return findChildren
  398. }
  399. path.pop()
  400. }
  401. }
  402. forFn(tree, id)
  403. return path
  404. }
  405. /**
  406. *
  407. * @param arr1
  408. * @param arr2
  409. */
  410. export const diffArray = (arr1: Array<number | string>, arr2: Array<number | string>): Array< number | string>=> {
  411. const diff: Array<number | string> = []
  412. for (let idx = 0; idx < arr1.length; idx++) {
  413. if (!arr2.includes(arr1[idx])) {
  414. diff.push(arr1[idx])
  415. }
  416. }
  417. return diff
  418. }