import { h, unref } from 'vue'; import type { App, Plugin } from 'vue'; import { NIcon, NTag } from 'naive-ui'; import { PageEnum } from '@/enums/pageEnum'; import { isObject } from './is/index'; import { cloneDeep } from 'lodash'; import dayjs from 'dayjs'; import EventEmitter from 'eventemitter3'; export const eventGlobal = new EventEmitter(); /** * render 图标 * */ export function renderIcon(icon: any) { return () => h(NIcon, null, { default: () => h(icon) }); } /** * font 图标(Font class) * */ export function renderFontClassIcon(icon: string, iconName = 'iconfont') { return () => h('span', { class: [iconName, icon] }); } /** * font 图标(Unicode) * */ export function renderUnicodeIcon(icon: string, iconName = 'iconfont') { return () => h('span', { class: [iconName], innerHTML: icon }); } /** * font svg 图标 * */ export function renderfontsvg(icon: any) { return () => h(NIcon, null, { default: () => h( 'svg', { class: `icon`, 'aria-hidden': 'true' }, h('use', { 'xlink:href': `#${icon}` }) ) }); } /** * render new Tag * */ const newTagColors = { color: '#f90', textColor: '#fff', borderColor: '#f90' }; export function renderNew( type = 'warning', text = 'New', color: object = newTagColors ) { return () => h( NTag as any, { type, round: true, size: 'small', color }, { default: () => text } ); } /** * 递归组装菜单格式 */ export function generatorMenu(routerMap: Array) { return filterRouter(routerMap).map(item => { const isRoot = isRootRouter(item); if (isRoot) { console.log(item.children[0], 'isRoot'); } const info = isRoot ? item.children[0] : item; // console.log(item) const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.key, icon: info.meta?.icon }; // 是否有子菜单,并递归处理 if (info.children && info.children.length > 0) { // Recursion currentMenu.children = generatorMenu(info.children); } return currentMenu; }); } /** * 混合菜单 * */ export function generatorMenuMix( routerMap: Array, routerName: string, location: string ) { const cloneRouterMap = cloneDeep(routerMap); const newRouter = filterRouter(cloneRouterMap); if (location === 'header') { const firstRouter: any[] = []; newRouter.forEach(item => { const isRoot = isRootRouter(item); const info = isRoot ? item.children[0] : item; info.children = undefined; const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.name }; firstRouter.push(currentMenu); }); return firstRouter; } else { // 混合菜单 console.log('混合菜单'); return getChildrenRouter( newRouter.filter(item => item.name === routerName) ); } } /** * 递归组装子菜单 * */ export function getChildrenRouter(routerMap: Array) { return filterRouter(routerMap).map(item => { const isRoot = isRootRouter(item); const info = isRoot ? item.children[0] : item; const currentMenu = { ...info, ...info.meta, label: info.meta?.title, key: info.name }; // 是否有子菜单,并递归处理 if (info.children && info.children.length > 0) { // Recursion currentMenu.children = getChildrenRouter(info.children); } return currentMenu; }); } /** * 判断根路由 Router * */ export function isRootRouter(item: any) { return item.meta?.isRoot === true; } /** * 排除Router * */ export function filterRouter(routerMap: Array) { return routerMap.filter(item => { // console.log( // (item.meta?.hidden || false) != true && // !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(item.path), // '过滤完之后的路由' // ) return ( (item.meta?.hidden || false) != true && !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes( item.path ) ); }); } export const withInstall = (component: T, alias?: string) => { const comp = component as any; comp.install = (app: App) => { app.component(comp.name || comp.displayName, component as any); if (alias) { app.config.globalProperties[alias] = component; } }; return component as T & Plugin; }; /** * 找到对应的节点 * */ let result = null as any; export function getTreeItem(data: any[], key?: string | number): any { data.map(item => { if (item.key === key) { result = item; } else { if (item.children && item.children.length) { getTreeItem(item.children, key); } } }); return result; } /** * 找到所有节点 * */ const treeAll: any[] = []; export function getTreeAll(data: any[]): any[] { data.map(item => { treeAll.push(item.key); if (item.children && item.children.length) { getTreeAll(item.children); } }); return treeAll; } export function deepMerge(src: any = {}, target: any = {}): T { let key: string; for (key in target) { src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]); } return src; } /** * Sums the passed percentage to the R, G or B of a HEX color * @param {string} color The color to change * @param {number} amount The amount to change the color by * @returns {string} The processed part of the color */ function addLight(color: string, amount: number) { const cc = parseInt(color, 16) + amount; const c = cc > 255 ? 255 : cc; return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`; } /** * Lightens a 6 char HEX color according to the passed percentage * @param {string} color The color to change * @param {number} amount The amount to change the color by * @returns {string} The processed color represented as HEX */ export function lighten(color: string, amount: number) { color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color; amount = Math.trunc((255 * amount) / 100); return `#${addLight(color.substring(0, 2), amount)}${addLight( color.substring(2, 4), amount )}${addLight(color.substring(4, 6), amount)}`; } /** * 判断是否 url * */ export function isUrl(url: string) { return /^(http|https):\/\//g.test(url); } /** 递归清除空数据 */ export function clearEmtryData(list: any[], key: string) { for (let i = 0; i < list.length; i++) { if (Array.isArray(list[i][key]) && !list[i][key].length) { list[i][key] = ''; } else { list[i][key] = clearEmtryData(list[i][key], key); } } return list; } // 秒转分 export const getSecondRPM = (second: number, type?: string) => { if (isNaN(second)) return '00:00'; const mm = Math.floor(second / 60) .toString() .padStart(2, '0'); const dd = Math.floor(second % 60) .toString() .padStart(2, '0'); if (type === 'cn') { return mm + '分' + dd + '秒'; } else { return mm + ':' + dd; } }; // 秒转分 export const getSecond = (second: number, type?: string) => { if (isNaN(second)) return '0000'; const mm = Math.floor(second / 60) .toString() .padStart(2, '0'); const dd = Math.floor(second % 60) .toString() .padStart(2, '0'); return `${mm}${dd}`; }; /** 滚动到表单填写错误的地方 */ export function scrollToErrorForm() { const isError = document.querySelector('.n-input--error-status') || document.querySelector('.n-base-selection--error-status'); isError?.scrollIntoView({ block: 'center', behavior: 'smooth' }); } export const getTimes = ( times: any, keys: Array = [], format = 'YYYY-MM-DD' ) => { if (times && times.length) { return format == 'YYYY-MM-DD' ? { [keys[0] || 'start']: dayjs(times[0]).isValid() ? dayjs(times[0]).format(format) + ' 00:00:00' : '', [keys[1] || 'end']: dayjs(times[1]).isValid() ? dayjs(times[1]).format(format) + ' 23:59:59' : '' } : { [keys[0] || 'start']: dayjs(times[0]).isValid() ? dayjs(times[0]).format(format) : '', [keys[1] || 'end']: dayjs(times[1]).isValid() ? dayjs(times[1]).format(format) : '' }; } return {}; }; export const px2vw = (px: number): string => `${(px / 1920) * 100}vw`; export const px2vwH = (px: number): string => `${(((px / 1920) * 1920) / 1188) * 100}vw`; export const fscreen = () => { const el = document.documentElement; //进入全屏 (el.requestFullscreen && el.requestFullscreen()) || (el.mozRequestFullScreen && el.mozRequestFullScreen()) || (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) || (el.msRequestFullscreen && el.msRequestFullscreen()); //退出全屏 }; export const exitFullscreen = () => { document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen ? document.webkitExitFullscreen() : ''; }; /** 检测链接格式 */ export function checkUrlType(urlType: string) { const subfix = (urlType || '').split('.').pop(); if (subfix === 'wav' || subfix === 'mp3' || subfix === 'm4a') { return 'audio'; } return 'video'; } const instruments: any = { 'Acoustic Grand Piano': '大钢琴', 'Bright Acoustic Piano': '明亮的钢琴', 'Electric Grand Piano': '电钢琴', 'Rhodes Piano': '柔和的电钢琴', 'Chorused Piano': '加合唱效果的电钢琴', Harpsichord: '羽管键琴', Clavichord: '科拉维科特琴', Celesta: '钢片琴', Glockenspiel: '钢片琴', 'Music box': '八音盒', Vibraphone: '颤音琴', Marimba: '马林巴', Xylophone: '木琴', 'Tubular Bells': '管钟', Dulcimer: '大扬琴', 'Hammond Organ': '击杆风琴', 'Percussive Organ': '打击式风琴', 'Rock Organ': '摇滚风琴', 'Church Organ': '教堂风琴', 'Reed Organ': '簧管风琴', Accordian: '手风琴', Harmonica: '口琴', 'Tango Accordian': '探戈手风琴', 'Acoustic Guitar': '钢弦吉他', 'Electric Guitar': '闷音电吉他', 'Overdriven Guitar': '加驱动效果的电吉他', 'Distortion Guitar': '加失真效果的电吉他', 'Guitar Harmonics': '吉他和音', 'Acoustic Bass': '大贝司', 'Electric Bass': '电贝司', 'Fretless Bass': '无品贝司', 'Slap Bass': '掌击', 'Synth Bass': '电子合成', Violin: '小提琴', Viola: '中提琴', Cello: '大提琴', Contrabass: '低音大提琴', 'Tremolo Strings': '弦乐群颤音音色', 'Pizzicato Strings': '弦乐群拨弦音色', 'Orchestral Harp': '竖琴', Timpani: '定音鼓', 'String Ensemble': '弦乐合奏音色', 'Synth Strings': '合成弦乐合奏音色', 'Choir Aahs': '人声合唱', 'Voice Oohs': '人声', 'Synth Voice': '合成人声', 'Orchestra Hit': '管弦乐敲击齐奏', Trumpet: '小号', Trombone: '长号', Tuba: '大号', 'Muted Trumpet': '加弱音器小号', 'French Horn': '法国号', 'Brass Section': '铜管组', 'Synth Brass': '合成铜管音色', 'Soprano Sax': '高音萨克斯管', 'Alto Sax': '中音萨克斯管', 'Tenor Sax': '次中音萨克斯管', 'Baritone Sax': '低音萨克斯管', Oboe: '双簧管', 'English Horn': '英国管', Bassoon: '巴松', Clarinet: '单簧管', 'Soprano Saxophone': '高音萨克斯管', 'Alto Saxophone': '中音萨克斯管', 'Tenor Saxophone': '次中音萨克斯管', 'Baritone Saxophone': '低音萨克斯管', Piccolo: '短笛', Flute: '长笛', Recorder: '竖笛', 'Soprano Recorder': '高音竖笛', 'Pan Flute': '排箫', 'Bottle Blow': '瓶木管', Whistle: '口哨声', Ocarina: '陶笛', Lead: '合成主音', 'Lead lead': '合成主音', 'Pad age': '合成音色', Pad: '合成音色', FX: '合成效果 科幻', Sitar: '西塔尔', Banjo: '班卓琴', Shamisen: '三昧线', Koto: '十三弦筝', Kalimba: '卡林巴', Bagpipe: '风笛', Fiddle: '民族提琴', Shanai: '山奈', 'Tinkle Bell': '叮当铃', Agogos: '阿戈戈铃', 'Steel Drums': '钢鼓', 'Taiko Drum': '太鼓', 'Melodic Toms': '嗵嗵鼓', 'Synth Drums': '合成鼓', 'Reverse Cymbals': '反向镲', 'Agogo Bells': '阿戈戈铃', 'Taiko Drums': '太鼓', Bongos: '邦戈鼓', 'Bongo Bell': '邦戈铃', Congas: '康加鼓', Guiro: '刮壶', 'Guitar Fret Noise': '吉他换把杂音', 'Breath Noise': '呼吸声', Seashore: '海浪声', 'Bird Tweet': '鸟鸣', 'Telephone Ring': '电话铃', Helicopter: '直升机', Applause: '鼓掌声', Gunshot: '枪声', 'Acoustic Bass Drum': '大鼓', 'Bass Drum': '大鼓', 'Side Drum': '小鼓鼓边', 'Acoustic Snare': '小鼓', 'Hand Claps': '拍手', 'Electric Snare': '小鼓', 'Low Floor Tom': '低音嗵鼓', 'Closed Hi-Hat': '闭合踩镲', 'High Floor Tom': '高音落地嗵鼓', 'Pedal Hi-Hat': '脚踏踩镲', 'Low Tom': '低音嗵鼓', 'Open Hi-Hat': '开音踩镲', 'Low-Mid Tom': '中低音嗵鼓', 'Hi Mid Tom': '高音鼓', 'Crash Cymbals': '对镲', 'High Tom': '高音嗵鼓', 'Ride Cymbals': '叮叮镲', 'Chinese Cymbals': '中国镲', 'Ride Bell': '圆铃', Tambourine: '铃鼓', 'Splash Cymbal': '溅音镲', Cowbell: '牛铃', 'Crash Cymbal': '强音钹', 'Vibra-Slap': '颤音器', 'Ride Cymbal': '打点钹', 'Hi Bongo': '高音邦戈鼓', 'Low Bongo': '低音邦戈鼓', 'Mute Hi Conga': '弱音高音康加鼓', 'Open Hi Conga': '强音高音康加鼓', 'Low Conga': '低音康加鼓', 'High Timbale': '高音天巴鼓', 'Low Timbale': '低音天巴鼓', 'High Agogo': '高音阿戈戈铃', 'Low Agogo': '低音阿戈戈铃', Cabasa: '卡巴萨', Maracas: '沙锤', 'Short Whistle': '短口哨', 'Long Whistle': '长口哨', 'Short Guiro': '短刮壶', 'Long Guiro': '长刮壶', Claves: '响棒', 'Hi Wood Block': '高音木鱼', 'Low Wood Block': '低音木鱼', 'Mute Triangle': '弱音三角铁', 'Open Triangle': '强音三角铁', 'Drum Set': '架子鼓', 'Hulusi flute': '葫芦丝', Melodica: '口风琴', Nai: '口风琴', 'Snare Drum': '小军鼓', Cymbal: '镲', Cymbals: '镲', 'Horn in F': '圆号', Triangle: '三角铁', Vibrato: '颤音琴', 'Suspend Cymbals': '吊镲', 'Suspended Cymbals': '吊镲', 'Tom-Toms': '嗵嗵鼓', Bell: '铃铛', Bells: '铃铛', 'Alto Clarinet': '中音单簧管', 'Bass Clarinet': '低音单簧管', Cornet: '短号', Euphonium: '上低音号', 'crash cymbals': '对镲', Castanets: '响板', Shaker: '沙锤', 'Mark tree': '音树', Chimes: '管钟', 'Mark Tree': '音树', 'Tom-toms': '嗵嗵鼓', 'Hi-Hat': '踩镲', 'Sleigh Bells': '雪橇铃', Flexatone: '弹音器', 'Brake drum': '闸鼓', Gong: '锣', 'concert tom': '音乐会嗵嗵鼓', 'brake drum': '车轮鼓', 'finger cymbal': '指钹', 'ride cymbal': '叮叮镲', 'Concert Toms': '音乐会嗵嗵鼓', Vibraslap: '弹音器', 'Wood Blocks': '木鱼', 'Temple Blocks': '木鱼', 'Wood Block': '木鱼', 'Field Drum': '军鼓', 'Quad-Toms': '筒鼓', Quads: '筒鼓', 'Drums set': '架子鼓', 'High Bongo': '邦戈', Timbales: '天巴鼓' }; /** 获取分轨名称 */ export const getInstrumentName = (name = '') => { name = name.toLocaleLowerCase().replace(/ /g, ''); if (!name) return ''; for (let key in instruments) { const _key = key.toLocaleLowerCase().replace(/ /g, ''); if (_key.includes(name)) { return instruments[key]; } } for (let key in instruments) { const _key = key.toLocaleLowerCase().replace(/ /g, ''); if (name.includes(_key)) { return instruments[key]; } } return ''; }; /** * 乐器排序 * 排序顺序:长笛、单簧管、中音单簧管、低音单簧管、高音萨克斯风、中音萨克斯风、次中音萨克斯风、低音萨克斯风、小号、长号、圆号、大号、上低音号 * */ export const sortMusical = (name: string, index: number) => { let sortId = 0; switch (name) { case '长笛': sortId = 1; break; case '单簧管': sortId = 2; break; case '中音单簧管': sortId = 3; break; case '低音单簧管': sortId = 4; break; case '高音萨克斯风': sortId = 5; break; case '中音萨克斯风': sortId = 6; break; case '次中音萨克斯风': sortId = 7; break; case '低音萨克斯风': sortId = 8; break; case '小号': sortId = 9; break; case '长号': sortId = 10; break; case '圆号': sortId = 11; break; case '大号': sortId = 12; break; case '上低音号': sortId = 13; break; default: sortId = index + 14; break; } return sortId; };