HY博客

所有的为时已晚都是恰逢其时

Spring Boot + uni-app + Docker 实现 ERP/MES 生产协同轻量化 APP

面向制造业订单与生产协同场景,开发轻量化APP打通ERP/MES数据流,实现订单同步、生产进度反馈、库存联动与移动端展示。

HY
HY Developer
2026年04月18日
预计阅读 11 分钟
2976 字

一、项目背景

本项目面向制造业订单与生产协同场景,主要解决业务订单与生产数据之间的信息流转问题。

目标是开发一个轻量化 APP,与 ERP、MES 系统进行数据互通,实现:

  1. 订单同步
  2. 生产进度反馈
  3. 库存联动
  4. 异常 / 待办展示
  5. 移动端数据查看与上报

项目最终实现了一个最小可用版本 MVP,打通了:

订单进入系统 → 生产进度上报 → 订单状态流转 → 库存自动更新 → 移动端展示


二、技术选型

后端技术

技术作用
Java后端开发语言
Spring Boot搭建 RESTful API 服务
Spring Data JPA数据库 ORM 映射
MySQL存储订单、生产进度、库存数据
Docker容器化部署后端服务与数据库
JSON前后端数据交互格式
RESTful API提供移动端与外部系统调用接口

前端 / APP 技术

技术作用
uni-app开发轻量化移动端 APP
Vue页面开发与数据绑定
uni.request调用后端接口
HBuilderXuni-app 开发与打包工具

三、项目功能设计

1. 订单管理

订单模块主要负责订单的新增、查询、删除和状态展示。

已实现功能:

  • 新增订单
  • 查询订单列表
  • 查询待办订单
  • 查询异常订单
  • 删除订单
  • 根据订单状态进行展示

订单状态包括:

  • 待生产
  • 生产中
  • 已完成
  • 异常

2. 生产进度反馈

生产进度模块用于记录生产现场的上报数据。

移动端可以选择订单并填写:

  • 完成数量
  • 状态
  • 备注

其中状态主要包括:

  • 生产中
  • 异常

系统根据上报的完成数量进行累计判断。

例如:

订单数量为 500。

第一次上报 200:

累计完成数量 = 200
订单总数量 = 500
订单状态 = 生产中

第二次再上报 300:

累计完成数量 = 500
订单总数量 = 500
订单状态 = 已完成

这样可以避免出现“只完成一部分,订单却直接变成已完成”的问题。


3. 库存联动

当生产进度上报后,系统会根据完成数量更新库存。

当前采用分批入库逻辑:

  • 每次上报有效完成数量后,库存增加对应数量
  • 当累计完成数量达到订单数量后,订单状态改为已完成

库存字段主要包括:

  • 产品编码
  • 产品名称
  • 库存数量
  • 更新时间

4. 异常 / 待办展示

首页显示两个关键指标:

  • 待办订单数
  • 异常订单数

其中:

待办订单 = 待生产 + 生产中
异常订单 = 异常

移动端首页每次返回时都会重新刷新数据,保证统计信息实时更新。


5. ERP / MES 模拟接口

为了模拟 ERP 和 MES 系统对接,项目提供了两个同步接口:

接口作用
/sync/erp/order模拟 ERP 同步订单
/sync/mes/report模拟 MES 同步生产进度

后续如果对接真实 SAP、用友或 MES 系统,可以将这些接口替换为真实 API 对接或中间表同步。


四、数据库设计

项目使用 MySQL 存储业务数据。

1. 订单表 order_info

主要字段:

字段说明
id主键
order_no订单号
product_name产品名称
quantity订单数量
status订单状态
customer_name客户名称
create_time创建时间

2. 生产进度表 production_report

主要字段:

字段说明
id主键
order_no订单号
completed_qty完成数量
report_status上报状态
remark备注
report_time上报时间

3. 库存表 inventory_info

主要字段:

字段说明
id主键
product_code产品编码
product_name产品名称
stock_qty库存数量
update_time更新时间

五、后端接口设计

后端统一返回格式如下:

{
"code": 200,
"message": "success",
"data": {}
}

1. 订单接口

方法接口说明
GET/orders查询全部订单
GET/orders/{id}根据 ID 查询订单
GET/orders/orderNo/{orderNo}根据订单号查询订单
GET/orders/pending查询待办订单
GET/orders/exception查询异常订单
POST/orders新增订单
PUT/orders/{id}/status修改订单状态
DELETE/orders/{id}删除订单

