开源鸿蒙跨平台Flutter开发:快递单号批量查询应用

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

一、项目概述

运行效果图

1.1 应用简介

快递单号批量查询应用是一款便捷的物流查询工具,用户可以一次输入多个快递单号,批量查询物流状态,还能设置到货提醒,再也不用一个个查快递了。

应用以蓝色为主色调,象征物流的高效与可靠。涵盖快递查询、批量管理、到货提醒、历史记录四大模块。用户可以通过简洁的界面输入多个快递单号,系统自动识别快递公司并查询物流状态,同时支持设置到货提醒,让用户及时了解快递动态。

1.2 核心功能

功能模块 功能描述 实现方式
批量查询 一次输入多个单号 文本解析
自动识别 自动识别快递公司 正则匹配
物流追踪 实时物流状态查询 API调用
到货提醒 设置到货通知 本地通知
历史记录 保存查询历史 本地存储
快递分类 按状态分类管理 数据排序

1.3 快递状态定义

序号 状态名称 描述 颜色标识
1 待揽收 快递尚未被揽收 灰色
2 运输中 快递正在运输途中 蓝色
3 派送中 快递正在派送中 黄色
4 已签收 快递已被签收 绿色
5 异常 快递出现异常 红色
6 未知 无法查询到信息 灰色

1.4 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
网络请求 http -
本地存储 shared_preferences -
通知系统 flutter_local_notifications -
目标平台 鸿蒙OS / Web API 21+

1.5 项目结构

复制代码
lib/
└── main_courier_tracker.dart
    ├── CourierTrackerApp         # 应用入口
    ├── TrackingNumber           # 快递单号模型
    ├── CourierStatus            # 快递状态枚举
    ├── CourierService           # 快递服务
    ├── TrackingController       # 追踪控制器
    ├── NotificationService      # 通知服务
    ├── CourierTrackerHomePage   # 主页面
    ├── _buildInputPage          # 输入页面
    ├── _buildTrackingPage       # 追踪页面
    ├── _buildHistoryPage        # 历史页面
    └── _buildSettingsPage       # 设置页面

二、系统架构

2.1 整体架构图

Data Layer
Business Layer
Presentation Layer
主页面

CourierTrackerHomePage
输入页面
追踪页面
历史页面
设置页面
单号输入
批量解析
开始查询
物流列表
物流详情
状态更新
历史记录
记录管理
提醒设置
通知管理
追踪控制器

TrackingController
快递服务

CourierService
通知服务

NotificationService
数据管理

DataManager
TrackingNumber

单号模型
CourierStatus

状态枚举
LocalStorage

本地存储
API Client

API客户端

2.2 类图设计

uses
uses
uses
creates
returns
uses
CourierTrackerApp
+Widget build()
TrackingNumber
+String number
+String courierName
+CourierStatus status
+String latestUpdate
+List<String> trackingDetails
+DateTime createdAt
+bool notifyOnDelivery
<<enumeration>>
CourierStatus
+String label
+Color color
+awaitingPickup()
+inTransit()
+outForDelivery()
+delivered()
+exception()
+unknown()
CourierService
+Future track(String number)
+String identifyCourier(String number)
+Future getTrackingDetails(String number)
TrackingController
+List<TrackingNumber> trackingNumbers
+Future addTrackingNumber(String number)
+Future addMultipleTrackingNumbers(List<String> numbers)
+Future updateTrackingStatus(TrackingNumber number)
+void toggleNotification(TrackingNumber number)
+void removeTrackingNumber(TrackingNumber number)
NotificationService
+Future initialize()
+Future scheduleNotification(TrackingNumber number)
+Future cancelNotification(TrackingNumber number)
CourierTrackerHomePage
+Widget build()
+void _buildInputPage()
+void _buildTrackingPage()
+void _buildHistoryPage()
+void _buildSettingsPage()

2.3 页面导航流程

输入
追踪
历史
设置
应用启动
输入页面
底部导航
输入快递单号
查看物流状态
查看历史记录
管理提醒设置
批量输入
开始查询
自动识别快递公司
查询物流状态
显示结果
查看详情
设置提醒
查看历史
管理记录
通知设置
管理权限

2.4 物流查询流程

