✨ 添加新的依赖
This commit is contained in:
parent
b32093a9b0
commit
f116067708
|
@ -0,0 +1,12 @@
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import localeData from 'dayjs/plugin/localeData';
|
||||||
|
import weekday from 'dayjs/plugin/weekday';
|
||||||
|
|
||||||
|
dayjs.extend(weekday);
|
||||||
|
dayjs.extend(localeData);
|
||||||
|
|
||||||
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
|
export default dayjs;
|
|
@ -0,0 +1,29 @@
|
||||||
|
import type { RouteComponent } from 'vue-router';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 完整子路由的`meta`配置表
|
||||||
|
*/
|
||||||
|
interface CustomizeRouteMeta {
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
transition: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 整体路由配置表(包括完整子路由)
|
||||||
|
*/
|
||||||
|
interface RouteConfigsTable {
|
||||||
|
/** 路由地址 `必填` */
|
||||||
|
path: string;
|
||||||
|
/** 路由名字(保持唯一)`可选` */
|
||||||
|
name?: string;
|
||||||
|
/** `Layout`组件 `可选` */
|
||||||
|
component?: RouteComponent;
|
||||||
|
/** 路由重定向 `可选` */
|
||||||
|
redirect?: string;
|
||||||
|
meta?: CustomizeRouteMeta;
|
||||||
|
/** 子路由配置项 */
|
||||||
|
children?: Array<RouteConfigsTable>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { RouteConfigsTable };
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { useEventListener } from '@vueuse/core';
|
||||||
|
import type { EChartsType } from 'echarts';
|
||||||
|
|
||||||
|
/** 通用重置图表样式 */
|
||||||
|
export const debounceChart = (myChart: EChartsType) => {
|
||||||
|
useEventListener(
|
||||||
|
window,
|
||||||
|
'resize',
|
||||||
|
() => {
|
||||||
|
myChart.resize();
|
||||||
|
},
|
||||||
|
500
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 数字格式化 */
|
||||||
|
export const formatter = (number) => {
|
||||||
|
const numbers = number.toString().split('').reverse();
|
||||||
|
const segs = [];
|
||||||
|
|
||||||
|
while (numbers.length) segs.push(numbers.splice(0, 3).join(''));
|
||||||
|
|
||||||
|
return segs.join(',').split('').reverse().join('');
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* 复制到剪切板
|
||||||
|
* @param text 文本内容
|
||||||
|
*/
|
||||||
|
export const copy = (text: string) => {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = text;
|
||||||
|
textarea.style.position = 'fixed';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const success = document.execCommand('copy');
|
||||||
|
if (success) {
|
||||||
|
(window as any as any).$message.success('复制成功!');
|
||||||
|
} else {
|
||||||
|
(window as any).$message.success('复制失败!');
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
(window as any).$message.success('复制失败!请手动复制');
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
export function downloadTextAsFile(text: string, filename: string) {
|
||||||
|
// 直接创建 File 对象(比 Blob 更高级)
|
||||||
|
const file = new File([text], filename, { type: 'text/plain' });
|
||||||
|
|
||||||
|
// 创建下载链接
|
||||||
|
const url = URL.createObjectURL(file);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = filename;
|
||||||
|
|
||||||
|
// 触发下载
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// 清理
|
||||||
|
requestIdleCallback(() => {
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(a.href);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadBlob = (response: any) => {
|
||||||
|
try {
|
||||||
|
// 从响应头获取文件名
|
||||||
|
const contentDisposition = response.headers['content-disposition'];
|
||||||
|
let fileName = 'download.zip';
|
||||||
|
if (contentDisposition) {
|
||||||
|
const fileNameMatch = contentDisposition.match(/filename="?(.+)"?/);
|
||||||
|
if (fileNameMatch && fileNameMatch[1]) {
|
||||||
|
fileName = fileNameMatch[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = window.URL.createObjectURL(new Blob([response.data]));
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute('download', fileName);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
/** 判断是否是CSS颜色 */
|
||||||
|
function isCSSColor(str) {
|
||||||
|
// 匹配十六进制颜色(如 #fff, #ffffff)
|
||||||
|
const hexColor = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||||
|
|
||||||
|
// 匹配RGB/RGBA颜色(如 rgb(255, 255, 255), rgba(255, 255, 255, 0.5))
|
||||||
|
const rgbColor = /^rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*(,\s*[\d\.]+)?\s*\)$/;
|
||||||
|
|
||||||
|
// 匹配HSL/HSLA颜色(如 hsl(120, 100%, 50%), hsla(120, 100%, 50%, 0.5))
|
||||||
|
const hslColor = /^hsla?\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*(,\s*[\d\.]+)?\s*\)$/;
|
||||||
|
|
||||||
|
// 匹配预定义颜色名称(如 red, blue, green)
|
||||||
|
const namedColor = /^[a-zA-Z]+$/;
|
||||||
|
|
||||||
|
return hexColor.test(str) || rgbColor.test(str) || hslColor.test(str) || namedColor.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 判断是否是相对路径或绝对路径 */
|
||||||
|
function isPath(str) {
|
||||||
|
// 匹配相对路径(如 ./path, ../path, path/to/file)
|
||||||
|
const relativePath = /^\.{0,2}\/[^\/].*$/;
|
||||||
|
|
||||||
|
// 匹配绝对路径(如 /path/to/file, C:\path\to\file)
|
||||||
|
const absolutePath = /^(?:\/|[A-Za-z]:\\).*$/;
|
||||||
|
|
||||||
|
return relativePath.test(str) || absolutePath.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { isCSSColor, isPath };
|
Loading…
Reference in New Issue