Flutter 框架跨平台鸿蒙开发 - 旅行预算管家

旅行预算管家应用


欢迎加入开源鸿蒙跨平台社区:

https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

1.1 应用简介

旅行预算管家是一款旅行探索类应用,为旅行者提供全程预算管理服务。支持预算规划、实时记账、多币种换算、支出分析四大核心功能,帮助用户在旅途中合理控制开支,避免超支尴尬。无论是短途周末游还是长途跨国旅行,都能轻松掌握财务状况。

应用以清新的青色为主色调,象征旅途的轻松与自由。涵盖预算概览、支出记录、支出分析、我的旅行四大模块。用户可以创建旅行计划、设定预算、记录每笔支出、查看分析报告,实现旅行财务的全方位管理。

1.2 核心功能

功能模块 功能描述 实现方式
预算规划 创建旅行并设定预算 表单输入
实时记账 快速记录每笔支出 分类记账
多币种 支持10种货币换算 汇率转换
支出分析 分类统计与可视化 饼图展示
进度追踪 预算使用进度监控 进度条
旅行管理 多次旅行统一管理 列表展示

1.3 货币类型定义

序号 货币名称 符号 代码 汇率(参考)
1 人民币 ¥ CNY 1.0
2 美元 $ USD 0.14
3 欧元 EUR 0.13
4 日元 ¥ JPY 21.0
5 韩元 KRW 188.0
6 泰铢 ฿ THB 4.9
7 港币 HK$ HKD 1.09
8 新币 S$ SGD 0.19
9 马币 RM MYR 0.66
10 澳元 A$ AUD 0.21

1.4 支出分类定义

序号 分类名称 Emoji 颜色代码 描述
1 交通 🚗 #2196F3 机票、车票等
2 住宿 🏨 #9C27B0 酒店、民宿
3 餐饮 🍜 #FF9800 餐厅、小吃
4 购物 🛍️ #E91E63 纪念品、特产
5 娱乐 🎢 #4CAF50 游乐、表演
6 门票 🎫 #00BCD4 景点门票
7 通讯 📱 #795548 电话卡、WiFi
8 医疗 💊 #F44336 药品、就医
9 其他 📦 #607D8B 其他支出

1.5 旅行状态定义

序号 状态名称 Emoji 颜色代码 描述
1 计划中 📋 #9E9E9E 尚未出发
2 进行中 ✈️ #4CAF50 正在旅行
3 已完成 #2196F3 旅行结束
4 已取消 #F44336 取消计划

1.6 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
自定义绘制 CustomPainter -
图表展示 饼图绘制 -
目标平台 鸿蒙OS / Web API 21+

1.7 项目结构

复制代码
lib/
└── main_travel_budget.dart
    ├── TravelBudgetApp              # 应用入口
    ├── Currency                     # 货币类型枚举
    ├── ExpenseCategory              # 支出分类枚举
    ├── TripStatus                   # 旅行状态枚举
    ├── Trip                         # 旅行模型
    ├── Expense                      # 支出模型
    ├── BudgetAllocation             # 预算分配模型
    ├── TravelBudgetHomePage         # 主页面(底部导航)
    ├── _buildOverviewPage           # 预算概览页
    ├── _buildExpensesPage           # 支出记录页
    ├── _buildAnalysisPage           # 支出分析页
    ├── _buildTripsPage              # 我的旅行页
    └── PieChartPainter              # 饼图绘制器

二、系统架构

2.1 整体架构图

Data Layer
Business Layer
Presentation Layer
主页面

TravelBudgetHomePage
预算概览
支出记录
支出分析
我的旅行
预算进度
今日支出
统计卡片
日期分组
支出列表
添加支出
饼图展示
分类明细
旅行列表
创建旅行
货币转换器

CurrencyConverter
支出计算器

ExpenseCalculator
图表绘制器

ChartPainter
Trip

旅行模型
Expense

支出模型
Currency

