在现代制造业和大型设备服务领域,售后备件的管理效率直接关系到企业的运营成本和服务质量。传统的手工记录和分散式管理方式导致备件信息不透明、流转跟踪困难、库存积压与短缺并存等问题频发。针对这一痛点,我们设计并实现了一套企业级售后备件全生命周期管理平台,通过数字化手段对备件从入库、存储、领用到安装的全流程进行精细化管控。
系统架构与技术栈
该平台采用经典的SSM(Spring + Spring MVC + MyBatis)框架组合,构建了清晰的三层架构体系。Spring框架作为核心容器,通过IoC机制管理业务对象的生命周期,利用AOP实现声明式事务管理,确保业务操作的数据一致性。Spring MVC负责Web层的请求分发和响应处理,采用前端控制器模式统一处理HTTP请求,通过注解驱动的方式简化控制器开发。数据持久层选用MyBatis,通过灵活的XML映射文件实现Java对象与关系数据库的高效映射,支持动态SQL和复杂的查询优化。
前端技术栈基于传统的HTML、CSS和JavaScript,结合JSP模板引擎实现页面动态渲染。整个系统采用Maven进行项目构建和依赖管理,数据库使用MySQL 5.7版本,确保了系统的稳定性和性能。
数据库设计亮点分析
用户权限管理体系
sysuser表的设计体现了完善的用户权限控制机制:
CREATE TABLE `sysuser` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`uname` varchar(255) DEFAULT NULL COMMENT '用户名',
`upass` varchar(255) DEFAULT NULL COMMENT '密码',
`utype` varchar(255) DEFAULT NULL COMMENT '用户类型',
`tname` varchar(255) DEFAULT NULL COMMENT '姓名',
`idno` varchar(255) DEFAULT NULL COMMENT '身份证',
`sex` varchar(255) DEFAULT NULL COMMENT '性别',
`email` varchar(255) DEFAULT NULL COMMENT '邮箱',
`addrs` varchar(255) DEFAULT NULL COMMENT '地址',
`birth` varchar(255) DEFAULT NULL COMMENT '生日',
`tel` varchar(255) DEFAULT NULL COMMENT '联系电话',
`status` varchar(255) DEFAULT NULL COMMENT '状态',
`filename` varchar(255) DEFAULT NULL COMMENT '头像',
`savetime` varchar(255) DEFAULT NULL COMMENT '数据入库时间',
`passques` varchar(255) DEFAULT NULL COMMENT '密保问题',
`passans` varchar(255) DEFAULT NULL COMMENT '密保答案',
`departkey` varchar(255) DEFAULT NULL COMMENT '关联表主键,表名depart,关联字段departkey',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='用户表'
该表设计具有以下技术亮点:
- 多维度用户分类:通过
utype字段区分管理员、技术人员、客户等不同角色,实现基于角色的访问控制 - 安全机制完善:除基本的用户名密码外,还设计了密保问题和答案字段,支持账户安全验证
- 扩展性考虑:
departkey字段预留了部门关联接口,支持未来的组织架构扩展 - 性能优化:主键采用自增BIGINT类型,确保在大数据量下的插入性能和索引效率
服务预约流程设计
serviceapply表实现了完整的服务预约业务流程:
CREATE TABLE `serviceapply` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`uname` varchar(255) DEFAULT NULL COMMENT '客户',
`tosaleno` varchar(255) DEFAULT NULL COMMENT '销售单号',
`remo` varchar(255) DEFAULT NULL COMMENT '情况说明',
`sdate` varchar(255) DEFAULT NULL COMMENT '预约日期',
`jsuname` varchar(255) DEFAULT NULL COMMENT '技术人员',
`jhour` varchar(255) DEFAULT NULL COMMENT '到达时间',
`fshstatus` varchar(255) DEFAULT NULL COMMENT '审核状态',
`fshremo` varchar(255) DEFAULT NULL COMMENT '审核意见',
`savetime` varchar(255) DEFAULT NULL COMMENT '登记时间',
`tosalenokey` varchar(255) DEFAULT NULL COMMENT '销售单号_关联表ID',
`sysuserkey` varchar(255) DEFAULT NULL COMMENT '用户表主键',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='服务预约表'
该表设计的精妙之处在于:
- 业务流程状态跟踪:
fshstatus字段明确记录审核状态,配合fshremo审核意见,形成完整的审批流水 - 多表关联设计:通过
tosalenokey和sysuserkey实现与销售单和用户表的外键关联,确保数据一致性 - 时间维度完整:包含预约日期、到达时间和登记时间,支持复杂的时序查询和统计分析
核心功能实现详解
1. 备件检修计划管理
检修计划管理模块实现了对设备维护任务的计划制定、执行跟踪和结果记录。系统通过repairplan表存储计划信息,支持周期性维护和临时性检修任务的统一管理。

