# 后端架构 > **入口**: [_index.md](_index.md) --- ## 1. 技术栈 | 技术 | 版本 | 用途 | |------|------|------| | Node.js | 18.x | 运行时 | | Express | 4.x | Web框架 | | TypeScript | 5.x | 类型系统 | | Knex.js | 3.x | 数据库ORM | | Redis | 6.x | 缓存/队列 | | BullMQ | 4.x | 任务队列 | --- ## 2. 目录结构 ``` server/src/ ├── api/ # API层 │ ├── routes/ # 路由定义 │ ├── controllers/ # 控制器 │ └── middlewares/ # 中间件 ├── services/ # 服务层 │ ├── ProductService.ts │ ├── OrderService.ts │ └── ... ├── models/ # 数据模型 ├── repositories/ # 数据访问层 ├── core/ # 核心模块 │ ├── connectors/ # 平台连接器 │ └── orchestrator/ # 编排器 ├── utils/ # 工具函数 ├── types/ # 类型定义 └── config/ # 配置文件 ``` --- ## 3. 分层架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ API层 (Controller) │ │ - 请求处理 │ │ - 参数校验 │ │ - 权限检查 │ └─────────────────────────┬───────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 服务层 (Service) │ │ - 业务逻辑 │ │ - 事务管理 │ │ - 状态流转 │ └─────────────────────────┬───────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 数据访问层 (Repository) │ │ - 数据库操作 │ │ - 缓存操作 │ │ - 外部API调用 │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 4. 服务层设计 ### 4.1 服务模板 ```typescript /** * [BE-P001] 商品服务 * @description 商品主数据管理 */ export class ProductService { private static TABLE_NAME = 'cf_product'; static async list(params: ListParams): Promise { const query = db(this.TABLE_NAME) .where('tenant_id', params.tenantId); if (params.status) { query.where('status', params.status); } return query; } static async get(id: string): Promise { return db(this.TABLE_NAME).where({ id }).first(); } static async create(data: CreateProductRequest): Promise { const [product] = await db(this.TABLE_NAME) .insert({ ...data, id: generateId(), created_at: new Date(), updated_at: new Date(), }) .returning('*'); return product; } static async update(id: string, data: UpdateProductRequest): Promise { const [product] = await db(this.TABLE_NAME) .where({ id }) .update({ ...data, updated_at: new Date(), }) .returning('*'); return product; } } ``` ### 4.2 服务命名规范 | 后缀 | 说明 | 示例 | |------|------|------| | Service | 业务服务 | ProductService | | Repository | 数据访问 | ProductRepository | | Connector | 平台连接 | ShopifyConnector | | Orchestrator | 编排器 | PublishOrchestrator | --- ## 5. 中间件 ### 5.1 权限中间件 ```typescript export const authorize = (permission: string) => { return async (ctx: Context, next: Next) => { const { user } = ctx.state; if (!user) { throw new UnauthorizedError('未登录'); } const hasPermission = await checkPermission(user, permission); if (!hasPermission) { throw new ForbiddenError('无权限'); } await next(); }; }; ``` ### 5.2 使用方式 ```typescript router.get( '/api/v1/products', authorize('product:read'), ProductController.list ); ``` --- ## 6. 任务队列 ### 6.1 队列定义 ```typescript import { Queue, Worker } from 'bullmq'; export const collectionQueue = new Queue('collection', { connection: redis, }); export const collectionWorker = new Worker( 'collection', async (job) => { const { platform, shopId, type } = job.data; // 执行采集任务 const result = await CollectionAdapterService.executeCollectionTask( platform, shopId, type ); return result; }, { connection: redis, concurrency: 10 } ); ``` ### 6.2 任务添加 ```typescript await collectionQueue.add('collect-products', { platform: 'SHOPIFY', shopId: 'shop-001', type: 'product', }); ``` --- ## 7. 错误处理 ### 7.1 错误类型 ```typescript export class AppError extends Error { constructor( public code: string, public message: string, public statusCode: number = 500 ) { super(message); } } export class ValidationError extends AppError { constructor(message: string) { super('VAL_INVALID_PARAM', message, 400); } } export class UnauthorizedError extends AppError { constructor(message: string) { super('AUTH_UNAUTHORIZED', message, 401); } } export class ForbiddenError extends AppError { constructor(message: string) { super('AUTH_FORBIDDEN', message, 403); } } export class NotFoundError extends AppError { constructor(message: string) { super('BIZ_NOT_FOUND', message, 404); } } ``` ### 7.2 错误处理中间件 ```typescript export const errorHandler = async (ctx: Context, next: Next) => { try { await next(); } catch (error) { if (error instanceof AppError) { ctx.status = error.statusCode; ctx.body = { success: false, error: { code: error.code, message: error.message, }, }; } else { ctx.status = 500; ctx.body = { success: false, error: { code: 'SYS_INTERNAL_ERROR', message: '内部服务器错误', }, }; } } }; ``` --- *最后更新: 2026-03-22*