货币枚举
ExpenseCategory

支出分类

2.2 类图设计

uses
has
uses
has
belongs to
TravelBudgetApp
+Widget build()
<<enumeration>>
Currency
+String label
+String symbol
+String code
+double rate
+toCny(amount)
+fromCny(amount)
+cny()
+usd()
+eur()
+jpy()
+krw()
+thb()
<<enumeration>>
ExpenseCategory
+String label
+String icon
+Color color
+transport()
+accommodation()
+food()
+shopping()
+entertainment()
+tickets()
<<enumeration>>
TripStatus
+String label
+String icon
+Color color
+planning()
+ongoing()
+completed()
+cancelled()
Trip
+String id
+String name
+String destination
+DateTime startDate
+DateTime endDate
+double budget
+Currency currency
+TripStatus status
+int days
+int daysRemaining
Expense
+String id
+String tripId
+String title
+double amount
+Currency currency
+ExpenseCategory category
+DateTime date
+double amountInCny

2.3 页面导航流程

概览
记录
分析
旅行
应用启动
预算概览
底部导航
查看预算进度
支出列表
饼图分析
旅行列表
添加支出
填写支出信息
保存支出
创建旅行
填写旅行信息
保存旅行
查看分类明细

2.4 记账流程

概览页 支出管理 记账弹窗 用户 概览页 支出管理 记账弹窗 用户 点击记一笔 显示表单 输入支出名称 输入金额 选择货币 选择分类 创建支出记录 计算人民币金额 更新统计数据 显示更新后的进度


三、核心模块设计

3.1 数据模型设计

3.1.1 货币类型枚举 (Currency)
dart 复制代码
enum Currency {
  cny('人民币', '¥', 'CNY', 1.0),
  usd('美元', '\$', 'USD', 0.14),
  eur('欧元', '€', 'EUR', 0.13),
  jpy('日元', '¥', 'JPY', 21.0),
  krw('韩元', '₩', 'KRW', 188.0),
  thb('泰铢', '฿', 'THB', 4.9),
  hkd('港币', 'HK\$', 'HKD', 1.09),
  sgd('新币', 'S\$', 'SGD', 0.19),
  myr('马币', 'RM', 'MYR', 0.66),
  aud('澳元', 'A\$', 'AUD', 0.21);

  final String label;
  final String symbol;
  final String code;
  final double rate;

  double toCny(double amount) => amount / rate;
  double fromCny(double amount) => amount * rate;
}
3.1.2 支出分类枚举 (ExpenseCategory)
dart 复制代码
enum ExpenseCategory {
  transport('交通', '🚗', Color(0xFF2196F3)),
  accommodation('住宿', '🏨', Color(0xFF9C27B0)),
  food('餐饮', '🍜', Color(0xFFFF9800)),
  shopping('购物', '🛍️', Color(0xFFE91E63)),
  entertainment('娱乐', '🎢', Color(0xFF4CAF50)),
  tickets('门票', '🎫', Color(0xFF00BCD4)),
  communication('通讯', '📱', Color(0xFF795548)),
  medical('医疗', '💊', Color(0xFFF44336)),
  other('其他', '📦', Color(0xFF607D8B));

  final String label;
  final String icon;
  final Color color;
}
3.1.3 旅行模型 (Trip)
dart 复制代码
class Trip {
  final String id;              // 旅行ID
  final String name;            // 旅行名称
  final String destination;     // 目的地
  final DateTime startDate;     // 开始日期
  final DateTime endDate;       // 结束日期
  final double budget;          // 预算金额
  final Currency currency;      // 预算货币
  final TripStatus status;      // 旅行状态
  final String? coverImage;     // 封面图片
  final DateTime createdAt;     // 创建时间