控制器层的关键代码实现:
@Controller
@RequestMapping("/repairplan")
public class RepairPlanController {
@Autowired
private RepairPlanService repairPlanService;
@RequestMapping("/save")
@ResponseBody
public Map<String, Object> savePlan(@RequestBody RepairPlan plan,
HttpServletRequest request) {
Map<String, Object> result = new HashMap<>();
try {
if(plan.getId() == null) {
plan.setSavetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
repairPlanService.saveOrUpdate(plan);
result.put("success", true);
result.put("message", "计划保存成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "保存失败:" + e.getMessage());
}
return result;
}
@RequestMapping("/list")
public String planList(@RequestParam Map<String, String> params,
ModelMap model,
HttpServletRequest request) {
// 分页查询逻辑
PageManager pm = new PageManager();
pm.setPageSize(20);
pm.setCurrentPage(StrUtil.str2Int(params.get("page"), 1));
String where = " where 1=1 ";
if(StringUtils.isNotBlank(params.get("stitle"))) {
where += " and stitle like '%" + params.get("stitle") + "%'";
}
if(StringUtils.isNotBlank(params.get("sdate"))) {
where += " and sdate = '" + params.get("sdate") + "'";
}
List<RepairPlan> list = repairPlanService.findByWhere(where + " order by id desc",
pm.getPageSize(),
(pm.getCurrentPage()-1)*pm.getPageSize());
int total = repairPlanService.getCount(where);
pm.setTotal(total);
model.addAttribute("list", list);
model.addAttribute("pm", pm);
model.addAttribute("params", params);
return "repairplan/list";
}
}
服务层的事务控制实现:
@Service
@Transactional
public class RepairPlanServiceImpl implements RepairPlanService {
@Autowired
private RepairPlanDAO repairPlanDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrUpdate(RepairPlan plan) {
if(plan.getId() == null) {
repairPlanDAO.save(plan);
// 同时生成相关的检修任务记录
generateRepairTasks(plan);
} else {
repairPlanDAO.update(plan);
}
}
private void generateRepairTasks(RepairPlan plan) {
// 根据计划内容生成具体的检修任务
// 实现业务逻辑...
}
}
2. 备件库存实时查询与追踪
库存查询模块支持多条件组合查询,技术人员可以快速定位所需备件的库存状态和位置信息。系统通过复杂的SQL查询实现实时库存数据的准确展示。

MyBatis映射文件中的动态SQL实现:
<!-- 备件多条件查询映射 -->
<select id="findSparePartsByCondition" parameterType="map" resultType="SparePart">
SELECT
sp.id,
sp.part_no,
sp.part_name,
sp.specification,
sp.current_stock,
sp.safe_stock,
sp.location,
sp.status,
c.category_name
FROM spare_parts sp
LEFT JOIN category c ON sp.category_id = c.id
<where>
<if test="partNo != null and partNo != ''">
AND sp.part_no LIKE CONCAT('%', #{partNo}, '%')
</if>
<if test="partName != null and partName != ''">
AND sp.part_name LIKE CONCAT('%', #{partName}, '%')
</if>
<if test="categoryId != null">
AND sp.category_id = #{categoryId}
</if>
<if test="status != null and status != ''">
AND sp.status = #{status}
</if>
<if test="minStock != null">
AND sp.current_stock >= #{minStock}
</if>
<if test="maxStock != null">
AND sp.current_stock <= #{maxStock}
</if>
</where>
ORDER BY sp.id DESC
LIMIT #{start}, #{pageSize}
</select>
<!-- 库存统计查询 -->
<select id="getStockStatistics" resultType="map">
SELECT
status,
COUNT(*) as total_count,
SUM(current_stock) as total_stock,
AVG(current_stock) as avg_stock
FROM spare_parts
GROUP BY status
</select>
3. 服务预约与工单管理
客户可以通过系统提交服务预约申请,系统自动分配技术人员并跟踪服务进度。整个流程涉及多角色协同操作,体现了系统的业务流程管理能力。

预约审批流程的控制器实现:
@Controller
@RequestMapping("/serviceapply")
public class ServiceApplyController {
@Autowired
private ServiceApplyService serviceApplyService;
@RequestMapping("/approve")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> approveApplication(@RequestParam Long id,
@RequestParam String status,
@RequestParam(required = false) String remark,
HttpServletRequest request) {
Map<String, Object> result = new HashMap<>();
try {
ServiceApply apply = serviceApplyService.findById(id);
if(apply == null) {
result.put("success", false);
result.put("message", "申请记录不存在");
return result;
}
// 更新审核状态和意见
apply.setFshstatus(status);
apply.setFshremo(remark);
apply.setFshflow("审核人:" + getCurrentUser(request).getTname() +
" 时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
serviceApplyService.update(apply);
// 如果审核通过,生成工单并通知技术人员
if("已通过".equals(status)) {
generateWorkOrder(apply);
notifyTechnician(apply);
}
result.put("success", true);
result.put("message", "审核操作成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "审核失败:" + e.getMessage());
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return result;
}
private void generateWorkOrder(ServiceApply apply) {
// 生成工单的业务逻辑
WorkOrder order = new WorkOrder();
order.setApplyId(apply.getId());
order.setCustomerName(apply.getUname());
order.setTechnician(apply.getJsuname());
order.setScheduleDate(apply.getSdate());
order.setStatus("待处理");
order.setCreateTime(new Date());
// 保存工单...
}
}
4. 备件出入库审批流程
出入库管理实现了严格的审批控制,确保备件流转的规范性和可追溯性。系统通过工作流引擎驱动审批流程,支持多级审核机制。

出入库业务逻辑的核心实现:
@Service
public class InventoryServiceImpl implements InventoryService {
@Autowired
private OutboundDAO outboundDAO;
@Autowired
private SparePartDAO sparePartDAO;
@Override
@Transactional(rollbackFor = Exception.class)
public void approveOutbound(Long outboundId, String approvalResult, String remark) {
OutboundRecord record = outboundDAO.findById(outboundId);
if(record == null) {
throw new RuntimeException("出库记录不存在");
}
if("APPROVED".equals(approvalResult)) {
// 更新库存数量
SparePart part = sparePartDAO.findById(record.getPartId());
if(part.getCurrentStock() < record.getQuantity()) {
throw new RuntimeException("库存不足,当前库存:" + part.getCurrentStock());
}
part.setCurrentStock(part.getCurrentStock() - record.getQuantity());
sparePartDAO.update(part);
record.setStatus("出库完成");
record.setOutboundTime(new Date());
} else {
record.setStatus("审批驳回");
}
record.setApprovalRemark(remark);
record.setApprovalTime(new Date());
outboundDAO.update(record);
// 记录操作日志
logOperation(record, approvalResult);
}
private void logOperation(OutboundRecord record, String action) {
OperationLog log = new OperationLog();
log.setModule("库存管理");
log.setAction(action);
log.setTargetId(record.getId());
log.setOperationTime(new Date());
log.setOperator(getCurrentUser());
// 保存日志...
}
}
实体模型设计精要
系统采用标准的JavaBean规范设计实体类,每个实体对应数据库中的一张表。以检修计划实体为例,展示了完整的ORM映射设计:
@Entity
@Table(name = "repairplan")
public class RepairPlan implements java.io.Serializable {
private Long id;
private String stitle; // 计划标题
private String sdate; // 检修日期
private String remo; // 检修内容
private String planstatus; // 计划执行情况
private String savetime; // 登记时间
// 默认构造器
public RepairPlan() {}
// 全参数构造器
public RepairPlan(Long id, String stitle, String sdate,
String remo, String planstatus, String savetime) {
this.id = id;
this.stitle = stitle;
this.sdate = sdate;
this.remo = remo;
this.planstatus = planstatus;
this.savetime = savetime;
}
// Getter和Setter方法
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "stitle", length = 255)
public String getStitle() {
return this.stitle;
}
public void setStitle(String stitle) {
this.stitle = stitle;
}
// 其他属性的Getter和Setter...
}
实体类设计体现了以下技术特点:
- 序列化支持:实现Serializable接口,支持对象序列化传输
- JPA注解:使用标准的JPA注解实现对象关系映射
- 分层构造器:提供默认构造器和全参数构造器,满足不同场景需求
- 严格的访问控制:属性私有化,通过公共方法进行访问
功能展望与优化方向
基于当前系统架构,未来可以从以下几个方向进行功能增强和技术优化:
1. 引入Redis缓存提升性能
在库存查询、用户会话管理等高频访问场景引入Redis缓存,显著提升系统响应速度。具体实现方案:
@Service
public class SparePartServiceWithCache {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private SparePartDAO sparePartDAO;
private static final String CACHE_KEY_PREFIX = "sparepart:";
private static final long CACHE_EXPIRE_TIME = 1800; // 30分钟
public SparePart findByIdWithCache(Long id) {
String cacheKey = CACHE_KEY_PREFIX + id;
SparePart part = (SparePart) redisTemplate.opsForValue().get(cacheKey);
if(part == null) {
part = sparePartDAO.findById(id);
if(part != null) {
redisTemplate.opsForValue().set(cacheKey, part, CACHE_EXPIRE_TIME, TimeUnit.SECONDS);
}
}
return part;
}
}
2. 微服务架构改造
将单体应用拆分为多个微服务,如用户服务、库存服务、工单服务等,提升系统可扩展性和维护性。使用Spring Cloud实现服务治理:
# application.yml 微服务配置示例
spring:
application:
name: inventory-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
loadbalancer:
enabled: true
server:
port: 8081
# 库存服务独立配置
inventory:
datasource:
url: jdbc: