util.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import { removeToken } from './request'
  21. import {
  22. DEFAULT_FONT_FAMILY,
  23. DEFAULT_FONT_SIZE,
  24. DEFAULT_FONT_WEIGHT
  25. } from 'app/globalConstants'
  26. import { message } from 'antd'
  27. import { OptionProps } from 'antd/lib/select'
  28. /**
  29. * UUID生成器
  30. * @param len 长度 number
  31. * @param radix 随机数基数 number
  32. * @returns {string}
  33. */
  34. export const uuid = (len: number, radix: number = 62) => {
  35. const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(
  36. ''
  37. )
  38. const uuid = []
  39. let i
  40. if (len) {
  41. // Compact form
  42. for (i = 0; i < len; i++) {
  43. uuid[i] = chars[Math.floor(Math.random() * radix)]
  44. }
  45. } else {
  46. // rfc4122, version 4 form
  47. let r
  48. // rfc4122 requires these characters
  49. uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
  50. uuid[14] = '4'
  51. // Fill in random data. At i==19 set the high bits of clock sequence as
  52. // per rfc4122, sec. 4.1.5
  53. for (i = 0; i < 36; i++) {
  54. if (!uuid[i]) {
  55. r = Math.floor(Math.random() * 16)
  56. uuid[i] = chars[i === 19 ? ((r % 4) % 8) + 8 : r]
  57. }
  58. }
  59. }
  60. return uuid.join('')
  61. }
  62. export function safeAddition(num1, num2) {
  63. const decimalDigits = Math.max(
  64. `${num1}`.indexOf('.') >= 0
  65. ? `${num1}`.substr(`${num1}`.indexOf('.') + 1).length
  66. : 0,
  67. `${num2}`.indexOf('.') >= 0
  68. ? `${num2}`.substr(`${num2}`.indexOf('.') + 1).length
  69. : 0
  70. )
  71. if (decimalDigits) {
  72. const times = Math.pow(10, decimalDigits)
  73. return (Math.round(num1 * times) + Math.round(num2 * times)) / times
  74. } else {
  75. return num1 + num2
  76. }
  77. }
  78. /**
  79. * 通用saga异常处理
  80. * @param error 异常内容: Error
  81. */
  82. export function errorHandler(error) {
  83. if (error.response) {
  84. switch (error.response.status) {
  85. case 403:
  86. message.error('未登录或会话过期,请重新登录', 1)
  87. removeToken()
  88. break
  89. case 401:
  90. message.error('您没有权限访问此数据', 2)
  91. break
  92. default:
  93. message.error(
  94. error.response.data.header
  95. ? error.response.data.header.msg
  96. : error.message,
  97. 3
  98. )
  99. break
  100. }
  101. } else if (error.message) {
  102. console.log(error.message, '====')
  103. // message.error(error.message, 3)
  104. } else {
  105. throw error
  106. }
  107. }
  108. export function getErrorMessage(error) {
  109. return error.response
  110. ? error.response.data.header
  111. ? error.response.data.header.msg
  112. : error.message
  113. : error.message
  114. }
  115. export function getBase64(img, callback) {
  116. const reader = new FileReader()
  117. reader.addEventListener('load', () => callback(reader.result))
  118. reader.readAsDataURL(img)
  119. }
  120. let utilCanvas = null
  121. export const getTextWidth = (
  122. text: string,
  123. fontWeight: string = DEFAULT_FONT_WEIGHT,
  124. fontSize: string = DEFAULT_FONT_SIZE,
  125. fontFamily: string = DEFAULT_FONT_FAMILY
  126. ): number => {
  127. const canvas = utilCanvas || (utilCanvas = document.createElement('canvas'))
  128. const context = canvas.getContext('2d')
  129. context.font = `${fontWeight} ${fontSize} ${fontFamily}`
  130. const metrics = context.measureText(text)
  131. return Math.ceil(metrics.width)
  132. }
  133. // ref: https://github.com/segmentio/is-url/blob/master/index.js
  134. const protocolAndDomainReg = /^(?:\w+:)?\/\/(\S+)$/
  135. const localhostDomainReg = /^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/
  136. const nonLocalhostDomainReg = /^[^\s\.]+\.\S{2,}$/
  137. export function isUrl(str: string) {
  138. if (typeof str !== 'string') {
  139. return false
  140. }
  141. const match = str.match(protocolAndDomainReg)
  142. if (!match) {
  143. return false
  144. }
  145. const everythingAfterProtocol = match[1]
  146. if (!everythingAfterProtocol) {
  147. return false
  148. }
  149. if (
  150. localhostDomainReg.test(everythingAfterProtocol) ||
  151. nonLocalhostDomainReg.test(everythingAfterProtocol)
  152. ) {
  153. return true
  154. }
  155. return false
  156. }
  157. const imageReg = /\.(bmp|png|jpg|jpeg|gif)$/
  158. export function isImagePath(pathname: string) {
  159. if (typeof pathname !== 'string') {
  160. return false
  161. }
  162. return imageReg.test(pathname)
  163. }
  164. export function hasProperty<T extends object, U extends keyof T>(
  165. obj: T,
  166. key: U
  167. ) {
  168. return obj[key] ? obj[key] : false
  169. }
  170. export const tuple = <T extends string[]>(...args: T) => args
  171. export const tupleNum = <T extends number[]>(...args: T) => args
  172. export function filterSelectOption(
  173. input: string,
  174. option: React.ReactElement<OptionProps>
  175. ): boolean {
  176. const text = option.props.children as string
  177. return text.toLowerCase().includes(input.toLowerCase())
  178. }
  179. export function filterTreeSelectOption(
  180. input: string,
  181. treeNode
  182. ): boolean {
  183. const text = treeNode.props.title
  184. return text.toLowerCase().includes(input.toLowerCase())
  185. }