第2章:ERP系统架构设计
架构设计这事儿,说白了就是给系统搭骨架。骨架搭好了,后面加功能、修bug都顺溜。搭不好?嗯,那后面就有得哭了。我见过太多项目,前期图省事随便搞搞,结果后期改一次架构比重新写还痛苦。
今天咱们聊聊ERP系统的架构设计。我会把单体架构、微服务架构、分层设计、技术选型这些核心内容掰开揉碎了讲。你想想看,一个ERP系统要管采购、销售、库存、财务、生产……这么多模块,架构选错了,后面就是无底洞。
2.1 单体架构 vs 微服务架构
先说说最基础的选择题:用单体还是微服务?
单体架构,就是把所有功能都塞进一个应用里。前端、后端、数据库,全在一个项目里跑。优点是简单,开发快,部署也方便。我早期做的一个ERP项目就是单体架构,团队就5个人,三个月就上线了。
但单体有个致命问题——牵一发动全身。你改个采购模块的代码,可能把财务模块搞崩了。我记得有一次,团队里一个小伙子在库存模块加了个缓存,结果订单模块的查询全乱了。排查了两天才找到原因。
微服务架构就不一样了。每个模块独立成一个服务,各自部署,各自维护。采购一个服务,库存一个服务,财务一个服务。服务之间通过API通信。
微服务的优势很明显:
- 独立部署:改采购模块不用重启整个系统
- 技术异构:采购用Java,财务用Python,都行
- 故障隔离:库存服务挂了,不影响订单服务
- 团队自治:每个团队管自己的服务
但微服务也不是银弹。我见过一个团队,项目刚启动就上微服务,结果光搭建基础设施就花了两个月。服务间通信、数据一致性、分布式事务……这些坑一个接一个。
我的建议:
- 团队小于10人,业务复杂度不高 → 单体架构
- 团队大于20人,模块间耦合低 → 微服务架构
- 不确定?先单体,等业务膨胀了再拆分
避坑指南:我曾经接手过一个项目,团队为了"技术先进"硬上微服务,结果每个服务只有几百行代码,却要维护一套完整的部署流水线。说白了,微服务是解决复杂度的工具,不是炫技的手段。
2.2 分层架构
不管单体还是微服务,内部都得分层。经典的三层架构:表现层、业务逻辑层、数据访问层。
表现层:负责和用户打交道。接收请求,返回响应。说白了就是Controller那层。我个人习惯把表现层做得尽量薄,只做参数校验和结果封装,不写任何业务逻辑。
业务逻辑层:核心中的核心。所有业务规则、流程控制、计算逻辑都放这里。我见过一些新手把业务逻辑写在Controller里,结果后面想复用都找不到地方。
数据访问层:和数据库打交道。CRUD操作、事务管理、缓存策略。这一层要尽量通用,换数据库的时候只改这一层就行。
举个例子,一个订单创建流程:
// 表现层
@PostMapping("/orders")
public Result createOrder(@RequestBody OrderDTO dto) {
// 参数校验
if (dto.getProductId() == null) {
return Result.error("商品ID不能为空");
}
// 调用业务层
return orderService.createOrder(dto);
}
// 业务逻辑层
@Service
public class OrderService {
public Result createOrder(OrderDTO dto) {
// 检查库存
Stock stock = stockRepo.findByProductId(dto.getProductId());
if (stock.getQuantity() < dto.getQuantity()) {
return Result.error("库存不足");
}
// 计算价格
BigDecimal total = priceService.calculate(dto);
// 创建订单
Order order = new Order(dto, total);
orderRepo.save(order);
// 扣减库存
stockRepo.decrease(dto.getProductId(), dto.getQuantity());
return Result.success(order);
}
}
// 数据访问层
@Repository
public class OrderRepository {
public void save(Order order) {
// 执行SQL
jdbcTemplate.update("INSERT INTO orders ...");
}
}
注意:分层不是死的。我见过一些项目,为了"严格分层",连DTO转换都要写三层。其实没必要。小项目可以适当简化,比如表现层直接调用数据访问层。但大项目一定要分层清晰,否则后期维护成本会指数级上升。
2.3 技术选型
技术选型这事儿,我踩过的坑比走过的路还多。咱们一个个说。
后端:Java/Spring Boot
Java在ERP领域是绝对的主流。为什么?稳定、生态好、人才多。Spring Boot更是把Java开发的门槛降到了最低。
我个人习惯用Spring Boot + MyBatis Plus。Spring Boot负责框架,MyBatis Plus负责数据库操作。为什么不用JPA?嗯,ERP系统里复杂查询太多了,JPA的自动生成SQL有时候不太可控。
举个例子,一个多表关联的分页查询:
@Service
public class ReportService {
public PageResult<ReportVO> queryReport(ReportQuery query) {
// 使用MyBatis Plus的Lambda查询
LambdaQueryWrapper<Report> wrapper = new LambdaQueryWrapper<>()
.eq(Report::getCompanyId, query.getCompanyId())
.between(Report::getCreateTime, query.getStartDate(), query.getEndDate())
.orderByDesc(Report::getCreateTime);
Page<Report> page = new Page<>(query.getPageNum(), query.getPageSize());
Page<Report> result = reportMapper.selectPage(page, wrapper);
// 转换为VO
List<ReportVO> voList = result.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList());
return new PageResult<>(voList, result.getTotal());
}
}
前端:Vue vs React
这两个框架我都用过。说实话,没有绝对的好坏。
| 维度 | Vue | React |
|---|---|---|
| 学习曲线 | 平缓,上手快 | 陡峭,概念多 |
| 生态 | 官方全家桶 | 社区驱动 |
| 适合场景 | 中小型项目 | 大型复杂项目 |
| 国内流行度 | 高 | 中等 |
我的建议是:如果团队前端经验不足,选Vue。如果团队有React高手,选React。ERP系统里表单多、表格多、流程多,Vue的模板语法写起来更直观。但如果你要做复杂的交互,比如拖拽、实时协作,React的灵活性更强。
数据库:MySQL vs PostgreSQL
这两个数据库我都在生产环境用过。MySQL胜在生态好,文档多,运维工具丰富。PostgreSQL胜在功能强,支持JSON、数组、全文检索。
ERP系统里,我一般这样选:
- 业务数据(订单、库存、财务)→ MySQL,稳定可靠
- 配置数据(流程定义、规则引擎)→ PostgreSQL,JSON支持好
- 日志数据 → Elasticsearch,全文检索
我的经验:曾经有个项目,用MySQL存JSON字段,查询性能惨不忍睹。后来换成PostgreSQL的JSONB类型,查询速度提升了10倍。所以,选数据库要看具体场景,别盲目跟风。
2.4 API设计原则
API设计这事儿,看似简单,实则坑多。我见过太多API设计得乱七八糟的项目,前端和后端天天吵架。
RESTful原则,说白了就是用HTTP动词表达操作:
- GET → 查询
- POST → 创建
- PUT → 更新
- DELETE → 删除
举个例子,订单相关的API:
GET /api/orders # 查询订单列表
GET /api/orders/{id} # 查询单个订单
POST /api/orders # 创建订单
PUT /api/orders/{id} # 更新订单
DELETE /api/orders/{id} # 删除订单
但RESTful不是万能的。有些操作用RESTful表达很别扭,比如"审核订单"、"取消订单"。这时候我建议用动词:
POST /api/orders/{id}/approve # 审核订单
POST /api/orders/{id}/cancel # 取消订单
API设计还有几个要点:
- 版本控制:URL里带版本号,比如 /api/v1/orders
- 统一返回格式:{ code: 200, message: "成功", data: {} }
- 分页:查询列表必须支持分页,返回总条数
- 错误处理:返回有意义的错误信息,别只给个500
避坑指南:我曾经见过一个项目,API返回格式五花八门。有的返回{ success: true },有的返回{ status: "ok" },前端解析的时候还得猜。后来我定了个规范:所有API统一返回Result对象,包含code、message、data三个字段。从此天下太平。
好了,架构设计这块就聊这么多。记住一句话:架构没有银弹,只有最适合当前场景的方案。下一章咱们聊聊数据库设计,那可是ERP系统的地基,打不好后面全白搭。