通知服务 API 快递服务 追踪控制器 输入页面 用户 通知服务 API 快递服务 追踪控制器 输入页面 用户 输入快递单号 添加单号 识别快递公司 返回快递公司 查询物流状态 请求物流信息 返回物流数据 返回物流状态 更新状态 显示物流信息 设置到货提醒 启用提醒 调度通知 确认设置 更新设置 显示设置成功


三、核心模块设计

3.1 数据模型设计

3.1.1 快递单号模型 (TrackingNumber)
dart 复制代码
class TrackingNumber {
  final String number;
  final String courierName;
  CourierStatus status;
  String latestUpdate;
  List<String> trackingDetails;
  final DateTime createdAt;
  bool notifyOnDelivery;
  
  TrackingNumber({
    required this.number,
    required this.courierName,
    required this.status,
    required this.latestUpdate,
    required this.trackingDetails,
    required this.createdAt,
    this.notifyOnDelivery = false,
  });
}
3.1.2 快递状态枚举 (CourierStatus)
dart 复制代码
enum CourierStatus {
  awaitingPickup(label: '待揽收', color: Colors.grey),
  inTransit(label: '运输中', color: Colors.blue),
  outForDelivery(label: '派送中', color: Colors.yellow),
  delivered(label: '已签收', color: Colors.green),
  exception(label: '异常', color: Colors.red),
  unknown(label: '未知', color: Colors.grey);

  final String label;
  final Color color;

  const CourierStatus({required this.label, required this.color});
}
3.1.3 快递服务 (CourierService)
dart 复制代码
class CourierService {
  final http.Client _client;

  CourierService(this._client);

  Future<CourierStatus> track(String number) async {
    // 模拟物流状态查询
    await Future.delayed(Duration(seconds: 1));
    return CourierStatus.inTransit;
  }

  String identifyCourier(String number) {
    // 模拟快递公司识别
    return '顺丰速运';
  }

  Future<List<String>> getTrackingDetails(String number) async {
    // 模拟获取物流详情
    await Future.delayed(Duration(seconds: 1));
    return [
      '【深圳市】快递已到达【深圳转运中心】',
      '【广州市】快递离开【广州转运中心】,下一站【深圳转运中心】',
      '【广州市】快递已到达【广州转运中心】',
      '【广州市】快递已揽收',
    ];
  }
}

3.2 页面结构设计

3.2.1 主页面布局

CourierTrackerHomePage
IndexedStack
输入页面
追踪页面
历史页面
设置页面
NavigationBar
输入 Tab
追踪 Tab
历史 Tab
设置 Tab

3.2.2 输入页面结构

输入页面
文本输入框
批量输入提示
开始查询按钮
最近单号
支持多行输入
自动去重
解析单号
识别快递公司
查询物流
显示结果

3.2.3 追踪页面结构

追踪页面
物流列表
状态筛选
搜索功能
物流卡片
单号信息
快递公司
当前状态
最新更新
详情展开
物流轨迹
时间线
提醒设置

3.3 物流查询逻辑

用户输入单号
解析输入文本
提取单号列表
去重处理
遍历单号
识别快递公司
查询物流状态
获取物流详情
更新UI显示
保存到本地
检查是否设置提醒
设置到货通知

3.4 到货提醒逻辑







用户启用提醒
检查通知权限
有权限?
请求权限
权限授予?
提示用户手动开启
调度通知
保存提醒设置
定期检查物流状态
状态为已签收?
发送通知
标记通知已发送


四、UI设计规范

4.1 配色方案

应用以蓝色为主色调,象征物流的高效与可靠:

颜色类型 色值 用途
主色 #1976D2 (Blue) 导航、主题元素
辅助色 #64B5F6 按钮、强调
第三色 #BBDEFB 背景、卡片
背景色 #F5F5F5 页面背景
卡片背景 #FFFFFF 信息卡片

4.2 状态色彩映射

状态 色值 视觉效果
待揽收 #9E9E9E 灰色
运输中 #1976D2 蓝色
派送中 #FFC107 黄色
已签收 #4CAF50 绿色
异常 #F44336 红色
未知 #9E9E9E 灰色

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
单号信息 18px Medium #333333
状态文本 16px Regular 对应状态色
物流信息 14px Regular #666666
时间信息 12px Light #999999

4.4 组件规范

