升鮮寶生鮮配送供應(yīng)鏈管理系統(tǒng)---- 門店收銀 POS 離線工作設(shè)計文檔(支持線上線下一體化)---02
門店收銀 POS 離線工作設(shè)計文檔(支持線上線下一體化)
- ?? 背景與目標(biāo)
在門店運營中,POS 端(收銀機/安卓終端)經(jīng)常會遇到以下情況:
? 網(wǎng)絡(luò)中斷(Wi-Fi、4G、服務(wù)器不可達(dá));
? 臨時維護或總部系統(tǒng)升級;
? 云端數(shù)據(jù)同步延遲。
因此,系統(tǒng)必須支持 離線工作模式(Offline Mode),保證收銀業(yè)務(wù)不中斷,并在網(wǎng)絡(luò)恢復(fù)后實現(xiàn)數(shù)據(jù)自動同步與校驗。
目標(biāo)
目標(biāo)
描述
? 離線可用
斷網(wǎng)時仍能銷售、掛單、打印、收款
? 數(shù)據(jù)安全
所有離線交易加密存儲本地
? 自動同步
網(wǎng)絡(luò)恢復(fù)后自動上傳銷售單、更新庫存
? 差異對賬
離線與云端自動校驗、沖突檢測
? 快速響應(yīng)
商品、會員、價格從本地緩存讀取
- ?? 總體架構(gòu)設(shè)計
2.1 架構(gòu)圖(簡化)
┌───────────────┐ ┌───────────────┐
│ 云端服務(wù)端 │ ←Kafka→ │ 消息中間件 │
│ (Spring Boot) │ │ (Redis / MQ) │
└───────────────┘ └───────────────┘
↑ ↑
│HTTP/API │Push
│ │
┌────────────────────────────┐
│ POS 端離線緩存引擎 (WPF/Android) │
│ - SQLite本地數(shù)據(jù)庫 │
│ - 數(shù)據(jù)版本號控制 │
│ - 本地消息隊列(未同步訂單) │
└────────────────────────────┘
2.2 數(shù)據(jù)同步機制
模塊
數(shù)據(jù)流方向
同步方式
商品、會員、價格
云端 → POS
增量拉取 + WebSocket 推送
庫存變動
雙向
Kafka 消息同步
訂單
POS → 云端
離線緩存后自動上報
交接班記錄
POS → 云端
上傳并鎖定
打印模板
云端 → POS
手動或定時拉取
- ?? 本地緩存設(shè)計(SQLite)
離線POS端通過內(nèi)嵌SQLite存儲關(guān)鍵數(shù)據(jù)表:
表名
描述
local_member
會員緩存(member_id、姓名、手機號、余額、積分、等級)
local_product
商品信息(sku_code、名稱、價格、庫存、本地版本號)
local_price
門店價格與會員價、階梯價
local_order
本地訂單主表(含未同步標(biāo)志)
local_order_item
本地訂單明細(xì)
local_stock
本地庫存緩存
local_version
各模塊版本號對照表
sync_log
同步任務(wù)記錄與狀態(tài)(PENDING / SYNCED / FAILED)
- ?? 數(shù)據(jù)同步策略
4.1 版本號控制機制
每類數(shù)據(jù)(商品、會員、價格、庫存)均維護一個版本號字段。
字段
說明
version_id
自增版本號(云端維護)
last_sync_version
POS 端上次同步版本
change_flag
記錄數(shù)據(jù)是否變動
同步邏輯示例:
SELECT * FROM product WHERE version_id > @last_sync_version;
UPDATE local_version SET last_sync_version = @max_version;
4.2 離線訂單同步流程
- POS 在離線狀態(tài)下創(chuàng)建訂單:
INSERT INTO local_order (order_code, member_id, total_amount, sync_status)
VALUES ('POS20251017001', 1001, 89.50, 'PENDING'); - 網(wǎng)絡(luò)恢復(fù) → 啟動同步任務(wù):
? 批量上傳訂單到云端 API /api/orders/offlineSync
? 云端落表并返回成功狀態(tài) - POS 更新狀態(tài):
UPDATE local_order SET sync_status='SYNCED' WHERE order_code='POS20251017001';
?? 若同步失敗 → 寫入 sync_log 記錄錯誤原因并重試。
4.3 數(shù)據(jù)沖突處理策略
場景
策略
同一會員離線充值+線上消費
優(yōu)先云端交易,POS沖正
離線銷售庫存與線上庫存沖突
按時間先后順序補差
同步時商品被下架
自動標(biāo)記訂單為異常待審核
網(wǎng)絡(luò)恢復(fù)后部分明細(xì)上傳失敗
自動重傳三次并記錄日志
- ?? 數(shù)據(jù)安全設(shè)計
5.1 本地加密
? 離線SQLite文件加密(AES-256)。
? 離線訂單敏感字段(手機號、金額)二次加密存儲。
? 啟動時需POS授權(quán)碼校驗。
5.2 安全機制
項目
措施
用戶登錄
Token緩存(斷網(wǎng)可使用本地令牌)
本地數(shù)據(jù)
AES 加密 + 文件鎖
同步接口
HTTPS + 簽名校驗
數(shù)據(jù)追蹤
所有訂單、同步記錄帶簽名校驗值(MD5/簽名字段)
- ?? 離線POS前端邏輯結(jié)構(gòu)
[本地緩存管理器]
├── 數(shù)據(jù)加載器(DataLoader)
│ ├── 從云端同步 → SQLite
│ └── 定期校驗版本號
├── 訂單緩存器(OrderBuffer)
│ ├── 離線銷售單存儲
│ ├── 恢復(fù)后批量上傳
├── 同步管理器(SyncManager)
│ ├── 自動定時任務(wù)
│ └── 異常記錄與重試
├── 網(wǎng)絡(luò)檢測器(NetWatcher)
│ ├── 監(jiān)聽網(wǎng)絡(luò)狀態(tài)
│ └── 啟動同步
- ?? 同步任務(wù)調(diào)度邏輯(偽代碼)
if (NetworkUtils.isConnected()) {
ListunsyncedOrders = localDb.getOrdersByStatus("PENDING");
for (Order order : unsyncedOrders) {
boolean result = api.upload(order);
if (result) localDb.updateOrderStatus(order.getId(), "SYNCED");
else localDb.logSyncFailure(order);
}
}
- ?? 離線狀態(tài)提示與操作限制
功能
離線狀態(tài)下
恢復(fù)后
開單收銀
? 支持
? 同步
掛單取單
? 支持本機掛單
? 云端同步
會員余額支付
?? 限當(dāng)前緩存余額
? 云端驗證
積分消費
?? 暫不允許
? 可同步
價格更新
? 暫停自動更新
? 恢復(fù)后自動刷新
打印小票
? 可離線打印
? 云端歸檔
交接班
? 本地統(tǒng)計
? 上報結(jié)算數(shù)據(jù)
- ?? 同步日志表結(jié)構(gòu)(SQLite)
CREATE TABLE sync_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
entity_type TEXT NOT NULL, -- 'ORDER','MEMBER','STOCK'
entity_id TEXT,
sync_status TEXT DEFAULT 'PENDING',
last_try_time DATETIME,
error_message TEXT
);
- ? 網(wǎng)絡(luò)恢復(fù)后任務(wù)順序
- 上傳未同步訂單(local_order → order_h)
- 上傳交接班數(shù)據(jù)
- 同步庫存、會員余額、積分狀態(tài)
- 拉取商品與價格更新
- 更新本地版本號表
- 清理成功同步的本地緩存數(shù)據(jù)
- ?? 優(yōu)化建議
模塊
優(yōu)化方向
同步模塊
引入批量事務(wù)與壓縮傳輸(gzip/json batch)
訂單號生成
離線采用「本機號 + 時間戳」避免沖突
安全性
本地離線文件每日自動備份(USB/云)
可視化
POS端提供「離線模式」明顯標(biāo)識與狀態(tài)條
差異日志
支持對賬頁面查看云端與本地差異記錄
- ?? 小結(jié)
功能
支持離線
同步方向
商品查詢
?
云 → POS
價格查詢
?
云 → POS
下單銷售
?
POS → 云
會員識別
?(緩存匹配)
雙向
積分、余額
?? 部分
POS緩存
打印功能
?
本地
庫存同步
?
雙向(沖突檢測)
數(shù)據(jù)加密
?
本地AES
異常恢復(fù)
?
自動補償機制

浙公網(wǎng)安備 33010602011771號