  int get days => endDate.difference(startDate).inDays + 1;
  int get daysRemaining => endDate.difference(DateTime.now()).inDays;
}
3.1.4 支出模型 (Expense)
dart 复制代码
class Expense {
  final String id;              // 支出ID
  final String tripId;          // 所属旅行ID
  final String title;           // 支出名称
  final double amount;          // 金额
  final Currency currency;      // 货币类型
  final ExpenseCategory category; // 支出分类
  final DateTime date;          // 支出日期
  final String? notes;          // 备注
  final String? receipt;        // 小票图片

  double get amountInCny => currency.toCny(amount);
}
3.1.5 支出分类分布

30% 25% 20% 15% 5% 5% 支出分类分布示例 交通 住宿 餐饮 购物 门票 其他

3.2 页面结构设计

3.2.1 主页面布局

TravelBudgetHomePage
IndexedStack
预算概览页
支出记录页
支出分析页
我的旅行页
NavigationBar
概览 Tab
记录 Tab
分析 Tab
旅行 Tab

3.2.2 预算概览页结构

预算概览页
预算进度卡
统计卡片组
今日支出
总预算显示
进度条
已支出/剩余
行程天数
目的地
日均预算
预计支出
今日支出列表
空状态提示

3.2.3 支出记录页结构

支出记录页
统计头部
日期分组列表
日期组
日期标题
当日合计
支出项列表
支出项
分类图标
支出名称
金额显示

3.2.4 支出分析页结构

支出分析页
统计头部
饼图区域
分类明细列表
饼图绘制
中心总金额
分类项
分类图标
进度条
金额/百分比

3.3 货币换算逻辑

CNY
其他
获取支出金额
货币类型
直接使用
获取汇率
计算人民币金额
amount / rate
累加统计
更新预算进度
更新分类统计

3.4 预算进度计算



获取旅行预算
转换为人民币
获取总支出
计算进度百分比
percentage = spent / budget
是否超支
显示红色警告
显示正常进度
计算剩余金额
更新UI显示


四、UI设计规范

4.1 配色方案

应用以清新的青色为主色调,象征旅途的轻松与自由:

颜色类型 色值 用途
主色 #00ACC1 (Cyan) 导航、主题元素
辅助色 #00838F 支出记录页
第三色 #006064 分析页面
强调色 #00BCD4 进度条
背景色 #006064 页面背景
卡片背景 #00838F 统计卡片

4.2 分类颜色规范

分类 色值 视觉效果
交通 #2196F3 蓝色
住宿 #9C27B0 紫色
餐饮 #FF9800 橙色
购物 #E91E63 粉色
娱乐 #4CAF50 绿色
门票 #00BCD4 青色
通讯 #795548 棕色
医疗 #F44336 红色
其他 #607D8B 灰蓝

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 白色
预算金额 28px Bold 白色
支出名称 16px Bold #000000
分类标签 12px Regular 灰色
统计数字 20px Bold 白色

4.4 组件规范

4.4.1 预算进度卡片
复制代码
┌─────────────────────────────────────┐
│  总预算                    进行中   │
│  ¥15000                             │
│  ████████████░░░░░░░░  65%          │
│  已支出 ¥9750      剩余 ¥5250       │
└─────────────────────────────────────┘
4.4.2 统计卡片组
复制代码
┌─────────────────────────────────────┐
│  📅 行程天数    📍 目的地           │
│     7天           东京              │
├─────────────────────────────────────┤
│  💰 日均预算    📊 预计支出         │
│    ¥2143          ¥6429             │
└─────────────────────────────────────┘
4.4.3 支出项卡片
复制代码
┌─────────────────────────────────────┐
│  🍜 餐饮                            │
│      拉面                ¥1200      │
│                          ≈¥57      │
└─────────────────────────────────────┘
4.4.4 分类明细项
复制代码
┌─────────────────────────────────────┐
│  🏨 住宿                            │
│      ████████████░░░░░░░░           │
│                   ¥4500    30.0%    │
└─────────────────────────────────────┘
4.4.5 旅行卡片
复制代码
┌─────────────────────────────────────┐
│  日本东京之旅              进行中   │
│  📍 日本东京                        │
│  📅 3/15 - 3/21  ⏱️ 7天             │
│  预算: ¥15000      已用: 65%        │
│  ████████████░░░░░░░░               │
└─────────────────────────────────────┘

