作为一名在零售行业摸爬滚打多年的技术负责人,我深知库存管理对于超市运营的重要性。最近刚完成了一个基于SSM框架的低价批发超市库存管理系统,今天就来分享一下这个项目的完整实现过程。
这个系统主要解决传统超市库存管理中的三大痛点:手工记录效率低下、数据准确性难以保证、缺乏实时统计分析。系统采用B/S架构,前端使用HTML5+CSS3+JavaScript,后端基于Spring+SpringMVC+MyBatis框架组合,数据库选用MySQL 8.0。整个开发周期约3个月,目前已在实际业务场景中稳定运行半年多。
提示:系统设计时特别考虑了低价批发超市的业务特点,比如高频次的小批量进货、快速周转的商品特性等。
在技术选型阶段,我们对比了多种Java Web开发框架,最终选择SSM组合主要基于以下考虑:
Spring框架:提供了完善的IoC容器和AOP支持,特别是声明式事务管理对库存操作这类需要强一致性的业务场景非常关键。我们通过@Transactional注解就能确保进货、销售等操作的原子性。
SpringMVC:轻量级的MVC框架,与Spring无缝集成。它的拦截器机制让我们能方便地实现权限验证、日志记录等横切关注点。比如下面这段登录验证的拦截器代码:
java复制public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if(!tokenService.verifyToken(token)){
response.sendError(401, "未授权的访问");
return false;
}
return true;
}
}
xml复制<select id="queryStockAlert" resultType="Product">
SELECT * FROM product_info
WHERE stock <
<choose>
<when test="type == 'fastMoving'">#{fastMovingThreshold}</when>
<otherwise>#{normalThreshold}</otherwise>
</choose>
</select>
数据库设计采用了符合第三范式的结构,主要包含以下几类表:
特别说明几个关键设计:
库存字段设计:商品信息表中不仅有当前库存量(current_stock),还设置了安全库存量(safety_stock),当current_stock低于safety_stock时会触发补货提醒。
价格字段:采用DECIMAL(10,2)类型存储,避免浮点数精度问题。同时记录进货价(purchase_price)和销售价(selling_price),便于毛利计算。
操作日志:详细记录每个关键操作的操作用户、时间、IP等信息,满足审计要求。
商品管理是系统的基础模块,实现了完整的CRUD操作。特别优化了以下几个功能点:
java复制public List<Product> importProducts(MultipartFile file) {
try (InputStream is = file.getInputStream();
Workbook workbook = new XSSFWorkbook(is)) {
Sheet sheet = workbook.getSheetAt(0);
List<Product> products = new ArrayList<>();
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
Product product = new Product();
product.setCode(row.getCell(0).getStringCellValue());
product.setName(row.getCell(1).getStringCellValue());
// 其他字段处理...
products.add(product);
}
return productMapper.batchInsert(products);
} catch (IOException e) {
throw new RuntimeException("导入失败", e);
}
}
xml复制<select id="searchProducts" resultType="Product">
SELECT * FROM product_info
<where>
<if test="categoryId != null">
AND category_id = #{categoryId}
</if>
<if test="keyword != null and keyword != ''">
AND (name LIKE CONCAT('%',#{keyword},'%')
OR code LIKE CONCAT('%',#{keyword},'%'))
</if>
<if test="minPrice != null">
AND selling_price >= #{minPrice}
</if>
<if test="maxPrice != null">
AND selling_price <= #{maxPrice}
</if>
</where>
ORDER BY update_time DESC
</select>
库存管理是系统的核心模块,实现了以下关键功能:
入库操作的事务处理示例:
java复制@Transactional
public void stockIn(StockInRecord record) {
// 1. 插入入库记录
stockInMapper.insert(record);
// 2. 更新商品库存
productMapper.updateStock(record.getProductId(),
record.getQuantity());
// 3. 记录库存变动
stockChangeMapper.insert(new StockChange(
record.getProductId(),
record.getQuantity(),
"IN",
record.getOperator()
));
}
库存检查逻辑:
java复制public void validateStock(Long productId, int quantity) {
Integer stock = productMapper.getStockById(productId);
if (stock == null) {
throw new BusinessException("商品不存在");
}
if (stock < quantity) {
throw new BusinessException(
String.format("库存不足,当前库存:%d", stock));
}
}
系统提供了多维度的统计分析功能:
销售分析:
库存分析:
毛利分析:
使用ECharts实现的数据可视化示例:
javascript复制function initSalesChart() {
const chart = echarts.init(document.getElementById('sales-chart'));
const option = {
title: { text: '月度销售趋势' },
tooltip: {},
xAxis: { data: ['1月','2月','3月','4月','5月','6月'] },
yAxis: {},
series: [{
name: '销售额',
type: 'bar',
data: [12500, 18200, 19180, 23490, 29000, 33000]
}]
};
chart.setOption(option);
}
系统采用分层部署架构:
针对库存系统的高并发特点,我们做了以下优化:
数据库优化:
缓存策略:
java复制@Cacheable(value = "product", key = "#id")
public Product getProductById(Long id) {
return productMapper.selectById(id);
}
乐观锁实现示例:
java复制public boolean sellProduct(Long productId, int quantity) {
Product product = productMapper.selectById(productId);
if (product.getStock() < quantity) {
return false;
}
int rows = productMapper.updateStockWithVersion(
productId,
quantity,
product.getVersion());
return rows > 0;
}
在项目开发过程中,我们积累了一些宝贵经验:
库存一致性问题:
批量操作性能:
批量插入配置:
xml复制<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO product(name,code,price) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.name},#{item.code},#{item.price})
</foreach>
</insert>
日期处理:
金额计算:
目前系统已经稳定运行,未来计划从以下几个方向进行扩展:
这个项目让我深刻体会到,一个好的库存系统不仅要技术过关,更要深入理解业务需求。特别是在低价批发这种薄利多销的场景下,每一分库存效率的提升都能直接转化为利润。