From 8096228d96f95a3b0aa7458c2cf002608090bd0a Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 5 Apr 2025 00:26:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=9D=E5=AD=98=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - pnpm-lock.yaml | 3 --- src/config/keep | 1 + src/middlewares/keep | 1 + src/types/keep | 1 + 5 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 README.md create mode 100644 src/config/keep create mode 100644 src/middlewares/keep create mode 100644 src/types/keep diff --git a/README.md b/README.md deleted file mode 100644 index 8cb6192..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -晶灵云数据处理中心 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79d89cb..6e1285d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,9 +17,6 @@ importers: express: specifier: ^4.18.0 version: 4.21.2 - mkdirp: - specifier: ^3.0.1 - version: 3.0.1 devDependencies: '@types/express': specifier: ^4.17.0 diff --git a/src/config/keep b/src/config/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/config/keep @@ -0,0 +1 @@ +keep diff --git a/src/middlewares/keep b/src/middlewares/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/middlewares/keep @@ -0,0 +1 @@ +keep diff --git a/src/types/keep b/src/types/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/types/keep @@ -0,0 +1 @@ +keep From 55de8a14bb6dd73bb31df9cc3a88a3fb17cb2cc2 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 5 Apr 2025 01:20:04 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- pnpm-lock.yaml | 3 +++ src/app.ts | 43 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index b00f9c7..fcb657a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "dependencies": { "chalk": "4", "dotenv": "^16.0.0", - "express": "^4.18.0" + "express": "^4.18.0", + "mkdirp": "^3.0.1" }, "devDependencies": { "@types/express": "^4.17.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e1285d..79d89cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: express: specifier: ^4.18.0 version: 4.21.2 + mkdirp: + specifier: ^3.0.1 + version: 3.0.1 devDependencies: '@types/express': specifier: ^4.17.0 diff --git a/src/app.ts b/src/app.ts index 5a00f04..ed9cf9c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,23 +1,48 @@ import express from 'express'; import logger from './utils/logger'; -import fc from './utils/file'; import paths from './utils/path'; import sampleController from './modules/sample/sample.controller'; import imageController from './modules/image/image.controller'; +import config from './utils/config'; +import fc from './utils/file'; const apps = { createApp() { const app = express(); + logger.info('晶灵核心初始化..'); + app.use(express.json()); - app.use('/public', express.static(paths.get('public'))); - logger.debug(`路由/public挂载成功..`); - app.use('/api/sample', sampleController.getRouter()); - logger.debug(`路由/api/sample挂载成功..`); - app.use('/images', imageController.getRouter()); - logger.debug(`路由/images挂载成功..`); - fc.createDir(paths.get('log')); - logger.info('晶灵核心初始化成功!'); + logger.debug('成功加载express.json()中间件'); + + const publicPath = paths.get('public'); + app.use('/public', express.static(publicPath)); + logger.debug(`静态资源路由挂载:/public → ${publicPath}`); + + const modules = [ + { path: '/api/sample', name: '测试模块', controller: sampleController }, + { path: '/images', name: '图像模块', controller: imageController }, + ]; + + modules.forEach((module) => { + app.use(module.path, module.controller.getRouter()); + logger.debug(`模块路由挂载: ${module.path.padEnd(12)} → ${module.name}`); + + if (config.get('DEBUG', false)) { + module.controller.getRouter().stack.forEach((layer) => { + if (layer.route) { + const methods = Object.keys(layer.route) + .map((m) => m.toUpperCase()) + .join(','); + logger.debug(` ↳ ${methods.padEnd(6)} ${module.path}${layer.route.path}`); + } + }); + } + }); + const logPath = paths.get('log'); + fc.createDir(logPath); + logger.debug(`日志目录初始化: ${logPath}`); + logger.info('晶灵核心初始化完毕!'); return app; }, }; From 267f81a008b5676c4fbf1d84f64de3fe6e1e179a Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 6 Apr 2025 02:13:20 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/codeStyles/Project.xml | 62 +++++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/prettier.xml | 8 +++ .idea/webResources.xml | 14 +++++ src/app.ts | 12 ++-- src/main.ts | 2 +- src/modules/image/image.controller.ts | 2 +- src/modules/image/image.service.ts | 4 +- src/modules/monitor/kep | 1 + src/modules/sample/sample.controller.ts | 28 +++------- src/modules/sample/sample.service.ts | 4 +- src/modules/trss/keep | 1 + src/utils/config.ts | 23 -------- src/utils/constants/keep | 1 + src/utils/core/config.ts | 72 ++++++++++++++++++++++++ src/utils/core/date.ts | 74 +++++++++++++++++++++++++ src/utils/{ => core}/file.ts | 19 ++++--- src/utils/core/logger.ts | 68 +++++++++++++++++++++++ src/utils/core/path.ts | 62 +++++++++++++++++++++ src/utils/core/response.ts | 61 ++++++++++++++++++++ src/utils/{ => core}/tool.ts | 0 src/utils/date.ts | 11 ---- src/utils/helpers/keep | 1 + src/utils/index.ts | 0 src/utils/lib/keep | 1 + src/utils/logger.ts | 30 ---------- src/utils/path.ts | 24 -------- 27 files changed, 463 insertions(+), 127 deletions(-) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/prettier.xml create mode 100644 .idea/webResources.xml create mode 100644 src/modules/monitor/kep create mode 100644 src/modules/trss/keep delete mode 100644 src/utils/config.ts create mode 100644 src/utils/constants/keep create mode 100644 src/utils/core/config.ts create mode 100644 src/utils/core/date.ts rename src/utils/{ => core}/file.ts (87%) create mode 100644 src/utils/core/logger.ts create mode 100644 src/utils/core/path.ts create mode 100644 src/utils/core/response.ts rename src/utils/{ => core}/tool.ts (100%) delete mode 100644 src/utils/date.ts create mode 100644 src/utils/helpers/keep create mode 100644 src/utils/index.ts create mode 100644 src/utils/lib/keep delete mode 100644 src/utils/logger.ts delete mode 100644 src/utils/path.ts diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..0af511b --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..ea0f3cf --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/.idea/webResources.xml b/.idea/webResources.xml new file mode 100644 index 0000000..edf30b3 --- /dev/null +++ b/.idea/webResources.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index ed9cf9c..5789f49 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,10 +1,10 @@ import express from 'express'; -import logger from './utils/logger'; -import paths from './utils/path'; +import logger from './utils/core/logger'; +import paths from './utils/core/path'; import sampleController from './modules/sample/sample.controller'; import imageController from './modules/image/image.controller'; -import config from './utils/config'; -import fc from './utils/file'; +import Config from './utils/core/config'; +import fc from './utils/core/file'; const apps = { createApp() { @@ -12,6 +12,8 @@ const apps = { logger.info('晶灵核心初始化..'); + Config.check(['PORT', 'DEBUG']); + app.use(express.json()); logger.debug('成功加载express.json()中间件'); @@ -28,7 +30,7 @@ const apps = { app.use(module.path, module.controller.getRouter()); logger.debug(`模块路由挂载: ${module.path.padEnd(12)} → ${module.name}`); - if (config.get('DEBUG', false)) { + if (Config.get('DEBUG', false)) { module.controller.getRouter().stack.forEach((layer) => { if (layer.route) { const methods = Object.keys(layer.route) diff --git a/src/main.ts b/src/main.ts index 9210984..c41a07c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import apps from './app'; -import logger from './utils/logger'; +import logger from './utils/core/logger'; const PORT = process.env.PORT || 3000; diff --git a/src/modules/image/image.controller.ts b/src/modules/image/image.controller.ts index f594e8c..206984d 100644 --- a/src/modules/image/image.controller.ts +++ b/src/modules/image/image.controller.ts @@ -1,6 +1,6 @@ import express from 'express'; import ImageService from './image.service'; -import logger from '../../utils/logger'; +import logger from '../../utils/core/logger'; class ImageController { private readonly router: express.Router; diff --git a/src/modules/image/image.service.ts b/src/modules/image/image.service.ts index 4d9f0f6..f7a33ac 100644 --- a/src/modules/image/image.service.ts +++ b/src/modules/image/image.service.ts @@ -1,7 +1,7 @@ import path from 'path'; import fs from 'fs'; -import paths from '../../utils/path'; -import logger from '../../utils/logger'; +import paths from '../../utils/core/path'; +import logger from '../../utils/core/logger'; class ImageService { private readonly imageDir: string; diff --git a/src/modules/monitor/kep b/src/modules/monitor/kep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/modules/monitor/kep @@ -0,0 +1 @@ +keep diff --git a/src/modules/sample/sample.controller.ts b/src/modules/sample/sample.controller.ts index ad7f15c..d8741a4 100644 --- a/src/modules/sample/sample.controller.ts +++ b/src/modules/sample/sample.controller.ts @@ -1,5 +1,6 @@ import express from 'express'; import sampleService from './sample.service'; +import response from '../../utils/core/response'; class SampleController { private readonly router: express.Router; @@ -21,37 +22,24 @@ class SampleController { private getHello = (req: express.Request, res: express.Response): void => { try { const result = sampleService.getHello(); - this.sendSuccess(res, result); + response.success(res, result); } catch (error) { - this.sendError(res, error); + response.error(res, '请求失败了..', 500, error); } }; private postGreet = (req: express.Request, res: express.Response): void => { try { const { name } = req.body; + if (!name) { + return response.error(res, '姓名不能为空!', 400); + } const result = sampleService.generateGreeting(name); - this.sendSuccess(res, result); + response.success(res, result); } catch (error) { - this.sendError(res, error); + response.error(res, '请求失败了..', 500, error); } }; - - private sendSuccess(res: express.Response, data: any, statusCode = 200): void { - res.status(statusCode).json({ - success: true, - data, - timestamp: new Date().toISOString(), - }); - } - - private sendError(res: express.Response, error: any, statusCode = 500): void { - res.status(statusCode).json({ - success: false, - message: error.message, - timestamp: new Date().toISOString(), - }); - } } export default new SampleController(); diff --git a/src/modules/sample/sample.service.ts b/src/modules/sample/sample.service.ts index 1b63290..d1b170e 100644 --- a/src/modules/sample/sample.service.ts +++ b/src/modules/sample/sample.service.ts @@ -1,4 +1,4 @@ -import logger from '../../utils/logger'; +import logger from '../../utils/core/logger'; class SampleService { getHello() { @@ -6,7 +6,7 @@ class SampleService { return { message: 'Hello World!' }; } - generateGreeting(name: string) { + generateGreeting(name: string): object { logger.debug(`有个小可爱正在请求generateGreeting方法..`); if (!name) { logger.warn('Name is required'); diff --git a/src/modules/trss/keep b/src/modules/trss/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/modules/trss/keep @@ -0,0 +1 @@ +keep diff --git a/src/utils/config.ts b/src/utils/config.ts deleted file mode 100644 index 1c9a0d5..0000000 --- a/src/utils/config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import dotenv from 'dotenv'; - -dotenv.config(); - -let config = { - get: (key: string, defaultValue: any) => { - const value = process.env[key]; - if (value === undefined) { - if (defaultValue !== undefined) return defaultValue; - throw new Error(`环境变量${key}未定义..`); - } - - if (typeof defaultValue === 'number') return Number(value); - if (typeof defaultValue === 'boolean') return value === 'true'; - return value; - }, - - set: (key: string, value: any) => { - process.env[key] = value; - }, -}; - -export default config; diff --git a/src/utils/constants/keep b/src/utils/constants/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/utils/constants/keep @@ -0,0 +1 @@ +keep diff --git a/src/utils/core/config.ts b/src/utils/core/config.ts new file mode 100644 index 0000000..6e57436 --- /dev/null +++ b/src/utils/core/config.ts @@ -0,0 +1,72 @@ +import dotenv from 'dotenv'; +import logger from './logger'; + +class ConfigManger { + private static instance: ConfigManger; + private env: NodeJS.ProcessEnv; + + private constructor() { + dotenv.config(); + this.env = process.env; + } + + /** + * 获取单例实例 + */ + public static getInstance(): ConfigManger { + if (!ConfigManger.instance) { + ConfigManger.instance = new ConfigManger(); + } + return ConfigManger.instance; + } + + /** + * 获取环境变量(带类型推断) + * @param key 环境变量键名 + * @param defaultValue 默认值(决定返回类型) + */ + public get(key: string, defaultValue?: T): T { + const value = this.env[key]; + if (value === undefined) { + if (defaultValue !== undefined) return defaultValue; + logger.error(`环境变量${key}未定义!`); + return undefined as T; + } + + switch (typeof defaultValue) { + case 'number': + return Number(value) as T; + case 'boolean': + return (value === 'true') as T; + default: + return value as T; + } + } + + /** + * 设置环境变量(运行时有效) + * @param key 键名 + * @param value 值 + */ + public set(key: string, value: string | number | boolean): void { + this.env[key] = String(value); + logger.debug(`成功更改环境变量${key}为${value}!`); + } + + /** + * 检查环境变量是否已加载 + */ + public check(keys: string[]): void { + keys.forEach((key) => { + if (!(key in this.env)) { + logger.error(`必须环境变量缺失:${key}`); + } else { + logger.debug(`检测到环境变量${key}!`); + } + }); + } +} + +const Config = ConfigManger.getInstance(); + +export default Config; diff --git a/src/utils/core/date.ts b/src/utils/core/date.ts new file mode 100644 index 0000000..eab46be --- /dev/null +++ b/src/utils/core/date.ts @@ -0,0 +1,74 @@ +class date { + /** + * 获取当前日期 (格式: YYYYMMDD) + */ + public static getCurrentDate(): string { + const now = new Date(); + return [ + now.getFullYear(), + (now.getMonth() + 1).toString().padStart(2, '0'), + now.getDate().toString().padStart(2, '0'), + ].join(''); + } + + /** + * 获取当前时间 (格式: HH:mm:ss) + */ + public static getCurrentTime(): string { + return new Date().toLocaleTimeString('en-US', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + }); + } + + /** + * 获取格式化日期时间 + * @param formatStr 格式字符串 (YYYY-年, MM-月, DD-日, HH-时, mm-分, ss-秒) + * @example format('YYYY-MM-DD HH:mm:ss') => '2023-10-15 14:30:45' + */ + public static format(formatStr: string = 'YYYY-MM-DD HH:mm:ss'): string { + const now = new Date(); + + const replacements: Record = { + YYYY: now.getFullYear().toString(), + MM: (now.getMonth() + 1).toString().padStart(2, '0'), + DD: now.getDate().toString().padStart(2, '0'), + HH: now.getHours().toString().padStart(2, '0'), + mm: now.getMinutes().toString().padStart(2, '0'), + ss: now.getSeconds().toString().padStart(2, '0'), + }; + + return formatStr.replace(/YYYY|MM|DD|HH|mm|ss/g, (match) => replacements[match]); + } + + /** + * 计算日期差值 + * @param start 开始日期 + * @param end 结束日期 (默认当前时间) + * @param unit 返回单位 ('days' | 'hours' | 'minutes' | 'seconds') + */ + public static diff( + start: Date, + end: Date = new Date(), + unit: 'days' | 'hours' | 'minutes' | 'seconds' = 'days' + ): number { + const msDiff = end.getTime() - start.getTime(); + + switch (unit) { + case 'seconds': + return Math.floor(msDiff / 1000); + case 'minutes': + return Math.floor(msDiff / (1000 * 60)); + case 'hours': + return Math.floor(msDiff / (1000 * 60 * 60)); + case 'days': + return Math.floor(msDiff / (1000 * 60 * 60 * 24)); + default: + return msDiff; + } + } +} + +export default date; diff --git a/src/utils/file.ts b/src/utils/core/file.ts similarity index 87% rename from src/utils/file.ts rename to src/utils/core/file.ts index b9603b1..d45d2f3 100644 --- a/src/utils/file.ts +++ b/src/utils/core/file.ts @@ -1,13 +1,14 @@ import path from 'path'; -import paths from './path'; -import date from './date'; import fs from 'fs'; import chalk from 'chalk'; +import paths from './path'; +import date from './date'; import logger from './logger'; -let fc = { - createDir: (targetPath: string = '', includeFile: boolean = false) => { +class fc { + public static createDir(targetPath: string = '', includeFile: boolean = false): void { const root = paths.get('root'); + if (path.isAbsolute(targetPath)) { if (includeFile) { const parentDir = path.dirname(targetPath); @@ -17,6 +18,7 @@ let fc = { } return; } + if (!fs.existsSync(targetPath)) { fs.mkdirSync(targetPath, { recursive: true }); logger.debug(`成功创建绝对目录: ${targetPath}`); @@ -27,20 +29,21 @@ let fc = { const fullPath = includeFile ? path.join(root, path.dirname(targetPath)) : path.join(root, targetPath); + if (!fs.existsSync(fullPath)) { fs.mkdirSync(fullPath, { recursive: true }); logger.debug(`成功创建相对目录: ${fullPath}`); } - }, + } - logToFile: (level: string, message: string) => { + public static logToFile(level: string, message: string): void { const logFile = path.join(paths.get('log'), `${date.getCurrentDate()}.log`); const logMessage = `[${date.getCurrentTime()}] [${level}] ${message}\n`; fs.appendFile(logFile, logMessage, (err) => { if (err) console.error(chalk.red('[LOGGER] 写入日志失败:'), err); }); - }, -}; + } +} export default fc; diff --git a/src/utils/core/logger.ts b/src/utils/core/logger.ts new file mode 100644 index 0000000..8f5ba23 --- /dev/null +++ b/src/utils/core/logger.ts @@ -0,0 +1,68 @@ +import chalk from 'chalk'; +import Config from './config'; +import fc from './file'; + +class Logger { + private static instance: Logger; + private readonly isDebug: boolean; + + private constructor() { + this.isDebug = Config.get('DEBUG', false); + } + + public static getInstance(): Logger { + if (!Logger.instance) { + Logger.instance = new Logger(); + } + return Logger.instance; + } + + public debug(...args: any[]): void { + if (this.isDebug) { + const message = this.formatMessage('DEBUG', args); + console.log(chalk.cyan(message)); + } + } + + public info(...args: any[]): void { + const message = this.formatMessage('INFO', args); + console.log(chalk.green(message)); + this.logToFile('INFO', message); + } + + public warn(...args: any[]): void { + const message = this.formatMessage('WARN', args); + console.log(chalk.yellow(message)); + this.logToFile('WARN', message); + } + + public error(...args: any[]): void { + const message = this.formatMessage('ERROR', args); + console.error(chalk.red(message)); + this.logToFile('ERROR', message); + } + + public fatal(args: any[], exitCode: number = 1): never { + const message = this.formatMessage('FATAL', args); + console.error(chalk.red.bold(message)); + this.logToFile('FATAL', message); + process.exit(exitCode); + } + + private formatMessage(level: string, args: any[]): string { + return `[${level}] ${args + .map((arg) => (typeof arg === 'object' ? JSON.stringify(arg) : arg)) + .join(' ')}`; + } + + private logToFile(level: string, message: string): void { + try { + fc.logToFile(level, `${new Date().toISOString()} ${message}`); + } catch (err: any) { + console.error(chalk.red(`[LOGGER] 写入日志失败: ${err.message}`)); + } + } +} + +const logger = Logger.getInstance(); +export default logger; diff --git a/src/utils/core/path.ts b/src/utils/core/path.ts new file mode 100644 index 0000000..4b7dcd2 --- /dev/null +++ b/src/utils/core/path.ts @@ -0,0 +1,62 @@ +import path from 'path'; +import fs from 'fs'; + +class PathManager { + private static instance: PathManager; + private readonly baseDir: string; + + private constructor() { + this.baseDir = path.join(__dirname, '../..'); + } + + /** + * 获取单例实例 + */ + public static getInstance(): PathManager { + if (!PathManager.instance) { + PathManager.instance = new PathManager(); + } + return PathManager.instance; + } + + /** + * 获取预定义路径 + * @param type 路径类型 + */ + public get(type?: PathType): string { + const mappings: Record = { + root: this.baseDir, + public: path.join(this.baseDir, 'public'), + images: path.join(this.baseDir, 'public/images'), + log: path.join(this.baseDir, 'logs'), + config: path.join(this.baseDir, 'config'), + temp: path.join(this.baseDir, 'temp'), + }; + + return type ? mappings[type] : this.baseDir; + } + + /** + * 解析相对路径(基于项目根目录) + * @param segments 路径片段 + */ + public resolve(...segments: string[]): string { + return path.join(this.baseDir, ...segments); + } + + /** + * 检查路径是否存在(同步) + */ + public existsSync(targetPath: string): boolean { + try { + return fs.existsSync(targetPath); + } catch { + return false; + } + } +} + +type PathType = 'root' | 'public' | 'images' | 'log' | 'config' | 'temp'; + +const paths = PathManager.getInstance(); +export default paths; diff --git a/src/utils/core/response.ts b/src/utils/core/response.ts new file mode 100644 index 0000000..70e128b --- /dev/null +++ b/src/utils/core/response.ts @@ -0,0 +1,61 @@ +import { Response } from 'express'; +import logger from './logger'; + +class response { + /** + * 成功响应 + * @param res Express响应对象 + * @param data 返回数据 + * @param statusCode HTTP状态码,默认200 + */ + static success(res: Response, data: any, statusCode = 200) { + res.status(statusCode).json({ + success: true, + data, + timestamp: new Date().toISOString(), + }); + } + + /** + * 错误响应 + * @param res Express响应对象 + * @param message 错误信息 + * @param statusCode HTTP状态码,默认500 + * @param error 原始错误对象(开发环境显示) + */ + static error(res: Response, message: string, statusCode = 500, error?: any) { + const response: Record = { + success: false, + message, + timestamp: new Date().toISOString(), + }; + + logger.debug(error instanceof Error ? error.stack : error); + + res.status(statusCode).json(response); + } + + /** + * 分页数据响应 + * @param res Express响应对象 + * @param data 数据数组 + * @param total 总条数 + * @param page 当前页码 + * @param pageSize 每页条数 + */ + static pagination(res: Response, data: any[], total: number, page: number, pageSize: number) { + res.status(200).json({ + success: true, + data, + pagination: { + total, + page, + pageSize, + totalPages: Math.ceil(total / pageSize), + }, + timestamp: new Date().toISOString(), + }); + } +} + +export default response; diff --git a/src/utils/tool.ts b/src/utils/core/tool.ts similarity index 100% rename from src/utils/tool.ts rename to src/utils/core/tool.ts diff --git a/src/utils/date.ts b/src/utils/date.ts deleted file mode 100644 index 6d1d100..0000000 --- a/src/utils/date.ts +++ /dev/null @@ -1,11 +0,0 @@ -let date = { - getCurrentDate: () => { - const now = new Date(); - return `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}`; - }, - getCurrentTime: () => { - return new Date().toLocaleTimeString('en-US', { hour12: false }); - }, -}; - -export default date; diff --git a/src/utils/helpers/keep b/src/utils/helpers/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/utils/helpers/keep @@ -0,0 +1 @@ +keep diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/lib/keep b/src/utils/lib/keep new file mode 100644 index 0000000..2fa992c --- /dev/null +++ b/src/utils/lib/keep @@ -0,0 +1 @@ +keep diff --git a/src/utils/logger.ts b/src/utils/logger.ts deleted file mode 100644 index 4f0be5f..0000000 --- a/src/utils/logger.ts +++ /dev/null @@ -1,30 +0,0 @@ -import chalk from 'chalk'; -import config from './config'; -import fc from './file'; - -const logger = { - debug: (...args: any[]) => { - if (config.get('DEBUG', false)) { - //const message = args.join(' '); - console.log(chalk.cyan('[DEBUG]'), ...args); - //fc.logToFile('DEBUG', message); - } - }, - info: (...args: any[]) => { - const message = args.join(' '); - console.log(chalk.green('[INFO]'), ...args); - fc.logToFile('INFO', message); - }, - warn: (...args: any[]) => { - const message = args.join(' '); - console.log(chalk.yellow('[WARN]'), ...args); - fc.logToFile('WARN', message); - }, - error: (...args: any[]) => { - const message = args.join(' '); - console.log(chalk.red('[ERROR]'), ...args); - fc.logToFile('ERROR', message); - }, -}; - -export default logger; diff --git a/src/utils/path.ts b/src/utils/path.ts deleted file mode 100644 index a84feaa..0000000 --- a/src/utils/path.ts +++ /dev/null @@ -1,24 +0,0 @@ -import path from 'path'; - -const paths = { - get: (value?: string) => { - switch (value) { - case 'root': - return path.join(__dirname, '..'); - case 'public': - return path.join(__dirname, '../public'); - case 'images': - return path.join(__dirname, '../../public/images/'); - case 'log': - return path.join(__dirname, '../../logs'); - default: - return path.join(__dirname, '..'); - } - }, - - resolve: (segments: string) => { - return path.join(__dirname, segments); - }, -}; - -export default paths;