2. 生产进度接口

方法接口说明
GET/reports查询全部生产进度
GET/reports/orderNo/{orderNo}查询某订单的生产进度
POST/reports上报生产进度

3. 库存接口

方法接口说明
GET/inventory查询库存列表
GET/inventory/{id}根据 ID 查询库存
POST/inventory新增库存
PUT/inventory/{id}修改库存

4. ERP / MES 模拟同步接口

方法接口说明
POST/sync/erp/order模拟 ERP 同步订单
POST/sync/mes/report模拟 MES 同步生产进度

六、后端核心业务逻辑

1. 生产进度累计判断

生产进度上报后,后端会查询该订单所有进度记录,并累计完成数量。

核心逻辑:

List<ProductionReport> reportList = productionReportRepository.findByOrderNo(report.getOrderNo());
int totalCompletedQty = reportList.stream()
.mapToInt(item -> item.getCompletedQty() == null ? 0 : item.getCompletedQty())
.sum();
int orderQty = orderInfo.getQuantity() == null ? 0 : orderInfo.getQuantity();
if (orderQty > 0 && totalCompletedQty >= orderQty) {
orderInfo.setStatus("已完成");
} else {
orderInfo.setStatus("生产中");
}

这样可以保证只有累计完成数量达到订单数量时,订单才真正变为已完成。


2. 异常优先处理

如果上报状态为异常,系统会直接将订单状态改为异常,不再继续执行库存更新逻辑。

if ("异常".equals(reportStatus)) {
orderInfo.setStatus("异常");
orderInfoRepository.save(orderInfo);
return savedReport;
}

这样可以避免异常订单误入库。


3. 库存联动

当上报数量有效时,系统会自动更新库存。

int addQty = report.getCompletedQty() == null ? 0 : report.getCompletedQty();
if (addQty > 0) {
inventoryInfo.setStockQty(inventoryInfo.getStockQty() + addQty);
inventoryInfo.setUpdateTime(LocalDateTime.now());
inventoryInfoRepository.save(inventoryInfo);
}

七、移动端 APP 开发

移动端使用 uni-app 开发,主要包括以下页面:

1. 首页

首页展示:

  • 待办订单数
  • 异常订单数
  • 订单列表入口
  • 进度上报入口
  • 库存查询入口

为了避免从其他页面返回首页后数据不刷新,首页同时使用:

onLoad() {
this.loadData()
}
onShow() {
this.loadData()
}

这样每次页面显示时都会重新请求最新数据。


2. 订单列表页

订单列表页展示:

  • 订单号
  • 产品名称
  • 数量
  • 客户名称
  • 订单状态

同时支持:

  • 新增订单
  • 删除订单

删除订单时增加二次确认,避免误删。


3. 新增订单页

新增订单页支持填写:

  • 订单号
  • 产品名称
  • 数量
  • 客户名称

提交后调用:

POST /orders

新增成功后自动返回订单列表页。


4. 生产进度上报页

生产进度上报页支持:

  • 选择订单
  • 自动显示产品名称、订单数量、当前状态
  • 填写完成数量
  • 选择状态
  • 填写备注

订单选择只显示未完成订单:

待生产
生产中

这样可以避免对已完成订单重复上报。


5. 库存查询页

库存页展示:

  • 产品编码
  • 产品名称
  • 当前库存
  • 更新时间

调用接口:

GET /inventory

八、后端部署过程

后端使用 Docker 部署。

1. 本地打包 Spring Boot 项目

在项目根目录执行:

Terminal window
.\mvnw.cmd clean package

打包成功后生成:

target/erp-mes-0.0.1-SNAPSHOT.jar

2. 编写 Dockerfile

服务器上准备 Dockerfile

FROM eclipse-temurin:17-jre
WORKDIR /app
COPY erp-mes-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

3. 上传 jar 到服务器

将打包好的 jar 上传到服务器目录,例如:

/andocker/erp-mes

服务器目录结构:

/andocker/erp-mes
├── Dockerfile
└── erp-mes-0.0.1-SNAPSHOT.jar

4. 构建 Docker 镜像

进入服务器目录:

Terminal window
cd /andocker/erp-mes

构建镜像:

Terminal window
docker build -t erp-mes-app .

5. 运行后端容器

后端程序内部端口是 8080,对外映射为 9000:

Terminal window
docker run -d --name erp-mes-app -p 9000:8080 erp-mes-app

