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

一、项目概述

运行效果图

image-20260410201109590

image-20260410201116831

image-20260410201123087

image-20260410201127810

image-20260410201133361

image-20260410201137947

1.1 应用简介

发票真伪查询是一款实用的财务工具应用,用户可以通过扫描发票二维码或输入发票信息,快速验证发票真伪,避免假发票风险。应用内置多种查询方式,支持历史记录管理,帮助用户轻松管理发票验证。

应用以专业的蓝色为主色调,象征可信与安全。涵盖扫码查询、手动输入、历史记录、帮助中心四大模块。用户可以选择不同的查询方式,快速验证发票真伪,查看历史查询记录,了解发票知识。

1.2 核心功能

功能模块 功能描述 实现方式
扫码查询 扫描发票二维码 相机扫描
手动输入 输入发票信息查询 表单输入
真伪验证 验证发票真伪 API调用
历史记录 保存查询历史 本地存储
发票详情 查看发票详细信息 详情页面

1.3 发票状态定义

序号 状态名称 Emoji 描述
1 有效 发票真实有效
2 无效 发票无效或伪造
3 已作废 ⚠️ 发票已被作废
4 已红冲 🔴 发票已红冲处理
5 查询失败 无法查询到信息

1.4 发票类型定义

序号 发票类型 描述
1 增值税专用发票 用于增值税抵扣
2 增值税普通发票 一般纳税人使用
3 电子发票 电子形式发票
4 机动车销售发票 购车专用发票
5 二手车销售发票 二手车交易发票

1.5 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
相机功能 camera -
二维码扫描 qr_code_scanner -
本地存储 shared_preferences -
目标平台 鸿蒙OS / Web API 21+

1.6 项目结构

lib/
└── main_invoice_verifier.dart
    ├── InvoiceVerifierApp     # 应用入口
    ├── Invoice               # 发票模型
    ├── InvoiceStatus         # 发票状态枚举
    ├── InvoiceType           # 发票类型枚举
    ├── InvoiceService        # 发票服务
    ├── InvoiceController     # 发票控制器
    ├── InvoiceVerifierHomePage # 主页面
    ├── _buildScanPage        # 扫码页面
    ├── _buildManualPage      # 手动输入页面
    ├── _buildHistoryPage     # 历史记录页面
    └── _buildHelpPage        # 帮助页面

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
InvoiceVerifierHomePage

扫码页面

手动输入页面

历史记录页面

帮助页面

相机预览

二维码识别

自动查询

表单输入

信息验证

提交查询

历史列表

记录详情

记录管理

使用说明

常见问题

发票控制器
InvoiceController

发票服务
InvoiceService

数据管理
DataManager

Invoice
发票模型

InvoiceStatus
状态枚举

InvoiceType
类型枚举

LocalStorage
本地存储

2.2 类图设计

uses

uses

creates

returns

uses

InvoiceVerifierApp

+Widget build()

Invoice

+String id

+String invoiceCode

+String invoiceNumber

+InvoiceType type

+double amount

+String sellerName

+String buyerName

+DateTime issueDate

+InvoiceStatus status

+DateTime verifiedAt

«enumeration»

InvoiceStatus

+String label

+String emoji

+valid()

+invalid()

+cancelled()

+redFlushed()

+queryFailed()

«enumeration»

InvoiceType

+String label

+String description

+vatSpecial()

+vatGeneral()

+electronic()

+vehicle()

+secondHandVehicle()

InvoiceService

+Future verifyInvoice(String code, String number)

+Future verifyByQRCode(String qrData)

+Invoice parseQRCode(String qrData)

InvoiceController

+List invoices

+Future loadInvoices()

+Future verifyByScan(String qrData)

+Future verifyByManual(String code, String number)

+void deleteInvoice(String id)

InvoiceVerifierHomePage

+Widget build()

+void _buildScanPage()

+void _buildManualPage()

+void _buildHistoryPage()

+void _buildHelpPage()

2.3 页面导航流程

扫码

手动

历史

帮助

应用启动

扫码页面

底部导航

打开相机

输入表单

查看记录

查看帮助

扫描二维码

识别成功

自动查询

显示结果

填写信息

提交查询

选择记录

查看详情

2.4 发票验证流程

API 发票服务 发票控制器 扫码页面 用户 API 发票服务 发票控制器 扫码页面 用户 扫描二维码 传递二维码数据 解析二维码 返回发票信息 验证发票真伪 返回验证结果 更新显示 显示验证结果 查看详情 显示发票详情

三、核心模块设计

3.1 数据模型设计

3.1.1 发票模型 (Invoice)
class Invoice {
  final String id;
  final String invoiceCode;
  final String invoiceNumber;
  final InvoiceType type;
  final double amount;
  final String sellerName;
  final String buyerName;
  final DateTime issueDate;
  final InvoiceStatus status;
  final DateTime verifiedAt;
  
