☰
Spring Boot服装制造综合管理系统:订单到生产全链路业务闭环设计
2026/10/13 13:47:11 网站建设 项目流程

做服装制造公司的综合管理系统,听起来像一个小型 ERP,放进毕业设计里却很有发挥空间。我这两年接触了不少拿“基于 Spring Boot 的服装制造有限公司综合管理系统”开题的同学,大家最开始都是一脸懵:不知道管什么、不知道表怎么建、不知道代码写到什么程度才能过答辩。其实这个题目的核心并不复杂,Spring Boot 后端 + Vue 前端 + MySQL 数据库,外加一套能讲清楚的状态流转和权限控制,就足够做成一份能拿得出手的毕设了。真正拉开差距的,不是你会不会用最新框架,而是你有没有把服装制造里的订单、BOM、采购、库存、生产工单串成一条完整的业务闭环。

如果你正准备做这个题目,或者已经在写但卡在某个模块上,这篇文章会从业务边界、技术选型、数据库设计、核心功能代码一直到答辩准备,把我认为最值得参考的思路完整过一遍。

1. 先从业务链条说起:这个系统到底要管什么

1.1 服装工厂的真实管理断点在哪里

很多人上来就写代码,结果写出来的是一个“客户管理 + 商品管理 + 订单管理”的普通进销存,跟服装制造没半毛钱关系,答辩时被老师一问就露馅了。要避免这个问题,得先理解服装制造公司的日常业务是怎么跑的。

我做过一个模拟项目的需求梳理,客户是某小型服装制造公司,大概一百多人的规模,主要接品牌方订单。他们的业务链条是这样的:销售接单后,技术部根据客户款式做版型和用料清单;采购部按用料清单买面料、里料、拉链、纽扣;仓库收货入库后,生产部开裁、缝制、锁钉、整烫、质检;最后包装入库、发货。整个链条里最折磨人的是信息靠 Excel 和口头传递,订单交期改一次,采购和生产完全不知道;面料库存到底够不够,要跑仓库现点;某一批货缝到哪个工序,车间主任得挨个问组长。

所以这个系统真正要解决的是三件事:第一,订单从接单到发货的全过程状态可见;第二,面料和辅料库存能自动算,缺料时提前提醒采购;第三,生产工单能拆成工序任务,每个人都有自己的一摊活,干没干完一眼能看出来。

1.2 系统边界:哪些功能要写,哪些故意不做

明确了痛点,接着就要定边界。毕设不是商业项目,你不可能做一个完整 ERP,也没必要。我在规划时通常建议把系统切成七个核心模块:

  • 用户与权限管理:管理员、销售员、采购员、车间组长、质检员五种角色。
  • 基础资料管理:客户、供应商、面料、辅料、产品款式。
  • 销售订单管理:下单、审核、状态流转、订单明细。
  • 物料清单管理:每个款式的用料明细,也就是 BOM。
  • 采购管理:采购单、采购明细、到货确认。
  • 库存管理:面料辅料库存、成品库存、库存预警。
  • 生产工单管理:工单生成、工序任务拆解、报工、质检入库。

这几块已经够完整了。至于排产算法、自动计件工资、财务应收应付、移动端小程序,都不建议放进核心范围。你可以把这些当成“后续扩展”写在论文结尾,作为展望,但别真的去实现。做完核心闭环,再配合测试、论文、演示,比塞一堆半成品功能稳得多。

2. 技术选型复盘:Spring Boot + Vue 这套组合为什么最适合

2.1 后端骨架与关键依赖

后端技术栈我推荐的是 Spring Boot 2.7.x + MyBatis-Plus + MySQL 8.0。为什么是 2.7 而不是 3.x?因为很多学校机房的 JDK 还是 1.8,Spring Boot 3.x 强制要求 JDK 17,万一答辩现场环境不兼容,你会很被动。2.7 照样能用 Jakarta 那套常用注解,稳定性也经过了大量生产验证,完全够用。

在pom.xml里,我建议必加这几项:

  • spring-boot-starter-web:提供 MVC 和内置 Tomcat。
  • mybatis-plus-boot-starter:单表 CRUD 基本不用写 SQL,分页也内置了。
  • mysql-connector-j:数据库驱动。
  • jjwt:生成和解析 JWT 令牌。
  • lombok:减少实体类的 Getter/Setter 代码。
  • spring-boot-starter-validation:参数校验。
  • hutool:工具类库,处理日期、随机数、Bean 拷贝很省事。

