小程序进销存管理系统技术实现
系统支持采购单录入、审核、入库、退货等采购过程记录追踪,以及销售、出库、审核、退货等跟踪。支持产品出入库数据导出,并具备用户与仓库管理能力。

采购流程状态管理
采购单状态配置如下:
// 采购单状态配置
const PURCHASE_STATUS = {
DRAFT: {code: 0, name: '草稿'},
AUDIT: {code: 1, name: '待审核'},
STOCK_IN: {code: 2, name: '已入库'},
RETURNED: {code: 3, name: '已退货'}
};
状态流转使用 Vuex 做全局管理,审核动作触发时会校验仓库权限。不同仓库管理员只能操作自己管辖的仓库,权限验证中间件逻辑如下:
// 仓库操作权限校验
export const warehouseAuth = (warehouseId) => {
return async (ctx, next) => {
const userWarehouses = ctx.state.user.warehouses;
if (!userWarehouses.includes(warehouseId)) {
throw new Error('无该仓库操作权限');
}
await next();
};
};
销售模块库存扣减
销售模块最实用的是出库防呆设计。生成出库单时会实时校验库存,用 MongoDB 的原子操作避免超卖:
// 库存扣减原子操作
ProductSchema.methods.deductStock = function(num) {
return this.updateOne({
$inc: { stock: -num },
$set: { updateTime: Date.now() }
});
};
数据导出与多仓库设计
数据导出功能使用了 uni-file-picker 组件,导出 Excel 时注意处理时间格式:
<uni-file-picker limitType="[.xlsx]" @select="handleExport" />
// 处理时间戳转换
function formatDate(timestamp) {
return new Date(timestamp).toISOString().split('T')[0];
}
多仓库实现的关键在数据库设计,每个库存记录都带 warehouseId 字段。调拨操作其实可以看作出库加入库的组合事务,记得加@Transactional 注解防止数据不一致。

用户权限体系
用户体系用 RBAC 模型,权限树存在 Redis 里加速鉴权。创建用户时自动生成仓库白名单,这个关联关系在用户 - 仓库中间表里维护。

状态机与性能优化
状态机设计较为复杂,特别是退货流程要和采购销售状态联动。后来用策略模式封装不同状态的操作,代码清爽不少。比如退货处理器基类:
abstract class ReturnHandler {
abstract validate(order: Order): boolean;
abstract execute(order: Order): Promise<void>;
}
性能优化上有个方案——给高频接口加了 redis 缓存,但库存相关的一律不走缓存。用装饰器实现还挺方便:
@Cacheable({ ttl: 60 })
async getProductList() {
// 查询逻辑
}
项目架构中值得借鉴的是错误处理机制,用 uni-app 的全局拦截器统一处理:
// 请求拦截
uni.addInterceptor('request', {
fail: (err) => {
if (err.statusCode === 403) {
uni.showToast({ title: '权限不足', icon: 'none' });
}
}
});
该系统业务流程闭环完整。二次开发时建议先理清状态流转图,改起来才不容易出错。仓库模块的树形结构可以套用现成组件,但注意深度别超过三级,手机端展示会变形。



