Swee-NestJS后端服务
Swee Server 是 Swee 平台的 Node.js 后端服务,基于 NestJS 10 + TypeORM + MySQL 构建。负责多语言文案管理(8 语言 JSON 存储 + 微软翻译器集成)、文件管理(阿里云 OSS + CDN 自动刷新)、通用配置管理(版本控制 + 一键回滚)、素材库(树形结构 Materialized Path)以及 AI 新闻聚合定时任务(9 大新闻源 + Levenshtein 距离去重 + 飞书推送)等核心功能。
一、项目技术架构
1.1 整体架构图
1.2 核心技术栈
| 领域 | 技术选型 | 版本 |
|---|---|---|
| 框架 | NestJS | 10.4.4 |
| ORM | TypeORM + MySQL2 | 0.3.20 / 3.11.5 |
| 缓存 | @nestjs/cache-manager | 2.3.0 |
| 定时任务 | @nestjs/schedule | 6.0.0 |
| API 文档 | @nestjs/swagger | 8.1.0 |
| 配置管理 | @nestjs/config | 3.3.0 |
| 文件存储 | ali-oss | 6.21.0 |
| CDN | @alicloud/cdn + @alicloud/dcdn | 4.2.2 / 2.5.0 |
| HTML 解析 | cheerio | 1.1.2 |
| NLP | natural + stopword | 8.1.0 / 3.1.4 |
| JSON 修复 | jsonrepair | 3.12.0 |
| 文件上传 | multer | 1.4.5-lts.1 |
| 编译 | SWC | latest |
选择 NestJS 作为框架是因为其模块化架构天然适合多业务线并行开发,TypeORM 的 Tree 装饰器为素材库的树形结构管理提供了开箱即用的支持,SWC 编译器则将开发环境的冷启动时间缩短至秒级。
二、模块架构
2.1 模块全景
三、文案管理模块
3.1 多语言文案系统
3.2 数据库设计
3.3 微软翻译器集成
3.4 ZIP 打包导出
// 开放接口,供代码生成工具使用
GET /copywriting/item/open/get_copywriting_zip
→ StreamableFile (ZIP 压缩包)
支持 @swee/codegen 调用,生成 Web/iOS/Android 三端文案代码。
四、文件管理模块
4.1 阿里云 OSS 集成
4.2 JSON 修复服务
// 处理前端传入的不规范 JSON
POST /file/open/get_repaired_json
→ 使用 jsonrepair 库自动修复 JSON 语法错误
五、配置管理模块
5.1 双存储架构
通过 lastContent 字段保存上一版本的配置内容,实现了轻量级的版本控制。相比引入完整的版本管理系统,这种方案在满足"配置出错快速恢复"需求的同时,保持了数据模型的简洁。
5.2 版本控制与回滚
5.3 数据库实体
六、素材库模块
6.1 树形结构管理
6.2 TypeORM Tree 实现
@Entity('material_library')
@Tree("materialized-path") // Materialized Path 算法
export class LibraryEntity {
id: string;
name: string;
description: string;
type: string; // 'folder' | 'file'
size: number;
createdAt: Date;
createdBy: string; // 创建人
deletedAt: Date;
deletedBy: string; // 删除人
@TreeParent()
parent: LibraryEntity; // 父节点
@TreeChildren()
children: LibraryEntity[]; // 子节点列表
}
6.3 功能特性
| 功能 | 说明 |
|---|---|
| 创建文件夹 | 支持嵌套创建,自动构建 OSS 路径 |
| 上传文件 | 批量上传到指定文件夹 |
| 更新文件 | 替换现有文件 |
| 文件名验证 | 重复检查 + 扩展名验证 |
| 级联删除 | 删除文件夹时递归删除子内容 |
| 路径构建 | material/{folder_path}{file_name} |
七、AI 新闻聚合系统
7.1 系统架构
Levenshtein 距离去重是新闻聚合系统的核心竞争力——通过动态规划计算标题相似度,配合 7 天缓存窗口和停用词过滤,实现了 9 大新闻源的高质量去重,大幅降低了信息噪音。
7.2 Levenshtein 距离去重算法
核心代码逻辑:
removeSimilarNews(newsList: INews[], threshold: number = 0.25) {
const kept = [newsList[0]];
for (let i = 1; i < newsList.length; i++) {
const isSimilar = kept.some(keptItem => {
const distance = getEditDistance(newsList[i].title, keptItem.title);
const similarity = 1 - distance / Math.max(
newsList[i].title.length, keptItem.title.length
);
return similarity > threshold;
});
if (!isSimilar) kept.push(newsList[i]);
}
return kept;
}
7.3 网页内容提取
7.4 飞书集成
八、中间件与拦截器
NestJS 的请求处理遵循严格的管道顺序:Middleware → Guard → Interceptor (pre) → Pipe → Controller → Interceptor (post) → Exception Filter。理解这个顺序对调试和性能排查至关重要。
8.1 请求处理流水线
8.2 统一响应格式
{
"code": 200,
"msg": "success",
"path": "/copywriting/item/admin/get_copywriting_list",
"date": "2025-01-01T10:47:42.364Z",
"data": { ... },
"traceId": "3f1c16d9-c62c-4511-a240-19bba35d0a54"
}
8.3 缓存拦截器
// 自定义缓存键:URL + Authorization Header
// 实现按用户隔离缓存
@Cache({ ttl: 60000, auth: true }) // 60秒缓存
async getContent() { ... }
九、认证与权限
9.1 认证流程
9.2 权限 ID 体系
| 权限 ID | 对应功能 |
|---|---|
system:copywriting:collection | 文案集合管理 |
system:copywriting:detail | 文案详情编辑 |
system:copywriting:log | 操作日志查看 |
system:setting:json | JSON 配置管理 |
system:setting:general | 通用配置管理 |
十、多环境配置
10.1 配置管理架构
生产环境使用 DCDN (Edge Security Acceleration) 而非普通 CDN,两者 API 不同(@alicloud/cdn vs @alicloud/dcdn),切勿混用。同时,开发环境开启了 synchronize: true 自动同步表结构,生产环境严禁开启,否则可能导致数据丢失。
10.2 关键环境差异
| 配置项 | 开发 | 测试 | 生产 |
|---|---|---|---|
| 数据库 | localhost:3306 | 阿里云 RDS | 阿里云 RDS (Singapore) |
| API 网关 | swee-gateway.x3live.info | swee-gateway.x3live.info | K8s 内网 SVC |
| OSS Bucket | swee-test | swee-test | swee-prod |
| CDN 域名 | assets.x3live.info | assets.x3live.info | assets.swee.live |
| CDN 类型 | CDN | CDN | DCDN (Edge Security) |
| 数据库同步 | synchronize: true | false | false |
| 飞书文档 | 测试文档 | 测试文档 | 生产文档 |
十一、部署架构
11.1 Docker 多阶段构建
11.2 Kubernetes 部署
- 使用 Kustomize 管理多环境配置
- 生产环境 Java API 通过 K8s 内网 SVC 通信
- 内存 / CPU 资源限制配置
十二、技术亮点总结
12.1 Levenshtein 距离去重
- 动态规划算法:O(n*m) 时间复杂度计算编辑距离
- 相似度阈值:可调节阈值(默认 0.25)控制去重精度
- 停用词处理:结合 natural + stopword 提升准确性
- 7 天缓存窗口:避免同一新闻在 7 天内重复推送
12.2 树形素材库
- Materialized Path:TypeORM Tree 装饰器实现高效树形查询
- OSS 路径映射:数据库树形结构与 OSS 存储路径一致
- 级联操作:删除文件夹时自动递归删除子内容
12.3 版本控制配置
- 一键回滚:
lastContent字段保存上一版本,支持即时回滚 - 权限隔离:每个配置独立授权,超管可见全部
- 缓存加速:60 秒内存缓存,减少数据库压力
12.4 多语言文案管线
- JSON 多语言存储:
{ 语言ID: 文案文本 }结构化存储 - 微软翻译器:一键批量翻译,支持多目标语言
- ZIP 导出:StreamableFile 流式输出,支持 @swee/codegen 消费
- 完整审计日志:操作前后内容对比 + IP + 操作人
12.5 飞书深度集成
- Bot 卡片消息:使用模板化卡片推送新闻摘要
- 云文档 API:自动写入新闻到协作文档
- Token 管理:自动获取 tenant_access_token
- 消息回调:接收飞书 Bot 消息并处理
12.6 CDN 智能刷新
- 环境自适应:测试环境用 CDN,生产环境用 DCDN (Edge Security)
- 自动刷新:文件上传/更新后自动刷新对应 CDN 缓存
- 多域名支持:测试/生产使用不同 CDN 域名
12.7 统一的请求追踪
- TraceMiddleware:所有请求自动生成
X-Trace-Id - 全链路日志:请求/响应/异常都携带 traceId
- 统一响应格式:code + msg + data + traceId + path + date
12.8 9 源新闻聚合
- 覆盖国内主流 AI 科技媒体
- cheerio HTML 解析 + JSON API 双模式
- OxyLabs 代理突破访问限制
- 英文标题自动翻译为中文
十三、项目数据概览
| 指标 | 数据 |
|---|---|
| TypeScript 源文件 | 77 |
| NestJS 模块 | 6 个 |
| 数据库实体 | 6 个 |
| API 端点 | 50+ |
| 新闻源 | 9 个 |
| 支持语言(翻译) | 8 种 |
| 定时任务 | 1 个(每日凌晨 2 点) |
| 文件上传限制 | 1GB / 100 个 |
| 缓存 TTL | 60 秒 |
| 部署端口 | 16666 |
十四、@swee 公共包生态
作为 Swee 全栈生态的一部分,后端服务也依赖并支撑着 @swee 公共包体系:
| 公共包 | 职责 | 核心能力 |
|---|---|---|
@swee/constant | 常量定义 | 环境自适应、设备追踪、域名管理 |
@swee/function | 工具函数 | Token 多源获取、URL 处理、多语言检测 |
@swee/hooks | React Hooks | BroadcastChannel 跨标签通信 |
@swee/uikit | UI 组件库 | 60+ SVG 图标、HeroUI 集成、Mobile/Web 双端 |
@swee/request | HTTP 请求 | Axios 拦截器、请求取消、登录过期处理 |
@swee/login | 认证系统 | AuthProvider、多方式登录、跨标签同步 |
@swee/codegen | 代码生成 | DCG/TCG 双引擎、Web/iOS/Android 三端输出 |
@swee/report-sdk | 数据上报 | Google Analytics + Facebook + Twitter 三平台 |
@swee/js-bridge-sdk | App 桥接 | User/Device/Router/Share 四模块、DSBridge |