# 离线功能触发机制与页面集成规划
**版本**: v1.0
**创建日期**: 2026-02-26
---
## 一、离线/同步触发机制
### 1.1 离线触发场景
```
┌─────────────────────────────────────────────────────────────┐
│ 离线触发场景 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 网络断开 │
│ - 用户进入电梯、地下室、隧道等信号弱区域 │
│ - 用户关闭移动数据/WiFi │
│ - 飞行模式开启 │
│ │
│ 2. 服务器不可达 │
│ - 服务器维护 │
│ - 网关超时 │
│ - DNS解析失败 │
│ │
│ 3. 请求失败 │
│ - 请求超时 │
│ - 连接错误 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 1.2 同步触发场景
```
┌─────────────────────────────────────────────────────────────┐
│ 同步触发场景 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 自动触发 │
│ ├── 网络恢复时 (onNetworkStatusChange) │
│ ├── 操作完成后立即尝试 (如果在线) │
│ └── 定时同步 (可配置,默认30秒) │
│ │
│ 2. 手动触发 │
│ ├── 用户下拉刷新 │
│ ├── 用户点击"同步"按钮 │
│ └── 用户重试失败项 │
│ │
│ 3. 应用生命周期 │
│ ├── 应用启动时 │
│ ├── 应用从后台恢复时 │
│ └── 应用退出前 (可选) │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 1.3 当前代码中的触发点
| 触发点 | 文件 | 触发条件 | 处理逻辑 |
|--------|------|---------|---------|
| 网络状态变化 | `sync-queue.ts:36-44` | `uni.onNetworkStatusChange` | 离线→在线时自动处理队列 |
| 操作添加时 | `sync-queue.ts:74-76` | `add()` 方法调用 | 如果在线立即尝试同步 |
| 定时重试 | `sync-queue.ts:184-188` | 重试延迟后 | 检查网络后处理 |
| 手动触发 | `sync-queue.ts:205-215` | `retryFailed()` 调用 | 重置失败项并处理 |
### 1.4 业务操作触发流程
```
用户操作 (如: 接单)
│
▼
┌───────────────────────────────────────┐
│ Repository 方法 (如: accept) │
│ if (在线) { │
│ 直接调用API │
│ 成功 → 更新本地状态 │
│ 失败 → 加入同步队列 │
│ } else { │
│ 更新本地状态 │
│ 加入同步队列 │
│ } │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ 同步队列 (syncQueue.add) │
│ - 生成唯一ID │
│ - 记录时间戳 │
│ - 设置优先级 │
│ - 持久化到本地存储 │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ 如果在线 → 立即尝试同步 │
│ 如果离线 → 等待网络恢复 │
└───────────────────────────────────────┘
```
---
## 二、页面集成规划
### 2.1 需要集成的页面
| 页面 | 文件路径 | 集成内容 |
|------|---------|---------|
| 工单列表 | `pages/work-order/list.vue` | 离线工单显示、状态筛选 |
| 工单详情 | `pages/work-order/detail.vue` | 离线操作按钮、同步状态 |
| 巡检任务 | `pages/inspection/task/index.vue` | 离线任务显示 |
| 巡检执行 | `pages/inspection/execute/index.vue` | 离线签到、结果提交 |
| 访客登记 | `pages/visitor/register.vue` | 离线登记 |
| 访客记录 | `pages/visitor/records.vue` | 离线记录显示 |
| 首页 | `pages/index/index.vue` | 离线状态提示、待同步数量 |
### 2.2 公共组件
需要创建以下公共组件:
```
src/components/offline/
├── OfflineStatus.vue # 离线状态指示器
├── SyncIndicator.vue # 同步进度指示器
├── PendingBadge.vue # 待同步数量徽章
└── OfflineNotice.vue # 离线通知横幅
```
---
## 三、UI组件设计
### 3.1 离线状态指示器 (OfflineStatus.vue)
```vue
{{ isOnline ? '📶' : '📵' }}
{{ statusText }}
{{ pendingCount }}
```
### 3.2 同步进度指示器 (SyncIndicator.vue)
```vue
🔄
正在同步...
```
### 3.3 离线通知横幅 (OfflineNotice.vue)
```vue
⚠️
当前处于离线状态,操作将在联网后自动同步
```
### 3.4 待同步徽章 (PendingBadge.vue)
```vue
{{ count > 99 ? '99+' : count }}
```
---
## 四、页面集成示例
### 4.1 工单详情页集成
```vue
⏳ 待同步
⚠️ 同步冲突
✅ 已同步
```
### 4.2 首页集成
```vue
{{ failedCount }}项同步失败,点击重试
{{ pendingWorkOrders }}
待处理工单
{{ todayInspections }}
今日巡检
{{ todayVisitors }}
今日访客
```
---
## 五、初始化集成
### 5.1 main.ts 集成
```typescript
// src/main.ts
import { createSSRApp } from 'vue'
import App from './App.vue'
import { initOfflineStorage } from './offline'
// 初始化离线存储
initOfflineStorage()
export function createApp() {
const app = createSSRApp(App)
return { app }
}
```
### 5.2 App.vue 全局状态
```vue
```
---
## 六、实施计划
### 阶段一:公共组件开发 (1天)
| 任务 | 预计时间 |
|------|---------|
| 创建 OfflineStatus.vue | 1小时 |
| 创建 SyncIndicator.vue | 1小时 |
| 创建 OfflineNotice.vue | 0.5小时 |
| 创建 PendingBadge.vue | 0.5小时 |
| 组件测试 | 2小时 |
### 阶段二:页面集成 (2天)
| 任务 | 预计时间 |
|------|---------|
| 首页集成 | 2小时 |
| 工单列表/详情集成 | 3小时 |
| 巡检任务/执行集成 | 3小时 |
| 访客登记/记录集成 | 2小时 |
| 集成测试 | 4小时 |
### 阶段三:优化完善 (1天)
| 任务 | 预计时间 |
|------|---------|
| 照片离线处理 | 3小时 |
| 消息模块离线 | 2小时 |
| 性能优化 | 2小时 |
| 文档完善 | 1小时 |
---
## 七、注意事项
1. **数据一致性**: 离线操作可能与服务器数据冲突,需要处理冲突场景
2. **存储容量**: 注意本地存储容量限制,定期清理过期数据
3. **用户体验**: 离线操作要有明确提示,避免用户困惑
4. **错误处理**: 同步失败要有重试机制和错误提示
5. **测试覆盖**: 需要覆盖离线/在线切换场景的测试