utils.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. import { h } from 'vue'
  2. import { NIcon } from 'naive-ui'
  3. import screenfull from 'screenfull'
  4. import throttle from 'lodash/throttle'
  5. import Image_404 from '../assets/images/exception/image-404.png'
  6. import html2canvas from 'html2canvas'
  7. import { downloadByA } from './file'
  8. import { toString } from './type'
  9. import cloneDeep from 'lodash/cloneDeep'
  10. import { WinKeyboard } from '@/enums/editPageEnum'
  11. import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
  12. import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
  13. /**
  14. * * 判断是否是开发环境
  15. * @return { Boolean }
  16. */
  17. export const isDev = () => {
  18. return import.meta.env.DEV
  19. }
  20. /**
  21. * * 生成一个不重复的ID
  22. * @param { Number } randomLength
  23. */
  24. export const getUUID = (randomLength = 10) => {
  25. return Number(Math.random().toString().substring(2, randomLength) + Date.now()).toString(36)
  26. }
  27. /**
  28. * * render 图标
  29. * @param icon 图标
  30. * @param set 设置项
  31. */
  32. export const renderIcon = (icon: any, set = {}) => {
  33. return () => h(NIcon, set, { default: () => h(icon) })
  34. }
  35. /**
  36. * * render 语言
  37. * @param lang 语言标识
  38. * @param set 设置项
  39. * @param tag 要渲染成的标签
  40. */
  41. export const renderLang = (lang: string, set = {}, tag = 'span') => {
  42. return () => h(tag, set, { default: () => window['$t'](lang) })
  43. }
  44. /**
  45. * * 获取错误处理图片,默认 404 图
  46. * @returns url
  47. */
  48. export const requireErrorImg = () => {
  49. return Image_404
  50. }
  51. /**
  52. * * 全屏操作函数
  53. * @param isFullscreen
  54. * @param isEnabled
  55. * @returns
  56. */
  57. export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
  58. // 是否是全屏
  59. if (isFullscreen) return screenfull.isFullscreen
  60. // 是否支持全屏
  61. if (isEnabled) return screenfull.isEnabled
  62. if (screenfull.isEnabled) {
  63. screenfull.toggle()
  64. return
  65. }
  66. // TODO lang
  67. window['$message'].warning('您的浏览器不支持全屏功能!')
  68. }
  69. /**
  70. * 修改元素位置
  71. * @param target 对象
  72. * @param x X轴
  73. * @param y Y轴
  74. */
  75. export const setComponentPosition = (
  76. target: CreateComponentType | CreateComponentGroupType,
  77. x?: number,
  78. y?: number
  79. ) => {
  80. x && (target.attr.x = x)
  81. y && (target.attr.y = y)
  82. }
  83. /**
  84. * * 设置元素属性
  85. * @param HTMLElement 元素
  86. * @param key 键名
  87. * @param value 键值
  88. */
  89. export const setDomAttribute = <K extends keyof CSSStyleDeclaration, V extends CSSStyleDeclaration[K]>(
  90. HTMLElement: HTMLElement,
  91. key: K,
  92. value: V
  93. ) => {
  94. if (HTMLElement) {
  95. HTMLElement.style[key] = value
  96. }
  97. }
  98. /**
  99. * * 判断是否是 mac
  100. * @returns boolean
  101. */
  102. export const isMac = () => {
  103. return /macintosh|mac os x/i.test(navigator.userAgent)
  104. }
  105. /**
  106. * * file转url
  107. */
  108. export const fileToUrl = (file: File): string => {
  109. const Url = URL || window.URL || window.webkitURL
  110. const ImageUrl = Url.createObjectURL(file)
  111. return ImageUrl
  112. }
  113. /**
  114. * * file转base64
  115. */
  116. export const fileTobase64 = (file: File, callback: Function) => {
  117. let reader = new FileReader()
  118. reader.readAsDataURL(file)
  119. reader.onload = function (e: ProgressEvent<FileReader>) {
  120. if (e.target) {
  121. let base64 = e.target.result
  122. callback(base64)
  123. }
  124. }
  125. }
  126. /**
  127. * * 挂载监听
  128. */
  129. // eslint-disable-next-line no-undef
  130. export const addEventListener = <K extends keyof WindowEventMap>(
  131. target: HTMLElement | Document,
  132. type: K,
  133. listener: any,
  134. delay?: number,
  135. // eslint-disable-next-line no-undef
  136. options?: boolean | AddEventListenerOptions | undefined
  137. ) => {
  138. if (!target) return
  139. target.addEventListener(
  140. type,
  141. throttle(listener, delay || 300, {
  142. leading: true,
  143. trailing: false
  144. }),
  145. options
  146. )
  147. }
  148. /**
  149. * * 卸载监听
  150. */
  151. // eslint-disable-next-line no-undef
  152. export const removeEventListener = <K extends keyof WindowEventMap>(
  153. target: HTMLElement | Document,
  154. type: K,
  155. listener: any
  156. ) => {
  157. if (!target) return
  158. target.removeEventListener(type, listener)
  159. }
  160. /**
  161. * * 截取画面为图片并下载
  162. * @param html 需要截取的 DOM
  163. */
  164. export const canvasCut = (html: HTMLElement | null, callback?: Function) => {
  165. if (!html) {
  166. window['$message'].error('导出失败!')
  167. if (callback) callback()
  168. return
  169. }
  170. html2canvas(html, {
  171. backgroundColor: null,
  172. allowTaint: true,
  173. useCORS: true
  174. }).then((canvas: HTMLCanvasElement) => {
  175. window['$message'].success('导出成功!')
  176. downloadByA(canvas.toDataURL(), undefined, 'png')
  177. if (callback) callback()
  178. })
  179. }
  180. /**
  181. * * 函数过滤器
  182. * @param data 数据值
  183. * @param res 返回顶级对象
  184. * @param funcStr 函数字符串
  185. * @param isToString 是否转为字符串
  186. * @param errorCallBack 错误回调函数
  187. * @param successCallBack 成功回调函数
  188. * @returns
  189. */
  190. export const newFunctionHandle = (
  191. data: any,
  192. res: any,
  193. funcStr?: string,
  194. isToString?: boolean,
  195. errorCallBack?: Function,
  196. successCallBack?: Function
  197. ) => {
  198. try {
  199. if (!funcStr) return data
  200. const fn = new Function('data', 'res', funcStr)
  201. const fnRes = fn(cloneDeep(data), cloneDeep(res))
  202. const resHandle = isToString ? toString(fnRes) : fnRes
  203. // 成功回调
  204. successCallBack && successCallBack(resHandle)
  205. return resHandle
  206. } catch (error) {
  207. // 失败回调
  208. errorCallBack && errorCallBack(error)
  209. return '函数执行错误'
  210. }
  211. }
  212. /**
  213. * * 处理请求事件单位
  214. * @param num 时间间隔
  215. * @param unit RequestHttpIntervalEnum
  216. * @return number 秒数
  217. */
  218. export const intervalUnitHandle = (num: number, unit: RequestHttpIntervalEnum) => {
  219. switch (unit) {
  220. // 秒
  221. case RequestHttpIntervalEnum.SECOND:
  222. return num * 1000
  223. // 分
  224. case RequestHttpIntervalEnum.MINUTE:
  225. return num * 1000 * 60
  226. // 时
  227. case RequestHttpIntervalEnum.HOUR:
  228. return num * 1000 * 60 * 60
  229. // 天
  230. case RequestHttpIntervalEnum.DAY:
  231. return num * 1000 * 60 * 60 * 24
  232. default:
  233. return num * 1000
  234. }
  235. }
  236. /**
  237. * * 对象转换 cookie 格式
  238. * @param obj
  239. * @returns string
  240. */
  241. export const objToCookie = (obj: RequestParamsObjType) => {
  242. if (!obj) return ''
  243. let str = ''
  244. for (const key in obj) {
  245. str += key + '=' + obj[key] + ';'
  246. }
  247. return str.substring(0, str.length - 1)
  248. }
  249. /**
  250. * * 设置按下键盘按键的底部展示
  251. * @param keyCode
  252. * @returns
  253. */
  254. export const setKeyboardDressShow = (keyCode?: number) => {
  255. const code = new Map([
  256. [17, WinKeyboard.CTRL],
  257. [32, WinKeyboard.SPACE]
  258. ])
  259. const dom = document.getElementById('keyboard-dress-show')
  260. if (!dom) return
  261. if (!keyCode) {
  262. window.onKeySpacePressHold?.(false)
  263. dom.innerText = ''
  264. return
  265. }
  266. if (keyCode && code.has(keyCode)) {
  267. if (keyCode == 32) window.onKeySpacePressHold?.(true)
  268. dom.innerText = `按下了「${code.get(keyCode)}」键`
  269. }
  270. }
  271. /**
  272. * * JSON序列化,支持函数和 undefined
  273. * @param data
  274. */
  275. export const JSONStringify = (data: object) => {
  276. return JSON.stringify(
  277. data,
  278. (key, val) => {
  279. // 处理函数丢失问题
  280. if (typeof val === 'function') {
  281. return `${val}`
  282. }
  283. // 处理 undefined 丢失问题
  284. if (typeof val === 'undefined') {
  285. return 'undefined'
  286. }
  287. return val
  288. },
  289. 2
  290. )
  291. }
  292. /**
  293. * * JSON反序列化,支持函数和 undefined
  294. * @param data
  295. */
  296. export const JSONParse = (data: string) => {
  297. return JSON.parse(data, (k, v) => {
  298. if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
  299. return eval(`(function(){return ${v}})()`)
  300. }
  301. return v
  302. })
  303. }