Files
smart-project/docs/offline.md
Jesxion cb0ef8c30c docs: 全面审阅修复
- architecture.md: 全面重写,对齐 Node.js+MySQL 技术栈,
  新增三个模块(隐患随手拍/施工日志/AI分析)到模块列表和架构图,
  更新数据流、租户隔离模型、部署架构、安全设计
- h5.md: 补充 6 个新页面 wireframe(3.7~3.14),
  更新页面清单(15个页面),API endpoint 前缀 /api → /v1,
  更新已知待确认项为已确认状态
- offline.md: 补充 hazards/construction_logs/ai_analyses 三个
  IndexedDB store,更新刷新策略表,
  补充 6 种离线操作类型(action 类型表)
- SPEC.md: 状态升级为"设计完成",版本升至 v0.2.1,
  所有待确认项均已确认(部署地址/推送凭证/OSS路径/JWT/台账)
2026-04-14 16:53:33 +08:00

5.9 KiB
Raw Permalink Blame History

离线数据方案

状态: 设计中MVP 阶段可简化)


1. 背景

工地现场网络环境不稳定H5 移动端可能出现网络中断。需要保证:

  1. 已加载数据可继续浏览(设备列表、预警等)
  2. 网络恢复后数据自动同步
  3. 离线期间的操作不丢失

2. 离线存储策略

2.1 存储层级

层级 技术 容量 适用场景
Memory JavaScript 变量 无限 页面运行期间
LocalStorage 浏览器本地存储 ~5MB 永久存储(小数据)
IndexedDB 浏览器索引数据库 ~50MB+ 结构化数据存储

选型: 以 IndexedDB 为主LocalStorage 辅助。


3. 离线缓存设计

3.1 IndexedDB 表设计

// 数据库: SmartProjectDB
// 版本: 1

// 对象存储 1: devices设备台账
{
  store: 'devices',
  keyPath: 'id',
  indexes: ['type', 'status'],
  data: { id, name, type, model, location, status, last_seen }
}

// 对象存储 2: alerts预警记录
{
  store: 'alerts',
  keyPath: 'id',
  indexes: ['status', 'level', 'created_at'],
  data: { id, device_id, device_name, level, message, metric, value, status, created_at }
}

// 对象存储 3: hazards隐患随手拍
{
  store: 'hazards',
  keyPath: 'id',
  indexes: ['status', 'category', 'severity', 'reported_at'],
  data: { id, category, severity, description, photo_count, status,
          reporter_id, reporter_role, reported_at, assignee_id, resolved_at }
}

// 对象存储 4: construction_logs施工日志
{
  store: 'construction_logs',
  keyPath: 'id',
  indexes: ['date', 'author_id'],
  data: { id, date, part, content, workers, equipment, photo_count,
          author_id, author_role, created_at }
}

// 对象存储 5: ai_analysesAI 智能分析)
{
  store: 'ai_analyses',
  keyPath: 'id',
  indexes: ['device_id', 'analysis_type', 'triggered_at'],
  data: { id, device_id, device_name, analysis_type, confidence,
          description, triggered_at }
}

// 对象存储 6: sync_queue离线操作队列
{
  store: 'sync_queue',
  keyPath: 'id',
  autoIncrement: true,
  data: { id, action, payload, created_at, status }
}

3.2 缓存更新策略

数据类型 更新频率 缓存策略
设备列表 每 5 分钟 后台静默更新
设备详情 每 30 秒 页面打开时拉取 + 定时刷新
预警列表 每 1 分钟 后台静默更新 + 新预警推送
隐患列表 每 2 分钟 后台静默更新
施工日志列表 每 5 分钟 后台静默更新
AI 分析列表 每 5 分钟 后台静默更新
隐患详情 实时 打开时拉取
日志详情 实时 打开时拉取
AI 分析详情 实时 打开时拉取

更新流程:

用户打开页面
    │
    ├─ 有网络 → API 请求 → 更新 IndexedDB → 渲染
    │
    └─ 无网络 → 读取 IndexedDB → 渲染(显示"离线模式"

4. 离线操作队列

4.1 场景

用户在离线状态下执行操作(如处理预警、提交隐患、处理日志),操作记录存入 sync_queue,网络恢复后自动同步。

4.2 支持的离线操作类型

action 说明 对应 API
handle_alert 处理预警 POST /v1/alerts/:id/handle
ignore_alert 忽略预警 POST /v1/alerts/:id/ignore
create_hazard 上报隐患 POST /v1/hazards
assign_hazard 认领隐患 POST /v1/hazards/:id/assign
resolve_hazard 处理完成 POST /v1/hazards/:id/resolve
create_log 新建日志 POST /v1/logs

4.3 同步流程

检测到网络恢复navigator.onLine 事件)
    │
    ▼
读取 sync_queuestatus: pending
    │
    ▼
逐条执行 API 请求
    │
    ├─ 成功 → 删除队列记录,更新本地数据
    │
    └─ 失败 → 重试3次仍失败标记为 failed用户手动处理

4.3 队列记录格式

{
  id: 1,
  action: 'handle_alert',
  payload: {
    alert_id: 'alert_001',
    action: 'handled',
    note: '已现场确认'
  },
  created_at: '2026-04-14T10:00:00Z',
  status: 'pending',   // pending / syncing / failed
  retry_count: 0
}

5. Service Worker

5.1 职责

  • 拦截 H5 页面的 HTTP 请求
  • 实现缓存策略(静态资源优先缓存,网络优先等)
  • 离线时返回缓存的页面

5.2 缓存策略

资源类型 缓存策略 说明
HTML Network First 始终尝试获取最新
CSS/JS Cache First 优先使用缓存,性能优先
API 数据 Network Only 实时性要求高,不缓存
图标/字体 Cache First 长期不变

5.3 Service Worker 注册

// main.js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(reg => console.log('SW registered'))
    .catch(err => console.error('SW registration failed:', err));
}

6. 网络状态提示

页面监听网络状态,给用户明确反馈:

// 监听网络状态
window.addEventListener('online', () => {
  showToast('网络已恢复,正在同步...');
  syncPendingOperations();
});

window.addEventListener('offline', () => {
  showToast('网络已断开,显示离线数据');
});

7. 简化方案MVP

MVP 阶段可降低离线复杂度:

方案 说明
简单缓存 仅在 LocalStorage 缓存用户信息 + 最后设备列表H5 页面可离线展示
无离线操作 离线期间禁用操作按钮,提示"网络异常"
手动刷新 网络恢复后用户下拉刷新

后续迭代再实现完整离线能力


8. 待确认

  • 是否需要 PWA可安装到桌面/主屏幕)
  • IndexedDB 库选型idb / Dexie.js 还是原生)
  • 离线数据保留时长策略