1. 项目背景与核心价值
在传统制造业和零售行业中,物料采购和供应链管理一直是企业运营的关键环节。我最近用SpringBoot和微信小程序开发了一套完整的物料采购供应链管理系统,这套系统解决了中小企业在采购流程中的几个痛点:
- 采购流程不透明:传统纸质审批和Excel表格管理导致信息滞后
- 供应商管理混乱:缺乏统一的供应商评估和准入机制
- 库存周转率低:人工盘点容易出错,无法实时掌握库存动态
- 移动端支持弱:现有ERP系统大多缺乏便捷的移动端操作界面
微信小程序作为入口的优势非常明显:
- 无需安装,扫码即用
- 完善的用户身份体系(直接对接微信开放平台)
- 原生体验接近APP但开发成本更低
2. 系统架构设计
2.1 技术栈选型
后端核心:
- SpringBoot 2.7 + MyBatis-Plus
- Redis缓存(采购单状态、库存快照)
- RocketMQ消息队列(异步处理采购审批流)
- MinIO对象存储(物料图片、合同附件)
前端方案:
- 微信小程序原生框架
- Vant Weapp组件库
- ECharts-for-Weixin(数据可视化)
特别说明选型理由:
- 放弃Vue+Uniapp方案:虽然开发效率高,但在复杂表单交互和性能上不如原生
- 选择RocketMQ而非ActiveMQ:考虑到后续可能对接IoT设备做智能仓储
- MinIO替代FastDFS:更简单的集群部署和维护
2.2 微服务拆分
com.modules ├── auth # 认证中心(微信登录+RBAC) ├── supplier # 供应商管理 ├── procurement # 采购核心 ├── inventory # 库存管理 ├── payment # 财务结算 └── analytics # 数据分析每个模块都包含:
- controller(API入口)
- service(业务逻辑)
- mapper(数据访问)
- entity(持久化对象)
- dto(数据传输对象)
3. 核心功能实现
3.1 微信登录与权限控制
// 微信小程序登录接口示例 @PostMapping("/wxLogin") public Result wxLogin(@RequestBody WxLoginDTO dto) { // 1. 用code换openid String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code"; String response = restTemplate.getForObject(url, String.class, appId, appSecret, dto.getCode()); // 2. 解析unionid JSONObject json = JSON.parseObject(response); String openid = json.getString("openid"); // 3. 查询或创建用户 User user = userService.getOrCreate(openid); // 4. 生成JWT String token = JwtUtil.generateToken(user); return Result.success(token); }权限设计要点:
- 基于角色的访问控制(RBAC)
- 微信openid作为唯一标识
- 小程序端缓存token有效期2小时
- 敏感操作需二次验证(如采购审批)
3.2 采购流程状态机
stateDiagram-v2 [*] --> DRAFT DRAFT --> PENDING_APPROVAL : 提交 PENDING_APPROVAL --> APPROVED : 主管通过 PENDING_APPROVAL --> REJECTED : 主管驳回 APPROVED --> PURCHASING : 开始采购 PURCHASING --> PART_RECEIVED : 部分到货 PART_RECEIVED --> COMPLETED : 全部到货 COMPLETED --> CLOSED : 验收入库关键实现:
- 使用Spring StateMachine框架
- 状态变更通过RocketMQ通知相关方
- 每个状态对应不同的操作权限
3.3 库存实时预警
-- 库存预警视图 CREATE VIEW inventory_alert_view AS SELECT i.material_id, m.name, i.current_quantity, m.min_stock, CASE WHEN i.current_quantity < m.min_stock * 0.2 THEN 'CRITICAL' WHEN i.current_quantity < m.min_stock THEN 'WARNING' ELSE 'NORMAL' END AS alert_level FROM inventory i JOIN material m ON i.material_id = m.id;优化技巧:
- 使用Redis缓存热点物料库存
- 预警信息聚合后通过小程序模板消息推送
- 支持安全库存动态计算(基于历史消耗量)
4. 性能优化实践
4.1 采购单列表优化
问题现象:
- 当采购单超过1万条时,小程序端加载缓慢
- 翻页出现重复或丢失记录
解决方案:
- 采用游标分页替代传统分页
public Page<Procurement> listByCursor(Long cursorId, Integer size) { return lambdaQuery() .gt(cursorId != null, Procurement::getId, cursorId) .orderByAsc(Procurement::getId) .last("LIMIT " + size) .page(new Page<>(1, size)); }- 小程序端实现下拉刷新+上拉加载
onReachBottom() { if(this.data.loading || !this.data.hasMore) return this.setData({ loading: true }) wx.request({ url: '/procurement/list', data: { cursorId: this.data.lastId, size: 10 }, success: (res) => { this.setData({ list: [...this.data.list, ...res.data], lastId: res.data[res.data.length-1].id, hasMore: res.data.length >= 10 }) } }) }4.2 高并发库存扣减
典型场景:多个采购员同时操作同一物料的入库
最终方案:
@Transactional public boolean deductInventory(Long materialId, Integer quantity) { // 1. 查询当前库存(带锁) Inventory inventory = inventoryMapper.selectByIdForUpdate(materialId); // 2. 校验库存 if(inventory.getCurrentQuantity() < quantity) { throw new BusinessException("库存不足"); } // 3. 扣减 inventory.setCurrentQuantity(inventory.getCurrentQuantity() - quantity); return inventoryMapper.updateById(inventory) > 0; }踩坑记录:
- 初期使用乐观锁导致大量失败重试
- 分布式环境下需要用Redis分布式锁
- 最终采用MySQL行锁+短事务方案
5. 部署与监控
5.1 容器化部署
# 采购服务Dockerfile示例 FROM openjdk:11-jre COPY target/procurement-0.0.1.jar /app.jar ENTRYPOINT ["java","-jar","/app.jar"] EXPOSE 8080最佳实践:
- 每个微服务独立容器
- 使用Jib插件构建镜像(无需Dockerfile)
- 资源限制:CPU 1核,内存1GB
5.2 微信小程序发布
注意事项:
服务器域名配置:
- request合法域名
- socket合法域名
- uploadFile合法域名
- downloadFile合法域名
体验版测试:
# 生成体验版二维码 cli -u --project ./ --upload-version 1.0.0 --upload-desc '采购模块优化'- 正式发布前检查:
- 接口权限(是否所有角色测试通过)
- 性能测试(页面加载时间<1s)
- 安全审核(XSS/SQL注入)
6. 扩展思考
这套系统后续可以扩展的方向:
智能采购预测
- 基于历史数据训练采购量预测模型
- 集成Python服务(Flask+TensorFlow)
区块链存证
- 关键采购合同上链
- 使用Hyperledger Fabric私有链
IoT集成
- 通过MQTT协议对接智能货架
- 自动触发补货采购单
实际开发中最大的体会是:供应链系统最复杂的不是技术实现,而是对业务规则的理解和抽象。建议在开发前至少用2周时间深入业务现场,画出完整的业务流程泳道图。