Controller 保持薄,Service 放业务逻辑,Mapper 只做数据访问,这是最基本的三层结构。很多同学拿到代码生成器后,把全部逻辑堆在 Controller 里,看起来代码很多,实际业务一点没实现,这是最忌讳的。

2.2 前端选型:Vue + Element UI 能少走多少弯路

前端我建议用 Vue 3 + Vite + Element Plus,如果你对 Vue 2 更熟,用 Vue 2 + Element UI 也完全没毛病,不用为了追新而换。Vite 启动速度快,热更新舒服,打包出来就是几个静态文件,部署到 Nginx 或者在 Spring Boot 里做静态资源映射都可以。

管理后台的套路非常固定:左边菜单、顶栏、主内容区。用 Element Plus 的el-menu、el-table、el-form、el-dialog就能拼出 90% 的页面。我自己的习惯是先用 Vue Router 把登录页、首页、各个业务模块页面搭好,再用 Axios 封装请求,加一层拦截器,在响应里统一处理 401 和业务错误码。

重点提醒一下:前端不要做得花里胡哨。用官方模板或者简单布局反而更稳,因为你的核心分数在功能完整性和业务逻辑,不在视觉炫技。把订单状态、库存预警、工单进度这些关键数据清晰展示出来,比任何动画都值钱。

2.3 为什么不要在这个课题上引入微服务

每次有人问我要不要用 Spring Cloud Alibaba 做微服务,我都劝他打住。不是说微服务不好,而是它解决的是多团队、多系统、高并发的分布式问题。毕业设计通常部署在一台服务器上,最多两千行核心代码,用微服务会导致三件事很难收场:事务一致性讲不清楚,部署演示容易出幺蛾子,论文里还要花大量篇幅解释注册中心、网关、熔断,跟“服装制造综合管理”这个主题彻底跑偏。

技术栈的价值在于匹配问题场景。Spring Boot 单体 + 前后端分离,对几十个并发用户的内部管理系统来说已经完全够了。这个题目答辩时,老师更关心的是你有没有把一个业务流程做通,而不是你把架构搞得有多复杂。

3. 数据库设计:把面料、款式、订单、工单装进 MySQL

3.1 主数据表:用户、客户、面料、产品怎么分

数据库设计是整个项目的地基,我见过太多人把订单表和订单明细合在一张表里,结果查明细只能用逗号分隔存字符串,越做越痛苦。这里给出一套我验证过的表结构方案,不追求覆盖每个细节,但骨架是完整的。

表名作用关键字段
sys_user系统用户id, username, password, role_id, real_name, status
sys_role角色id, role_code, role_name
customer客户id, customer_name, contact, phone, address
supplier供应商id, supplier_name, contact, phone, address
fabric面料辅料主数据id, material_code, material_name, category, color, safe_stock
product产品款式id, product_code, product_name, style, price, status
bom物料清单明细id, product_id, material_id, material_type, quantity, loss_rate
sale_order销售订单主表id, order_no, customer_id, order_date, delivery_date, status
sale_order_item销售订单明细id, order_id, product_id, quantity, unit_price, finished_quantity
purchase_order采购单主表id, purchase_no, supplier_id, purchase_date, status
purchase_order_item采购单明细id, purchase_id, material_id, quantity, arrived_quantity
inventory实时库存id, material_id, stock_qty, locked_qty, update_time
production_order生产工单id, work_no, order_id, plan_start, plan_end, status
production_task工序任务id, work_order_id, task_name, task_order, assignee, plan_qty, finish_qty, status
work_report报工记录id, task_id, work_date, worker, qualified_qty, defective_qty

表之间怎么关联,一句话就能记住:客户下销售订单,订单明细里放产品;产品通过 BOM 关联面料辅料;采购单对应供应商和物料;库存表只按物料记最新存量;生产工单来源于销售订单;工序任务属于生产工单;报工记录落在工序任务上。

注意一个容易踩坑的点:所有表都要带create_time和update_time,建议用datetime类型,并让 MyBatis-Plus 的自动填充功能帮你维护这两个字段,而不是每个插入语句都手动传时间。

3.2 服装 BOM 设计的特殊之处

