【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天可落地,稳定性高。
相关推荐
岁岁种桃花儿2 小时前
Nginx 站点垂直扩容(单机性能升级)全攻略
网络·nginx·dns
Xの哲學2 小时前
Linux SMP 实现机制深度剖析
linux·服务器·网络·算法·边缘计算
VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue校园社团管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
一颗青果4 小时前
公网构建全流程与参与主体深度解析
网络
低保和光头哪个先来5 小时前
场景6:对浏览器内核的理解
开发语言·前端·javascript·vue.js·前端框架
小北方城市网5 小时前
Python + 前后端全栈进阶课程(共 10 节|完整版递进式|从技术深化→项目落地→就业进阶,无缝衔接基础课)
大数据·开发语言·网络·python·数据库架构
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vueOA工程项目管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
山上三树6 小时前
task_struct 详解
运维·服务器·网络
独自破碎E6 小时前
Spring Boot工程启动以后,怎么将数据库中已有的固定内容打入到Redis缓存中?
数据库·spring boot·缓存
传感器与混合集成电路7 小时前
175℃持续工作:专为随钻测量系统设计的高温AC-DC电源
网络·能源