在服装租赁行业快速发展的背景下,传统手工管理模式已无法满足现代化运营需求。手工记录导致数据不一致、库存盘点困难、订单跟踪效率低下等问题日益突出。针对这些行业痛点,设计并实现了一套基于SSM框架的智能服装租赁与库存管理系统,该系统通过数字化手段实现了业务流程的全面优化。
系统采用经典的三层架构设计,Spring框架作为核心控制容器,负责依赖注入和事务管理;Spring MVC处理Web层请求响应,实现前后端分离;MyBatis作为数据持久层框架,通过XML配置实现灵活的SQL映射。前端采用HTML+CSS+JavaScript技术栈,结合Ajax实现异步数据交互,整体架构清晰、耦合度低。

数据库设计采用MySQL关系型数据库,共设计10张核心数据表。其中服装信息表(clothing)的设计体现了系统的专业性:
CREATE TABLE clothing (
id INT PRIMARY KEY AUTO_INCREMENT,
clothing_number VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
type_id INT NOT NULL,
size VARCHAR(20),
color VARCHAR(30),
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0,
status ENUM('AVAILABLE','RENTED','MAINTENANCE') DEFAULT 'AVAILABLE',
description TEXT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (type_id) REFERENCES clothing_type(id)
);
该表通过状态字段实现服装生命周期管理,唯一编号确保每件服装的可追溯性,价格和库存数量字段为租赁计费提供数据支撑。时间戳字段自动记录数据变更,便于审计和数据分析。
租赁订单表(rental_order)的设计同样具有亮点:
CREATE TABLE rental_order (
id INT PRIMARY KEY AUTO_INCREMENT,
order_number VARCHAR(60) UNIQUE NOT NULL,
customer_id INT NOT NULL,
clothing_id INT NOT NULL,
rental_date DATE NOT NULL,
expected_return_date DATE NOT NULL,
actual_return_date DATE,
rental_days INT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
deposit DECIMAL(10,2) DEFAULT 0,
status ENUM('PENDING','ACTIVE','COMPLETED','OVERDUE') DEFAULT 'PENDING',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customer(id),
FOREIGN KEY (clothing_id) REFERENCES clothing(id)
);
订单表通过状态机设计实现租赁流程控制,预计归还日期和实际归还日期的分离为逾期计算提供基础,押金字段支持灵活的收费策略。
在核心功能实现方面,服装信息管理模块通过分层架构实现了完整的数据操作。实体类设计遵循JavaBean规范:
@Entity
@Table(name = "clothing")
public class Clothing {
private Integer id;
private String clothingNumber;
private String name;
private ClothingType type;
private String size;
private String color;
private BigDecimal price;
private Integer stockQuantity;
private String status;
private String description;
// Getter和Setter方法
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
@Column(name = "clothing_number", unique = true, nullable = false)
public String getClothingNumber() { return clothingNumber; }
public void setClothingNumber(String clothingNumber) {
this.clothingNumber = clothingNumber;
}
}
数据访问层采用MyBatis的注解方式实现CRUD操作:
@Mapper
public interface ClothingMapper {
@Insert("INSERT INTO clothing(clothing_number, name, type_id, size, " +
"color, price, stock_quantity, status, description) " +
"VALUES(#{clothingNumber}, #{name}, #{type.id}, #{size}, " +
"#{color}, #{price}, #{stockQuantity}, #{status}, #{description})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Clothing clothing);
@Update("UPDATE clothing SET name=#{name}, type_id=#{type.id}, " +
"size=#{size}, color=#{color}, price=#{price}, " +
"stock_quantity=#{stockQuantity}, status=#{status}, " +
"description=#{description} WHERE id=#{id}")
int update(Clothing clothing);
@Select("SELECT c.*, ct.name as type_name FROM clothing c " +
"LEFT JOIN clothing_type ct ON c.type_id = ct.id " +
"WHERE c.id = #{id}")
@Results({
@Result(property = "type.id", column = "type_id"),
@Result(property = "type.name", column = "type_name")
})
Clothing selectById(Integer id);
}
业务逻辑层封装了复杂的业务规则,确保数据一致性:
@Service
@Transactional
public class ClothingService {
@Autowired
private ClothingMapper clothingMapper;
@Autowired
private InventoryService inventoryService;
public void addClothing(Clothing clothing) {
// 验证服装编号唯一性
if (clothingMapper.selectByNumber(clothing.getClothingNumber()) != null) {
throw new BusinessException("服装编号已存在");
}
// 设置默认状态
if (clothing.getStatus() == null) {
clothing.setStatus("AVAILABLE");
}
// 插入服装记录
clothingMapper.insert(clothing);
// 初始化库存记录
InventoryRecord record = new InventoryRecord();
record.setClothingId(clothing.getId());
record.setChangeType("INIT");
record.setChangeQuantity(clothing.getStockQuantity());
record.setRemarks("初始入库");
inventoryService.addInventoryRecord(record);
}
public void updateStock(Integer clothingId, Integer quantity) {
Clothing clothing = clothingMapper.selectById(clothingId);
if (clothing == null) {
throw new BusinessException("服装不存在");
}
int newStock = clothing.getStockQuantity() + quantity;
if (newStock < 0) {
throw new BusinessException("库存不足");
}
clothingMapper.updateStock(clothingId, newStock);
}
}
控制层处理HTTP请求,提供RESTful API接口:
@Controller
@RequestMapping("/clothing")
public class ClothingController {
@Autowired
private ClothingService clothingService;
@PostMapping("/add")
@ResponseBody
public Result addClothing(@Valid @RequestBody Clothing clothing,
BindingResult result) {
if (result.hasErrors()) {
return Result.error(result.getFieldError().getDefaultMessage());
}
try {
clothingService.addClothing(clothing);
return Result.success("添加成功");
} catch (BusinessException e) {
return Result.error(e.getMessage());
}
}
@GetMapping("/list")
@ResponseBody
public PageResult<Clothing> getClothingList(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
String keyword, Integer typeId) {
PageHelper.startPage(page, limit);
List<Clothing> list = clothingService.getClothingList(keyword, typeId);
PageInfo<Clothing> pageInfo = new PageInfo<>(list);
return new PageResult<>(pageInfo.getTotal(), list);
}
}

租赁管理模块实现了完整的业务流程控制。租赁订单创建服务包含复杂的业务逻辑验证:
@Service
public class RentalService {
public RentalOrder createRentalOrder(RentalOrder order) {
// 验证服装可用性
Clothing clothing = clothingService.getById(order.getClothingId());
if (!"AVAILABLE".equals(clothing.getStatus())) {
throw new BusinessException("服装当前不可租赁");
}
if (clothing.getStockQuantity() <= 0) {
throw new BusinessException("服装库存不足");
}
// 计算租赁费用
BigDecimal totalAmount = calculateRentalAmount(
clothing.getPrice(), order.getRentalDays());
order.setTotalAmount(totalAmount);
// 生成唯一订单号
order.setOrderNumber(generateOrderNumber());
// 保存订单记录
rentalOrderMapper.insert(order);
// 更新服装状态和库存
clothingService.updateStock(order.getClothingId(), -1);
clothingService.updateStatus(order.getClothingId(), "RENTED");
return order;
}
private String generateOrderNumber() {
return "RO" + System.currentTimeMillis() +
String.format("%04d", new Random().nextInt(10000));
}
}
库存管理模块通过触发器式的设计实现库存变化的自动跟踪:
@Service
public class InventoryService {
@Transactional
public void processInventoryChange(InventoryChange change) {
// 记录库存变更历史
InventoryHistory history = new InventoryHistory();
history.setClothingId(change.getClothingId());
history.setChangeType(change.getChangeType());
history.setChangeQuantity(change.getQuantity());
history.setRemarks(change.getRemarks());
inventoryHistoryMapper.insert(history);
// 更新当前库存
Clothing clothing = clothingMapper.selectById(change.getClothingId());
int newStock = clothing.getStockQuantity() + change.getQuantity();
clothingMapper.updateStock(change.getClothingId(), newStock);
// 自动更新服装状态
if (newStock > 0 && !"AVAILABLE".equals(clothing.getStatus())) {
clothingMapper.updateStatus(change.getClothingId(), "AVAILABLE");
} else if (newStock == 0) {
clothingMapper.updateStatus(change.getClothingId(), "SOLD_OUT");
}
}
}

系统通过统一的异常处理机制保障稳定性:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
@ResponseBody
public Result handleBusinessException(BusinessException e) {
return Result.error(e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseBody
public Result handleException(Exception e) {
logger.error("系统异常:", e);
return Result.error("系统繁忙,请稍后重试");
}
}
public class Result {
private boolean success;
private String message;
private Object data;
public static Result success(Object data) {
return new Result(true, "操作成功", data);
}
public static Result error(String message) {
return new Result(false, message, null);
}
}
用户管理和权限控制模块确保系统安全性:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User login(String username, String password) {
User user = userMapper.selectByUsername(username);
if (user == null) {
throw new BusinessException("用户不存在");
}
if (!password.equals(user.getPassword())) {
throw new BusinessException("密码错误");
}
if (!"ACTIVE".equals(user.getStatus())) {
throw new BusinessException("账户已被禁用");
}
return user;
}
@Transactional
public void changePassword(Integer userId, String oldPassword, String newPassword) {
User user = userMapper.selectById(userId);
if (!oldPassword.equals(user.getPassword())) {
throw new BusinessException("原密码错误");
}
userMapper.updatePassword(userId, newPassword);
}
}

系统在数据查询优化方面采用了多种策略。复杂查询通过MyBatis的动态SQL实现:
<select id="selectRentalOrders" parameterType="map" resultMap="RentalOrderResult">
SELECT o.*, c.name as customer_name, cl.name as clothing_name
FROM rental_order o
LEFT JOIN customer c ON o.customer_id = c.id
LEFT JOIN clothing cl ON o.clothing_id = cl.id
<where>
<if test="customerName != null and customerName != ''">
AND c.name LIKE CONCAT('%', #{customerName}, '%')
</if>
<if test="clothingName != null and clothingName != ''">
AND cl.name LIKE CONCAT('%', #{clothingName}, '%')
</if>
<if test="status != null and status != ''">
AND o.status = #{status}
</if>
<if test="startDate != null">
AND o.rental_date >= #{startDate}
</if>
<if test="endDate != null">
AND o.rental_date <= #{endDate}
</if>
</where>
ORDER BY o.create_time DESC
</select>
在系统性能优化方面,通过数据库索引设计和查询优化提升响应速度:
-- 为频繁查询的字段创建索引
CREATE INDEX idx_clothing_type ON clothing(type_id);
CREATE INDEX idx_clothing_status ON clothing(status);
CREATE INDEX idx_rental_order_date ON rental_order(rental_date);
CREATE INDEX idx_rental_order_status ON rental_order(status);
CREATE INDEX idx_customer_name ON customer(name);
针对未来系统扩展,可以考虑以下几个优化方向:首先,引入Redis缓存层,将热点数据如服装分类、用户信息等缓存至内存,减少数据库访问压力。实现方案可以通过Spring Cache注解统一管理缓存策略。
其次,开发移动端应用,通过RESTful API为手机客户端提供数据接口,使用JWT令牌实现跨平台身份认证。移动端可以重点实现扫码租赁、移动支付等便捷功能。
第三,集成智能预警系统,基于历史租赁数据建立预测模型,实现库存预警、租赁高峰期预测等功能。可以通过Spring Batch处理批量数据,使用Quartz调度定时分析任务。
第四,引入微服务架构重构系统,将用户服务、库存服务、订单服务等拆分为独立微服务,通过Spring Cloud实现服务治理,提升系统可扩展性和容错能力。
最后,增强数据分析功能,利用ELK栈实现操作日志分析,通过数据可视化技术展示经营指标,为管理决策提供数据支持。可以集成ECharts等前端图表库实现丰富的可视化效果。
系统通过严谨的架构设计和细致的功能实现,为服装租赁行业提供了完整的数字化解决方案。模块化的设计使得系统具有良好的可维护性和扩展性,为后续功能迭代奠定了坚实的技术基础。