| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- import { h } from 'vue'
- import { NIcon } from 'naive-ui'
- import screenfull from 'screenfull'
- import throttle from 'lodash/throttle'
- import Image_404 from '../assets/images/exception/image-404.png'
- import html2canvas from 'html2canvas'
- import { downloadByA } from './file'
- import { toString } from './type'
- import cloneDeep from 'lodash/cloneDeep'
- import { WinKeyboard } from '@/enums/editPageEnum'
- import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
- import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
- import { excludeParseEventKeyList, excludeParseEventValueList } from '@/enums/eventEnum'
- /**
- * * 判断是否是开发环境
- * @return { Boolean }
- */
- export const isDev = () => {
- return import.meta.env.DEV
- }
- /**
- * * 生成一个不重复的ID
- * @param { Number } randomLength
- */
- export const getUUID = (randomLength = 10) => {
- return 'id_' + Number(Math.random().toString().substring(2, randomLength) + Date.now()).toString(36)
- }
- /**
- * * render 图标
- * @param icon 图标
- * @param set 设置项
- */
- export const renderIcon = (icon: any, set = {}) => {
- return () => h(NIcon, set, { default: () => h(icon) })
- }
- /**
- * * render 语言
- * @param lang 语言标识
- * @param set 设置项
- * @param tag 要渲染成的标签
- */
- export const renderLang = (lang: string, set = {}, tag = 'span') => {
- return () => h(tag, set, { default: () => window['$t'](lang) })
- }
- /**
- * * 获取错误处理图片,默认 404 图
- * @returns url
- */
- export const requireErrorImg = () => {
- return Image_404
- }
- /**
- * * 全屏操作函数
- * @param isFullscreen
- * @param isEnabled
- * @returns
- */
- export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
- // 是否是全屏
- if (isFullscreen) return screenfull.isFullscreen
- // 是否支持全屏
- if (isEnabled) return screenfull.isEnabled
- if (screenfull.isEnabled) {
- screenfull.toggle()
- return
- }
- // TODO lang
- window['$message'].warning('您的浏览器不支持全屏功能!')
- }
- /**
- * 修改元素位置
- * @param target 对象
- * @param x X轴
- * @param y Y轴
- */
- export const setComponentPosition = (
- target: CreateComponentType | CreateComponentGroupType,
- x?: number,
- y?: number
- ) => {
- x && (target.attr.x = x)
- y && (target.attr.y = y)
- }
- /**
- * * 设置元素属性
- * @param HTMLElement 元素
- * @param key 键名
- * @param value 键值
- */
- export const setDomAttribute = <K extends keyof CSSStyleDeclaration, V extends CSSStyleDeclaration[K]>(
- HTMLElement: HTMLElement,
- key: K,
- value: V
- ) => {
- if (HTMLElement) {
- HTMLElement.style[key] = value
- }
- }
- /**
- * * 判断是否是 mac
- * @returns boolean
- */
- export const isMac = () => {
- return /macintosh|mac os x/i.test(navigator.userAgent)
- }
- /**
- * * file转url
- */
- // export const fileToUrl = (file: File): string => {
- // const Url = URL || window.URL || window.webkitURL
- // const ImageUrl = Url.createObjectURL(file)
- // return ImageUrl
- // }
- /**
- * * file转base64
- */
- // export const fileTobase64 = (file: File, callback: Function) => {
- // let reader = new FileReader()
- // reader.readAsDataURL(file)
- // reader.onload = function (e: ProgressEvent<FileReader>) {
- // if (e.target) {
- // let base64 = e.target.result
- // callback(base64)
- // }
- // }
- // }
- /**
- * * 挂载监听
- */
- // eslint-disable-next-line no-undef
- export const addEventListener = <K extends keyof WindowEventMap>(
- target: HTMLElement | Document,
- type: K,
- listener: any,
- delay?: number,
- // eslint-disable-next-line no-undef
- options?: boolean | AddEventListenerOptions | undefined
- ) => {
- if (!target) return
- target.addEventListener(
- type,
- throttle(listener, delay || 300, {
- leading: true,
- trailing: false
- }),
- options
- )
- }
- /**
- * * 卸载监听
- */
- // eslint-disable-next-line no-undef
- export const removeEventListener = <K extends keyof WindowEventMap>(
- target: HTMLElement | Document,
- type: K,
- listener: any
- ) => {
- if (!target) return
- target.removeEventListener(type, listener)
- }
- /**
- * * 截取画面为图片并下载
- * @param html 需要截取的 DOM
- */
- export const canvasCut = (html: HTMLElement | null, callback?: Function) => {
- if (!html) {
- window['$message'].error('导出失败!')
- if (callback) callback()
- return
- }
- html2canvas(html, {
- backgroundColor: null,
- allowTaint: true,
- useCORS: true
- }).then((canvas: HTMLCanvasElement) => {
- window['$message'].success('导出成功!')
- downloadByA(canvas.toDataURL(), undefined, 'png')
- if (callback) callback()
- })
- }
- /**
- * * 函数过滤器
- * @param data 数据值
- * @param res 返回顶级对象
- * @param funcStr 函数字符串
- * @param isToString 是否转为字符串
- * @param errorCallBack 错误回调函数
- * @param successCallBack 成功回调函数
- * @returns
- */
- export const newFunctionHandle = (
- data: any,
- res: any,
- funcStr?: string,
- isToString?: boolean,
- errorCallBack?: Function,
- successCallBack?: Function
- ) => {
- try {
- if (!funcStr) return data
- const fn = new Function('data', 'res', funcStr)
- const fnRes = fn(cloneDeep(data), cloneDeep(res))
- const resHandle = isToString ? toString(fnRes) : fnRes
- // 成功回调
- successCallBack && successCallBack(resHandle)
- return resHandle
- } catch (error) {
- // 失败回调
- errorCallBack && errorCallBack(error)
- return '函数执行错误'
- }
- }
- /**
- * * 处理请求事件单位
- * @param num 时间间隔
- * @param unit RequestHttpIntervalEnum
- * @return number 秒数
- */
- export const intervalUnitHandle = (num: number, unit: RequestHttpIntervalEnum) => {
- switch (unit) {
- // 秒
- case RequestHttpIntervalEnum.SECOND:
- return num * 1000
- // 分
- case RequestHttpIntervalEnum.MINUTE:
- return num * 1000 * 60
- // 时
- case RequestHttpIntervalEnum.HOUR:
- return num * 1000 * 60 * 60
- // 天
- case RequestHttpIntervalEnum.DAY:
- return num * 1000 * 60 * 60 * 24
- default:
- return num * 1000
- }
- }
- /**
- * * 对象转换 cookie 格式
- * @param obj
- * @returns string
- */
- export const objToCookie = (obj: RequestParamsObjType) => {
- if (!obj) return ''
- let str = ''
- for (const key in obj) {
- str += key + '=' + obj[key] + ';'
- }
- return str.substring(0, str.length - 1)
- }
- /**
- * * 设置按下键盘按键的底部展示
- * @param keyCode
- * @returns
- */
- export const setKeyboardDressShow = (keyCode?: number) => {
- const code = new Map([
- [17, WinKeyboard.CTRL],
- [32, WinKeyboard.SPACE]
- ])
- const dom = document.getElementById('keyboard-dress-show')
- if (!dom) return
- if (!keyCode) {
- window.onKeySpacePressHold?.(false)
- dom.innerText = ''
- return
- }
- if (keyCode && code.has(keyCode)) {
- if (keyCode == 32) window.onKeySpacePressHold?.(true)
- dom.innerText = `按下了「${code.get(keyCode)}」键`
- }
- }
- /**
- * * JSON序列化,支持函数和 undefined
- * @param data
- */
- export const JSONStringify = <T>(data: T) => {
- return JSON.stringify(
- data,
- (key, val) => {
- // 处理函数丢失问题
- if (typeof val === 'function') {
- return `${val}`
- }
- // 处理 undefined 丢失问题
- if (typeof val === 'undefined') {
- return null
- }
- return val
- },
- 2
- )
- }
- export const evalFn = (fn: string) => {
- var Fun = Function // 一个变量指向Function,防止前端编译工具报错
- return new Fun('return ' + fn)()
- }
- /**
- * * JSON反序列化,支持函数和 undefined
- * @param data
- */
- export const JSONParse = (data: string) => {
- if (data.trim() === '') return
- return JSON.parse(data, (k, v) => {
- // // 过滤函数字符串
- // if (excludeParseEventKeyList.includes(k)) return v
- // // 过滤函数值表达式
- // if (typeof v === 'string') {
- // const someValue = excludeParseEventValueList.some(excludeValue => v.indexOf(excludeValue) > -1)
- // if (someValue) return v
- // }
- if (k !== 'formatter') {
- return v
- }
- // 还原函数值
- if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
- return evalFn(`(function(){return ${v}})()`)
- } else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
- const baseLeftIndex = v.indexOf('(')
- if (baseLeftIndex > -1) {
- const newFn = `function ${v.substring(baseLeftIndex)}`
- return evalFn(`(function(){return ${newFn}})()`)
- }
- }
- return v
- })
- }
- /**
- * * 修改顶部标题
- * @param title
- */
- export const setTitle = (title?: string) => {
- title && (document.title = title)
- }
- /**
- * 时间日期转换
- * @param date 当前时间,new Date() 格式
- * @param format 需要转换的时间格式字符串
- * @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd`
- * @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ"
- * @description format 星期:"YYYY-mm-dd HH:MM:SS WWW"
- * @description format 几周:"YYYY-mm-dd HH:MM:SS ZZZ"
- * @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ"
- * @returns 返回拼接后的时间字符串
- */
- export function formatDate(date: Date, format: string): string {
- const we = date.getDay() // 星期
- const z = getWeek(date) // 周
- const qut = Math.floor((date.getMonth() + 3) / 3).toString() // 季度
- const opt: { [key: string]: string } = {
- 'Y+': date.getFullYear().toString(), // 年
- 'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1)
- 'd+': date.getDate().toString(), // 日
- 'H+': date.getHours().toString(), // 时
- 'M+': date.getMinutes().toString(), // 分
- 'S+': date.getSeconds().toString(), // 秒
- 'q+': qut // 季度
- }
- // 中文数字 (星期)
- const week: { [key: string]: string } = {
- '0': '日',
- '1': '一',
- '2': '二',
- '3': '三',
- '4': '四',
- '5': '五',
- '6': '六'
- }
- // 中文数字(季度)
- const quarter: { [key: string]: string } = {
- '1': '一',
- '2': '二',
- '3': '三',
- '4': '四'
- }
- if (/(W+)/.test(format))
- format = format.replace(
- RegExp.$1,
- RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]
- )
- if (/(Q+)/.test(format))
- format = format.replace(
- RegExp.$1,
- RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]
- )
- if (/(Z+)/.test(format))
- format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + '')
- for (const k in opt) {
- const r = new RegExp('(' + k + ')').exec(format)
- // 若输入的长度不为1,则前面补零
- if (r)
- format = format.replace(
- r[1],
- RegExp.$1.length == 1 ? opt[k] : opt[k].padStart(RegExp.$1.length, '0')
- )
- }
- return format
- }
- /**
- * 获取当前日期是第几周
- * @param dateTime 当前传入的日期值
- * @returns 返回第几周数字值
- */
- export function getWeek(dateTime: Date): number {
- const temptTime = new Date(dateTime.getTime())
- // 周几
- const weekday = temptTime.getDay() || 7
- // 周1+5天=周六
- temptTime.setDate(temptTime.getDate() - weekday + 1 + 5)
- let firstDay = new Date(temptTime.getFullYear(), 0, 1)
- const dayOfWeek = firstDay.getDay()
- let spendDay = 1
- if (dayOfWeek != 0) spendDay = 7 - dayOfWeek + 1
- firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay)
- const d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 86400000)
- const result = Math.ceil(d / 7)
- return result
- }
|