10-1 总结核心业务服务开发与扩展(交易、内容)
本节对核心业务服务开发阶段的重点知识进行系统性总结,并扩展尚未实现的功能模块及后续学习方向。
业务模块全景
知识付费管理系统涉及以下核心业务模块:
| 模块 | 说明 | 实现状态 |
|---|---|---|
| 用户认证 | 注册、登录、JWT 鉴权 | 已完成 |
| RBAC 角色权限 | 接口级别访问控制 | 已完成 |
| 策略权限 (CASL) | 字段级别细粒度控制 | 已完成 |
| 菜单权限 | 角色菜单关联 | 已完成 |
| 课程管理 | 课程 CRUD + 标签 | 已完成 |
| 内容管理 | 课程内容 CRUD + 附件 + 标签 | 代码已提供 |
| 课程笔记 | 用户关联的增删改查 | 代码已提供 |
| 用户评论/私信 | 评论 CRUD | 代码已提供 |
| 促销管理 | 红包卡券 + 价格计算 | 数据库已设计 |
| 交易管理 | 订单 + 钱包 + 支付对接 | 数据库已设计 |
内容管理的扩展点
内容(Content)模块比课程(Course)模块更复杂,主要体现在:
- 附件(Attachment):课程内容支持附件上传
- 标签(Tag):内容需要独立打标签以支持筛选
- 关联关系:内容需要与课程(Course)进行关联
其 CRUD 结构与课程模块高度一致,同样包含创建、查询单个、查询全部、更新、删除等标准操作。
泛型公共方法的权衡
当多个模块的创建/删除标签逻辑高度相似时,可以考虑抽取公共方法:
// shared/shared.service.ts
@Injectable()
export class SharedService {
// 通用创建标签方法
async createTagGeneric(model: any, data: any) {
return model.create({ data });
}
// 通用删除标签方法
async deleteTagGeneric(model: any, id: number) {
return model.delete({ where: { id } });
}
}
typescript
但这种写法存在潜在风险:
| 风险 | 说明 |
|---|---|
| 误删数据 | model 参数拼写错误可能导致删除错误表的数据 |
| 高权限隐患 | 方法直接操作任意 model,缺少条件校验 |
| 维护困难 | 后续不同 model 的差异化逻辑会导致大量 if-else |
建议:当重复代码超过 4-5 处且仅 model 不同时,才使用泛型方法;否则保持独立实现更安全。
课程笔记的数据库设计
笔记(Note)表采用直接关联用户 ID 的方式,而非创建 UserNote 中间表:
model Note {
id Int @id @default(autoincrement())
title String
content String
userId Int
user User @relation(fields: [userId], references: [id])
// ...
}
prisma
设计原则:多对多关系创建关联表,一对多/多对一关系直接在实体中记录关联 ID + @relation。
评论服务的泛型实现
评论(Comment)模块使用泛型方法同时支持课程评论和内容评论:
// comment/comment.service.ts
@Injectable()
export class CommentService {
async genericCreate(model: any, data: any) {
// model 限定为合法类型,防止误操作
const allowedModels = ['courseComment', 'contentComment'];
if (!allowedModels.includes(model)) {
throw new ForbiddenException('非法的操作对象');
}
return model.create({ data });
}
}
typescript
权限控制体系总结
整个权限控制体系按颗粒度从粗到细排列:
RBAC(接口级别)
└─> CASL 策略权限(字段级别)
└─> 数据库策略(条件级别)
text
CASL 实现的三种权限控制:
- 基于角色:判断用户角色是否满足要求
- 基于条件:通过 MongoDB 风格查询表达式控制
- 基于函数:通过
handleFunctionType执行动态逻辑
局限性:数据库层面无法存储函数及其参数,只能通过 Guard 传递固定的三个参数(Reflector 元数据、请求信息、用户信息)。
数据库嵌套关系规律
所有业务模块的嵌套关系不超过三层:
课程 → 标签 → 标签分类
订单 → 商品 → 促销规则
用户 → 角色 → 权限
text
掌握这一规律后,新模块的数据库设计可快速套用相同模式。
后续学习方向
- 支付对接:小程序支付流程(后续章节专题讲解)
- 促销引擎:红包、卡券与商品价格的联动计算
- 数据迁移:开发阶段脏数据的清理策略与 SQL 脚本维护
- 代码规范:以模块为单元管理依赖注入的导入与导出
↑