feat(utils): 完善工具函数库

- 优化coi.ts工具函数
- 完善消息提示封装
- 改进通用工具方法
- 加强错误处理机制

提供更强大的工具函数支持
This commit is contained in:
Leo 2025-07-06 00:59:50 +08:00
parent e04a756ff1
commit 8eaea603af

View File

@ -1,44 +1,45 @@
// 工具类提示信息 - 统一使用 Naive UI
import { createDiscreteApi, darkTheme, lightTheme } from "naive-ui";
// 工具类提示信息
import { createDiscreteApi, darkTheme, lightTheme } from 'naive-ui'
type MessageType = "info" | "success" | "error" | "warning";
type MessageType = 'info' | 'success' | 'error' | 'warning'
// 缓存 API 实例
let naiveApiCache: any = null;
let currentTheme: "light" | "dark" | null = null;
let naiveApiCache: any = null
let currentTheme: 'light' | 'dark' | null = null
// 检测当前主题
const isDark = (): boolean => {
return document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark";
};
function isDark(): boolean {
return document.documentElement.classList.contains('dark') || document.documentElement.getAttribute('data-theme') === 'dark'
}
// 获取当前主题
const getCurrentTheme = (): "light" | "dark" => {
return isDark() ? "dark" : "light";
};
function getCurrentTheme(): 'light' | 'dark' {
return isDark() ? 'dark' : 'light'
}
// 创建或获取 Naive UI API 实例
const getNaiveApi = () => {
const theme = getCurrentTheme();
function getNaiveApi() {
const theme = getCurrentTheme()
// 如果主题没有变化且已有缓存,直接返回
if (naiveApiCache && currentTheme === theme) {
return naiveApiCache;
return naiveApiCache
}
try {
// 创建完整的 API 实例,包括 message, notification, dialog
const api = createDiscreteApi(["message", "notification", "dialog"], {
const api = createDiscreteApi(['message', 'notification', 'dialog'], {
configProviderProps: {
theme: theme === "dark" ? darkTheme : lightTheme
}
});
theme: theme === 'dark' ? darkTheme : lightTheme,
},
})
naiveApiCache = api;
currentTheme = theme;
return api;
} catch (error) {
console.warn("Failed to create Naive UI API:", error);
naiveApiCache = api
currentTheme = theme
return api
}
catch (error) {
console.warn('Failed to create Naive UI API:', error)
// 返回 fallback 实现,避免应用崩溃
return {
message: {
@ -47,339 +48,348 @@ const getNaiveApi = () => {
warning: console.warn,
error: console.error,
loading: console.log,
destroyAll: () => {}
destroyAll: () => {},
},
notification: {
info: console.info,
success: console.log,
warning: console.warn,
error: console.error,
destroyAll: () => {}
destroyAll: () => {},
},
dialog: {
info: (_options: any) => Promise.resolve(true),
success: (_options: any) => Promise.resolve(true),
warning: (_options: any) => Promise.resolve(true),
error: (_options: any) => Promise.resolve(true),
destroyAll: () => {}
destroyAll: () => {},
},
}
};
}
};
}
// 安全的 API 调用函数
const safeApiCall = (apiType: "message" | "notification" | "dialog", method: string, ...args: any[]) => {
function safeApiCall(apiType: 'message' | 'notification' | 'dialog', method: string, ...args: any[]) {
// 延迟执行函数
const executeCall = () => {
try {
const api = getNaiveApi();
return api[apiType][method](...args);
} catch (error) {
console.warn(`Failed to call ${apiType}.${method}:`, error);
const api = getNaiveApi()
return api[apiType][method](...args)
}
catch (error) {
console.warn(`Failed to call ${apiType}.${method}:`, error)
// fallback 到 console
if (apiType === "message" || apiType === "notification") {
const logMethod = method === "success" ? "log" : method;
if (logMethod === "info" || logMethod === "log" || logMethod === "warn" || logMethod === "error") {
console[logMethod](args[0]);
if (apiType === 'message' || apiType === 'notification') {
const logMethod = method === 'success' ? 'log' : method
if (logMethod === 'info' || logMethod === 'log' || logMethod === 'warn' || logMethod === 'error') {
console[logMethod](args[0])
}
}
return apiType === "dialog" ? Promise.resolve(false) : null;
return apiType === 'dialog' ? Promise.resolve(false) : null
}
}
};
// 如果 document 还未准备好,延迟执行
if (typeof document === "undefined" || document.readyState === "loading") {
if (apiType === "dialog") {
return new Promise(resolve => {
setTimeout(() => resolve(executeCall()), 100);
});
if (typeof document === 'undefined' || document.readyState === 'loading') {
if (apiType === 'dialog') {
return new Promise((resolve) => {
setTimeout(() => resolve(executeCall()), 100)
})
}
setTimeout(executeCall, 100);
return null;
setTimeout(executeCall, 100)
return null
}
return executeCall();
};
return executeCall()
}
/** 封装任意提示类型通知默认info */
export function coiNotice(message: any, title = "温馨提示", duration = 2000, type: MessageType = "info", parseHtml = false) {
const api = getNaiveApi();
api.notification.destroyAll();
export function coiNotice(message: any, title = '温馨提示', duration = 2000, type: MessageType = 'info', parseHtml = false) {
const api = getNaiveApi()
api.notification.destroyAll()
return safeApiCall("notification", type, {
return safeApiCall('notification', type, {
title,
content: message,
duration,
closable: true,
// Naive UI 不支持 dangerouslyUseHTMLString需要处理 HTML
...(parseHtml &&
{
...(parseHtml
&& {
// 如果需要解析HTML可以考虑使用 render 函数或其他方式
}),
})
});
}
/** 封装提示通知默认success */
export function coiNoticeSuccess(
message: any,
title = "温馨提示",
title = '温馨提示',
duration = 2000,
type: MessageType = "success",
parseHtml = false
type: MessageType = 'success',
parseHtml = false,
) {
return coiNotice(message, title, duration, type, parseHtml);
return coiNotice(message, title, duration, type, parseHtml)
}
/** 封装提示通知默认error */
export function coiNoticeError(
message: any,
title = "温馨提示",
title = '温馨提示',
duration = 2000,
type: MessageType = "error",
parseHtml = false
type: MessageType = 'error',
parseHtml = false,
) {
return coiNotice(message, title, duration, type, parseHtml);
return coiNotice(message, title, duration, type, parseHtml)
}
/** 封装提示通知默认warning */
export function coiNoticeWarning(
message: any,
title = "温馨提示",
title = '温馨提示',
duration = 2000,
type: MessageType = "warning",
parseHtml = false
type: MessageType = 'warning',
parseHtml = false,
) {
return coiNotice(message, title, duration, type, parseHtml);
return coiNotice(message, title, duration, type, parseHtml)
}
/** 封装提示通知默认info */
export function coiNoticeInfo(message: any, title = "温馨提示", duration = 2000, type: MessageType = "info", parseHtml = false) {
return coiNotice(message, title, duration, type, parseHtml);
export function coiNoticeInfo(message: any, title = '温馨提示', duration = 2000, type: MessageType = 'info', parseHtml = false) {
return coiNotice(message, title, duration, type, parseHtml)
}
/** 封装提示信息默认info */
export function coiMsg(message: any, _plain = false, duration = 2000, type: MessageType = "info", _parseHtml = false) {
const api = getNaiveApi();
api.message.destroyAll();
export function coiMsg(message: any, _plain = false, duration = 2000, type: MessageType = 'info', _parseHtml = false) {
const api = getNaiveApi()
api.message.destroyAll()
return safeApiCall("message", type, message, {
return safeApiCall('message', type, message, {
duration,
closable: true
});
closable: true,
})
}
/** 封装提示信息默认success */
export function coiMsgSuccess(message: any, _plain = false, duration = 2000, _type: MessageType = "success", _parseHtml = false) {
const api = getNaiveApi();
api.message.destroyAll();
export function coiMsgSuccess(message: any, _plain = false, duration = 2000, _type: MessageType = 'success', _parseHtml = false) {
const api = getNaiveApi()
api.message.destroyAll()
return safeApiCall("message", "success", message, {
return safeApiCall('message', 'success', message, {
duration,
closable: true
});
closable: true,
})
}
/** 封装提示信息默认error */
export function coiMsgError(message: any, _plain = false, duration = 2000, _type: MessageType = "error", _parseHtml = false) {
const api = getNaiveApi();
api.message.destroyAll();
export function coiMsgError(message: any, _plain = false, duration = 2000, _type: MessageType = 'error', _parseHtml = false) {
const api = getNaiveApi()
api.message.destroyAll()
return safeApiCall("message", "error", message, {
return safeApiCall('message', 'error', message, {
duration,
closable: true
});
closable: true,
})
}
/** 封装提示信息默认warning */
export function coiMsgWarning(message: any, _plain = false, duration = 2000, _type: MessageType = "warning", _parseHtml = false) {
const api = getNaiveApi();
api.message.destroyAll();
export function coiMsgWarning(message: any, _plain = false, duration = 2000, _type: MessageType = 'warning', _parseHtml = false) {
const api = getNaiveApi()
api.message.destroyAll()
return safeApiCall("message", "warning", message, {
return safeApiCall('message', 'warning', message, {
duration,
closable: true
});
closable: true,
})
}
/** 封装提示信息默认info */
export function coiMsgInfo(message: any, _plain = false, duration = 2000, _type: MessageType = "info", _parseHtml = false) {
const api = getNaiveApi();
api.message.destroyAll();
export function coiMsgInfo(message: any, _plain = false, duration = 2000, _type: MessageType = 'info', _parseHtml = false) {
const api = getNaiveApi()
api.message.destroyAll()
return safeApiCall("message", "info", message, {
return safeApiCall('message', 'info', message, {
duration,
closable: true
});
closable: true,
})
}
/** 封装确认信息默认warning */
export function coiMsgBox(
message: any = "您确定进行关闭么?",
title: string = "温馨提示:",
confirmButtonText: string = "确定",
cancelButtonText: string = "取消",
type: string = "warning"
message: any = '您确定进行关闭么?',
title: string = '温馨提示:',
confirmButtonText: string = '确定',
cancelButtonText: string = '取消',
type: string = 'warning',
): Promise<boolean> {
return new Promise((resolve, reject) => {
const executeDialog = () => {
try {
const api = getNaiveApi();
const api = getNaiveApi()
api.dialog[type as keyof typeof api.dialog]({
title,
content: message,
positiveText: confirmButtonText,
negativeText: cancelButtonText,
onPositiveClick: () => {
resolve(true);
resolve(true)
},
onNegativeClick: () => {
reject(false);
reject(false)
},
onClose: () => {
reject(false);
reject(false)
},
})
}
catch (error) {
console.warn('Failed to show dialog:', error)
reject(false)
}
});
} catch (error) {
console.warn("Failed to show dialog:", error);
reject(false);
}
};
if (typeof document === "undefined" || document.readyState === "loading") {
setTimeout(executeDialog, 100);
} else {
executeDialog();
if (typeof document === 'undefined' || document.readyState === 'loading') {
setTimeout(executeDialog, 100)
}
});
else {
executeDialog()
}
})
}
/** 封装确认信息默认warning - HTML 版本 */
export function coiMsgBoxHtml(
message: any = `<p style="color: teal">您确定进行关闭么?</p>`,
title: string = "温馨提示:",
confirmButtonText: string = "确定",
cancelButtonText: string = "取消",
type: string = "warning"
title: string = '温馨提示:',
confirmButtonText: string = '确定',
cancelButtonText: string = '取消',
type: string = 'warning',
): Promise<boolean> {
// Naive UI 的 dialog 可以通过 render 函数支持 HTML
// 这里先使用纯文本,如果需要 HTML 可以进一步优化
const textMessage = message.replace(/<[^>]*>/g, ""); // 简单去除HTML标签
return coiMsgBox(textMessage, title, confirmButtonText, cancelButtonText, type);
const textMessage = message.replace(/<[^>]*>/g, '') // 简单去除HTML标签
return coiMsgBox(textMessage, title, confirmButtonText, cancelButtonText, type)
}
/** Prompt 类型的消息框 */
export function coiMsgBoxPrompt(
message: any = "请输入需要修改的数据?",
_title: string = "温馨提示:",
_confirmButtonText: string = "确定",
_cancelButtonText: string = "取消",
_type: string = "info",
_inputPattern: string = "",
_inputErrorMessage: string = "无效输入"
message: any = '请输入需要修改的数据?',
_title: string = '温馨提示:',
_confirmButtonText: string = '确定',
_cancelButtonText: string = '取消',
_type: string = 'info',
_inputPattern: string = '',
_inputErrorMessage: string = '无效输入',
): Promise<any> {
return new Promise((resolve, reject) => {
const executeDialog = () => {
try {
// Naive UI 没有直接的 prompt需要使用自定义 dialog
// 这里先简化实现,返回一个输入的结果
const userInput = prompt(message); // 使用原生 prompt 作为临时方案
const userInput = prompt(message) // 使用原生 prompt 作为临时方案
if (userInput !== null) {
resolve({ value: userInput });
} else {
reject(false);
resolve({ value: userInput })
}
else {
reject(false)
}
}
catch (error) {
console.warn('Failed to show prompt dialog:', error)
reject(false)
}
} catch (error) {
console.warn("Failed to show prompt dialog:", error);
reject(false);
}
};
if (typeof document === "undefined" || document.readyState === "loading") {
setTimeout(executeDialog, 100);
} else {
executeDialog();
if (typeof document === 'undefined' || document.readyState === 'loading') {
setTimeout(executeDialog, 100)
}
});
else {
executeDialog()
}
})
}
/** Alert 类型的消息框 */
export function coiMsgBoxAlert(
message: any = "请输入需要修改的数据?",
title: string = "温馨提示:",
confirmButtonText: string = "确定",
type: string = "info"
message: any = '请输入需要修改的数据?',
title: string = '温馨提示:',
confirmButtonText: string = '确定',
type: string = 'info',
): Promise<boolean> {
return new Promise((resolve, reject) => {
const executeDialog = () => {
try {
const api = getNaiveApi();
const api = getNaiveApi()
api.dialog[type as keyof typeof api.dialog]({
title,
content: message,
positiveText: confirmButtonText,
onPositiveClick: () => {
resolve(true);
resolve(true)
},
onClose: () => {
resolve(true);
resolve(true)
},
})
}
catch (error) {
console.warn('Failed to show alert dialog:', error)
reject(false)
}
});
} catch (error) {
console.warn("Failed to show alert dialog:", error);
reject(false);
}
};
if (typeof document === "undefined" || document.readyState === "loading") {
setTimeout(executeDialog, 100);
} else {
executeDialog();
if (typeof document === 'undefined' || document.readyState === 'loading') {
setTimeout(executeDialog, 100)
}
});
else {
executeDialog()
}
})
}
// 导出 naiveMessage 对象,保持向后兼容
export const naiveMessage = {
info: (content: string, options?: any) => {
return safeApiCall("message", "info", content, {
return safeApiCall('message', 'info', content, {
duration: 3000,
closable: true,
...options
});
...options,
})
},
success: (content: string, options?: any) => {
return safeApiCall("message", "success", content, {
return safeApiCall('message', 'success', content, {
duration: 3000,
closable: true,
...options
});
...options,
})
},
warning: (content: string, options?: any) => {
return safeApiCall("message", "warning", content, {
return safeApiCall('message', 'warning', content, {
duration: 3000,
closable: true,
...options
});
...options,
})
},
error: (content: string, options?: any) => {
return safeApiCall("message", "error", content, {
return safeApiCall('message', 'error', content, {
duration: 3000,
closable: true,
...options
});
...options,
})
},
loading: (content: string, options?: any) => {
return safeApiCall("message", "loading", content, {
return safeApiCall('message', 'loading', content, {
duration: 0, // loading 默认不自动关闭
...options
});
...options,
})
},
destroyAll: () => {
try {
const api = getNaiveApi();
api.message.destroyAll();
} catch (error) {
console.warn("Failed to destroy all messages:", error);
const api = getNaiveApi()
api.message.destroyAll()
}
catch (error) {
console.warn('Failed to destroy all messages:', error)
}
};
},
}