6. 查看运行日志

Terminal window
docker logs -f erp-mes-app

如果看到类似:

Tomcat started on port 8080
Started ErpMesApplication

说明后端启动成功。

7. 外网访问测试

浏览器访问:

http://服务器IP:9000/orders

如果返回 JSON 数据,说明部署成功。


九、MySQL Docker 部署

MySQL 使用 Docker Compose 部署。

docker-compose.yml

services:
mysql:
image: mysql:8.0
container_name: erp-mes-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root123456
MYSQL_DATABASE: erp_mes
MYSQL_USER: appuser
MYSQL_PASSWORD: app123456
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d

启动:

Terminal window
docker compose up -d

查看容器:

Terminal window
docker ps

十、后端配置文件

后端 application.properties 中配置 MySQL 连接:

spring.datasource.url=jdbc:mysql://服务器IP:3306/erp_mes?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=appuser
spring.datasource.password=app123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
server.port=8080

十一、前端打包成 APP

前端使用 HBuilderX 进行打包。

打包方式

选择:

发行 -> 原生 App 云打包

打包平台选择:

Android

可以先使用测试证书生成 APK。

打包完成后得到:

.apk 文件

安装到安卓手机后即可使用。


十二、部署更新流程

如果修改了后端代码,需要重新部署。

1. 本地重新打包

Terminal window
.\mvnw.cmd clean package

2. 上传新 jar 到服务器

覆盖旧的:

/andocker/erp-mes/erp-mes-0.0.1-SNAPSHOT.jar

3. 重新构建镜像

Terminal window
cd /andocker/erp-mes
docker build -t erp-mes-app .

4. 删除旧容器

Terminal window
docker stop erp-mes-app
docker rm erp-mes-app

5. 启动新容器

Terminal window
docker run -d --name erp-mes-app -p 9000:8080 erp-mes-app

6. 查看日志

Terminal window
docker logs -f erp-mes-app

十三、开发过程中遇到的问题

1. 订单部分完成却直接变成已完成

最开始的逻辑是只要上报状态为“已完成”,订单就直接改为已完成。

后来改成根据累计完成数量判断:

累计完成数量 >= 订单数量

订单才会真正变成已完成。

2. 异常订单没有显示

原因是前端传的状态文本不一致,比如传成了“异常数”,而后端只识别“异常”。

解决方式:

  • 前端状态选项固定为“生产中”“异常”
  • 后端用 "异常".equals(reportStatus) 判断

3. 首页返回后数据不刷新

原因是首页只在 onLoad() 加载了一次数据。

解决方式:

onShow() {
this.loadData()
}

这样每次返回首页都会重新加载统计数据。

4. 样式类名冲突

首页和订单页都使用了 .pending 类名,导致首页卡片文字颜色被订单页状态样式影响。

解决方式是将首页样式类名改成:

.pending-card
.exception-card

避免样式冲突。


十四、项目总结

本项目完成了一个 ERP/MES 生产协同系统的最小可用版本,主要实现了:

  • 订单管理
  • 生产进度上报
  • 库存联动
  • 待办 / 异常展示
  • ERP / MES 模拟同步接口
  • 移动端 APP 页面
  • Docker 化部署
  • 服务器远程访问

项目打通了制造业订单与生产数据之间的核心业务流程,为后续接入真实 ERP、MES 系统提供了基础。

后续还可以继续扩展:

  • 登录与权限控制
  • 真实 ERP / MES API 对接
  • 中间表同步
  • 操作日志
  • 分页查询
  • 数据统计报表
  • Nginx + HTTPS
  • 自动化部署脚本

十五、项目亮点

  1. 前后端分离设计,后端提供 RESTful API,移动端调用接口完成业务操作。
  2. 使用 Docker 部署 MySQL 和后端服务,方便迁移和维护。
  3. 设计订单状态流转逻辑,避免部分完成误判为整单完成。
  4. 支持生产进度上报和库存自动联动。
  5. 移动端优先展示待办和异常,符合轻量化 APP 使用场景。

觉得这篇文章怎么样?

点个赞,让更多人看到!

分享这篇文章

知识因分享而增值

分类

项目实战

标签

Spring Boot
uni-app
Docker
ERP
MES
生产协同

版权声明:本文作者为 HY,首发于 www.bcd.moe

遵循 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

评论区

本评论区由 EveSunMaple自主开发