更新概述

v1.11.0 版本为 OpenHarmony 钱包应用增加了完整的数据同步功能。用户现在可以将本地数据(交易、预算、标签等)同步到云端,实现多设备数据同步。新增的数据同步页面提供了直观的同步状态显示和队列管理功能。

在这里插入图片描述


核心功能更新

1. 数据同步模型

SyncData 类定义
/// 数据同步模型
class SyncData {
  final String id;
  final String type; // 'transaction', 'budget', 'tag'
  final Map<String, dynamic> data;
  final DateTime timestamp;
  final String deviceId;
  bool isSynced;

  SyncData({
    required this.id,
    required this.type,
    required this.data,
    required this.timestamp,
    required this.deviceId,
    this.isSynced = false,
  });
}

说明

  • 记录数据类型、内容、时间戳
  • 记录来源设备 ID
  • 跟踪同步状态
支持的数据类型
类型 说明 示例
transaction 交易数据 新增支出、收入
budget 预算数据 预算设置、修改
tag 标签数据 新增标签、编辑标签

2. 数据同步服务

DataSyncService 类
/// 数据同步服务
class DataSyncService {
  static final List<SyncData> _syncQueue = [];
  static bool _isSyncing = false;

  /// 添加数据到同步队列
  static void addToSyncQueue(
    String type,
    Map<String, dynamic> data,
    String deviceId,
  ) {
    _syncQueue.add(SyncData(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      type: type,
      data: data,
      timestamp: DateTime.now(),
      deviceId: deviceId,
    ));
  }

  /// 获取待同步数据
  static List<SyncData> getPendingSyncData() {
    return _syncQueue.where((item) => !item.isSynced).toList();
  }

  /// 模拟同步数据
  static Future<bool> syncData(List<SyncData> dataList) async {
    if (_isSyncing) return false;
    _isSyncing = true;

    try {
      // 模拟网络延迟
      await Future.delayed(const Duration(seconds: 2));

      // 标记为已同步
      for (var item in dataList) {
        item.isSynced = true;
      }

      return true;
    } catch (e) {
      return false;
    } finally {
      _isSyncing = false;
    }
  }

  /// 获取同步统计
  static Map<String, int> getSyncStats() {
    return {
      'total': _syncQueue.length,
      'synced': _syncQueue.where((item) => item.isSynced).length,
      'pending': _syncQueue.where((item) => !item.isSynced).length,
    };
  }

  /// 清空同步队列
  static void clearSyncQueue() {
    _syncQueue.clear();
  }

  /// 获取同步历史
  static List<SyncData> getSyncHistory() {
    return List.from(_syncQueue);
  }
}

说明

  • addToSyncQueue: 添加数据到同步队列
  • getPendingSyncData: 获取待同步的数据
  • syncData: 执行同步操作(模拟网络请求)
  • getSyncStats: 获取同步统计信息
  • clearSyncQueue: 清空同步队列
  • getSyncHistory: 获取完整的同步历史

3. 数据同步页面

同步状态卡片
/// 构建同步状态
Widget _buildSyncStatus(Map<String, int> stats) {
  final total = stats['total'] ?? 0;
  final synced = stats['synced'] ?? 0;
  final pending = stats['pending'] ?? 0;
  final syncRate = total > 0 ? (synced / total * 100).toStringAsFixed(1) : '0.0';

  return Padding(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: Container(
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [Colors.cyan.shade400, Colors.cyan.shade800],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.circular(20),
        boxShadow: [
          BoxShadow(
            color: Colors.cyan.withOpacity(0.3),
            blurRadius: 10,
            offset: const Offset(0, 5),
          ),
        ],
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            '同步状态',
            style: Theme.of(context).textTheme.titleMedium?.copyWith(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
          ),
          const SizedBox(height: 20),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              _buildStatItem('总数据', total.toString(), Colors.white),
              _buildStatItem('已同步', synced.toString(), Colors.green),
              _buildStatItem('待同步', pending.toString(), Colors.orange),
            ],
          ),
          const SizedBox(height: 20),
          ClipRRect(
            borderRadius: BorderRadius.circular(8),
            child: LinearProgressIndicator(
              value: total > 0 ? synced / total : 0,
              minHeight: 8,
              backgroundColor: Colors.white.withOpacity(0.3),
              valueColor: const AlwaysStoppedAnimation<Color>(Colors.green),
            ),
          ),
          const SizedBox(height: 8),
          Text(
            '同步进度: $syncRate%',
            style: const TextStyle(
              color: Colors.white,
              fontSize: 12,
              fontWeight: FontWeight.w500,
            ),
          ),
        ],
      ),
    ),
  );
}

说明

  • 显示总数据、已同步、待同步的数量
  • 进度条显示同步进度
  • 青色渐变背景,区别于其他页面

在这里插入图片描述