五、核心功能实现

5.1 货币换算实现

dart 复制代码
enum Currency {
  cny('人民币', '¥', 'CNY', 1.0),
  jpy('日元', '¥', 'JPY', 21.0),
  // ...

  final double rate;

  // 换算为人民币
  double toCny(double amount) => amount / rate;
  
  // 从人民币换算
  double fromCny(double amount) => amount * rate;
}

汇率换算公式:

AmountCNY=AmountforeignRateforeign Amount_{CNY} = \frac{Amount_{foreign}}{Rate_{foreign}} AmountCNY=RateforeignAmountforeign

5.2 支出统计实现

dart 复制代码
double _getTotalExpenses(String tripId) {
  return _expenses
    .where((e) => e.tripId == tripId)
    .fold(0.0, (sum, e) => sum + e.amountInCny);
}

Map<ExpenseCategory, double> _getExpensesByCategory(String tripId) {
  Map<ExpenseCategory, double> result = {};
  for (var expense in _expenses.where((e) => e.tripId == tripId)) {
    result[expense.category] = 
      (result[expense.category] ?? 0) + expense.amountInCny;
  }
  return result;
}

5.3 饼图绘制实现

dart 复制代码
class PieChartPainter extends CustomPainter {
  final Map<ExpenseCategory, double> data;
  final double total;

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width < size.height 
      ? size.width / 2 - 20 
      : size.height / 2 - 20;

    double startAngle = -pi / 2;

    for (var entry in data.entries) {
      final sweepAngle = (entry.value / total) * 2 * pi;
      
      final paint = Paint()
        ..color = entry.key.color
        ..style = PaintingStyle.fill;

      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius),
        startAngle,
        sweepAngle,
        true,
        paint,
      );

      startAngle += sweepAngle;
    }

    // 绘制中心圆
    canvas.drawCircle(center, radius * 0.5, innerPaint);
  }
}

5.4 预算进度计算

预算使用百分比计算:

Percentage=TotalSpentTotalBudget×100% Percentage = \frac{TotalSpent}{TotalBudget} \times 100\% Percentage=TotalBudgetTotalSpent×100%

日均预算计算:

DailyBudget=TotalBudgetTripDays DailyBudget = \frac{TotalBudget}{TripDays} DailyBudget=TripDaysTotalBudget

预计支出计算:

ExpectedSpent=DailyBudget×DaysPassed ExpectedSpent = DailyBudget \times DaysPassed ExpectedSpent=DailyBudget×DaysPassed

5.5 添加支出实现

dart 复制代码
void _addExpense() {
  if (_selectedTrip == null) return;

  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Row(
        children: [
          Icon(Icons.add_circle, color: Colors.cyanAccent),
          SizedBox(width: 8),
          Text('添加支出'),
        ],
      ),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextField(decoration: InputDecoration(hintText: '支出名称')),
          Row(
            children: [
              Expanded(child: TextField(keyboardType: TextInputType.number)),
              DropdownButtonFormField<Currency>(...),
            ],
          ),
          DropdownButtonFormField<ExpenseCategory>(...),
        ],
      ),
    ),
  );
}

六、交互设计

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 2024-04-07 基础UI框架 预算管理 多币种支持 实时汇率 预算提醒 导出报表 多人分账 云端同步 AI智能建议 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 旅行预算管家应用开发计划

7.2 功能扩展建议

7.2.1 实时汇率

汇率功能:

  • 接入汇率API
  • 自动更新汇率
  • 离线汇率缓存
  • 汇率趋势图
7.2.2 预算提醒

提醒功能:

  • 超支预警
  • 日预算提醒
  • 分类预算限制
  • 自定义提醒规则
