开源鸿蒙跨平台Flutter开发:发票真伪查询应用
摘要: 发票真伪查询应用是一款基于Flutter开发的跨平台工具,支持扫码或手动输入验证发票真伪。核心功能包括二维码扫描、表单查询、状态验证(有效/无效/作废等)及历史记录管理,采用Material Design 3设计规范,技术栈涵盖相机扫描、本地存储等模块。系统采用分层架构(表现层、业务层、数据层),通过枚举类管理发票状态和类型,提供完整的发票验证服务。适用于鸿蒙OS/Web平台,帮助用户高效
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图






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 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 发票验证流程
三、核心模块设计
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 主页面布局
3.2.2 扫码页面结构
3.2.3 手动输入页面结构
3.2.4 历史记录页面结构
3.3 二维码解析逻辑
3.4 发票验证逻辑
四、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 后续版本规划
7.2 功能扩展建议
7.2.1 批量验证
批量功能:
- 批量扫描发票
- 批量导入图片
- 批量验证真伪
- 导出验证报告
7.2.2 云端同步
同步功能:
- 账号登录
- 云端备份记录
- 多设备同步
- 数据恢复
7.2.3 企业版功能
企业功能:
- 企业认证
- 多用户管理
- 权限控制
- 审计日志
八、注意事项
8.1 开发注意事项
-
相机权限:扫码功能需要申请相机权限
-
数据安全:发票信息属于敏感数据,需安全存储
-
网络依赖:验证功能需要网络连接,需处理离线情况
-
API限制:验证API可能有调用频率限制
-
兼容性:确保在不同设备上的相机功能正常
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
十、总结
发票真伪查询应用通过扫码查询、手动输入、历史记录、帮助中心四大模块,为用户提供了一个便捷的发票验证平台。用户可以通过扫描发票二维码或输入发票信息,快速验证发票真伪,避免假发票风险。
核心功能包括扫码查询、手动输入、真伪验证、历史记录等。应用采用专业的蓝色为主色调,象征可信与安全,界面简洁美观,交互流畅自然。
通过本应用,希望能够帮助用户轻松验证发票真伪,避免假发票带来的经济损失,保障财务安全。
发票真伪查询——验证真伪,保障安全
更多推荐


所有评论(0)