BOM 是制造类系统的灵魂,也是服装制造区别于普通电商系统最明显的地方。一件成衣不是一行商品数据,它由面布、里布、粘合衬、拉链、纽扣、缝线等多种物料组成,而且不同尺码的用量可能不同。因此绝对不要把 BOM 做成一个长文本字段,而是要用明细行。

我建议 BOM 表至少包含这些信息:

  • product_id:哪个款式。
  • material_id:用了哪种面料或辅料。
  • material_type:标记是面料、里料、辅料还是包装材料。
  • quantity:单件用量,比如某款外套一件耗用 1.2 米面布。
  • loss_rate:损耗率,比如裁剪损耗 5%,采购时要按实际数量乘以1 + loss_rate计算。
  • remark:备注,比如某个辅料指定颜色或克重。

这里有一个很实用的逻辑:系统生成采购建议时,不能直接拿订单数量乘以 BOM 用量,还要考虑库存和安全库存。计算公式大概是:

建议采购量 = 订单数量 × 单件耗用量 × (1 + 损耗率) - 当前可用库存 + 安全库存

如果一个款式的 BOM 有 5 条物料,订单有 300 件,那么每个物料都要按上述公式算一遍,不够的物料才进采购建议。这样系统在业务上才站得住脚,答辩时也能讲出真实逻辑。

3.3 销售订单与生产工单的状态流转

状态字段千万不要随意写数字而不注释。我建议用数字字典统一维护,并写进论文的数据字典里。

销售订单状态,我设置的是:

  • 0:待审核
  • 1:审核通过,待生产
  • 2:生产中
  • 3:已完工
  • 4:已发货
  • 5:已取消

生产工单状态,我设置的是:

  • 0:待开工
  • 1:裁剪中
  • 2:缝制中
  • 3:后道处理中
  • 4:质检中
  • 5:完工入库

状态之间要有明确的驱动关系。比如销售订单从“审核通过”变为“生产中”,只能在系统完成生产工单生成之后执行;生产工单的缝制工序任务全部完成,工单才能从缝制中进入后道处理中。不要在代码里直接写一个updateStatus方法谁都能乱调,而是写在各自的 Service 业务方法里。比如“报工完成”是一个独立方法,它内部先更新工序任务状态,再判断是否推进工单状态,这样状态流转不会错乱。

4. 核心功能落地:登录鉴权、工单生成、库存预警

4.1 JWT 登录与多角色权限:不用 Spring Security 也能讲明白

权限控制是毕设答辩最容易被追问的点。Spring Security 功能强大,但配置复杂,很多同学引入了又配不明白,反而扣分。我建议用一个 JWT + 自定义拦截器 + 自定义注解的方式实现,代码量少,逻辑又清楚。

JWT 的核心就是用户登录成功后,服务器签发一个带过期时间的令牌,之后每次请求都在 Header 里带上这个令牌,服务端解析出来就知道是谁、是什么角色。实现时只需要三样东西:

  • JwtUtil:负责生成和解析令牌。
  • JwtInterceptor:一个过滤器,拦下所有非登录接口。
  • RequireRole 注解:标注在 Controller 方法上,配合拦截器做角色校验。

令牌生成的代码大致这样:

public String createToken(Integer userId, String roleCode) { return Jwts.builder() .setSubject(String.valueOf(userId)) .claim("roleCode", roleCode) .setExpiration(new Date(System.currentTimeMillis() + 1440 * 60 * 1000)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }

拦截器里的核心逻辑是解析 Header 中的Authorization,校验令牌,再把用户信息放进 Request 属性中。这样 Controller 想要当前登录人 ID 时,直接从 Request 里取就可以了。

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { return true; } String token = request.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { throw new BusinessException(401, "未登录或登录已过期"); } Claims claims = JwtUtil.parseToken(token.substring(7)); request.setAttribute("userId", claims.getSubject()); request.setAttribute("roleCode", claims.get("roleCode")); return true; }

角色校验可以用一个简单的@RequireRole("admin")注解,拦截器中判断当前用户的角色是否在允许列表里。权限矩阵也不复杂,按下表控制即可:

角色可访问模块
管理员全部模块
销售员客户、产品、销售订单、发货
采购员供应商、BOM、采购、库存查看
车间组长生产工单、工序任务、库存领料
质检员生产工单查询、质检、报表

前端菜单不用做太复杂的动态路由,用 Vue Router 的addRoute按角色注册路由,或者直接在菜单渲染时用v-if过滤,都能实现效果。我一般建议后者,代码更好懂,也方便演示时切换账号。