7.2.3 多人分账

分账功能:

  • 创建旅行群组
  • 成员费用记录
  • 自动分账计算
  • 结算报表导出

八、注意事项

8.1 开发注意事项

  1. 汇率精度:货币换算需注意精度问题

  2. 数据持久化:支出数据需本地持久化存储

  3. 状态管理:旅行切换时需正确更新状态

  4. 图表绘制:CustomPainter需正确实现shouldRepaint

  5. 日期计算:跨日期计算需注意时区问题

8.2 常见问题

问题 原因 解决方案
汇率不准 使用固定汇率 接入实时API
金额显示异常 精度丢失 使用Decimal
饼图不显示 数据为空 添加空判断
进度超100% 超支未处理 添加clamp
日期计算错误 时区问题 统一时区

8.3 使用技巧

💰 旅行预算管理技巧 💰

预算规划建议

  • 交通费用:预留20%弹性空间
  • 住宿费用:提前预订享优惠
  • 餐饮费用:按人均×天数计算
  • 购物费用:设定上限避免冲动

记账习惯培养

  • 每日睡前整理当日支出
  • 大额支出及时记录
  • 保留小票便于核对
  • 分类准确便于分析

超支应对策略

  • 调整后续行程预算
  • 减少非必要支出
  • 寻找免费替代活动
  • 合理使用优惠券

九、运行说明

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_travel_budget.dart --web-port 8140

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

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

十、总结

旅行预算管家应用通过预算概览、支出记录、支出分析、我的旅行四大模块,为旅行者提供了一个便捷的预算管理平台。应用支持10种货币换算、9种支出分类、4种旅行状态,帮助用户在旅途中合理控制开支,避免超支尴尬。

核心功能涵盖预算规划、实时记账、多币种换算、支出分析四大模块。预算规划支持创建旅行并设定预算上限;实时记账支持快速记录每笔支出并自动换算;多币种换算支持10种常用货币;支出分析通过饼图直观展示消费分布。

应用采用 Material Design 3 设计规范,以清新的青色为主色调,象征旅途的轻松与自由。通过本应用,希望能够帮助旅行者轻松掌握财务状况,享受无忧旅程。

旅行预算管家------不超支的旅行


相关推荐
李李李勃谦2 小时前
Flutter 框架跨平台鸿蒙开发 - 星空识别助手
flutter·华为·harmonyos
李李李勃谦2 小时前
Flutter 框架跨平台鸿蒙开发 - 本地生活服务预约
flutter·华为·生活·harmonyos
我的世界洛天依2 小时前
胡桃讲编程:早期华为手机(比如畅享等)可以升级鸿蒙吗?
华为·harmonyos
2301_822703202 小时前
开源鸿蒙跨平台Flutter开发:幼儿疫苗全生命周期追踪系统:基于 Flutter 的免疫接种档案与状态机设计
算法·flutter·华为·开源·harmonyos·鸿蒙
2301_822703203 小时前
鸿蒙flutter三方库实战——教育与学习平台:Flutter Markdown
学习·算法·flutter·华为·harmonyos·鸿蒙
humors2214 小时前
各厂商工具包网址
java·数据库·python·华为·sdk·苹果·工具包
2301_822703206 小时前
开源鸿蒙跨平台Flutter开发:蛋白质序列特征提取:氨基酸组成与理化性质计算
flutter·华为·开源·harmonyos·鸿蒙
钛态6 小时前
Flutter 三方库 ethereum_addresses 的鸿蒙化适配指南 - 掌控区块链地址资产、精密校验治理实战、鸿蒙级 Web3 专家
flutter·harmonyos·鸿蒙·openharmony·ethereum_addresses
提子拌饭1336 小时前
开源鸿蒙跨平台Flutter开发:中小学百米跑信息记录表:基于 Flutter 的高精计时与运动学曲线引擎
flutter·华为·开源·harmonyos