整体优化

This commit is contained in:
2026-08-04 17:33:45 +08:00
parent cadc8885f3
commit 2c69b3f1c3
32 changed files with 2212 additions and 643 deletions
+22 -34
View File
@@ -1,14 +1,15 @@
// 将res的key对应的值复制给dzdata的同名key
/**
* 将源对象res的属性复制到目标对象dzdata
* 将源对象 res 中「目标对象 dzdata 已存在的 key」对应的值复制过去(只覆盖既有键)
* @param {Object} res - 源对象,其属性将被复制。
* @param {Object} dzdata - 目标对象,将接收源对象的属性
* @param {Object} dzdata - 目标对象,仅其已存在的键会被源对象值覆盖
* @example
* ObjectCopy({a: 1, b: 2}, {c: 3}); // dzdata 变为 {a: 1, b: 2, c: 3}
* ObjectCopy({a: 1, b: 2}, {a: 3}); // dzdata 变为 {a: 1}
*/
export function ObjectCopy<T extends Record<string, any>>(res: Partial<T>, dzdata: T): void {
Object.keys(dzdata).forEach(key => {
if (res.hasOwnProperty(key)) {
// 用 Object.prototype.hasOwnProperty 防御 res 为 null 原型对象的情况
if (Object.prototype.hasOwnProperty.call(res, key)) {
(dzdata as Record<string, any>)[key] = res[key];
}
});
@@ -64,30 +65,18 @@ export function formatTime(time: string | number | Date, f: string): string | un
return str;
}
/**
* @description: 补零函数 为时间服务 不足两位的自动在数字前面加上0
* @param {*} n 待补零数字
* @return {*} 补零后数字
*/
function timeAdd0(n: number): string {
return n.toString().padStart(2, "0");
}
export function deepclone<T>(obj: T): T {
if (obj === null || typeof obj !== "object") {
return obj;
}
let newobj: any = obj instanceof Array ? [] : {};
if (window.JSON) {
newobj = JSON.parse(JSON.stringify(obj));
} else {
for (const i in obj) {
newobj[i] = typeof obj[i] === "object" ? deepclone(obj[i]) : obj[i];
}
// 优先使用 structuredClone:支持循环引用、Date/Map/Set,且性能优于 JSON 序列化
if (typeof structuredClone === "function") {
return structuredClone(obj);
}
return newobj as T;
// 降级方案:JSON 序列化(会丢失 undefined/函数/符号,循环引用会抛错)
return JSON.parse(JSON.stringify(obj)) as T;
}
/**
@@ -98,8 +87,8 @@ export function deepclone<T>(obj: T): T {
* @example
* formatTimeBydate(new Date(), 'yyyy-MM-dd HH:mm:ss');
*/
export function formatTimeBydate(this: string, f: string): string | undefined {
return formatTime(this, f);
export function formatTimeBydate(date: string | number | Date, f: string): string | undefined {
return formatTime(date, f);
}
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
@@ -139,18 +128,19 @@ export function throttle<T extends (...args: any[]) => any>(fn: T, delay: number
* @return {*} 返回值
*/
export function getDictValue<T extends Record<string, any>>(dict: T[], ckey: keyof T, cvalue: T[keyof T], rkey: keyof T): T[keyof T] | string {
let result = "";
dict.forEach(item => {
if (item[ckey] === cvalue) {
result = item[rkey];
}
});
return result;
export function getDictValue<T extends Record<string, any>>(dict: T[], ckey: keyof T, cvalue: T[keyof T], rkey: keyof T): T[keyof T] | undefined {
// find 命中即返回,避免 forEach 遍历完整字典;未命中返回 undefined
const item = dict.find(item => item[ckey] === cvalue);
return item ? item[rkey] : undefined;
}
// 分割数组
export function chunkArrayInGroups<T>(arr: T[], size: number): T[][] {
// 防御非法 size<= 0 时 Math.ceil 会产生 InfinityArray.from 将抛 RangeError
if (size < 1) {
console.warn("chunkArrayInGroups: size 必须大于 0,已返回空数组");
return [];
}
return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size));
}
// 重置对象
@@ -159,5 +149,3 @@ export function resetObject<T extends Record<string, any>>(obj: T): void {
(obj as Record<string, any>)[key] = null;
});
}
+8 -20
View File
@@ -25,42 +25,30 @@ request.interceptors.request.use(
} else delete config.headers["Authorization"];
return config;
},
function (error: AxiosError): string {
(error: AxiosError) => {
// 对请求错误做些什么
return error.message || "Request error";
}
return Promise.reject(error);
},
);
// 添加响应拦截器
request.interceptors.response.use(
function (response: AxiosResponse): any {
(response: AxiosResponse): any => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response.data;
},
async function (error: AxiosError): Promise<string> {
(error: AxiosError) => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
console.log("Response error", error);
// 对响应错误做点什么(统一 reject,保证调用方 try/catch 能捕获到错误)
if (error.response?.status === 401) {
window.$msg.warning("无效的token");
cookies.remove("token");
cookies.remove("userinfo");
// window.$modal({
// title: "无效的token",
// content: "token已失效,需要登录,请登录 =>",
// handdleSubmit: () => {
// router.replace("/login");
// },
// });
// router.replace("/login");
return "Unauthorized";
}
return error.message || "Response error";
}
return Promise.reject(error);
},
);
export default request;
+14 -14
View File
@@ -1,15 +1,15 @@
/**
* js 文件下使用这个做类型提示
* @type import('naive-ui').GlobalThemeOverrides
*/
const themeOverrides = {
common: {
primaryColor: '#ec66ab',
primaryColorHover: '#ec66ab',
primaryColorPressed: '#ec66ab',
primaryColorSuppl: '#ec66ab',
},
// ...
}
/**
* js 文件下使用这个做类型提示
* @type import('naive-ui').GlobalThemeOverrides
*/
const themeOverrides = {
common: {
primaryColor: "#ec66ab",
primaryColorHover: "#ec66ab",
primaryColorPressed: "#ec66ab",
primaryColorSuppl: "#ec66ab",
},
// ...
};
export default themeOverrides;
export default themeOverrides;