markdown复制## 1. 项目背景与核心价值
在快消品行业摸爬滚打多年,最让人头疼的就是库存管理问题。商品效期短、周转快,一个不留神就可能造成大量临期损耗。去年我们团队用Flutter重构了原有库存系统,实现了鸿蒙与Android/iOS多端适配,特别是动态库存可视化与效期预警功能上线后,门店损耗率直接下降了37%。这套方案的核心在于:
- **多端一致性**:基于Flutter的跨平台特性,一套代码同时运行在鸿蒙、iOS和Android设备上
- **实时数据驱动**:通过WebSocket连接后端ERP系统,库存变动秒级响应
- **智能预警算法**:结合商品特性动态计算安全库存阈值,不同品类有不同的预警策略
- **三维可视化**:用CustomPaint实现仓库货架立体展示,红黄绿三色标识效期状态
> 关键提示:快消品库存管理必须考虑"先进先出"原则,可视化设计要能直观反映货架位置和入库时间
## 2. 技术架构设计
### 2.1 整体技术栈选型
这套系统采用分层架构设计,主要技术决策如下:
| 层级 | 技术方案 | 选型理由 |
|-------------|-----------------------------------|--------------------------------------------------------------------------|
| 前端框架 | Flutter 3.7 | 支持鸿蒙OS的skia渲染引擎,一套代码多端部署 |
| 状态管理 | Riverpod + Freezed | 类型安全的不可变状态管理,适合高频更新的库存数据流 |
| 图表库 | 自研基于CustomPaint的3D货架渲染 | 现有图表库无法满足立体货架展示需求 |
| 通信协议 | WebSocket + Protobuf | 实时数据传输效率比REST高60%,Protobuf减小报文体积 |
| 本地缓存 | Hive + Isar | 支持离线操作,网络恢复后自动同步 |
### 2.2 核心业务逻辑实现
库存预警的核心算法采用动态权重计算:
```dart
class InventoryAlertLogic {
// 效期权重 = (当前日期 - 生产日期) / (保质期天数) * 100
double _calculateExpiryWeight(Product product) {
final daysPassed = DateTime.now().difference(product.produceDate).inDays;
return (daysPassed / product.shelfLife) * 100;
}
// 动态安全库存 = 日均销量 × (补货周期 + 安全系数)
double _calculateSafetyStock(Product product) {
final avgSales = product.last30DaysSales / 30;
return avgSales * (product.replenishCycle + _getSeasonalFactor());
}
// 季节性系数算法(春节/双11等场景)
double _getSeasonalFactor() {...}
}
3. 关键功能实现细节
3.1 动态库存可视化
货架三维展示采用矩阵变换实现透视效果:
-
数据建模:将仓库物理货架映射为二维矩阵
dart复制class WarehouseShelf { final List<List<Pallet>> grid; // 货架网格 final double depthFactor; // 景深系数 } -
视觉渲染:通过Transform矩阵实现3D效果
dart复制Transform( transform: Matrix4.identity() ..setEntry(3, 2, 0.001) // 透视 ..rotateX(0.2), // 俯视角度 child: CustomPaint(...) ) -
颜色编码:
- 绿色:效期剩余>70%
- 黄色:30%-70%
- 红色:<30%或低于安全库存
3.2 效期预警系统
预警触发逻辑包含多级处理:
-
初级预警:库存量低于安全线时触发
- 通知采购人员
- 在可视化界面闪烁货位
-
中级预警:商品效期过半且周转率低于阈值
- 推送店长APP通知
- 自动生成促销建议
-
紧急预警:临期7天内
- 触发声光报警
- 锁定库存禁止出库
- 生成报废处理单
4. 性能优化实践
4.1 大数据量渲染优化
当单仓SKU超过5000时,常规渲染会导致卡顿。我们采用以下方案:
- 按需加载:只渲染可视区域内的货架
- 对象池复用:复用Pallet组件避免频繁创建销毁
- 离屏渲染:对静态货架背景预渲染为图片
dart复制class PalletPool {
final Queue<Pallet> _available = Queue();
Pallet getPallet() {
return _available.isEmpty ? _createPallet() : _available.removeFirst();
}
void release(Pallet pallet) {
_available.add(pallet..resetState());
}
}
4.2 多端适配技巧
鸿蒙平台的特别处理:
-
字体渲染:鸿蒙默认字体与Android不同,需要显式指定字体族
yaml复制flutter: fonts: - family: HarmonySans fonts: - asset: assets/fonts/HarmonyOS_Sans_SC_Regular.ttf -
手势冲突:鸿蒙的返回手势需要特别处理
dart复制WillPopScope( onWillPop: () async { if (_isEditing) { showSaveDialog(); return false; } return true; }, child: Scaffold(...) )
5. 踩坑实录与解决方案
5.1 WebSocket断连问题
在弱网环境下发现的典型问题:
- 现象:华为MatePad Pro切换WiFi时数据不同步
- 根因:网络切换时WebSocket没有自动重连
- 解决方案:
dart复制final socket = WebSocketChannel.connect( Uri.parse('wss://inventory.example.com'), pingInterval: Duration(seconds: 30), ); // 监听连接状态 socket.stream.listen( (data) => _handleData(data), onDone: () => _reconnect(), onError: (e) => _reconnect(), );
5.2 鸿蒙平台图表闪烁
特定设备上的渲染异常:
- 现象:荣耀平板V7 Pro上货架图表会随机闪烁
- 根因:鸿蒙的GPU驱动对skia的图层合成有兼容问题
- 修复方案:
dart复制RepaintBoundary( child: CustomPaint( painter: ShelfPainter(), child: const SizedBox.expand(), ), )
6. 扩展思考与优化方向
在实际运营中我们还发现几个可改进点:
-
预测算法增强:目前的安全库存计算没有考虑天气、节假日等外部因素,下一步准备接入气象数据API
-
AR货架导航:结合ARKit/ARCore实现通过手机摄像头快速定位问题货位
-
语音交互:仓库作业时双手不便操作,正在测试"小艺/小爱同学,查找临期商品"的语音控制方案
这套系统最让我意外的收获是:原本只为了解决库存问题做的技术方案,后来发现销售部门也会每天查看商品热力图来调整陈列位置,技术赋能业务往往会有意想不到的延伸价值。
code复制