4.2 从销售订单到生产工单的生成逻辑

这个环节是系统里最能体现“综合管理”的部分。我的实现思路是:当销售订单审核通过后,点击“生成生产工单”,后台做这几件事。

第一步,读取订单明细,得到每个产品和数量。第二步,根据产品 ID 展开 BOM,拿到所有需要的物料。第三步,逐条物料做库存检查,可用库存不足的物料自动写入采购建议表或提示消息。第四步,创建生产工单,并把订单状态更新为生产中。第五步,按工序模板生成工序任务:裁剪、缝制、锁钉、整烫、质检,每个工序计划数量等于订单数量。

为了让整个过程不出乱子,工单生成方法必须加事务注解:

@Transactional(rollbackFor = Exception.class) public Long createProductionOrder(SaleOrder order) { // 1. 创建工单主表 ProductionOrder workOrder = new ProductionOrder(); workOrder.setOrderId(order.getId()); workOrder.setWorkNo("WO" + System.currentTimeMillis()); workOrder.setStatus(0); productionOrderMapper.insert(workOrder); // 2. 展开订单明细 List<SaleOrderItem> items = saleOrderItemMapper.selectByOrderId(order.getId()); for (SaleOrderItem item : items) { List<BomDetail> boms = bomMapper.selectByProductId(item.getProductId()); for (BomDetail bom : boms) { BigDecimal needQty = bom.getQuantity() .multiply(BigDecimal.valueOf(item.getQuantity())) .multiply(BigDecimal.ONE.add(bom.getLossRate())); BigDecimal stock = inventoryMapper.getStockByMaterialId(bom.getMaterialId()); if (stock == null || stock.compareTo(needQty) < 0) { // 写入采购建议,等采购员确认 purchaseSuggestionMapper.insert(...); } } // 3. 生成工序任务 for (ProcessTemplate pt : processTemplateMapper.selectAll()) { ProductionTask task = new ProductionTask(); task.setWorkOrderId(workOrder.getId()); task.setTaskName(pt.getProcessName()); task.setPlanQty(item.getQuantity()); task.setStatus(0); productionTaskMapper.insert(task); } } return workOrder.getId(); }

这段逻辑里有一个细节很容易忽略:库存检查用的是“可用库存”,而不是总库存。可用库存要排除已经被其他工单锁定但还没出库的数量。所以 inventory 表里我专门加了一个locked_qty字段,做库存扣减时同时减少stock_qty和locked_qty,这样才能避免两张工单同时争抢同一批面料。

4.3 低于安全库存的预警提示与采购建议

库存预警的实现并不复杂,核心是安全库存字段。每条面料辅料都设置一个safe_stock,比如某个面料的常用安全值是 200 米,当实时库存低于这个值时,系统就要在首页和库存列表上提醒。

最简单可靠的 SQL 如下:

SELECT m.id, m.material_code, m.material_name, IFNULL(i.stock_qty, 0) AS stock_qty, m.safe_stock FROM fabric m LEFT JOIN inventory i ON i.material_id = m.id WHERE IFNULL(i.stock_qty, 0) < m.safe_stock;

但这里有个坑:如果只用这条 SQL 在页面上展示,那只有打开库存页的那一刻才会触发。所以我额外写了一个定时任务,每天凌晨跑一次全量检查,对低于安全库存的物料生成一条预警记录,同时给采购员生成待办消息。用了 Spring 自带的任务调度,零成本:

@Scheduled(cron = "0 30 8 * * ?") public void checkInventoryWarning() { List<MaterialStockVO> list = inventoryMapper.selectLowStockList(); // 逐条插入或更新预警表,并推送消息 }

注意安全库存不能一刀切。不同物料的采购周期和用量差异很大,像纽扣这种便宜又占地方的东西,安全库存可以高一点;一些特殊面料交期长,安全库存也应该提高。我建议系统里给“物料分类”加一个参数:采购提前期和日均用量,这样计算安全库存时就能更合理,也可以你在论文里多写一小节“基于采购周期的安全库存设定”,算是一个加分亮点。

5. 文档、演示和答辩:毕业设计的最后三公里

5.1 设计文档怎么写才不像流水账

源码一写完,很多同学就觉得大功告成,结果论文和设计说明书随便凑几万字,被导师打回来。其实这套系统是非常适合写文档的,因为它业务链条完整,每章都能落到实际功能上。

我建议文档结构这样安排:

  • 第一章 绪论:研究背景、国内外现状、研究内容。背景部分写服装制造企业管理的痛点,不要写空话。
  • 第二章 需求分析:画用例图,按角色列出功能需求,补充非功能需求如安全性和稳定性。
  • 第三章 系统设计:总体架构、技术选型理由、功能模块划分、数据库设计。
  • 第四章 详细设计:按登录模块、订单模块、BOM模块、工单模块、库存预警模块逐块讲。每一块要配流程图或时序图,重点是讲清楚数据怎么流转。
  • 第五章 系统实现:贴核心代码,但不要贴一整页,每段代码配一段解释,说明“为什么要这样写”。
  • 第六章 系统测试:写测试用例,比如正常登录、错误密码、越权访问、库存不足时生成工单等。
  • 最后是总结和展望。

写文档时最大的问题就是“复述代码”。答辩老师看的是你有没有思考,所以你要写“为什么”,不是写“是什么”。

5.2 远程调试环境准备和数据演示技巧

很多同学最后卡在演示环节,代码没问题,一演示就崩。常见原因无非是数据库连接串写错、前端接口地址没配、演示数据太乱、不同账号演示时没切换干净。

我建议你在答辩前先把环境固定下来:数据库用 MySQL 8.0,字符集统一utf8mb4;后端打包成 jar,用命令java -jar启动;前端 build 后丢进 Nginx 或者 Spring Boot 的static目录。演示现场不要开开发工具,直接用浏览器访问打包后的页面,稳定性高得多。

远程调试时,无论你用什么远程工具,都要提前准备好三套登录账号,并记住每个账号对应的菜单和数据:

  • 管理员:演示用户管理、基础资料、所有列表可见。
  • 销售员:演示客户下单、订单状态推进。
  • 车间组长:演示生产工单生成、工序任务、报工。

演示数据一定要真实。客户名称用“某某服饰公司”,供应商用“某面料供应商”,产品款号用“K-2025-01”,面料名称用“32支全棉平纹布”,订单状态不要全部停在同一个节点。让老师看到不同的状态和不同的待办事项,比空表直观得多。

5.3 几个答辩必问点,我建议你这样答

第一个高频问题:“为什么选择 Spring Boot?”不要只答“生态成熟、简化配置”,要结合系统说:Spring Boot 内置 Tomcat、自动配置能力强、用 starter 能快速整合 MyBatis 和数据库连接池,特别适合中小型管理系统这种单体内应用,开发效率高,部署成本低。

第二个高频问题:“数据库表是怎么设计的?”你可以从三范式切入:用户表、客户表、供应商表属于基础数据;订单主表和订单明细表是一对多;BOM 表和产品是一对多,和物料表是多对一;生产工单和工序任务也是一对多。这样设计保证了数据冗余少、扩展性好。

第三个高频问题:“你这个系统的亮点是什么?”我会答 BOM 展开和库存预警的联动。订单审核通过后,系统自动展开每个款式的物料清单,结合安全库存计算缺口,生成采购建议;生产时按工序拆任务,报工数据反过来驱动工单状态流转。这是一个完整的闭环,也是和其他普通 CRUD 项目最大的区别。

第四个高频问题:“并发情况下库存会不会超卖?”这个问题比较刁钻,但你只要答出“乐观锁”或者“条件更新”就能过关。扣库存的 SQL 不要先查后减,而是直接更新:UPDATE inventory SET stock_qty = stock_qty - #{needQty} WHERE id = #{materialId} AND stock_qty >= #{needQty},影响行数为 0 就说明库存不足,再回滚事务。这比用 synchronized 靠谱得多。

最后一个实际问题:“系统上线后怎么应对用户反馈?”可以从日志和权限角度答:加操作日志、登录日志,记录关键操作;系统留好角色和菜单的扩展位,后续加新模块不用改权限框架。

做这个项目时我感触最深的一点是:毕业设计不怕功能少,就怕流程断。哪怕你只做了四个模块,只要订单从销售到生产到库存是一条完整链路,每一步都有状态变化、有数据记录、有权限控制,就已经是一个能打的高分设计了。别贪大求全,把你做出来的每一条业务逻辑讲透,比堆十个半成品功能有用得多。代码之外,建议你把数据库说明文档、接口文档和测试用例也留好,这些东西在最后一周的演示和查重时,能帮你省下大量时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询