【vue】收银界面离线可用,本地缓存订单,网络恢复后同步

核心实现逻辑(Vue 技术栈适配)

核心依赖 IndexedDB(本地持久化存储) + 网络状态监听,搭配请求队列保证同步可靠性,完全满足离线下单、联网自动同步需求。

一、核心技术选型(明确唯一方案,快速落地)

  1. 本地存储:IndexedDB

    • 替代 localStorage(容量仅 5M),支持大容量(几十 MB 到 GB 级)、事务性操作,适配订单多字段存储,浏览器离线时稳定持久化数据。
    • 推荐工具:localForage(封装 IndexedDB,API 像 localStorage 一样简单,自动降级兼容,Vue 项目直接 npm 引入即用)。
  2. 网络状态监听:navigator.onLine

    • 原生 API 零依赖,实时监听网络切换,离线时写入本地缓存,联网时触发同步逻辑。
  3. 同步可靠性:请求队列 + 状态标记

    • 给每个本地订单加 syncStatus 字段(pending 待同步 / success 同步完成 / failed 同步失败),避免重复同步、漏同步。

二、分步实现流程(Vue 项目落地步骤)

1. 初始化本地存储(localForage)
javascript 复制代码
// src/utils/localStorage.js
import localForage from 'localForage';

// 初始化订单存储库(name 自定义,storeName 对应订单表名)
export const orderStore = localForage.createInstance({
  name: 'cashierOfflineDB',
  storeName: 'orders'
});

// 封装核心方法(增、查、改、删)
export const orderStorage = {
  // 新增离线订单(离线时调用)
  saveOfflineOrder: (order) => orderStore.setItem(order.id, { ...order, syncStatus: 'pending' }),
  // 获取所有待同步订单
  getPendingOrders: async () => {
    const orders = [];
    await orderStore.iterate((value) => {
      value.syncStatus === 'pending' && orders.push(value);
    });
    return orders;
  },
  // 更新订单同步状态(同步成功/失败后调用)
  updateOrderSyncStatus: (orderId, status) => orderStore.update(orderId, (order) => ({ ...order, syncStatus: status })),
  // 删除已同步成功的订单(可选,节省本地空间)
  deleteSyncedOrder: (orderId) => orderStore.removeItem(orderId)
};
2. 收银下单逻辑(区分在线/离线)
javascript 复制代码
// src/views/Cashier.vue
import { orderStorage } from '@/utils/localStorage';
import { createOrderApi } from '@/api/order'; // 后端创建订单接口

export default {
  methods: {
    async handleCreateOrder(order) {
      const isOnline = navigator.onLine;
      try {
        if (isOnline) {
          // 在线:直接调用后端接口,成功后无需本地缓存
          await createOrderApi(order);
          alert('下单成功');
        } else {
          // 离线:生成唯一订单id(uuid/v4 或时间戳+随机数),写入本地
          const offlineOrder = { id: `OFF-${Date.now()}-${Math.random().toString(36).slice(-6)}`, ...order };
          await orderStorage.saveOfflineOrder(offlineOrder);
          alert('已离线保存订单,联网后自动同步');
        }
      } catch (err) {
        // 在线但接口报错(如后端临时故障),也写入本地缓存,避免订单丢失
        const failOrder = { id: `OFF-${Date.now()}-${Math.random().toString(36).slice(-6)}`, ...order };
        await orderStorage.saveOfflineOrder(failOrder);
        alert('下单失败,已离线缓存');
      }
    }
  }
};
3. 网络恢复同步逻辑(全局监听,自动触发)
  • 方案1:组件内监听(仅收银页生效)
  • 方案2:main.js 全局监听(全项目生效,推荐)
javascript 复制代码
// src/main.js
import { orderStorage } from '@/utils/localStorage';
import { createOrderApi } from '@/api/order';

// 核心同步函数
const syncPendingOrders = async () => {
  if (!navigator.onLine) return; // 确保联网时执行
  const pendingOrders = await orderStorage.getPendingOrders();
  if (pendingOrders.length === 0) return;

  // 批量同步(也可串行,避免并发过多)
  for (const order of pendingOrders) {
    try {
      await createOrderApi(order); // 调用后端同步接口
      await orderStorage.updateOrderSyncStatus(order.id, 'success');
      await orderStorage.deleteSyncedOrder(order.id); // 同步成功删除本地缓存
    } catch (err) {
      await orderStorage.updateOrderSyncStatus(order.id, 'failed'); // 失败标记,后续重试
      console.error(`订单${order.id}同步失败:`, err);
    }
  }
};

// 1. 初始加载时,检查网络+触发同步(避免页面刷新后漏同步)
window.addEventListener('load', syncPendingOrders);

// 2. 网络从离线切在线时,触发同步
window.addEventListener('online', syncPendingOrders);

// 3. 可选:定时重试失败订单(防止同步一次失败后无法再次同步)
setInterval(syncPendingOrders, 5 * 60 * 1000); // 每5分钟重试一次
4. 异常处理(兜底保障)
  • 订单 ID 唯一性:用 uuid 库生成(npm install uuid),比时间戳+随机数更稳妥,避免本地订单 ID 重复。
  • 同步失败重试:除了定时重试,可在收银页加"手动同步"按钮,允许用户主动触发。
  • 后端兼容:同步时后端需支持"幂等性校验"(如通过订单 ID 判断是否已同步,避免重复创建订单),前端传递订单唯一 ID 即可。

三、关键注意点(避坑核心)

  1. 订单字段必须包含 唯一标识(id)下单时间(createTime)同步状态(syncStatus),方便后续查询、更新、去重。
  2. 本地存储容量:一般浏览器 IndexedDB 容量默认 50MB+,足够存储 thousands 级订单,若订单量极大,可定期清理已同步订单。
  3. 浏览器兼容性:主流浏览器(Chrome、Edge、Firefox、Safari 10+)均支持,适配收银场景常用设备(电脑、平板)。

四、实际价值与场景适配

  • 适配场景:超市、便利店等收银场景,网络波动/断网时不影响正常下单,避免流失订单;联网后自动同步到后端,不影响对账、库存更新。
  • 优势:零额外服务器成本(依赖浏览器本地存储),实现简单,Vue 项目1-2天可落地,稳定性高。
相关推荐
上海云盾安全满满21 小时前
选择高防IP时需要重点关注哪些因素
网络·网络协议·tcp/ip
智在碧得21 小时前
碧服打造DataOps全链路闭环,定义大数据工程化发布新标杆
大数据·网络·数据库
孟无岐21 小时前
【Laya】Byte 二进制数据处理
网络·typescript·游戏引擎·游戏程序·laya
负二代0.01 天前
Linux下的网络管理
linux·网络
刘一说1 天前
Vue3 模块语法革命:移除过滤器(Filters)的深度解析与迁移指南
前端·vue.js·js
欧洵.1 天前
深入理解TCP/IP协议栈:数据链路层核心知识点解析
网络
Trae1ounG1 天前
这是什么dom
前端·javascript·vue.js
513495921 天前
在Vue.js项目中使用docx和file-saver实现Word文档导出
前端·vue.js·word
雨声不在1 天前
udp穿透的方法V2
网络·网络协议·udp
嗨 ! 海洋1 天前
K8S创建pod,CNI插件的网络配置过程
网络·kubernetes·php