From 2a021cbaea3f87f2f413111d258027f4a60c1c23 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 8 Nov 2025 14:22:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=97=A5=E5=BF=97=E7=B3=BB=E7=BB=9Flogger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/utils/logger.ts | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 shared/utils/logger.ts diff --git a/shared/utils/logger.ts b/shared/utils/logger.ts new file mode 100644 index 0000000..c77d169 --- /dev/null +++ b/shared/utils/logger.ts @@ -0,0 +1,110 @@ +/** + * 日志等级枚举 + * + * - `debug` : 开发调试日志(最低) + * - `info` : 普通信息输出 + * - `warn` : 警告信息 + * - `error` : 错误信息(最高级别) + * - `silent` : 屏蔽所有日志 + */ +export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; + +/** + * 每个日志级别的优先级数值 + * 数值越小,级别越低 + */ +const levelPriority: Record = { + debug: 0, + info: 1, + warn: 2, + error: 3, + silent: 4, +}; + +/** + * 检测当前运行环境应使用的日志等级: + * + * - 开发环境:默认 `debug` + * - 生产环境:默认 `warn` + * - 浏览器允许通过 `localStorage.DEBUG = 'true'` 强制开启 `debug` + */ +function detectInitialLevel(): LogLevel { + const isProduction = process.env.NODE_ENV === 'production'; + if (import.meta.client && localStorage.getItem('DEBUG') === 'true') { + return 'debug'; + } + + return isProduction ? 'warn' : 'debug'; +} + +/** + * 核心日志类 + * + * 提供 `debug / info / warn / error` 四个级别 + * 并支持通过 `setLevel` 动态调整输出等级 + * + * @example + * ```ts + * logger.debug('User data:', user) + * logger.error(new Error('Something broke')) + * logger.setLevel('silent') + * ``` + */ +class Logger { + /** 当前日志等级(默认由 detectInitialLevel 判断) */ + private level: LogLevel = detectInitialLevel(); + + /** + * 手动设置日志输出级别 + * + * @param level 目标日志级别 + * + * @example + * ```ts + * logger.setLevel('silent') // 全部禁用 + * logger.setLevel('debug') // 强制打印全部日志 + * ``` + */ + setLevel(newLevel: LogLevel) { + this.level = newLevel; + } + + /** + * 判断当前等级是否允许输出指定日志 + */ + private canLog(level: LogLevel): boolean { + return levelPriority[level] >= levelPriority[this.level]; + } + + /** 输出调试日志(开发阶段使用) */ + debug(...args: unknown[]) { + if (this.canLog('debug')) console.debug('[DEBUG]', ...args); + } + + /** 输出普通信息日志 */ + info(...args: unknown[]) { + if (this.canLog('info')) console.info('[INFO]', ...args); + } + + /** 输出警告日志 */ + warn(...args: unknown[]) { + if (this.canLog('warn')) console.warn('[WARN]', ...args); + } + + /** 输出错误日志 */ + error(...args: unknown[]) { + if (this.canLog('error')) console.error('[ERROR]', ...args); + } +} + +/** + * 默认导出的单例 logger + * + * @example + * ```ts + * import { logger } from '~/utils/logger' + * + * logger.info('App started') + * ``` + */ +export const logger = new Logger(); From 660892f9e733d6e7525556c1c30e688b6a3ef7ca Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 8 Nov 2025 14:40:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E5=B0=86=E5=8E=9F=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=9A=84console=E8=BE=93=E5=87=BA=E6=94=B9=E4=B8=BAlogger?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加eslint,不允许使用console输出 --- app/composables/useMeilisearch.ts | 6 +++--- app/pages/about/index.vue | 2 +- app/pages/index.vue | 2 +- app/pages/products/[...slug].vue | 2 +- app/pages/products/index.vue | 2 +- app/pages/search.vue | 2 +- app/pages/solutions/[...slug].vue | 2 +- app/pages/solutions/index.vue | 2 +- app/pages/support/contact-us.vue | 2 +- app/pages/support/documents.vue | 2 +- app/pages/support/faq.vue | 2 +- eslint.config.mjs | 1 + server/utils/file.ts | 2 +- shared/utils/logger.ts | 2 ++ 14 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/composables/useMeilisearch.ts b/app/composables/useMeilisearch.ts index 05ffae6..ebf62fe 100644 --- a/app/composables/useMeilisearch.ts +++ b/app/composables/useMeilisearch.ts @@ -37,7 +37,7 @@ export const useMeilisearch = () => { const host = runtimeConfig.public?.meili?.host; if (!host) { - console.warn('Meilisearch host is not configured.'); + logger.warn('Meilisearch host is not configured.'); return null; } const apiKey = runtimeConfig.public?.meili?.searchKey; @@ -76,7 +76,7 @@ export const useMeilisearch = () => { const activeIndexes = indexes.value as K[]; if (!activeIndexes.length) { - console.warn('No Meilisearch indexes configured.'); + logger.warn('No Meilisearch indexes configured.'); return []; } const rawIndexMap = Object.fromEntries( @@ -105,7 +105,7 @@ export const useMeilisearch = () => { result.status === 'rejected' ) .forEach((result) => { - console.error('Meilisearch query failed', result.reason); + logger.error('Meilisearch query failed', result.reason); }); return settled diff --git a/app/pages/about/index.vue b/app/pages/about/index.vue index afd6b69..64dd05f 100644 --- a/app/pages/about/index.vue +++ b/app/pages/about/index.vue @@ -38,7 +38,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/index.vue b/app/pages/index.vue index d6556bc..f2eb413 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -23,7 +23,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/products/[...slug].vue b/app/pages/products/[...slug].vue index 0ecfd3a..cca08a3 100644 --- a/app/pages/products/[...slug].vue +++ b/app/pages/products/[...slug].vue @@ -55,7 +55,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/products/index.vue b/app/pages/products/index.vue index bb5aa99..28babe7 100644 --- a/app/pages/products/index.vue +++ b/app/pages/products/index.vue @@ -83,7 +83,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/search.vue b/app/pages/search.vue index f824f41..c29ac62 100644 --- a/app/pages/search.vue +++ b/app/pages/search.vue @@ -86,7 +86,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/solutions/[...slug].vue b/app/pages/solutions/[...slug].vue index cab1949..e3ec505 100644 --- a/app/pages/solutions/[...slug].vue +++ b/app/pages/solutions/[...slug].vue @@ -46,7 +46,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/solutions/index.vue b/app/pages/solutions/index.vue index f060d43..24f293d 100644 --- a/app/pages/solutions/index.vue +++ b/app/pages/solutions/index.vue @@ -83,7 +83,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/support/contact-us.vue b/app/pages/support/contact-us.vue index 1868f63..d6d09e2 100644 --- a/app/pages/support/contact-us.vue +++ b/app/pages/support/contact-us.vue @@ -28,7 +28,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/support/documents.vue b/app/pages/support/documents.vue index e340188..e67f386 100644 --- a/app/pages/support/documents.vue +++ b/app/pages/support/documents.vue @@ -104,7 +104,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/app/pages/support/faq.vue b/app/pages/support/faq.vue index 2c472d8..b47e058 100644 --- a/app/pages/support/faq.vue +++ b/app/pages/support/faq.vue @@ -105,7 +105,7 @@ watch(error, (value) => { if (value) { - console.error('数据获取失败: ', value); + logger.error('数据获取失败: ', value); } }); diff --git a/eslint.config.mjs b/eslint.config.mjs index 410eb6a..35af3ce 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -13,6 +13,7 @@ export default withNuxt( }, }, ], + 'no-console': 'warn', }, } ); diff --git a/server/utils/file.ts b/server/utils/file.ts index 5d4ae83..117d151 100644 --- a/server/utils/file.ts +++ b/server/utils/file.ts @@ -46,7 +46,7 @@ export async function getFileMeta(id: string): Promise { }; } catch (error) { if (error instanceof Error) { - console.error('Error fetching file metadata:', error.message); + logger.error('Error fetching file metadata:', error.message); } return null; } diff --git a/shared/utils/logger.ts b/shared/utils/logger.ts index c77d169..4a6dfd4 100644 --- a/shared/utils/logger.ts +++ b/shared/utils/logger.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-console -- console is allowed inside logger implementation */ + /** * 日志等级枚举 *