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

235 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 离线数据方案
> 状态: 设计中MVP 阶段可简化)
---
## 1. 背景
工地现场网络环境不稳定H5 移动端可能出现网络中断。需要保证:
1. **已加载数据可继续浏览**(设备列表、预警等)
2. **网络恢复后数据自动同步**
3. **离线期间的操作不丢失**
---
## 2. 离线存储策略
### 2.1 存储层级
| 层级 | 技术 | 容量 | 适用场景 |
|------|------|------|----------|
| Memory | JavaScript 变量 | 无限 | 页面运行期间 |
| LocalStorage | 浏览器本地存储 | ~5MB | 永久存储(小数据) |
| IndexedDB | 浏览器索引数据库 | ~50MB+ | 结构化数据存储 |
**选型**: 以 **IndexedDB** 为主LocalStorage 辅助。
---
## 3. 离线缓存设计
### 3.1 IndexedDB 表设计
```javascript
// 数据库: 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 队列记录格式
```javascript
{
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 注册
```javascript
// 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. 网络状态提示
页面监听网络状态,给用户明确反馈:
```javascript
// 监听网络状态
window.addEventListener('online', () => {
showToast('网络已恢复,正在同步...');
syncPendingOperations();
});
window.addEventListener('offline', () => {
showToast('网络已断开,显示离线数据');
});
```
---
## 7. 简化方案MVP
MVP 阶段可降低离线复杂度:
| 方案 | 说明 |
|------|------|
| 简单缓存 | 仅在 LocalStorage 缓存用户信息 + 最后设备列表H5 页面可离线展示 |
| 无离线操作 | 离线期间禁用操作按钮,提示"网络异常" |
| 手动刷新 | 网络恢复后用户下拉刷新 |
**后续迭代再实现完整离线能力**
---
## 8. 待确认
- [ ] 是否需要 PWA可安装到桌面/主屏幕)
- [ ] IndexedDB 库选型idb / Dexie.js 还是原生)
- [ ] 离线数据保留时长策略