4.4.1 输入框
复制代码
┌─────────────────────────────────────┐
│  输入快递单号(一行一个)            │
│                                     │
│  123456789012                       │
│  987654321098                       │
│                                     │
└─────────────────────────────────────┘
4.4.2 物流卡片
复制代码
┌─────────────────────────────────────┐
│  顺丰速运                            │
│  123456789012                       │
│  ─────────────────────────────────  │
│  📦 运输中                          │
│  【深圳市】快递已到达【深圳转运中心】  │
│  2024-01-01 12:00:00                │
│                                     │
│  [查看详情] [设置提醒]              │
└─────────────────────────────────────┘
4.4.3 物流详情
复制代码
┌─────────────────────────────────────┐
│  物流详情                            │
│  ─────────────────────────────────  │
│  ● 【深圳市】快递已到达【深圳转运中心】 │
│    2024-01-01 12:00:00              │
│  ● 【广州市】快递离开【广州转运中心】 │
│    2024-01-01 10:00:00              │
│  ● 【广州市】快递已到达【广州转运中心】 │
│    2024-01-01 08:00:00              │
│  ● 【广州市】快递已揽收              │
│    2024-01-01 06:00:00              │
└─────────────────────────────────────┘
4.4.4 提醒设置
复制代码
┌─────────────────────────────────────┐
│  到货提醒                            │
│  ─────────────────────────────────  │
│  ☐ 开启到货提醒                      │
│  ☐ 开启派送提醒                      │
│  ☐ 开启异常提醒                      │
│                                     │
│  [保存设置]                         │
└─────────────────────────────────────┘

五、核心功能实现

5.1 追踪控制器实现

dart 复制代码
class TrackingController {
  final CourierService _courierService;
  final NotificationService _notificationService;
  final DataManager _dataManager;
  final List<TrackingNumber> trackingNumbers = [];

  TrackingController(this._courierService, this._notificationService, this._dataManager);

  Future<void> initialize() async {
    await _notificationService.initialize();
    final savedNumbers = await _dataManager.loadTrackingNumbers();
    trackingNumbers.addAll(savedNumbers);
  }

  Future<void> addTrackingNumber(String number) async {
    final courierName = _courierService.identifyCourier(number);
    final status = await _courierService.track(number);
    final details = await _courierService.getTrackingDetails(number);
    
    final trackingNumber = TrackingNumber(
      number: number,
      courierName: courierName,
      status: status,
      latestUpdate: details.isNotEmpty ? details[0] : '暂无信息',
      trackingDetails: details,
      createdAt: DateTime.now(),
    );

    trackingNumbers.add(trackingNumber);
    await _dataManager.saveTrackingNumbers(trackingNumbers);
  }

  Future<void> addMultipleTrackingNumbers(List<String> numbers) async {
    for (final number in numbers) {
      await addTrackingNumber(number);
    }
  }

  Future<void> updateTrackingStatus(TrackingNumber number) async {
    final index = trackingNumbers.indexOf(number);
    if (index == -1) return;

    final status = await _courierService.track(number.number);
    final details = await _courierService.getTrackingDetails(number.number);

    trackingNumbers[index] = TrackingNumber(
      number: number.number,
      courierName: number.courierName,
      status: status,
      latestUpdate: details.isNotEmpty ? details[0] : '暂无信息',
      trackingDetails: details,
      createdAt: number.createdAt,
      notifyOnDelivery: number.notifyOnDelivery,
    );

    await _dataManager.saveTrackingNumbers(trackingNumbers);

    if (number.notifyOnDelivery && status == CourierStatus.delivered) {
      await _notificationService.scheduleNotification(trackingNumbers[index]);
    }
  }

  void toggleNotification(TrackingNumber number) {
    final index = trackingNumbers.indexOf(number);
    if (index == -1) return;

    trackingNumbers[index] = TrackingNumber(
      number: number.number,
      courierName: number.courierName,
      status: number.status,
      latestUpdate: number.latestUpdate,
      trackingDetails: number.trackingDetails,
      createdAt: number.createdAt,
      notifyOnDelivery: !number.notifyOnDelivery,
    );

    if (trackingNumbers[index].notifyOnDelivery) {
      _notificationService.scheduleNotification(trackingNumbers[index]);
    } else {
      _notificationService.cancelNotification(trackingNumbers[index]);
    }

    _dataManager.saveTrackingNumbers(trackingNumbers);
  }

