基于SSM框架的红酒溯源与库存管理系统 - 源码深度解析
在当今红酒行业,品质保证和供应链透明度已成为企业核心竞争力的关键要素。随着消费者对产品来源和质量要求的不断提高,传统模式下从葡萄种植到终端消费的漫长供应链中存在的信息断层和管理粗放问题日益凸显。针对这一行业痛点,我们设计并实现了一套企业级红酒溯源与库存管理平台,通过数字化手段为每瓶红酒赋予唯一数字身份,实现从原料到成品的全生命周期精细化管理。
系统架构与技术栈选型
该平台采用业界成熟的SSM(Spring + Spring MVC + MyBatis) 框架组合,基于Maven进行依赖管理,MySQL作为核心数据存储。这种技术选型在保证系统高稳定性的同时,兼顾了开发效率和后期可维护性,特别适合中大型企业级应用开发。
技术架构分层设计
表现层
- Spring MVC框架负责请求路由和视图渲染
- 采用RESTful风格接口设计,支持前后端分离架构
- 集成Jackson实现JSON数据序列化,提升API响应效率
业务层
- Spring IoC容器统一管理所有业务组件,实现松耦合架构
- AOP切面编程处理事务控制和操作日志记录
- 声明式事务管理确保数据一致性
持久层
- MyBatis实现灵活的数据访问层,支持动态SQL
- MyBatis Plus增强插件提供通用CRUD操作
- 二级缓存机制优化高频查询性能
数据层
- MySQL 5.7+关系型数据库确保数据ACID特性
- 合理的索引设计和表分区策略提升查询效率
- 数据库连接池管理优化资源利用率
<!-- 核心依赖配置示例 -->
<dependencies>
<!-- Spring MVC Web框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- MyBatis与Spring整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- MyBatis Plus增强功能 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
</dependencies>
数据库设计亮点分析
溯源记录表创新设计
tb_syly(溯源记录表)的设计体现了对红酒溯源业务的深度理解。表结构采用纵向扩展模式,通过syqyid(溯源企业ID)和syncpid(溯源农产品ID)建立多维度关联,支持复杂的溯源链查询。
CREATE TABLE `tb_syly` (
`syid` varchar(50) NOT NULL COMMENT '溯源ID - 主键',
`syip` varchar(50) DEFAULT NULL COMMENT '溯源IP - 记录客户端IP地址',
`sysj` date DEFAULT NULL COMMENT '溯源时间 - 记录查询时间点',
`syncpid` varchar(50) DEFAULT NULL COMMENT '溯源农产品ID - 外键关联农产品',
`syqyid` varchar(50) DEFAULT NULL COMMENT '溯源企业ID - 外键关联企业',
PRIMARY KEY (`syid`),
KEY `idx_syncpid` (`syncpid`),
KEY `idx_sysj` (`sysj`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='溯源记录表'
设计亮点深度解析:
IP地址智能记录
syip字段记录每次溯源的客户端IP地址- 支持地理信息解析,为防伪分析和异常访问监控提供数据支撑
- 结合IP黑名单机制实现安全防护
时间维度优化设计
sysj采用DATE类型而非DATETIME,在保证溯源时间精度的同时优化存储空间- 支持按日期分区,提升历史数据查询性能
- 时间索引加速时间范围查询
国际化字符集支持
- 采用utf8mb4字符集,完美支持emoji等特殊字符
- 适应多语言环境,为国际化业务扩展预留空间
- 排序规则支持多语言排序需求
农产品与二维码智能关联设计
tb_ncp(农产品表)与tb_ewm(二维码表)的关联设计实现了物理产品与数字身份的智能绑定,构建了完整的溯源基础。
-- 农产品基础信息表
CREATE TABLE `tb_ncp` (
`ncpid` varchar(50) NOT NULL COMMENT '农产品ID - 主键',
`ncpmc` varchar(50) NOT NULL COMMENT '农产品名称',
`cd` varchar(50) DEFAULT NULL COMMENT '产地信息',
`pz` varchar(50) DEFAULT NULL COMMENT '葡萄品种',
`ccrq` date DEFAULT NULL COMMENT '产出日期',
`zzfs` varchar(50) DEFAULT NULL COMMENT '种植方式(有机/传统)',
`qyid` varchar(20) NOT NULL COMMENT '企业ID - 外键关联企业表',
`ewmid` varchar(50) NOT NULL COMMENT '二维码ID - 外键关联二维码表',
PRIMARY KEY (`ncpid`),
UNIQUE KEY `uk_ewmid` (`ewmid`),
KEY `idx_qyid` (`qyid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='农产品表'
-- 二维码映射表
CREATE TABLE `tb_ewm` (
`ewmid` varchar(20) NOT NULL COMMENT '二维码ID - 主键',
`ewmsj` varchar(200) NOT NULL COMMENT '二维码数据(URL或加密数据)',
`create_time` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`status` tinyint(1) DEFAULT '1' COMMENT '状态(1-有效,0-无效)',
PRIMARY KEY (`ewmid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='二维码表'
关联设计优势分析:
- 唯一性绑定机制:每个农产品对应唯一二维码,通过唯一索引确保溯源信息准确性
- 扩展性架构设计:二维码数据字段长度200字符,预留足够空间存储复杂URL或加密数据
- 多租户支持:通过
qyid明确产品所属企业,支持SaaS化多租户架构 - 生命周期管理:状态字段支持二维码的启用/停用管理

核心功能实现详解
管理员权限控制体系
系统采用分级权限管理架构,超级管理员(tb_cjgly)拥有系统最高权限。登录验证采用MyBatis Plus的QueryWrapper构建动态查询条件,确保安全性。
@Controller
@RequestMapping("/handle")
public class CjglyController {
// 使用SLF4J日志框架记录操作日志
protected Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ICjglyService cjglyService;
/**
* 管理员登录接口
* @param cjgly 管理员登录信息(账号密码)
* @return 登录成功的管理员信息
*/
@RequestMapping(value = "/admin/login", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<Cjgly> adminLogin(@RequestBody @Valid Cjgly cjgly) {
logger.info("管理员登录请求: /handle/admin/login, 参数: {}", cjgly);
try {
// 构建动态查询条件
QueryWrapper<Cjgly> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("zh", cjgly.getZh())
.eq("mm", cjgly.getMm())
.eq("status", 1); // 只查询有效账号
Cjgly cjglyEntity = cjglyService.getOne(queryWrapper);
if (cjglyEntity != null) {
logger.info("管理员登录成功: {}", cjglyEntity.getZh());
return ResponseEntity.ok(cjglyEntity);
} else {
logger.warn("管理员登录失败: 账号或密码错误");
return ResponseEntity.status(401).build();
}
} catch (Exception e) {
logger.error("管理员登录异常", e);
return ResponseEntity.status(500).build();
}
}
}
安全特性深度优化:
- 多层参数校验:结合Spring Validation进行数据完整性验证
- 操作日志审计:使用SLF4J记录详细操作日志,便于安全审计追踪
- 防重复查询:
getOne()方法确保账号唯一性,避免数据重复 - 状态检查:只允许状态正常的账号登录,增强安全性
企业信息全生命周期管理
企业表(tb_qy)包含完整的工商信息字段,支持企业从注册到退出的全生命周期管理。控制器采用RESTful风格设计,实现标准化CRUD操作。
/**
* 企业信息添加接口
* @param cjgly 企业信息实体
* @return 操作结果
*/
@RequestMapping(value = "/admin/add", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<Map<String, Object>> adminAdd(@RequestBody Cjgly cjgly) {
logger.info("添加企业信息请求: /handle/admin/add, 参数: {}", cjgly);
Map<String, Object> result = new HashMap<>();
try {
// 数据完整性校验
if (cjgly.getId() == null || cjgly.getId().trim().isEmpty() ||
cjgly.getMc() == null || cjgly.getMc().trim().isEmpty() ||
cjgly.getMm() == null || cjgly.getMm().trim().isEmpty() ||
cjgly.getZh() == null || cjgly.getZh().trim().isEmpty()) {
result.put("success", false);
result.put("message", "必要参数不能为空");
return ResponseEntity.badRequest().body(result);
}
// 检查账号是否已存在
QueryWrapper<Cjgly> checkWrapper = new QueryWrapper<>();
checkWrapper.eq("zh", cjgly.getZh());
if (cjglyService.count(checkWrapper) > 0) {
result.put("success", false);
result.put("message", "账号已存在");
return ResponseEntity.badRequest().body(result);
}
boolean saveResult = cjglyService.save(cjgly);
result.put("success", saveResult);
result.put("message", saveResult ? "添加成功" : "添加失败");
return ResponseEntity.ok(result);
} catch (Exception e) {
logger.error("添加企业信息异常", e);
result.put("success", false);
result.put("message", "系统异常");
return ResponseEntity.status(500).body(result);
}
}

智能溯源查询与可视化展示
溯源记录查询结合了分页查询和多条件筛选,通过MyBatis的动态SQL能力实现灵活查询,支持复杂业务场景。
/**
* 溯源记录分页查询接口
* @param page 当前页码
* @param limit 每页记录数
* @param ncpName 农产品名称筛选条件
* @return 分页查询结果
*/
@RequestMapping(value = "/sy/list", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> traceabilityList(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int limit,
@RequestParam(required = false) String ncpName) {
logger.info("溯源记录查询: page={}, limit={}, ncpName={}", page, limit, ncpName);
try {
// 构建分页对象
Page<Syly> pageInfo = new Page<>(page, limit);
// 构建动态查询条件
QueryWrapper<Syly> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("sysj"); // 按时间倒序排列
// 农产品名称模糊查询
if (StringUtils.hasText(ncpName)) {
queryWrapper.like("ncpmc", ncpName.trim());
}
// 执行分页查询
IPage<Syly> resultPage = sylyService.page(pageInfo, queryWrapper);
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("code", 0);
result.put("msg", "查询成功");
result.put("count", resultPage.getTotal());
result.put("data", resultPage.getRecords());
logger.info("溯源记录查询成功,共{}条记录", resultPage.getTotal());
return result;
} catch (Exception e) {
logger.error("溯源记录查询异常", e);
Map<String, Object> errorResult = new HashMap<>();
errorResult.put("code", 500);
errorResult.put("msg", "查询失败");
errorResult.put("count", 0);
errorResult.put("data", Collections.emptyList());
return errorResult;
}
}
系统特色与技术创新
溯源链完整性保障
通过多表关联和事务控制,确保从葡萄种植到红酒销售的每一个环节都有完整的数字记录,构建不可篡改的溯源链条。
高性能查询优化
- 数据库索引优化:为关键查询字段建立复合索引
- 缓存机制:Redis缓存热点数据,提升查询响应速度
- 分页查询:大数据量场景下的分页优化,避免内存溢出
安全防护体系
- SQL注入防护:MyBatis参数化查询有效防止SQL注入
- XSS攻击防护:输入输出过滤,防止跨站脚本攻击
- 权限验证:基于角色的访问控制(RBAC)模型
本系统通过SSM框架的深度应用,结合红酒行业特性,打造了一套功能完善、性能优越、安全可靠的溯源与库存管理解决方案,为红酒企业的数字化转型提供了强有力的技术支撑。