934 lines
25 KiB
Markdown
934 lines
25 KiB
Markdown
|
|
# JS+JS 全栈架构技术方案 (V2.0)
|
|||
|
|
|
|||
|
|
> **版本**:V2.0
|
|||
|
|
> **更新日期**:2026-03-15
|
|||
|
|
> **状态**:优化版
|
|||
|
|
|
|||
|
|
## 1. 概述
|
|||
|
|
|
|||
|
|
本文档为 Crawlful Hub 项目提供完整的 JavaScript 全栈技术架构方案,涵盖前端框架选型、后端技术栈、数据库设计、API 规范、开发流程及部署策略。本方案基于项目现有技术基底(UmiJS + Node.js + MySQL + TypeScript),进行系统性技术升级与规范化。
|
|||
|
|
|
|||
|
|
### 1.1 架构目标
|
|||
|
|
|
|||
|
|
- **技术统一**:前后端均采用 JavaScript/TypeScript,实现代码复用与团队技能统一
|
|||
|
|
- **开发效率**:提升前后端协作效率,减少技术栈切换成本
|
|||
|
|
- **可维护性**:建立清晰的代码分层与模块化架构
|
|||
|
|
- **性能优化**:构建高性能、高可用的企业级应用
|
|||
|
|
- **务实可靠**:去除 AI 概念,采用成熟稳定的规则引擎方案
|
|||
|
|
|
|||
|
|
### 1.2 方案边界
|
|||
|
|
|
|||
|
|
本方案适用于以下业务场景:
|
|||
|
|
|
|||
|
|
- 电商中台前端控制台(Console)开发
|
|||
|
|
- 后端 RESTful API 服务
|
|||
|
|
- 实时数据交互与状态管理
|
|||
|
|
- 多租户 SaaS 平台架构
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 可行性分析
|
|||
|
|
|
|||
|
|
### 2.1 技术可行性评估
|
|||
|
|
|
|||
|
|
#### 2.1.1 运行时环境
|
|||
|
|
|
|||
|
|
| 技术组件 | 版本要求 | 状态 |
|
|||
|
|
|---------|---------|------|
|
|||
|
|
| Node.js | >= 20.x LTS | 现有技术栈 |
|
|||
|
|
| npm / yarn | >= 9.x | 现有技术栈 |
|
|||
|
|
| TypeScript | >= 5.x | 现有技术栈 |
|
|||
|
|
| MySQL | 8.0+ | 现有技术栈 |
|
|||
|
|
| Redis | 6.0+ | 现有技术栈 |
|
|||
|
|
|
|||
|
|
**结论**:项目基础设施已具备 JS+JS 全栈开发条件,无需额外环境搭建。
|
|||
|
|
|
|||
|
|
#### 2.1.2 团队能力矩阵
|
|||
|
|
|
|||
|
|
| 角色 | 当前技能 | 全栈扩展成本 |
|
|||
|
|
|-----|---------|-------------|
|
|||
|
|
| 前端开发 | React/Vue/UmiJS | 低(框架同源) |
|
|||
|
|
| 后端开发 | Node.js/Express/Koa | 低(语言统一) |
|
|||
|
|
| 全栈工程师 | 兼前端+后端 | 极低(技术同源) |
|
|||
|
|
|
|||
|
|
**结论**:TypeScript 作为粘合语言,可实现前后端代码无缝衔接,团队学习成本可控。
|
|||
|
|
|
|||
|
|
### 2.2 业务可行性评估
|
|||
|
|
|
|||
|
|
#### 2.2.1 业务复杂度适配
|
|||
|
|
|
|||
|
|
| 业务模块 | 复杂度 | 技术方案 |
|
|||
|
|
|---------|-------|---------|
|
|||
|
|
| 订单管理 | 高 | Node.js + MySQL 事务 |
|
|||
|
|
| 实时爬虫 | 中高 | Node.js 异步流处理 |
|
|||
|
|
| 数据分析 | 中 | Node.js + Redis 缓存 |
|
|||
|
|
| 规则引擎 | 高 | Node.js + 业务规则库 |
|
|||
|
|
|
|||
|
|
**结论**:Node.js 单线程模型适用于 IO 密集型业务,配合 Worker Threads 可处理 CPU 密集型任务。
|
|||
|
|
|
|||
|
|
### 2.3 风险预判
|
|||
|
|
|
|||
|
|
| 风险项 | 等级 | 缓解措施 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 后端单线程性能瓶颈 | 中 | 集群模式 + 负载均衡 |
|
|||
|
|
| 前后端代码耦合 | 低 | 明确分层架构 + Monorepo 管理 |
|
|||
|
|
| TypeScript 类型扩散 | 中 | 统一 shared types 包 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 技术选型标准
|
|||
|
|
|
|||
|
|
### 3.1 选型原则
|
|||
|
|
|
|||
|
|
#### 3.1.1 核心选型标准
|
|||
|
|
|
|||
|
|
1. **成熟度优先**:选择社区活跃、文档完善的稳定版本
|
|||
|
|
2. **生态兼容**:优先选择与现有技术栈兼容的方案
|
|||
|
|
3. **性能优先**:针对关键路径进行性能基准测试
|
|||
|
|
4. **维护可持续**:评估维护周期与社区活跃度
|
|||
|
|
5. **务实可靠**:优先选择经过大规模验证的方案
|
|||
|
|
|
|||
|
|
#### 3.1.2 技术债务控制
|
|||
|
|
|
|||
|
|
- 禁止引入已停止维护超过 12 个月的开源库
|
|||
|
|
- 核心依赖需有企业级支持或活跃社区
|
|||
|
|
- 定期进行依赖安全审计
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 前端框架选型
|
|||
|
|
|
|||
|
|
### 4.1 候选方案对比
|
|||
|
|
|
|||
|
|
| 维度 | React | Vue 3 | Angular | UmiJS(现有) |
|
|||
|
|
|-----|-------|-------|---------|--------------|
|
|||
|
|
| 社区活跃度 | 极高 | 高 | 中 | 中 |
|
|||
|
|
| 学习曲线 | 中 | 低 | 高 | 中 |
|
|||
|
|
| TypeScript 支持 | 原生 | 原生 | 原生 | 优秀 |
|
|||
|
|
| 生态丰富度 | 丰富 | 较丰富 | 完整 | 依赖 Ant Design |
|
|||
|
|
| 企业级组件 | Ant Design | Element Plus | Angular Material | Ant Design 5.x |
|
|||
|
|
| 与现有项目兼容 | 需重构 | 需重构 | 需重构 | 现有方案 |
|
|||
|
|
|
|||
|
|
### 4.2 推荐方案:保持 UmiJS 4.x
|
|||
|
|
|
|||
|
|
#### 4.2.1 选型理由
|
|||
|
|
|
|||
|
|
1. **项目延续性**:UmiJS 4.x 已是项目现有技术栈,降低迁移风险
|
|||
|
|
2. **Ant Design 深度集成**:与现有 UI 组件库完美兼容
|
|||
|
|
3. **企业级特性**:内置权限、国际化、路由、状态管理
|
|||
|
|
4. **TypeScript 优先**:开箱即用的 TS 支持
|
|||
|
|
|
|||
|
|
#### 4.2.2 升级路径
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
UmiJS 3.x -> UmiJS 4.x -> UmiJS 5.x (预览版)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 前端技术栈清单
|
|||
|
|
|
|||
|
|
| 层级 | 技术方案 | 版本要求 | 说明 |
|
|||
|
|
|-----|---------|---------|------|
|
|||
|
|
| 框架 | UmiJS | 4.x | 现有方案 |
|
|||
|
|
| UI 组件库 | Ant Design | 5.x | 企业级组件 |
|
|||
|
|
| 状态管理 | **Zustand** | >= 4.x | 替代 Valtio,更主流 |
|
|||
|
|
| 服务端状态 | **TanStack Query** | >= 5.x | 替代 Umi Model |
|
|||
|
|
| HTTP 客户端 | Axios / Umirequest | >= 1.x | 现有方案 |
|
|||
|
|
| 表单管理 | **React Hook Form + Zod** | 最新 | 替代 ProForm |
|
|||
|
|
| 可视化 | AntV G2 / G6 | >= 5.x | 现有方案 |
|
|||
|
|
| 构建工具 | Vite(UmiJS 内置) | 内置 | 现有方案 |
|
|||
|
|
| 代码规范 | ESLint + Prettier | 团队统一 | 现有方案 |
|
|||
|
|
|
|||
|
|
### 4.4 前端架构设计
|
|||
|
|
|
|||
|
|
#### 4.4.1 目录结构规范
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/
|
|||
|
|
├── components/ # 公共组件
|
|||
|
|
│ ├── Business/ # 业务组件
|
|||
|
|
│ └── Basic/ # 基础组件
|
|||
|
|
├── pages/ # 页面组件
|
|||
|
|
├── stores/ # Zustand 状态管理
|
|||
|
|
├── services/ # API 服务层 (TanStack Query)
|
|||
|
|
├── utils/ # 工具函数
|
|||
|
|
├── hooks/ # 自定义 Hooks
|
|||
|
|
├── types/ # TypeScript 类型定义
|
|||
|
|
└── assets/ # 静态资源
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4.4.2 状态管理策略
|
|||
|
|
|
|||
|
|
| 状态类型 | 管理方案 | 适用场景 |
|
|||
|
|
|---------|---------|---------|
|
|||
|
|
| 全局状态 | **Zustand** | 用户信息、租户配置 |
|
|||
|
|
| 页面状态 | **React Hook Form** | 表单数据 |
|
|||
|
|
| 服务端状态 | **TanStack Query** | API 数据缓存、同步 |
|
|||
|
|
| 表单验证 | **Zod** | 复杂表单验证 |
|
|||
|
|
|
|||
|
|
#### 4.4.3 Zustand 使用示例
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// stores/orderStore.ts
|
|||
|
|
import { create } from 'zustand';
|
|||
|
|
import { Order, OrderQueryParams } from '@/types/order';
|
|||
|
|
|
|||
|
|
interface OrderState {
|
|||
|
|
orders: Order[];
|
|||
|
|
selectedOrder: Order | null;
|
|||
|
|
queryParams: OrderQueryParams;
|
|||
|
|
setOrders: (orders: Order[]) => void;
|
|||
|
|
setSelectedOrder: (order: Order | null) => void;
|
|||
|
|
setQueryParams: (params: OrderQueryParams) => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export const useOrderStore = create<OrderState>((set) => ({
|
|||
|
|
orders: [],
|
|||
|
|
selectedOrder: null,
|
|||
|
|
queryParams: {},
|
|||
|
|
setOrders: (orders) => set({ orders }),
|
|||
|
|
setSelectedOrder: (order) => set({ selectedOrder: order }),
|
|||
|
|
setQueryParams: (params) => set({ queryParams: params }),
|
|||
|
|
}));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4.4.4 TanStack Query 使用示例
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// services/orderService.ts
|
|||
|
|
import { request } from 'umi';
|
|||
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|||
|
|
import { Order, CreateOrderDTO } from '@/types/order';
|
|||
|
|
|
|||
|
|
export const useOrders = (params: OrderQueryParams) => {
|
|||
|
|
return useQuery({
|
|||
|
|
queryKey: ['orders', params],
|
|||
|
|
queryFn: () => request<Order[]>('/api/v1/orders', { params }),
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const useCreateOrder = () => {
|
|||
|
|
const queryClient = useQueryClient();
|
|||
|
|
return useMutation({
|
|||
|
|
mutationFn: (data: CreateOrderDTO) =>
|
|||
|
|
request<Order>('/api/v1/orders', { method: 'POST', data }),
|
|||
|
|
onSuccess: () => {
|
|||
|
|
queryClient.invalidateQueries({ queryKey: ['orders'] });
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 后端技术栈
|
|||
|
|
|
|||
|
|
### 5.1 框架选型对比
|
|||
|
|
|
|||
|
|
| 框架 | Express | Koa2 | NestJS | Fastify |
|
|||
|
|
|-----|---------|------|--------|---------|
|
|||
|
|
| 架构风格 | 简约 | 中间件 | 模块化 | 极致性能 |
|
|||
|
|
| TypeScript 支持 | 需配置 | 需配置 | 原生 | 优秀 |
|
|||
|
|
| 装饰器支持 | 否 | 否 | 是 | 是 |
|
|||
|
|
| 生态成熟度 | 极高 | 高 | 高 | 中高 |
|
|||
|
|
| 学习成本 | 低 | 低 | 中 | 中 |
|
|||
|
|
| 性能 | 中 | 中 | 中高 | 极高 |
|
|||
|
|
|
|||
|
|
### 5.2 推荐方案:NestJS
|
|||
|
|
|
|||
|
|
#### 5.2.1 选型理由
|
|||
|
|
|
|||
|
|
1. **企业级架构**:模块化、装饰器、依赖注入,与 Spring Boot 理念相似
|
|||
|
|
2. **TypeScript 优先**:原生支持 TypeScript,类型安全
|
|||
|
|
3. **生态系统丰富**:微服务、GraphQL、WebSocket、任务队列
|
|||
|
|
4. **可测试性**:内置单元测试、E2E 测试框架
|
|||
|
|
|
|||
|
|
#### 5.2.2 架构对齐
|
|||
|
|
|
|||
|
|
项目现有后端采用 `core/domains/workers/api/shared` 分层结构,NestJS 模块系统可完美映射:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/
|
|||
|
|
├── core/ # NestJS Core (Guard, Interceptor, Pipe)
|
|||
|
|
├── modules/ # 业务模块 (对应 domains)
|
|||
|
|
│ ├── order/
|
|||
|
|
│ ├── product/
|
|||
|
|
│ ├── finance/
|
|||
|
|
│ └── trade/
|
|||
|
|
├── api/ # Controller 层
|
|||
|
|
├── workers/ # Background Jobs
|
|||
|
|
└── shared/ # Shared 模块 (DTO, Entities, Utils)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 后端技术栈清单
|
|||
|
|
|
|||
|
|
| 层级 | 技术方案 | 版本要求 | 说明 |
|
|||
|
|
|-----|---------|---------|------|
|
|||
|
|
| 运行时 | Node.js | 20.x LTS | 现有 |
|
|||
|
|
| 框架 | NestJS | 10.x | 企业级框架 |
|
|||
|
|
| 语言 | TypeScript | 5.x (strict) | 严格模式 |
|
|||
|
|
| ORM | **Prisma** | >= 5.x | 替代 Knex/TypeORM |
|
|||
|
|
| 数据库 | MySQL | 8.0 | 现有 |
|
|||
|
|
| 缓存 | Redis | 6.0+ | 现有 |
|
|||
|
|
| 消息队列 | BullMQ | 最新 | 现有 |
|
|||
|
|
| 验证 | class-validator + Zod | 最新 | 增强验证 |
|
|||
|
|
| 文档 | Swagger / OpenAPI | @nestjs/swagger | 现有 |
|
|||
|
|
|
|||
|
|
### 5.4 ORM 选型:Prisma
|
|||
|
|
|
|||
|
|
#### 5.4.1 为什么选择 Prisma
|
|||
|
|
|
|||
|
|
| 特性 | Prisma | TypeORM | Knex.js |
|
|||
|
|
|-----|--------|---------|---------|
|
|||
|
|
| TypeScript 支持 | 原生 | 好 | 需类型定义 |
|
|||
|
|
| 迁移体验 | 优秀 | 一般 | 一般 |
|
|||
|
|
| 查询构建 | Prisma Client | Entity | Query Builder |
|
|||
|
|
| 性能 | 高 | 中 | 高 |
|
|||
|
|
| 学习曲线 | 低 | 中 | 中高 |
|
|||
|
|
| 开发者体验 | 优秀 | 一般 | 一般 |
|
|||
|
|
|
|||
|
|
#### 5.4.2 Prisma Schema 示例
|
|||
|
|
|
|||
|
|
```prisma
|
|||
|
|
// schema.prisma
|
|||
|
|
generator client {
|
|||
|
|
provider = "prisma-client-js"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
datasource db {
|
|||
|
|
provider = "mysql"
|
|||
|
|
url = env("DATABASE_URL")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model Order {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
orderNo String @unique
|
|||
|
|
status OrderStatus @default(PENDING)
|
|||
|
|
totalAmount Decimal @db.Decimal(10, 2)
|
|||
|
|
tenantId String
|
|||
|
|
shopId String
|
|||
|
|
items OrderItem[]
|
|||
|
|
createdAt DateTime @default(now())
|
|||
|
|
updatedAt DateTime @updatedAt
|
|||
|
|
|
|||
|
|
@@index([tenantId, shopId])
|
|||
|
|
@@index([status])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model OrderItem {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
orderId String
|
|||
|
|
order Order @relation(fields: [orderId], references: [id])
|
|||
|
|
productId String
|
|||
|
|
quantity Int
|
|||
|
|
price Decimal @db.Decimal(10, 2)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.5 数据库设计
|
|||
|
|
|
|||
|
|
#### 5.5.1 关系型数据库:MySQL 8.0
|
|||
|
|
|
|||
|
|
| 表分类 | 命名规范 | 示例 |
|
|||
|
|
|-------|---------|-----|
|
|||
|
|
| 核心业务表 | cf_前缀 | cf_order, cf_product |
|
|||
|
|
| 租户隔离表 | cf_tenant_ | cf_tenant_config |
|
|||
|
|
| 日志审计表 | cf_log_ | cf_log_operation |
|
|||
|
|
|
|||
|
|
#### 5.5.2 数据库设计原则
|
|||
|
|
|
|||
|
|
1. **命名规范**:小写字母 + 下划线
|
|||
|
|
2. **主键策略**:使用 UUID 或雪花 ID
|
|||
|
|
3. **时间戳**:created_at, updated_at 字段必填
|
|||
|
|
4. **软删除**:使用 is_deleted 字段标记
|
|||
|
|
5. **索引优化**:高频查询字段添加索引
|
|||
|
|
|
|||
|
|
#### 5.5.3 非必要场景
|
|||
|
|
|
|||
|
|
| 场景 | 推荐方案 |
|
|||
|
|
|-----|---------|
|
|||
|
|
| 简单配置存储 | MySQL JSON 字段 |
|
|||
|
|
| 会话缓存 | Redis |
|
|||
|
|
| 实时计数器 | Redis INCR |
|
|||
|
|
| 大文件存储 | 对象存储(OSS/MinIO) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. API 设计规范
|
|||
|
|
|
|||
|
|
### 6.1 RESTful API 标准
|
|||
|
|
|
|||
|
|
#### 6.1.1 路由设计
|
|||
|
|
|
|||
|
|
| 方法 | 用途 | 示例 |
|
|||
|
|
|-----|-----|-----|
|
|||
|
|
| GET | 查询 | GET /api/v1/orders |
|
|||
|
|
| POST | 创建 | POST /api/v1/orders |
|
|||
|
|
| PUT | 完整更新 | PUT /api/v1/orders/:id |
|
|||
|
|
| PATCH | 部分更新 | PATCH /api/v1/orders/:id |
|
|||
|
|
| DELETE | 删除 | DELETE /api/v1/orders/:id |
|
|||
|
|
|
|||
|
|
#### 6.1.2 响应结构
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 成功响应
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"data": {
|
|||
|
|
"id": "uuid",
|
|||
|
|
"status": "PENDING"
|
|||
|
|
},
|
|||
|
|
"pagination": {
|
|||
|
|
"page": 1,
|
|||
|
|
"pageSize": 20,
|
|||
|
|
"total": 100
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 错误响应
|
|||
|
|
{
|
|||
|
|
"success": false,
|
|||
|
|
"error": {
|
|||
|
|
"code": "ORDER_NOT_FOUND",
|
|||
|
|
"message": "订单不存在",
|
|||
|
|
"details": {}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 错误码规范
|
|||
|
|
|
|||
|
|
| 错误类别 | 错误码前缀 | 说明 |
|
|||
|
|
|---------|-----------|-----|
|
|||
|
|
| 4xx | CLIENT_ERROR_ | 客户端错误(参数、权限) |
|
|||
|
|
| 5xx | SERVER_ERROR_ | 服务端错误(数据库、外部服务) |
|
|||
|
|
| 业务 | BIZ_ | 业务规则错误 |
|
|||
|
|
| 认证 | AUTH_ | 认证授权错误 |
|
|||
|
|
|
|||
|
|
### 6.3 版本控制
|
|||
|
|
|
|||
|
|
- URL 版本:`/api/v1/`, `/api/v2/`
|
|||
|
|
- 兼容策略:旧版本至少维护 6 个月
|
|||
|
|
- 废弃通知:提前 3 个月公告
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. 前后端数据交互
|
|||
|
|
|
|||
|
|
### 7.1 通信协议
|
|||
|
|
|
|||
|
|
| 交互方式 | 协议 | 适用场景 |
|
|||
|
|
|---------|-----|---------|
|
|||
|
|
| REST API | HTTP/1.1 | 常规 CRUD 操作 |
|
|||
|
|
| WebSocket | WS/WSS | 实时状态推送 |
|
|||
|
|
| Server-Sent Events | HTTP | 单向实时推送 |
|
|||
|
|
| GraphQL | HTTP | 复杂查询场景 |
|
|||
|
|
|
|||
|
|
### 7.2 数据类型共享
|
|||
|
|
|
|||
|
|
#### 7.2.1 Shared Types 包
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
packages/
|
|||
|
|
└── shared-types/
|
|||
|
|
├── index.ts
|
|||
|
|
├── order.types.ts
|
|||
|
|
├── product.types.ts
|
|||
|
|
└── api.types.ts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 7.2.2 类型同步机制
|
|||
|
|
|
|||
|
|
1. **Monorepo 架构**:使用 Nx 或 Turborepo 管理
|
|||
|
|
2. **npm 私有包**:发布 shared-types 到私有仓库
|
|||
|
|
3. **构建时同步**:CI/CD 自动同步类型定义
|
|||
|
|
|
|||
|
|
### 7.3 请求封装
|
|||
|
|
|
|||
|
|
#### 7.3.1 前端请求层
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// services/api.ts
|
|||
|
|
import { request } from 'umi';
|
|||
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|||
|
|
|
|||
|
|
export const orderService = {
|
|||
|
|
list: (params: OrderQueryParams) =>
|
|||
|
|
request('/api/v1/orders', { params }),
|
|||
|
|
|
|||
|
|
create: (data: CreateOrderDTO) =>
|
|||
|
|
request('/api/v1/orders', { method: 'POST', data }),
|
|||
|
|
|
|||
|
|
update: (id: string, data: UpdateOrderDTO) =>
|
|||
|
|
request(`/api/v1/orders/${id}`, { method: 'PATCH', data }),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// TanStack Query Hook 封装
|
|||
|
|
export const useOrders = (params: OrderQueryParams) => {
|
|||
|
|
return useQuery({
|
|||
|
|
queryKey: ['orders', params],
|
|||
|
|
queryFn: () => orderService.list(params),
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 7.3.2 统一错误处理
|
|||
|
|
|
|||
|
|
- 401 Unauthorized:跳转登录页
|
|||
|
|
- 403 Forbidden:显示权限不足
|
|||
|
|
- 429 Too Many Requests:显示限流提示
|
|||
|
|
- 5xx Server Error:显示服务异常
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. 开发环境配置
|
|||
|
|
|
|||
|
|
### 8.1 环境要求
|
|||
|
|
|
|||
|
|
| 环境 | 配置要求 |
|
|||
|
|
|-----|---------|
|
|||
|
|
| 开发环境 | Node.js 20.x, MySQL 8.0, Redis 6.0 |
|
|||
|
|
| 测试环境 | Docker 容器化部署 |
|
|||
|
|
| 生产环境 | 阿里云 ECS + RDS + Redis |
|
|||
|
|
|
|||
|
|
### 8.2 开发工具链
|
|||
|
|
|
|||
|
|
| 工具 | 用途 | 配置 |
|
|||
|
|
|-----|-----|-----|
|
|||
|
|
| VS Code | IDE | 推荐配置 |
|
|||
|
|
| ESLint | 代码检查 | .eslintrc.js |
|
|||
|
|
| Prettier | 代码格式化 | .prettierrc |
|
|||
|
|
| TypeScript | 类型检查 | tsconfig.json |
|
|||
|
|
| Husky | Git Hooks | .husky/ |
|
|||
|
|
| lint-staged | 增量检查 | package.json |
|
|||
|
|
|
|||
|
|
### 8.3 环境变量管理
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
.env # 本地开发
|
|||
|
|
.env.development # 开发环境
|
|||
|
|
.env.staging # 预发布环境
|
|||
|
|
.env.production # 生产环境
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| 变量分类 | 示例变量 |
|
|||
|
|
|---------|---------|
|
|||
|
|
| 数据库 | DB_HOST, DB_PORT, DB_USER |
|
|||
|
|
| Redis | REDIS_HOST, REDIS_PORT |
|
|||
|
|
| 认证 | JWT_SECRET, JWT_EXPIRES |
|
|||
|
|
| 第三方 | PLATFORM_APP_ID, PLATFORM_SECRET |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. 测试策略
|
|||
|
|
|
|||
|
|
### 9.1 测试分层
|
|||
|
|
|
|||
|
|
| 测试类型 | 覆盖目标 | 工具 |
|
|||
|
|
|---------|---------|-----|
|
|||
|
|
| 单元测试 | 业务逻辑、工具函数 | Jest / Vitest |
|
|||
|
|
| 集成测试 | API 接口、数据库操作 | Jest + Supertest |
|
|||
|
|
| E2E 测试 | 关键用户路径 | Playwright / Cypress |
|
|||
|
|
| 性能测试 | API 响应时间、并发 | k6 / Artillery |
|
|||
|
|
|
|||
|
|
### 9.2 测试覆盖率要求
|
|||
|
|
|
|||
|
|
| 模块 | 最低覆盖率 |
|
|||
|
|
|-----|-----------|
|
|||
|
|
| 核心业务 Service | 80% |
|
|||
|
|
| 工具函数 | 90% |
|
|||
|
|
| Controller | 70% |
|
|||
|
|
| 整体项目 | 75% |
|
|||
|
|
|
|||
|
|
### 9.3 测试数据管理
|
|||
|
|
|
|||
|
|
- 使用 Fixtures 管理测试数据
|
|||
|
|
- 避免依赖外部真实数据
|
|||
|
|
- 测试用例需有清理机制
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. 部署方案
|
|||
|
|
|
|||
|
|
### 10.1 部署架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[CDN]
|
|||
|
|
|
|
|||
|
|
[Nginx]
|
|||
|
|
|
|
|||
|
|
[负载均衡器]
|
|||
|
|
|
|
|||
|
|
+---------+---------+
|
|||
|
|
| |
|
|||
|
|
[Node Cluster] [Node Cluster]
|
|||
|
|
| |
|
|||
|
|
[MySQL RDS] [Redis Cache]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 10.2 容器化部署
|
|||
|
|
|
|||
|
|
#### 10.2.1 Docker 配置
|
|||
|
|
|
|||
|
|
```dockerfile
|
|||
|
|
# 后端 Dockerfile
|
|||
|
|
FROM node:20-alpine
|
|||
|
|
WORKDIR /app
|
|||
|
|
COPY package*.json ./
|
|||
|
|
RUN npm ci --only=production
|
|||
|
|
COPY dist/ ./dist/
|
|||
|
|
EXPOSE 3000
|
|||
|
|
CMD ["node", "dist/main.js"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 10.2.2 Docker Compose 开发环境
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
version: '3.8'
|
|||
|
|
services:
|
|||
|
|
app:
|
|||
|
|
build: .
|
|||
|
|
ports:
|
|||
|
|
- "3000:3000"
|
|||
|
|
environment:
|
|||
|
|
- NODE_ENV=development
|
|||
|
|
depends_on:
|
|||
|
|
- mysql
|
|||
|
|
- redis
|
|||
|
|
|
|||
|
|
mysql:
|
|||
|
|
image: mysql:8.0
|
|||
|
|
environment:
|
|||
|
|
MYSQL_ROOT_PASSWORD: root
|
|||
|
|
MYSQL_DATABASE: crawlfuhl_hub
|
|||
|
|
|
|||
|
|
redis:
|
|||
|
|
image: redis:6-alpine
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 10.3 CI/CD 流程
|
|||
|
|
|
|||
|
|
| 阶段 | 工具 | 执行内容 |
|
|||
|
|
|-----|-----|---------|
|
|||
|
|
| 代码检查 | ESLint, TypeScript | 语法检查、类型校验 |
|
|||
|
|
| 单元测试 | Jest | 覆盖率检查 |
|
|||
|
|
| 构建 | npm | 产物打包 |
|
|||
|
|
| 镜像构建 | Docker | 容器镜像 |
|
|||
|
|
| 部署 | GitLab CI / GitHub Actions | 灰度发布 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 11. 性能优化策略
|
|||
|
|
|
|||
|
|
### 11.1 前端性能优化
|
|||
|
|
|
|||
|
|
| 优化点 | 方案 | 预期收益 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 首屏加载 | Code Splitting, Lazy Loading | 减少 30% 首屏时间 |
|
|||
|
|
| 请求优化 | TanStack Query 缓存 | 减少 50% 请求数 |
|
|||
|
|
| 图片优化 | WebP, 懒加载 | 减少 40% 带宽 |
|
|||
|
|
| 渲染优化 | React.memo, useMemo | 减少重渲染开销 |
|
|||
|
|
| 构建优化 | Turborepo + esbuild | 提升 10x 构建速度 |
|
|||
|
|
|
|||
|
|
### 11.2 后端性能优化
|
|||
|
|
|
|||
|
|
| 优化点 | 方案 | 预期收益 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 数据库 | Prisma 连接池 + 索引优化 | 提升 10x 查询速度 |
|
|||
|
|
| 缓存 | Redis 多级缓存 | 减少 80% 数据库查询 |
|
|||
|
|
| 并发 | PM2 集群模式 | 提升 5x 并发能力 |
|
|||
|
|
| 异步 | BullMQ 消息队列 | 提升吞吐量 |
|
|||
|
|
| 压缩 | Express 压缩中间件 | 减少 60% 带宽 |
|
|||
|
|
|
|||
|
|
### 11.3 监控与告警
|
|||
|
|
|
|||
|
|
| 监控指标 | 工具 | 告警阈值 |
|
|||
|
|
|---------|-----|---------|
|
|||
|
|
| API 响应时间 | Prometheus + Grafana | > 500ms |
|
|||
|
|
| 错误率 | Sentry | > 1% |
|
|||
|
|
| CPU / 内存 | Node.js 内置 | > 80% |
|
|||
|
|
| 数据库连接 | MySQL 慢查询 | > 1s |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 12. 可扩展性设计
|
|||
|
|
|
|||
|
|
### 12.1 模块化架构
|
|||
|
|
|
|||
|
|
#### 12.1.1 模块注册机制
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 模块配置接口
|
|||
|
|
export interface ModuleConfig {
|
|||
|
|
name: string;
|
|||
|
|
version: string;
|
|||
|
|
controllers: Type<any>[];
|
|||
|
|
providers: Type<any>[];
|
|||
|
|
entities: Type<any>[];
|
|||
|
|
routes: RouteConfig[];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 动态模块加载器
|
|||
|
|
export class ModuleLoader {
|
|||
|
|
private modules: Map<string, ModuleConfig> = new Map();
|
|||
|
|
|
|||
|
|
async registerModule(config: ModuleConfig): Promise<void> {
|
|||
|
|
this.modules.set(config.name, config);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async loadModulesFromPath(path: string): Promise<void> {
|
|||
|
|
const files = await fs.readdir(path);
|
|||
|
|
for (const file of files) {
|
|||
|
|
if (file.endsWith('.module.ts')) {
|
|||
|
|
const module = await import(join(path, file));
|
|||
|
|
await this.registerModule(module.default);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 12.2 插件系统设计
|
|||
|
|
|
|||
|
|
#### 12.2.1 平台插件接口
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 平台插件接口
|
|||
|
|
export interface IPlatformPlugin {
|
|||
|
|
platform: string;
|
|||
|
|
version: string;
|
|||
|
|
|
|||
|
|
// 授权
|
|||
|
|
authorize(code: string): Promise<AuthToken>;
|
|||
|
|
refreshToken(token: AuthToken): Promise<AuthToken>;
|
|||
|
|
|
|||
|
|
// 商品
|
|||
|
|
fetchProducts(params: ProductQueryParams): Promise<Product[]>;
|
|||
|
|
publishProduct(product: Product): Promise<string>;
|
|||
|
|
|
|||
|
|
// 订单
|
|||
|
|
fetchOrders(params: OrderQueryParams): Promise<Order[]>;
|
|||
|
|
fulfillOrder(orderId: string, tracking: Tracking): Promise<void>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 插件注册
|
|||
|
|
@Injectable()
|
|||
|
|
export class PluginRegistry {
|
|||
|
|
private plugins: Map<string, IPlatformPlugin> = new Map();
|
|||
|
|
|
|||
|
|
register(plugin: IPlatformPlugin): void {
|
|||
|
|
this.plugins.set(plugin.platform, plugin);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
get(platform: string): IPlatformPlugin | undefined {
|
|||
|
|
return this.plugins.get(platform);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 12.2.2 支持的插件类型
|
|||
|
|
|
|||
|
|
| 插件类型 | 功能 | 示例 |
|
|||
|
|
|---------|-----|------|
|
|||
|
|
| 平台插件 | 接入新电商平台 | Amazon, eBay, TikTok |
|
|||
|
|
| 物流插件 | 接入新物流渠道 | 燕文, 4PX, 云途 |
|
|||
|
|
| 支付插件 | 接入新支付方式 | PayPal, Stripe |
|
|||
|
|
| 通知插件 | 接入新通知渠道 | 邮件, 短信, 钉钉 |
|
|||
|
|
|
|||
|
|
### 12.3 微服务演进路径
|
|||
|
|
|
|||
|
|
| 阶段 | 架构 | 适用场景 | 拆分策略 |
|
|||
|
|
|-----|-----|---------|---------|
|
|||
|
|
| 第一阶段 | 单体应用 | 初创期 | - |
|
|||
|
|
| 第二阶段 | 模块化单体 | 成长期 | 按业务域拆分 |
|
|||
|
|
| 第三阶段 | 微服务 | 成熟期 | 按服务拆分 |
|
|||
|
|
|
|||
|
|
**演进策略**:
|
|||
|
|
1. 先实现清晰的模块边界(当前阶段)
|
|||
|
|
2. 使用 NestJS 命名空间隔离
|
|||
|
|
3. 未来可通过 Kubernetes 拆分为独立服务
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 13. 安全性加固
|
|||
|
|
|
|||
|
|
### 13.1 认证授权
|
|||
|
|
|
|||
|
|
#### 13.1.1 JWT 双 Token 策略
|
|||
|
|
|
|||
|
|
| Token 类型 | 有效期 | 用途 |
|
|||
|
|
|-----------|--------|------|
|
|||
|
|
| Access Token | 15 分钟 | API 访问 |
|
|||
|
|
| Refresh Token | 7 天 | 刷新 Access Token |
|
|||
|
|
|
|||
|
|
#### 13.1.2 权限控制
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// RBAC 权限装饰器
|
|||
|
|
export const Permissions = (...permissions: string[]) =>
|
|||
|
|
SetMetadata('permissions', permissions);
|
|||
|
|
|
|||
|
|
// 权限守卫
|
|||
|
|
@Injectable()
|
|||
|
|
export class PermissionsGuard implements CanActivate {
|
|||
|
|
canActivate(context: ExecutionContext): boolean {
|
|||
|
|
const permissions = Reflect.getMetadata('permissions', context.getHandler());
|
|||
|
|
const user = context.switchToHttp().getRequest().user;
|
|||
|
|
|
|||
|
|
return permissions.every(p => user.permissions.includes(p));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 使用示例
|
|||
|
|
@UseGuards(JwtAuthGuard, PermissionsGuard)
|
|||
|
|
@Get('orders')
|
|||
|
|
@Permissions('order:read')
|
|||
|
|
async getOrders() {}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 13.2 数据安全
|
|||
|
|
|
|||
|
|
| 安全措施 | 实现方案 |
|
|||
|
|
|---------|---------|
|
|||
|
|
| SQL 注入 | Prisma 参数化查询 |
|
|||
|
|
| XSS 攻击 | Helmet + Content-Security-Policy |
|
|||
|
|
| CSRF | SameSite Cookie |
|
|||
|
|
| 敏感数据 | AES-256 加密存储 |
|
|||
|
|
| 传输加密 | TLS 1.3 |
|
|||
|
|
|
|||
|
|
### 13.3 审计日志
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 审计日志装饰器
|
|||
|
|
export const AuditLog = (action: string) =>
|
|||
|
|
SetMetadata('auditAction', action);
|
|||
|
|
|
|||
|
|
// 审计拦截器
|
|||
|
|
@Injectable()
|
|||
|
|
export class AuditInterceptor implements NestInterceptor {
|
|||
|
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
|||
|
|
const request = context.switchToHttp().getRequest();
|
|||
|
|
const user = request.user;
|
|||
|
|
const action = Reflect.getMetadata('auditAction', context.getHandler());
|
|||
|
|
|
|||
|
|
this.auditService.log({
|
|||
|
|
userId: user?.id,
|
|||
|
|
tenantId: user?.tenantId,
|
|||
|
|
action,
|
|||
|
|
resource: request.url,
|
|||
|
|
method: request.method,
|
|||
|
|
ip: request.ip,
|
|||
|
|
userAgent: request.headers['user-agent'],
|
|||
|
|
timestamp: new Date(),
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return next.handle();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 13.4 API 安全
|
|||
|
|
|
|||
|
|
| 防护措施 | 实现 |
|
|||
|
|
|---------|------|
|
|||
|
|
| 请求限流 | Redis 计数器 + 滑动窗口 |
|
|||
|
|
| IP 黑名单 | Nginx / 应用层 |
|
|||
|
|
| 请求验签 | HMAC-SHA256 |
|
|||
|
|
| CORS | 白名单配置 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 14. 风险评估与缓解措施
|
|||
|
|
|
|||
|
|
### 14.1 技术风险
|
|||
|
|
|
|||
|
|
| 风险项 | 等级 | 缓解措施 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 单线程性能瓶颈 | 中 | PM2 集群 + 负载均衡 |
|
|||
|
|
| 内存泄漏 | 中 | 定期内存分析 + 监控 |
|
|||
|
|
| 依赖安全漏洞 | 高 | 自动化安全审计 + Snyk |
|
|||
|
|
| TypeScript 类型膨胀 | 低 | 统一 shared-types 包 |
|
|||
|
|
|
|||
|
|
### 14.2 业务风险
|
|||
|
|
|
|||
|
|
| 风险项 | 等级 | 缓解措施 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 数据一致性 | 高 | 事务 + 补偿机制 |
|
|||
|
|
| 第三方 API 依赖 | 中 | 熔断器模式 + 降级策略 |
|
|||
|
|
| 租户数据隔离 | 高 | 强制 tenant_id 过滤 |
|
|||
|
|
|
|||
|
|
### 14.3 运维风险
|
|||
|
|
|
|||
|
|
| 风险项 | 等级 | 缓解措施 |
|
|||
|
|
|-------|-----|---------|
|
|||
|
|
| 服务不可用 | 高 | 多活架构 + 自动故障转移 |
|
|||
|
|
| 数据丢失 | 极高 | 定期备份 + 异地容灾 |
|
|||
|
|
| 性能退化 | 中 | 性能监控 + 容量规划 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 15. 实施路线图
|
|||
|
|
|
|||
|
|
### 15.1 阶段规划
|
|||
|
|
|
|||
|
|
| 阶段 | 时间 | 里程碑 | 优先级 |
|
|||
|
|
|-----|-----|-------|-------|
|
|||
|
|
| Phase 1 | 1 周 | NestJS + Prisma 框架搭建 | P0 |
|
|||
|
|
| Phase 2 | 2 周 | 状态管理迁移 (Zustand + TanStack Query) | P1 |
|
|||
|
|
| Phase 3 | 2 周 | 核心业务模块迁移 | P1 |
|
|||
|
|
| Phase 4 | 2 周 | API 规范化 + 测试补全 | P1 |
|
|||
|
|
| Phase 5 | 2 周 | 安全加固 + 审计日志 | P1 |
|
|||
|
|
| Phase 6 | 1 周 | 性能优化 + 监控部署 | P2 |
|
|||
|
|
| Phase 7 | 1 周 | 容器化 + CI/CD 完善 | P2 |
|
|||
|
|
| Phase 8 | 2 周 | 插件系统设计 | P2 |
|
|||
|
|
|
|||
|
|
### 15.2 验收标准
|
|||
|
|
|
|||
|
|
- 所有核心 API 具备单元测试
|
|||
|
|
- API 响应时间 P99 < 500ms
|
|||
|
|
- 前后端类型完全同步
|
|||
|
|
- 部署流程自动化
|
|||
|
|
- 安全审计通过
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 16. 附录
|
|||
|
|
|
|||
|
|
### 16.1 技术栈总览
|
|||
|
|
|
|||
|
|
| 层级 | 技术方案 | 版本 |
|
|||
|
|
|-----|---------|-----|
|
|||
|
|
| 前端框架 | UmiJS | 4.x |
|
|||
|
|
| UI 组件 | Ant Design | 5.x |
|
|||
|
|
| 状态管理 | Zustand | 4.x |
|
|||
|
|
| 服务端状态 | TanStack Query | 5.x |
|
|||
|
|
| 表单验证 | React Hook Form + Zod | 最新 |
|
|||
|
|
| 后端框架 | NestJS | 10.x |
|
|||
|
|
| ORM | Prisma | 5.x |
|
|||
|
|
| 数据库 | MySQL | 8.0 |
|
|||
|
|
| 缓存 | Redis | 6.0+ |
|
|||
|
|
| 消息队列 | BullMQ | 最新 |
|
|||
|
|
| 构建工具 | Vite | 内置 |
|
|||
|
|
| 语言 | TypeScript | 5.x (strict) |
|
|||
|
|
|
|||
|
|
### 16.2 参考资源
|
|||
|
|
|
|||
|
|
- [NestJS 官方文档](https://docs.nestjs.com)
|
|||
|
|
- [Prisma 官方文档](https://www.prisma.io/docs)
|
|||
|
|
- [Zustand 官方文档](https://zustand-demo.pmnd.rs)
|
|||
|
|
- [TanStack Query 官方文档](https://tanstack.com/query)
|
|||
|
|
- [UmiJS 官方文档](https://umijs.org)
|
|||
|
|
- [Ant Design Pro 组件](https://procomponents.ant.design)
|
|||
|
|
|
|||
|
|
### 16.3 版本历史
|
|||
|
|
|
|||
|
|
| 版本 | 日期 | 变更内容 |
|
|||
|
|
|-----|-----|---------|
|
|||
|
|
| V1.0 | 2024-01 | 初始版本 |
|
|||
|
|
| V2.0 | 2026-03-15 | 优化版:去除AI、技术栈升级、安全加固 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**文档维护者**:Crawlful Hub 架构团队
|
|||
|
|
**版本**:V2.0
|
|||
|
|
**状态**:已优化
|