  void removeTrackingNumber(TrackingNumber number) {
    trackingNumbers.remove(number);
    _notificationService.cancelNotification(number);
    _dataManager.saveTrackingNumbers(trackingNumbers);
  }
}

5.2 快递服务实现

dart 复制代码
class CourierService {
  final http.Client _client;

  CourierService(this._client);

  Future<CourierStatus> track(String number) async {
    try {
      // 模拟API调用
      await Future.delayed(Duration(seconds: 1));
      
      // 模拟返回不同状态
      final random = Random();
      final statuses = [
        CourierStatus.awaitingPickup,
        CourierStatus.inTransit,
        CourierStatus.outForDelivery,
        CourierStatus.delivered,
        CourierStatus.exception,
      ];
      return statuses[random.nextInt(statuses.length)];
    } catch (e) {
      print('Error tracking package: $e');
      return CourierStatus.unknown;
    }
  }

  String identifyCourier(String number) {
    // 模拟快递公司识别
    final couriers = [
      '顺丰速运',
      '中通快递',
      '申通快递',
      '韵达快递',
      '圆通快递',
      '百世快递',
    ];
    final random = Random();
    return couriers[random.nextInt(couriers.length)];
  }

  Future<List<String>> getTrackingDetails(String number) async {
    try {
      // 模拟API调用
      await Future.delayed(Duration(seconds: 1));
      
      // 模拟返回物流详情
      return [
        '【深圳市】快递已到达【深圳转运中心】',
        '【广州市】快递离开【广州转运中心】,下一站【深圳转运中心】',
        '【广州市】快递已到达【广州转运中心】',
        '【广州市】快递已揽收',
      ];
    } catch (e) {
      print('Error getting tracking details: $e');
      return [];
    }
  }
}

5.3 通知服务实现

dart 复制代码
class NotificationService {
  late FlutterLocalNotificationsPlugin _notifications;

  Future<void> initialize() async {
    _notifications = FlutterLocalNotificationsPlugin();
    const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
    final InitializationSettings initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
    );
    await _notifications.initialize(initializationSettings);
  }

  Future<void> scheduleNotification(TrackingNumber number) async {
    const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'courier_tracker_channel',
      '快递追踪',
      importance: Importance.max,
      priority: Priority.high,
    );
    const NotificationDetails platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
    );

    await _notifications.schedule(
      number.number.hashCode,
      '快递到货提醒',
      '您的快递 ${number.number} 已到达,请及时取件',
      DateTime.now().add(const Duration(seconds: 5)), // 模拟5秒后通知
      platformChannelSpecifics,
    );
  }

  Future<void> cancelNotification(TrackingNumber number) async {
    await _notifications.cancel(number.number.hashCode);
  }
}

5.4 数据管理实现

dart 复制代码
class DataManager {
  static const String _trackingNumbersKey = 'tracking_numbers';

  Future<List<TrackingNumber>> loadTrackingNumbers() async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = prefs.getString(_trackingNumbersKey);
    if (jsonString == null) return [];

    final jsonList = json.decode(jsonString) as List;
    return jsonList.map((json) => TrackingNumber.fromJson(json)).toList();
  }

  Future<void> saveTrackingNumbers(List<TrackingNumber> numbers) async {
    final prefs = await SharedPreferences.getInstance();
    final jsonList = numbers.map((number) => number.toJson()).toList();
    await prefs.setString(_trackingNumbersKey, json.encode(jsonList));
  }
}

六、交互设计

6.1 输入页面交互流程

快递服务 追踪控制器 输入页面 用户 快递服务 追踪控制器 输入页面 用户 输入多个快递单号 点击开始查询 解析单号列表 遍历查询每个单号 返回物流状态 更新查询结果 显示物流信息 点击设置提醒 启用提醒 确认设置 显示设置成功

6.2 追踪页面交互流程

点击卡片
下拉刷新
点击提醒开关
滑动删除
用户打开追踪页面
显示物流列表
用户操作
展开详情
更新状态
切换提醒
删除单号
查看物流轨迹
显示更新结果
保存提醒设置
确认删除

6.3 历史页面交互流程

历史记录
查看详情
重新追踪
清空历史
追踪页面
确认清空


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 基础UI框架 批量查询功能 物流追踪功能 到货提醒功能 历史记录管理 快递公司识别 扫码录入 多语言支持 云同步功能 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 快递单号批量查询应用开发计划