  Invoice({
    required this.id,
    required this.invoiceCode,
    required this.invoiceNumber,
    required this.type,
    required this.amount,
    required this.sellerName,
    required this.buyerName,
    required this.issueDate,
    required this.status,
    required this.verifiedAt,
  });
}
3.1.2 发票状态枚举 (InvoiceStatus)
enum InvoiceStatus {
  valid(label: '有效', emoji: '✅'),
  invalid(label: '无效', emoji: '❌'),
  cancelled(label: '已作废', emoji: '⚠️'),
  redFlushed(label: '已红冲', emoji: '🔴'),
  queryFailed(label: '查询失败', emoji: '❓');

  final String label;
  final String emoji;

  const InvoiceStatus({required this.label, required this.emoji});
}
3.1.3 发票类型枚举 (InvoiceType)
enum InvoiceType {
  vatSpecial(label: '增值税专用发票', description: '用于增值税抵扣'),
  vatGeneral(label: '增值税普通发票', description: '一般纳税人使用'),
  electronic(label: '电子发票', description: '电子形式发票'),
  vehicle(label: '机动车销售发票', description: '购车专用发票'),
  secondHandVehicle(label: '二手车销售发票', description: '二手车交易发票');

  final String label;
  final String description;

  const InvoiceType({required this.label, required this.description});
}

3.2 页面结构设计

3.2.1 主页面布局

InvoiceVerifierHomePage

IndexedStack

扫码页面

手动输入页面

历史记录页面

帮助页面

NavigationBar

扫码 Tab

手动 Tab

历史 Tab

帮助 Tab

3.2.2 扫码页面结构

扫码页面

相机预览

扫描框

提示信息

操作按钮

实时预览

二维码识别

扫描区域

动画效果

扫描提示

状态显示

手动输入

打开相册

3.2.3 手动输入页面结构

手动输入页面

发票代码

发票号码

开票日期

校验码

提交按钮

输入框

格式验证

输入框

长度验证

日期选择

输入框

格式验证

提交查询

3.2.4 历史记录页面结构

历史记录页面

记录列表

筛选功能

空状态

发票卡片

状态标签

操作按钮

按状态筛选

按日期筛选

提示信息

引导按钮

3.3 二维码解析逻辑

获取二维码数据

解析数据格式

格式正确?

提示错误

提取发票信息

发票代码

发票号码

开票日期

校验码

调用验证API

返回验证结果

3.4 发票验证逻辑

有效

无效

已作废

已红冲

提交验证请求

参数验证

参数有效?

提示错误

调用API

查询成功?

显示查询失败

解析结果

发票状态

显示有效

显示无效

显示已作废

显示已红冲

保存记录


四、UI设计规范

4.1 配色方案

应用以专业的蓝色为主色调,象征可信与安全:

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

4.2 状态色彩映射

状态 色值 视觉效果
有效 #4CAF50 绿色
无效 #F44336 红色
已作废 #FF9800 橙色
已红冲 #F44336 红色
查询失败 #9E9E9E 灰色

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
发票号码 18px Medium #333333
状态标签 14px Regular 对应状态色
发票信息 14px Regular #666666
按钮文本 16px Medium #FFFFFF

4.4 组件规范

4.4.1 扫描框
┌─────────────────────────────────────┐
│  将发票二维码放入框内                │
│                                     │
│  ┌─────────────────────────────┐   │
│  │                             │   │
│  │                             │   │
│  │                             │   │
│  │                             │   │
│  └─────────────────────────────┘   │
│                                     │
│  [手动输入] [打开相册]              │
└─────────────────────────────────────┘
4.4.2 发票卡片
┌─────────────────────────────────────┐
│  增值税专用发票                      │
│  ─────────────────────────────────  │
│  发票代码: 1100191130               │
│  发票号码: 12345678                 │
│  金额: ¥1,234.56                    │
│                                     │
│  ✅ 有效                            │
│                                     │
│  [查看详情] [删除]                  │
└─────────────────────────────────────┘
4.4.3 验证结果
┌─────────────────────────────────────┐
│  验证结果                            │
│  ─────────────────────────────────  │
│  ✅ 发票有效                        │
│                                     │
│  发票代码: 1100191130               │
│  发票号码: 12345678                 │
│  开票日期: 2024-01-01               │
│  销方名称: XX公司                   │
│  购方名称: YY公司                   │
│  金额: ¥1,234.56                    │
│                                     │
│  [保存记录] [返回]                  │
└─────────────────────────────────────┘
4.4.4 输入表单
┌─────────────────────────────────────┐
│  发票代码                            │
│  ┌─────────────────────────────┐   │
│  │ 1100191130                  │   │
│  └─────────────────────────────┘   │
│                                     │
│  发票号码                            │
│  ┌─────────────────────────────┐   │
│  │ 12345678                    │   │
│  └─────────────────────────────┘   │
│                                     │
│  开票日期                            │
│  ┌─────────────────────────────┐   │
│  │ 2024-01-01                  │   │
│  └─────────────────────────────┘   │
│                                     │
│  [提交查询]                         │
└─────────────────────────────────────┘

五、核心功能实现

5.1 发票服务实现

