1. 项目背景与核心价值
最近在帮一家小型商贸公司搭建库存管理系统时,发现市面上成熟的ERP系统对小微企业来说存在两个痛点:一是功能过于复杂,二是年费动辄上万元。于是我用Python+微信小程序开发了一套轻量级进销存系统,上线三个月来日均处理200+出入库单,稳定运行零故障。这种技术组合特别适合50人以下的企业,开发成本可控,员工上手门槛低。
微信小程序作为前端有天然优势:无需安装、跨平台、支持扫码功能。而后端选择Python主要考虑到快速开发和丰富的库支持。系统核心功能包括:
- 实时库存查询(含批次/效期管理)
- 采购入库/销售出库全流程电子化
- 自动生成库存周转率等经营报表
- 低库存预警和效期预警
2. 技术架构设计
2.1 整体技术栈选型
采用前后端分离架构:
code复制前端:微信小程序 + Vant Weapp组件库
后端:Python 3.8 + Flask框架
数据库:MySQL 8.0(小型企业可用SQLite替代)
部署:Nginx + uWSGI(Windows服务器可用Waitress)
选择Flask而非Django的原因是进销存系统业务逻辑相对简单但需要高度定制化。实测表明,在200并发量下,Flask响应时间能稳定在300ms以内。
2.2 数据库关键表设计
python复制class Product(db.Model):
__tablename__ = 'products'
id = db.Column(db.Integer, primary_key=True)
sku = db.Column(db.String(32), unique=True) # 商品编码
name = db.Column(db.String(64))
spec = db.Column(db.String(32)) # 规格
unit = db.Column(db.String(8)) # 单位
class Inventory(db.Model):
__tablename__ = 'inventory'
id = db.Column(db.Integer, primary_key=True)
product_id = db.Column(db.Integer, db.ForeignKey('products.id'))
batch_no = db.Column(db.String(32)) # 批次号
expiry_date = db.Column(db.Date) # 过期日期
quantity = db.Column(db.Integer)
locked = db.Column(db.Boolean) # 是否质检锁定
特别注意:库存变更必须通过事务处理,避免超卖:
python复制@transaction.atomic
def update_inventory(product_id, change_qty):
inv = Inventory.query.filter_by(product_id=product_id).first()
if inv.quantity + change_qty < 0:
raise ValueError("库存不足")
inv.quantity += change_qty
3. 核心功能实现细节
3.1 微信小程序扫码入库
前端关键代码:
javascript复制// 调用手机摄像头扫码
wx.scanCode({
success: (res) => {
this.setData({ sku: res.result }) // 自动填充商品编码
}
})
后端需处理扫码防重:
python复制@app.route('/api/scan', methods=['POST'])
def handle_scan():
sku = request.json.get('sku')
# 30秒内相同SKU扫码视为重复操作
if cache.get(f'scan_lock_{sku}'):
return jsonify(error="请勿重复扫码")
cache.set(f'scan_lock_{sku}', 1, timeout=30)
...
3.2 库存扣减分布式事务
采用预扣减+定时任务补偿的方案:
- 订单创建时先扣减"可用库存"
- 支付成功后扣减"实际库存"
- 每小时执行补偿任务:
python复制def inventory_compensation():
# 处理超时未支付订单
orders = Order.query.filter(
Order.status == 'unpaid',
Order.created_at < datetime.now() - timedelta(hours=1)
)
for order in orders:
rollback_inventory(order) # 库存回滚
4. 性能优化实践
4.1 库存查询缓存策略
使用两级缓存:
- 热数据:Redis缓存最近访问的100个商品库存
- 全量数据:MySQL定时同步到Elasticsearch(5000商品以下可不使用)
python复制def get_inventory(product_id):
# 先查Redis
cache_key = f'inventory_{product_id}'
cached = redis.get(cache_key)
if cached:
return json.loads(cached)
# 再查数据库
inv = Inventory.query.get(product_id)
# 写入Redis并设置5分钟过期
redis.setex(cache_key, 300, json.dumps(inv.to_dict()))
return inv
4.2 报表生成优化
采用预聚合技术:每天凌晨计算各商品销量、库存周转率等指标,存入statistics表。查询时直接读取预处理数据,响应时间从秒级降到毫秒级。
5. 部署与运维要点
5.1 微信小程序配置关键点
- 必须配置合法域名(需ICP备案)
- 在app.json中设置导航栏高度适配:
json复制{
"window": {
"navigationBarHeight": 48
}
}
5.2 Python服务部署建议
生产环境推荐配置:
ini复制[uwsgi]
http = :5000
master = true
processes = 4
threads = 2
buffer-size = 32768
6. 踩坑经验实录
-
微信小程序登录态维护
采用双Token方案(access_token + refresh_token),access_token有效期2小时,refresh_token有效期7天。注意refresh_token必须HTTPS传输。 -
库存超卖问题
初期使用简单SQL更新导致超卖,后改为:sql复制UPDATE inventory SET quantity = quantity - 1 WHERE product_id=123 AND quantity >= 1 -
批量导入性能
实测1000条商品数据导入:- 逐条INSERT:38秒
- 批量INSERT:1.2秒
- 使用LOAD DATA INFILE:0.3秒
建议使用pandas处理Excel导入:
python复制df = pd.read_excel(upload_file)
# 分批提交
for chunk in np.array_split(df, 10):
db.session.bulk_insert_mappings(Product, chunk.to_dict('records'))
7. 扩展功能建议
-
移动端盘点功能
增加蓝牙扫码枪支持,盘点时自动比对系统库存 -
供应商协同
开发供应商端小程序,实现采购订单自动同步 -
智能预警
基于历史销售数据,使用Prophet库预测未来库存需求
这套系统经过三个月的迭代开发,目前已在5家小微企业稳定运行。最大的收获是认识到:技术方案必须匹配业务规模,小微企业更需要"够用就好"的轻量级解决方案。