7.2 功能扩展建议

7.2.1 扫码录入

扫码功能:

  • 支持扫描快递单条形码
  • 自动识别单号并添加
  • 批量扫描多个快递单
  • 支持二维码识别
7.2.2 多语言支持

多语言功能:

  • 支持中文、英文等多语言
  • 根据系统语言自动切换
  • 提供语言手动切换选项
  • 适配不同语言的UI布局
7.2.3 云同步功能

云同步功能:

  • 支持账号登录
  • 云端备份快递信息
  • 多设备同步数据
  • 数据恢复功能

八、注意事项

8.1 开发注意事项

  1. API调用限制:物流查询API可能有调用频率限制,需做好限流处理

  2. 权限管理:通知功能需要申请权限,需合理处理权限请求

  3. 数据安全:快递单号属于敏感信息,需做好本地存储加密

  4. 网络依赖:物流查询需要网络连接,需处理离线情况

  5. 用户体验:批量查询时需显示加载状态,避免用户等待焦虑

8.2 常见问题

问题 原因 解决方案
单号识别失败 单号格式不正确 提示用户检查单号
查询无结果 网络连接问题 检查网络连接
通知不生效 权限未开启 引导用户开启权限
应用崩溃 数据解析错误 增加异常处理
保存失败 存储空间不足 提示用户清理空间

8.3 使用技巧

📦 快递单号批量查询使用技巧 📦

输入技巧

  • 一行输入一个快递单号
  • 支持复制粘贴多个单号
  • 系统会自动去重处理
  • 支持不同快递公司的单号

查询技巧

  • 点击开始查询后耐心等待
  • 下拉刷新可更新物流状态
  • 点击卡片查看详细轨迹
  • 长按卡片可进行管理操作

提醒设置

  • 开启到货提醒及时获取通知
  • 可同时设置多个快递提醒
  • 到货后自动发送通知
  • 在设置页面管理所有提醒

历史管理

  • 自动保存查询历史
  • 可查看历史快递状态
  • 支持清空历史记录
  • 可重新追踪历史单号

九、运行说明

9.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+
Web浏览器 Chrome 90+
网络连接 稳定网络

9.2 运行命令

bash 复制代码
# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_courier_tracker.dart --web-port 8146

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_courier_tracker.dart

# 代码分析
flutter analyze lib/main_courier_tracker.dart

十、总结

快递单号批量查询应用通过简洁的界面和高效的功能,为用户提供了便捷的物流查询体验。用户可以一次输入多个快递单号,系统自动识别快递公司并查询物流状态,同时支持设置到货提醒,让用户及时了解快递动态。

核心功能包括批量查询、自动识别、物流追踪、到货提醒、历史记录等。用户可以通过简洁的界面输入多个快递单号,系统自动处理并显示查询结果,同时支持设置到货提醒,让用户不再错过快递。

应用采用蓝色为主色调,象征物流的高效与可靠。通过本应用,希望能够帮助用户更方便地管理快递,节省时间和精力,让快递查询变得更加简单和高效。

快递单号批量查询------让物流追踪更简单


相关推荐
四谎真好看2 小时前
Redis学习笔记(高级篇2)
redis·笔记·学习·学习笔记
旺仔大牛2 小时前
Flutter中StatefulWidget的生命周期
flutter·statefulwidget
鱼鳞_2 小时前
Java学习笔记_Day26(不可变集合)
java·笔记·学习
浮芷.2 小时前
开源鸿蒙跨平台Flutter开发:校园兼职信息发布应用
科技·flutter·华为·开源·harmonyos·鸿蒙
AI_零食2 小时前
开源鸿蒙跨平台Flutter开发:密码生成器应用
网络·学习·flutter·华为·开源·harmonyos·鸿蒙
fengci.2 小时前
LilCTF2025web(前半部分)
开发语言·网络·学习·php
zhangrelay2 小时前
蓝桥云课一分钟-绚丽贪吃蛇-后续-cmake
笔记·学习
AI_零食2 小时前
开源鸿蒙跨平台Flutter开发:生日纪念日提醒应用
运维·flutter·开源·harmonyos·鸿蒙
世人万千丶2 小时前
Flutter 框架跨平台鸿蒙开发 - AR寻宝探险游戏应用
学习·flutter·游戏·华为·开源·ar·harmonyos