同步操作按钮
/// 构建同步操作按钮
Widget _buildSyncActions() {
  return Padding(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        ElevatedButton.icon(
          onPressed: _isSyncing ? null : _performSync,
          icon: _isSyncing
              ? SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                    valueColor: AlwaysStoppedAnimation<Color>(
                      Colors.blue.shade700,
                    ),
                  ),
                )
              : const Icon(Icons.cloud_upload),
          label: Text(_isSyncing ? '同步中...' : '立即同步'),
          style: ElevatedButton.styleFrom(
            backgroundColor: Colors.blue,
            foregroundColor: Colors.white,
            padding: const EdgeInsets.symmetric(vertical: 12),
          ),
        ),
        const SizedBox(height: 12),
        OutlinedButton.icon(
          onPressed: _clearSyncQueue,
          icon: const Icon(Icons.delete_outline),
          label: const Text('清空队列'),
          style: OutlinedButton.styleFrom(
            foregroundColor: Colors.red,
            side: const BorderSide(color: Colors.red),
            padding: const EdgeInsets.symmetric(vertical: 12),
          ),
        ),
        const SizedBox(height: 12),
        Container(
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.blue.shade50,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: Colors.blue.shade200),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                '设备 ID',
                style: Theme.of(context).textTheme.bodySmall?.copyWith(
                      fontWeight: FontWeight.w600,
                    ),
              ),
              const SizedBox(height: 6),
              Text(
                _deviceId,
                style: Theme.of(context).textTheme.bodySmall?.copyWith(
                      fontFamily: 'monospace',
                      color: Colors.grey.shade600,
                    ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

说明

  • 蓝色按钮执行同步
  • 红色按钮清空队列
  • 显示设备 ID(用于多设备同步标识)
同步历史列表
/// 构建同步历史
Widget _buildSyncHistory(List<SyncData> history) {
  if (history.isEmpty) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Container(
        padding: const EdgeInsets.all(32),
        decoration: BoxDecoration(
          color: Colors.grey.shade100,
          borderRadius: BorderRadius.circular(12),
        ),
        child: Center(
          child: Text(
            '暂无同步记录',
            style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                  color: Colors.grey,
                ),
          ),
        ),
      ),
    );
  }

  return Padding(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          '同步历史 (${history.length})',
          style: Theme.of(context).textTheme.titleMedium?.copyWith(
                fontWeight: FontWeight.bold,
              ),
        ),
        const SizedBox(height: 12),
        ...history.asMap().entries.map((entry) {
          final item = entry.value;
          final isSynced = item.isSynced;

          return Padding(
            padding: const EdgeInsets.only(bottom: 12),
            child: Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                border: Border.all(
                  color: isSynced ? Colors.green.shade300 : Colors.orange.shade300,
                ),
                borderRadius: BorderRadius.circular(12),
                color: isSynced ? Colors.green.shade50 : Colors.orange.shade50,
              ),
              child: Row(
                children: [
                  Container(
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                      color: isSynced ? Colors.green : Colors.orange,
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Center(
                      child: Icon(
                        isSynced ? Icons.check : Icons.schedule,
                        color: Colors.white,
                        size: 20,
                      ),
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text(
                              _getTypeLabel(item.type),
                              style: const TextStyle(
                                fontWeight: FontWeight.w600,
                                fontSize: 14,
                              ),
                            ),
                            Text(
                              isSynced ? '已同步' : '待同步',
                              style: TextStyle(
                                fontSize: 12,
                                color: isSynced ? Colors.green : Colors.orange,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 4),
                        Text(
                          _formatDateTime(item.timestamp),
                          style: TextStyle(
                            fontSize: 11,
                            color: Colors.grey.shade600,
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        }).toList(),
      ],
    ),
  );
}

说明

  • 显示所有同步记录
  • 绿色表示已同步,橙色表示待同步
  • 显示数据类型、状态、时间戳

UI 变化

数据同步页面布局

┌─────────────────────────────────┐
│  数据同步                        │
├─────────────────────────────────┤
│  同步状态                        │
│  总数据: 5  已同步: 3  待同步: 2 │
│  [████████░░░░░░░░░░] 60%       │
├─────────────────────────────────┤
│  [立即同步]                      │
│  [清空队列]                      │
│  设备 ID: Device-1702...        │
├─────────────────────────────────┤
│  同步历史 (5)                    │
│  ┌─────────────────────────┐   │
│  │ ✓ 交易数据   已同步      │   │
│  │   2024-12-24 10:30:45   │   │
│  └─────────────────────────┘   │
│  ┌─────────────────────────┐   │
│  │ ⏱ 预算数据   待同步      │   │
│  │   2024-12-24 10:35:20   │   │
│  └─────────────────────────┘   │
└─────────────────────────────────┘

同步工作流程

1. 用户在钱包页面添加交易
   ↓
2. 调用 DataSyncService.addToSyncQueue()
   ↓
3. 数据添加到同步队列
   ↓
4. 用户进入数据同步页面
   ↓
5. 显示待同步数据
   ↓
6. 用户点击"立即同步"
   ↓
7. 执行 syncData() 方法
   ↓
8. 模拟网络请求(2秒延迟)
   ↓
9. 标记数据为已同步
   ↓
10. 显示同步成功提示

版本对比

功能 v1.10.0 v1.11.0
预算提醒
预算警告显示
实时提醒
数据同步模型
数据同步服务
同步队列管理
同步历史记录
同步状态显示
多设备同步

使用场景

场景 1:查看同步状态

  1. 进入数据同步页面
  2. 查看同步状态卡片
  3. 了解待同步数据数量
  4. 查看同步进度

场景 2:执行数据同步

  1. 进入数据同步页面
  2. 点击"立即同步"按钮
  3. 等待同步完成(约 2 秒)
  4. 查看同步成功提示

场景 3:清空同步队列

  1. 进入数据同步页面
  2. 点击"清空队列"按钮
  3. 确认清空操作
  4. 队列立即清空

场景 4:查看同步历史

  1. 进入数据同步页面
  2. 查看同步历史列表
  3. 了解每条数据的同步状态
  4. 查看同步时间戳

下一步计划

v1.12.0 将继续增强功能,计划增加:

  • 🌙 深色模式支持
  • 📊 高级统计分析
  • 💾 本地数据持久化
  • 🔐 数据加密和安全

感谢使用 OpenHarmony 钱包! 🎉

如有建议或问题,欢迎反馈。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