mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
chore: format code style and update linting configuration
This commit is contained in:
302
src/Utils.ts
302
src/Utils.ts
@@ -1,227 +1,230 @@
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import {
|
||||
import type {
|
||||
ConfigProviderProps,
|
||||
NButton,
|
||||
NIcon,
|
||||
NTooltip,
|
||||
UploadFileInfo,
|
||||
} from 'naive-ui'
|
||||
import type { DiscreteApiType } from 'naive-ui/es/discrete/src/interface'
|
||||
import type { SongsInfo } from './api/api-models'
|
||||
import { SquareArrowForward24Filled } from '@vicons/fluent'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import {
|
||||
createDiscreteApi,
|
||||
darkTheme,
|
||||
dateZhCN,
|
||||
NButton,
|
||||
NIcon,
|
||||
NTooltip,
|
||||
useOsTheme,
|
||||
zhCN
|
||||
} from 'naive-ui';
|
||||
import { SongFrom, SongsInfo, ThemeType } from './api/api-models';
|
||||
import { computed } from 'vue';
|
||||
import { VTSURU_API_URL } from './data/constants';
|
||||
import { DiscreteApiType } from 'naive-ui/es/discrete/src/interface';
|
||||
import { SquareArrowForward24Filled } from '@vicons/fluent';
|
||||
import FiveSingIcon from '@/svgs/fivesing.svg';
|
||||
import NeteaseIcon from '@/svgs/netease.svg';
|
||||
zhCN,
|
||||
} from 'naive-ui'
|
||||
import { computed } from 'vue'
|
||||
import FiveSingIcon from '@/svgs/fivesing.svg'
|
||||
import NeteaseIcon from '@/svgs/netease.svg'
|
||||
import { SongFrom, ThemeType } from './api/api-models'
|
||||
import { VTSURU_API_URL } from './data/constants'
|
||||
|
||||
const { message } = createDiscreteApi(['message']);
|
||||
const { message } = createDiscreteApi(['message'])
|
||||
|
||||
const osThemeRef = useOsTheme(); //获取当前系统主题
|
||||
const themeType = useStorage('Settings.Theme', ThemeType.Auto);
|
||||
const osThemeRef = useOsTheme() // 获取当前系统主题
|
||||
const themeType = useStorage('Settings.Theme', ThemeType.Auto)
|
||||
export const theme = computed(() => {
|
||||
if (themeType.value == ThemeType.Auto) {
|
||||
var osThemeRef = useOsTheme(); //获取当前系统主题
|
||||
return osThemeRef.value === 'dark' ? darkTheme : null;
|
||||
const osThemeRef = useOsTheme() // 获取当前系统主题
|
||||
return osThemeRef.value === 'dark' ? darkTheme : null
|
||||
} else {
|
||||
return themeType.value == ThemeType.Dark ? darkTheme : null;
|
||||
return themeType.value == ThemeType.Dark ? darkTheme : null
|
||||
}
|
||||
});
|
||||
})
|
||||
export const configProviderPropsRef = computed<ConfigProviderProps>(() => ({
|
||||
theme: theme.value,
|
||||
locale: zhCN,
|
||||
dateLocale: dateZhCN,
|
||||
|
||||
}));
|
||||
}))
|
||||
export function createNaiveUIApi(types: DiscreteApiType[]) {
|
||||
return createDiscreteApi(types, {
|
||||
configProviderProps: configProviderPropsRef
|
||||
});
|
||||
configProviderProps: configProviderPropsRef,
|
||||
})
|
||||
}
|
||||
export function NavigateToNewTab(url: string) {
|
||||
window.open(url, '_blank');
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
export const isDarkMode = computed(() => {
|
||||
if (themeType.value == ThemeType.Auto) return osThemeRef.value === 'dark';
|
||||
else return themeType.value == ThemeType.Dark;
|
||||
});
|
||||
if (themeType.value == ThemeType.Auto) return osThemeRef.value === 'dark'
|
||||
else return themeType.value == ThemeType.Dark
|
||||
})
|
||||
export function copyToClipboard(text: string) {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text);
|
||||
message.success('已复制到剪切板');
|
||||
navigator.clipboard.writeText(text)
|
||||
message.success('已复制到剪切板')
|
||||
} else {
|
||||
message.warning('当前环境不支持自动复制, 请手动选择并复制');
|
||||
message.warning('当前环境不支持自动复制, 请手动选择并复制')
|
||||
}
|
||||
}
|
||||
export function objectsToCSV(arr: any[]) {
|
||||
const array = [Object.keys(arr[0])].concat(arr);
|
||||
const array = [Object.keys(arr[0])].concat(arr)
|
||||
return array
|
||||
.map((row) => {
|
||||
return Object.values(row)
|
||||
.map((value) => {
|
||||
return typeof value === 'string' ? JSON.stringify(value) : value;
|
||||
return typeof value === 'string' ? JSON.stringify(value) : value
|
||||
})
|
||||
.toString();
|
||||
.toString()
|
||||
})
|
||||
.join('\n');
|
||||
.join('\n')
|
||||
}
|
||||
export function GetGuardColor(level: number | null | undefined): string {
|
||||
if (level) {
|
||||
switch (level) {
|
||||
case 1: {
|
||||
return 'rgb(122, 4, 35)';
|
||||
return 'rgb(122, 4, 35)'
|
||||
}
|
||||
case 2: {
|
||||
return 'rgb(157, 155, 255)';
|
||||
return 'rgb(157, 155, 255)'
|
||||
}
|
||||
case 3: {
|
||||
return 'rgb(104, 136, 241)';
|
||||
return 'rgb(104, 136, 241)'
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
return ''
|
||||
}
|
||||
export function downloadImage(imageSrc: string, filename: string) {
|
||||
const image = new Image();
|
||||
image.crossOrigin = 'Anonymous'; // This might be needed depending on the image's server
|
||||
const image = new Image()
|
||||
image.crossOrigin = 'Anonymous' // This might be needed depending on the image's server
|
||||
image.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx!.drawImage(image, 0, 0);
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = image.width
|
||||
canvas.height = image.height
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx!.drawImage(image, 0, 0)
|
||||
canvas.toBlob((blob) => {
|
||||
if (blob) {
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
const link = document.createElement('a')
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.download = filename
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
}); // Omitted the 'image/jpeg' to use the original image format
|
||||
};
|
||||
image.src = imageSrc;
|
||||
}) // Omitted the 'image/jpeg' to use the original image format
|
||||
}
|
||||
image.src = imageSrc
|
||||
}
|
||||
export function getBase64(
|
||||
file: File | undefined | null
|
||||
export async function getBase64(
|
||||
file: File | undefined | null,
|
||||
): Promise<string | undefined> {
|
||||
if (!file) return new Promise((resolve) => resolve(undefined));
|
||||
if (!file) return new Promise(resolve => resolve(undefined))
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
const reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = () =>
|
||||
resolve(reader.result?.toString().split(',')[1] || undefined);
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
resolve(reader.result?.toString().split(',')[1] || undefined)
|
||||
reader.onerror = error => reject(error)
|
||||
})
|
||||
}
|
||||
export async function getImageUploadModel(
|
||||
files: UploadFileInfo[] | undefined | null,
|
||||
maxSize: number = 10 * 1024 * 1024
|
||||
maxSize: number = 10 * 1024 * 1024,
|
||||
) {
|
||||
const result = {
|
||||
existImages: [],
|
||||
newImagesBase64: []
|
||||
} as { existImages: string[]; newImagesBase64: string[]; };
|
||||
if (!files) return result;
|
||||
newImagesBase64: [],
|
||||
} as { existImages: string[], newImagesBase64: string[] }
|
||||
if (!files) return result
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const file = files[i]
|
||||
if ((file.file?.size ?? 0) > maxSize) {
|
||||
message.error('文件大小不能超过 ' + maxSize / 1024 / 1024 + 'MB');
|
||||
return result;
|
||||
message.error(`文件大小不能超过 ${maxSize / 1024 / 1024}MB`)
|
||||
return result
|
||||
}
|
||||
if (!file.file) {
|
||||
result.existImages.push(file.id); //用id绝对路径当的文件名
|
||||
result.existImages.push(file.id) // 用id绝对路径当的文件名
|
||||
} else {
|
||||
const base64 = await getBase64(file.file);
|
||||
const base64 = await getBase64(file.file)
|
||||
if (base64) {
|
||||
result.newImagesBase64.push(base64);
|
||||
result.newImagesBase64.push(base64)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
export function getUserAvatarUrl(userId: number | undefined | null) {
|
||||
if (!userId) return '';
|
||||
return VTSURU_API_URL + 'user-face/' + userId;
|
||||
if (!userId) return ''
|
||||
return `${VTSURU_API_URL}user-face/${userId}`
|
||||
}
|
||||
export function getOUIdAvatarUrl(ouid: string) {
|
||||
return VTSURU_API_URL + 'face/' + ouid;
|
||||
return `${VTSURU_API_URL}face/${ouid}`
|
||||
}
|
||||
|
||||
export class GuidUtils {
|
||||
// 将数字转换为GUID
|
||||
public static numToGuid(value: number): string {
|
||||
if (!Number.isSafeInteger(value) || value < 0) {
|
||||
throw new Error('输入必须是非负安全整数');
|
||||
throw new Error('输入必须是非负安全整数')
|
||||
}
|
||||
const buffer = new ArrayBuffer(16);
|
||||
const view = new DataView(buffer);
|
||||
view.setBigUint64(8, BigInt(value)); // 将数字写入后8个字节
|
||||
return GuidUtils.bufferToGuid(buffer);
|
||||
const buffer = new ArrayBuffer(16)
|
||||
const view = new DataView(buffer)
|
||||
view.setBigUint64(8, BigInt(value)) // 将数字写入后8个字节
|
||||
return GuidUtils.bufferToGuid(buffer)
|
||||
}
|
||||
|
||||
// 检查GUID是否由数字生成
|
||||
public static isGuidFromUserId(guid: string): boolean {
|
||||
try {
|
||||
const buffer = GuidUtils.guidToBuffer(guid);
|
||||
const view = new DataView(buffer);
|
||||
const buffer = GuidUtils.guidToBuffer(guid)
|
||||
const view = new DataView(buffer)
|
||||
for (let i = 0; i < 8; i++) {
|
||||
if (view.getUint8(i) !== 0) return false; // 检查前8个字节是否为0
|
||||
if (view.getUint8(i) !== 0) return false // 检查前8个字节是否为0
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
} catch (e) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 将GUID转换为数字
|
||||
public static guidToLong(guid: string): number {
|
||||
try {
|
||||
const buffer = GuidUtils.guidToBuffer(guid);
|
||||
const view = new DataView(buffer);
|
||||
return Number(view.getBigUint64(8));
|
||||
const buffer = GuidUtils.guidToBuffer(guid)
|
||||
const view = new DataView(buffer)
|
||||
return Number(view.getBigUint64(8))
|
||||
} catch (e) {
|
||||
throw new Error('无效的GUID格式');
|
||||
throw new Error('无效的GUID格式')
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法:将ArrayBuffer转换为GUID字符串
|
||||
private static bufferToGuid(buffer: ArrayBuffer): string {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
let hex = '';
|
||||
const bytes = new Uint8Array(buffer)
|
||||
let hex = ''
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
hex += bytes[i].toString(16).padStart(2, '0');
|
||||
hex += bytes[i].toString(16).padStart(2, '0')
|
||||
}
|
||||
|
||||
// 标准GUID格式:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
return hex.substring(0, 8) + '-' +
|
||||
hex.substring(8, 12) + '-' +
|
||||
hex.substring(12, 16) + '-' +
|
||||
hex.substring(16, 20) + '-' +
|
||||
hex.substring(20);
|
||||
return `${hex.substring(0, 8)}-${
|
||||
hex.substring(8, 12)}-${
|
||||
hex.substring(12, 16)}-${
|
||||
hex.substring(16, 20)}-${
|
||||
hex.substring(20)}`
|
||||
}
|
||||
|
||||
// 辅助方法:将GUID字符串转换为ArrayBuffer
|
||||
private static guidToBuffer(guid: string): ArrayBuffer {
|
||||
const hex = guid.replace(/-/g, '');
|
||||
if (hex.length !== 32) throw new Error('无效的GUID格式');
|
||||
const hex = guid.replace(/-/g, '')
|
||||
if (hex.length !== 32) throw new Error('无效的GUID格式')
|
||||
|
||||
const buffer = new ArrayBuffer(16);
|
||||
const view = new Uint8Array(buffer);
|
||||
const buffer = new ArrayBuffer(16)
|
||||
const view = new Uint8Array(buffer)
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
const byteValue = parseInt(hex.substr(i * 2, 2), 16);
|
||||
if (isNaN(byteValue)) throw new Error('GUID包含非法字符');
|
||||
view.set([byteValue], i);
|
||||
const byteValue = Number.parseInt(hex.substr(i * 2, 2), 16)
|
||||
if (isNaN(byteValue)) throw new Error('GUID包含非法字符')
|
||||
view.set([byteValue], i)
|
||||
}
|
||||
|
||||
return buffer;
|
||||
return buffer
|
||||
}
|
||||
}
|
||||
export function GetPlayButton(song: SongsInfo) {
|
||||
@@ -237,7 +240,7 @@ export function GetPlayButton(song: SongsInfo) {
|
||||
color: '#00BBB3',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(`http://5sing.kugou.com/bz/${song.id}.html`);
|
||||
window.open(`http://5sing.kugou.com/bz/${song.id}.html`)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -246,7 +249,7 @@ export function GetPlayButton(song: SongsInfo) {
|
||||
),
|
||||
),
|
||||
default: () => '在5sing打开',
|
||||
});
|
||||
})
|
||||
}
|
||||
case SongFrom.Netease:
|
||||
return h(NTooltip, null, {
|
||||
@@ -258,7 +261,7 @@ export function GetPlayButton(song: SongsInfo) {
|
||||
color: '#C20C0C',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(`https://music.163.com/#/song?id=${song.id}`);
|
||||
window.open(`https://music.163.com/#/song?id=${song.id}`)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -266,54 +269,47 @@ export function GetPlayButton(song: SongsInfo) {
|
||||
},
|
||||
),
|
||||
default: () => '在网易云打开',
|
||||
});
|
||||
})
|
||||
case SongFrom.Custom:
|
||||
return song.url
|
||||
? h(NTooltip, null, {
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#6b95bd',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(song.url);
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#6b95bd',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(song.url)
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: () => h(NIcon, { component: SquareArrowForward24Filled }),
|
||||
},
|
||||
),
|
||||
default: () => '打开链接',
|
||||
})
|
||||
: null;
|
||||
{
|
||||
icon: () => h(NIcon, { component: SquareArrowForward24Filled }),
|
||||
},
|
||||
),
|
||||
default: () => '打开链接',
|
||||
})
|
||||
: null
|
||||
}
|
||||
}
|
||||
export function getBrowserName() {
|
||||
var userAgent = navigator.userAgent;
|
||||
if (userAgent.indexOf("Opera") > -1 || userAgent.indexOf("OPR") > -1) {
|
||||
return 'Opera';
|
||||
const userAgent = navigator.userAgent
|
||||
if (userAgent.includes('Opera') || userAgent.includes('OPR')) {
|
||||
return 'Opera'
|
||||
} else if (userAgent.includes('compatible') && userAgent.includes('MSIE')) {
|
||||
return 'IE'
|
||||
} else if (userAgent.includes('Edge')) {
|
||||
return 'Edge'
|
||||
} else if (userAgent.includes('Firefox')) {
|
||||
return 'Firefox'
|
||||
} else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) {
|
||||
return 'Safari'
|
||||
} else if (userAgent.includes('Chrome') && userAgent.includes('Safari')) {
|
||||
return 'Chrome'
|
||||
} else if (!!window.ActiveXObject || 'ActiveXObject' in window) {
|
||||
return 'IE>=11'
|
||||
} else {
|
||||
return 'Unkonwn'
|
||||
}
|
||||
else if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1) {
|
||||
return 'IE';
|
||||
}
|
||||
else if (userAgent.indexOf("Edge") > -1) {
|
||||
return 'Edge';
|
||||
}
|
||||
else if (userAgent.indexOf("Firefox") > -1) {
|
||||
return 'Firefox';
|
||||
}
|
||||
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") == -1) {
|
||||
return 'Safari';
|
||||
}
|
||||
else if (userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1) {
|
||||
return 'Chrome';
|
||||
}
|
||||
else if (!!window.ActiveXObject || "ActiveXObject" in window) {
|
||||
return 'IE>=11';
|
||||
}
|
||||
else {
|
||||
return 'Unkonwn';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user