class InvoiceService {
  Future<Invoice> verifyInvoice(String code, String number) async {
    // 模拟API调用
    await Future.delayed(Duration(seconds: 2));
    
    // 模拟返回验证结果
    final random = Random();
    final statuses = [
      InvoiceStatus.valid,
      InvoiceStatus.invalid,
      InvoiceStatus.cancelled,
      InvoiceStatus.redFlushed,
    ];
    
    return Invoice(
      id: UniqueKey().toString(),
      invoiceCode: code,
      invoiceNumber: number,
      type: InvoiceType.vatSpecial,
      amount: 1234.56,
      sellerName: 'XX公司',
      buyerName: 'YY公司',
      issueDate: DateTime.now(),
      status: statuses[random.nextInt(statuses.length)],
      verifiedAt: DateTime.now(),
    );
  }

  Future<Invoice> verifyByQRCode(String qrData) async {
    // 解析二维码数据
    final invoiceInfo = parseQRCode(qrData);
    return await verifyInvoice(invoiceInfo['code'], invoiceInfo['number']);
  }

  Map<String, String> parseQRCode(String qrData) {
    // 模拟解析二维码
    return {
      'code': '1100191130',
      'number': '12345678',
      'date': '2024-01-01',
    };
  }
}

5.2 发票控制器实现

class InvoiceController {
  final InvoiceService _invoiceService;
  final DataManager _dataManager;
  final List<Invoice> invoices = [];

  InvoiceController(this._invoiceService, this._dataManager);

  Future<void> initialize() async {
    await loadInvoices();
  }

  Future<void> loadInvoices() async {
    invoices.clear();
    final savedInvoices = await _dataManager.loadInvoices();
    invoices.addAll(savedInvoices);
  }

  Future<Invoice> verifyByScan(String qrData) async {
    final invoice = await _invoiceService.verifyByQRCode(qrData);
    invoices.insert(0, invoice);
    await _dataManager.saveInvoices(invoices);
    return invoice;
  }

  Future<Invoice> verifyByManual(String code, String number) async {
    final invoice = await _invoiceService.verifyInvoice(code, number);
    invoices.insert(0, invoice);
    await _dataManager.saveInvoices(invoices);
    return invoice;
  }

  void deleteInvoice(String id) {
    invoices.removeWhere((invoice) => invoice.id == id);
    _dataManager.saveInvoices(invoices);
  }
}

5.3 数据管理实现

class DataManager {
  static const String _invoicesKey = 'invoices';

  // 模拟本地存储
  static Map<String, String> _storage = {};

  Future<List<Invoice>> loadInvoices() async {
    final jsonString = _storage[_invoicesKey];
    if (jsonString == null) return [];

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

  Future<void> saveInvoices(List<Invoice> invoices) async {
    final jsonList = invoices.map((invoice) => invoice.toJson()).toList();
    _storage[_invoicesKey] = json.encode(jsonList);
  }
}

5.4 二维码扫描实现

class QRScannerWidget extends StatefulWidget {
  final Function(String) onQRCodeScanned;

  const QRScannerWidget({Key? key, required this.onQRCodeScanned}) : super(key: key);

  
  _QRScannerWidgetState createState() => _QRScannerWidgetState();
}

class _QRScannerWidgetState extends State<QRScannerWidget> {
  
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Expanded(
            child: Container(
              color: Colors.black,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(Icons.qr_code_scanner, size: 64, color: Colors.white),
                    SizedBox(height: 16),
                    Text('模拟相机预览', style: TextStyle(color: Colors.white)),
                    SizedBox(height: 32),
                    ElevatedButton(
                      onPressed: () {
                        // 模拟扫描成功
                        widget.onQRCodeScanned('invoice_code_123456');
                      },
                      child: Text('模拟扫描'),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

六、交互设计

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 云端同步

同步功能:

  • 账号登录
  • 云端备份记录
  • 多设备同步
  • 数据恢复
7.2.3 企业版功能

企业功能:

  • 企业认证
  • 多用户管理
  • 权限控制
  • 审计日志

八、注意事项

8.1 开发注意事项

  1. 相机权限:扫码功能需要申请相机权限

  2. 数据安全:发票信息属于敏感数据,需安全存储

  3. 网络依赖:验证功能需要网络连接,需处理离线情况

  4. API限制:验证API可能有调用频率限制

  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 运行命令

# 查看可用设备
flutter devices

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

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

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

十、总结

发票真伪查询应用通过扫码查询、手动输入、历史记录、帮助中心四大模块,为用户提供了一个便捷的发票验证平台。用户可以通过扫描发票二维码或输入发票信息,快速验证发票真伪,避免假发票风险。

核心功能包括扫码查询、手动输入、真伪验证、历史记录等。应用采用专业的蓝色为主色调,象征可信与安全,界面简洁美观,交互流畅自然。

通过本应用,希望能够帮助用户轻松验证发票真伪,避免假发票带来的经济损失,保障财务安全。

发票真伪查询——验证真伪,保障安全


Logo

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

更多推荐