1. 项目背景与技术选型解析
福泰轴承进销存系统是一个典型的制造业企业资源管理解决方案。作为一家轴承制造企业,其业务涉及原材料采购、生产加工、库存管理和销售配送等多个环节,对数据的实时性和准确性要求极高。这套系统采用当前主流的Java Web技术栈实现,完美匹配了中型制造企业的数字化管理需求。
技术架构上采用前后端分离设计,后端基于SpringBoot2框架开发。SpringBoot的自动配置特性大幅简化了传统SSM框架的XML配置工作,内置Tomcat服务器也让部署变得异常简单。我们选择2.x版本而非最新的3.x,主要考虑到企业环境中JDK版本的兼容性要求——很多制造企业仍在使用JDK8运行环境。
前端选用Vue3组合式API开发,相比Options API更利于功能模块的封装复用。特别是对于包含大量表单操作的进销存系统,Vue3的响应式性能优化能显著提升操作体验。搭配Element Plus组件库,可在两周内快速构建出专业级的管理界面。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能模块详解
2.1 采购管理子系统
采用状态机模式设计采购单流转流程:
java复制public enum PurchaseStatus {
DRAFT, APPROVING, APPROVED,
STOCK_IN, FINISHED, CANCELLED
}
包含供应商评估模型,根据交货准时率、质量合格率等KPI自动计算供应商评级。核心数据库表设计:
sql复制CREATE TABLE `purchase_order` (
`id` bigint PRIMARY KEY COMMENT '雪花算法ID',
`supplier_id` bigint NOT NULL COMMENT '供应商ID',
`total_amount` decimal(12,2) COMMENT '含税总金额',
`status` varchar(20) COMMENT '审批状态',
`payment_terms` varchar(255) COMMENT '付款条件',
`creator_id` bigint COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.2 智能库存预警
实现动态安全库存计算算法:
java复制public BigDecimal calculateSafetyStock(Long itemId) {
// 获取最近30天日均消耗量
BigDecimal avgDailyUsage = inventoryMapper.selectDailyUsage(itemId, 30);
// 获取平均补货周期(天)
int leadTime = supplierService.getAvgLeadTime(itemId);
// 安全库存 = 日均用量 × 补货周期 × 安全系数(1.2-1.5)
return avgDailyUsage.multiply(new BigDecimal(leadTime))
.multiply(new BigDecimal(1.3));
}
当库存量低于安全阈值时,系统会自动生成采购建议单,并通过企业微信通知采购负责人。
3. 关键技术实现
3.1 MyBatis-Plus高级应用
在物料编码管理模块中,我们使用MP的Lambda表达式构建动态查询:
java复制public Page<Material> queryMaterials(MaterialQuery query) {
return lambdaQuery()
.like(StringUtils.isNotBlank(query.getCode()), Material::getCode, query.getCode())
.eq(query.getCategoryId() != null, Material::getCategoryId, query.getCategoryId())
.between(query.getCreateTimeRange() != null,
Material::getCreateTime,
query.getCreateTimeRange()[0],
query.getCreateTimeRange()[1])
.orderByDesc(Material::getCreateTime)
.page(new Page<>(query.getPage(), query.getSize()));
}
同时配置了逻辑删除标记:
yaml复制mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除字段
logic-delete-value: 1 # 删除值
logic-not-delete-value: 0 # 未删除值
3.2 Vue3组合式API封装
针对频繁使用的CRUD操作,我们封装了useTableComposable:
javascript复制export function useTable(api, columns) {
const loading = ref(false)
const dataSource = ref([])
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0
})
const fetchData = async (params = {}) => {
try {
loading.value = true
const res = await api({
...params,
pageNum: pagination.current,
pageSize: pagination.pageSize
})
dataSource.value = res.data.list
pagination.total = res.data.total
} finally {
loading.value = false
}
}
return {
loading,
dataSource,
pagination,
fetchData
}
}
4. 部署与性能优化
4.1 MySQL8.0特性应用
利用窗口函数优化报表查询:
sql复制SELECT
product_id,
month,
sales_amount,
SUM(sales_amount) OVER(PARTITION BY product_id ORDER BY month) AS cumulative_amount,
RANK() OVER(PARTITION BY month ORDER BY sales_amount DESC) AS sales_rank
FROM sales_statistics
WHERE year = 2023;
配置了多源数据同步,将高频访问的产品目录数据缓存到Redis:
java复制@Cacheable(value = "product", key = "#id")
public Product getProductById(Long id) {
return productMapper.selectById(id);
}
4.2 安全防护措施
- 采用Spring Security + JWT实现认证授权
- 所有接口添加@PreAuthorize注解进行权限控制
- 使用Log4j2异步日志记录关键操作审计
- 定期备份策略:每日增量备份 + 每周全量备份
5. 开发经验与避坑指南
- 批量导入性能优化:当需要导入上万条库存记录时,避免逐条insert,应采用MyBatis的批量插入:
java复制sqlSessionTemplate.execute(sqlSession -> {
MaterialMapper mapper = sqlSession.getMapper(MaterialMapper.class);
for (Material material : materials) {
mapper.insert(material);
if (i % 500 == 0) {
sqlSession.flushStatements();
}
}
return null;
});
- 树形结构存储方案:对于产品分类等树形数据,我们采用MP的@TableField(typeHandler = JsonTypeHandler)存储JSON结构,相比邻接表更方便递归查询:
java复制@Data
public class Category {
private Long id;
private String name;
@TableField(typeHandler = JsonTypeHandler.class)
private List<Long> childrenIds;
}
- 事务失效场景:在采购审批流程中,发现@Transactional在内部方法调用时不生效,最终采用AOP代理解决:
java复制@Service
public class PurchaseService {
// 必须通过代理对象调用
@Autowired
private PurchaseService selfProxy;
public void approve(Long id) {
// 其他逻辑...
selfProxy.updateStock(id); // 通过代理对象调用
}
@Transactional
public void updateStock(Long purchaseId) {
// 更新库存操作...
}
}
- 前端性能陷阱:在展示大型数据表格时,Element Plus的el-table组件需要设置virtual-scroll属性避免渲染卡顿:
vue复制<el-table
:data="tableData"
height="600"
virtual-scroll
:row-height="50">
<!-- 列定义 -->
</el-table>
