1. 项目背景与核心需求
福泰轴承是一家典型的机械零部件制造企业,日常经营涉及大量轴承产品的采购、库存管理和销售业务。传统的手工记账方式存在数据滞后、统计困难、易出错等问题,因此需要开发一套专业的进销存管理系统。这个毕业设计项目正是基于这样的实际需求场景,采用当前企业级开发的主流技术栈Java+Spring Boot+MySQL来实现。
提示:进销存系统是企业管理软件中最基础也最核心的类型之一,完整实现了"采购入库-库存管理-销售出库"的业务闭环,非常适合作为展示全栈开发能力的毕业设计选题。
系统需要实现的核心功能模块包括:
- 基础数据管理(产品信息、供应商信息、客户信息)
- 采购管理(采购单创建、审批、入库)
- 库存管理(库存查询、盘点、调拨)
- 销售管理(销售订单、出库、退货)
- 统计报表(销售分析、库存预警、利润统计)
- 系统管理(用户权限、操作日志)
2. 技术选型与架构设计
2.1 为什么选择Spring Boot+MySQL组合
Spring Boot是目前Java领域最流行的企业级开发框架,相比传统的SSH/SSM框架具有以下优势:
- 自动配置:简化了XML配置,约定优于配置
- 内嵌服务器:可直接打包成可执行JAR
- 丰富的Starter:快速集成各种常用组件
- Actuator:提供生产级监控端点
MySQL作为关系型数据库的代表,具有:
- 开源免费,社区活跃
- 性能稳定,支持事务ACID特性
- 与Java生态完美兼容
- 适合中小型数据量的业务场景
2.2 系统架构设计
采用经典的三层架构:
表现层:Thymeleaf模板引擎 + Bootstrap前端框架 业务层:Spring Boot + Spring MVC + Spring Security 数据层:Spring Data JPA + MySQL考虑到毕业设计的实现复杂度,没有采用微服务架构,而是选择了单体应用模式。但对于大型商业系统,可以考虑拆分为:
- 库存服务
- 订单服务
- 报表服务
- 用户服务
3. 数据库设计与实现
3.1 核心表结构设计
-- 产品表 CREATE TABLE product ( id BIGINT PRIMARY KEY AUTO_INCREMENT, product_code VARCHAR(50) UNIQUE NOT NULL, product_name VARCHAR(100) NOT NULL, specification VARCHAR(200), unit VARCHAR(20), purchase_price DECIMAL(10,2), selling_price DECIMAL(10,2), stock_quantity INT DEFAULT 0, min_stock INT COMMENT '最小库存预警值', status TINYINT DEFAULT 1 COMMENT '1-正常 0-停用', create_time DATETIME, update_time DATETIME ); -- 采购单表 CREATE TABLE purchase_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(50) UNIQUE NOT NULL, supplier_id BIGINT, total_amount DECIMAL(12,2), status TINYINT COMMENT '0-草稿 1-已提交 2-已审核 3-已入库 4-已取消', creator_id BIGINT, auditor_id BIGINT, create_time DATETIME, update_time DATETIME, FOREIGN KEY (supplier_id) REFERENCES supplier(id) ); -- 采购明细表 CREATE TABLE purchase_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, quantity INT, unit_price DECIMAL(10,2), amount DECIMAL(12,2), FOREIGN KEY (order_id) REFERENCES purchase_order(id), FOREIGN KEY (product_id) REFERENCES product(id) );3.2 数据库优化实践
索引设计:
- 为所有外键字段创建索引
- 为高频查询条件字段创建组合索引
- 避免过度索引,影响写入性能
事务处理:
@Transactional public void processPurchaseOrder(PurchaseOrderDTO orderDTO) { // 1. 保存采购单主表 PurchaseOrder order = convertToEntity(orderDTO); purchaseOrderRepository.save(order); // 2. 保存采购明细 List<PurchaseItem> items = convertItems(orderDTO.getItems(), order.getId()); purchaseItemRepository.saveAll(items); // 3. 更新库存 updateStock(items, StockOperationType.PURCHASE); }- 连接池配置:
spring: datasource: url: jdbc:mysql://localhost:3306/inventory_db?useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 300004. 核心功能实现细节
4.1 采购入库流程实现
采购业务的核心状态机设计:
草稿 → 已提交 → 已审核 → 已入库关键代码实现:
@PostMapping("/purchase/submit") public Result submitPurchaseOrder(@RequestBody PurchaseOrderDTO orderDTO) { // 参数校验 if (orderDTO.getItems() == null || orderDTO.getItems().isEmpty()) { return Result.fail("采购明细不能为空"); } // 状态转换 if (orderDTO.getStatus() != OrderStatus.DRAFT.getCode()) { return Result.fail("只有草稿状态的订单可以提交"); } orderDTO.setStatus(OrderStatus.SUBMITTED.getCode()); // 保存订单 PurchaseOrder order = purchaseService.saveOrder(orderDTO); return Result.success(order.getId()); }4.2 库存管理实现
库存变更的原子操作:
public void updateStock(List<StockOperationItem> items, StockOperationType operationType) { for (StockOperationItem item : items) { Product product = productRepository.findById(item.getProductId()) .orElseThrow(() -> new BusinessException("产品不存在")); int newStock; switch (operationType) { case PURCHASE: newStock = product.getStockQuantity() + item.getQuantity(); break; case SALE: newStock = product.getStockQuantity() - item.getQuantity(); if (newStock < 0) { throw new BusinessException("产品库存不足"); } break; // 其他操作类型... } product.setStockQuantity(newStock); productRepository.save(product); // 记录库存变更日志 stockLogService.recordOperation(product, operationType, item.getQuantity()); } }4.3 销售出库实现
销售业务涉及的关键点:
- 库存检查(防止超卖)
- 价格策略(会员折扣等)
- 出库单生成
@Transactional public SalesOrder createSalesOrder(SalesOrderDTO orderDTO) { // 1. 检查库存 checkStock(orderDTO.getItems()); // 2. 计算价格 calculatePrice(orderDTO); // 3. 保存订单 SalesOrder order = saveOrder(orderDTO); // 4. 扣减库存 updateStock(convertToStockItems(orderDTO.getItems()), StockOperationType.SALE); // 5. 生成出库单 generateDeliveryOrder(order); return order; }5. 系统安全与权限控制
5.1 基于Spring Security的权限管理
配置类示例:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/static/**").permitAll() .antMatchers("/purchase/**").hasAnyRole("PURCHASE", "ADMIN") .antMatchers("/sales/**").hasAnyRole("SALES", "ADMIN") .antMatchers("/inventory/**").hasAnyRole("INVENTORY", "ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/dashboard") .and() .logout() .logoutSuccessUrl("/login"); } }5.2 密码加密存储
使用BCryptPasswordEncoder:
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 用户注册时加密密码 public User registerUser(UserDTO userDTO) { User user = new User(); user.setUsername(userDTO.getUsername()); user.setPassword(passwordEncoder.encode(userDTO.getPassword())); // 其他字段... return userRepository.save(user); }6. 项目部署与测试
6.1 打包与运行
- 使用Maven打包:
mvn clean package- 运行JAR包:
java -jar inventory-system-0.0.1-SNAPSHOT.jar- 生产环境建议使用Docker部署:
FROM openjdk:8-jdk-alpine VOLUME /tmp COPY target/inventory-system-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]6.2 接口测试示例
使用Postman测试采购接口:
POST /api/purchase/submit Headers: Content-Type: application/json Authorization: Bearer [token] Body: { "supplierId": 1, "items": [ { "productId": 101, "quantity": 100, "unitPrice": 12.5 } ] }7. 毕业设计常见问题与解决方案
7.1 数据库连接问题
常见错误:Communications link failure
解决方案:
- 检查MySQL服务是否启动
- 检查连接URL中的端口和数据库名是否正确
- 检查用户名密码是否正确
- 添加连接参数:
?useSSL=false&serverTimezone=Asia/Shanghai
7.2 跨域问题
前端访问后端API时出现跨域错误,解决方案:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*"); } }7.3 日期时间处理
MySQL 8.0+与Java 8日期类型的映射:
spring: jpa: properties: hibernate: jdbc: time_zone: Asia/Shanghai实体类中使用:
@Column private LocalDateTime createTime;8. 项目扩展与优化方向
- 引入Redis缓存:缓存热点数据如产品信息、库存数量
- 加入消息队列:使用RabbitMQ处理异步任务如库存扣减
- 实现分布式事务:对于跨服务操作使用Seata
- 增加移动端支持:开发微信小程序或APP版本
- 接入第三方服务:集成支付宝/微信支付、物流查询等
// Redis缓存示例 public Product getProductById(Long id) { String key = "product:" + id; Product product = redisTemplate.opsForValue().get(key); if (product == null) { product = productRepository.findById(id).orElse(null); if (product != null) { redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS); } } return product; }在实现这个毕业设计项目的过程中,我发现最大的挑战不在于技术实现本身,而在于对业务流程的准确理解和建模。建议学弟学妹们在开始编码前,一定要先绘制完整的业务流程图和状态转换图,这样可以避免后期大量的返工。另外,Spring Boot的官方文档非常完善,遇到问题时首先查阅文档往往能快速找到解决方案。