Flutter+开源鸿蒙实战|城市共享驿站智能存取系统 Day3 扫码模块集成+智能寄存表单+时长计费算法+驿站详情页+本地缓存持久化
Flutter+开源鸿蒙实战|城市共享驿站智能存取系统 Day3 扫码模块集成+智能寄存表单+时长计费算法+驿站详情页+本地缓存持久化
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
<!-- Schema.org 结构化数据 -->
<script type="application/ld+json">
{
"@context":"https://schema.org",
"type":"BlogPosting",
"headline":"Flutter+开源鸿蒙实战 城市共享驿站智能存取系统Day3 扫码集成+寄存表单+时长计费+驿站详情+本地缓存",
"author":{"type":"Person","name":"鸿蒙跨端开发者"},
"publisher":{"type":"Organization","name":"开源鸿蒙技术社区"},
"datePublished":"2026-05-09",
"description":"商业级无校园项目Day3,集成二维码扫码开箱、搭建物品寄存表单、编写智能时长计费算法、开发驿站详情页、实现常用驿站本地缓存持久化、封装全局弹窗组件,超详细分步拆解+口语化讲解+规范代码块+新手避坑,全适配鸿蒙手机平板智能终端",
"keywords":"Flutter,开源鸿蒙,OpenHarmony,共享驿站,扫码开箱,寄存计费,表单提交,本地缓存,驿站详情页,商业毕设项目"
}
</script>
一、前言
哈喽小伙伴们,我们继续深耕城市共享驿站智能存取系统,全程脱离校园、聚焦城市商圈、小区、写字楼真实便民业务,不走烂大街套路,架构高级、逻辑完整、技术点密集,不管做毕设、作品集还是实战提升,都极具含金量。
先简单复盘前两日进度:
Day1 完成项目从零初始化、企业级分层目录、第三方依赖整合、用户/全局状态控制器、五大页面骨架、全局屏幕适配、底部导航完整基座;
Day2 搭建全局路由与路由守卫、完善驿站/快件/订单三大实体模型、创建驿站业务控制器、模拟城市网点数据、完成首页搜索+分类标签+驿站列表、封装通用卡片组件,实现分类筛选交互。
来到 Day3,我们正式进入项目核心业务层开发,不再只做页面骨架和列表展示,开始做用户真正能交互、能落地的核心功能:扫码开箱、物品寄存、计费计算、详情页面、本地缓存,全部都是真实商业APP必备能力。
依旧严格遵循你固定的写作标准:
全篇口语化叙事,不生硬机器文案,前言饱满、结尾总结详实;
每段代码上方附带超详细文字解析,讲清设计思路、业务逻辑、新手易错点;
代码块严格控制每段5~6行,只保留核心逻辑,干净易复制、易看懂;
结构分点清晰、步骤层层递进,零基础也能跟着逐行复刻;
全程适配开源鸿蒙手机、平板、大屏设备,多端布局不错乱、不挤压;
每篇完结配套4张实景配图,可直接插入CSDN文章发布。
今日Day3 核心开发任务(分点清晰,逐项落地)
- 配置扫码权限,适配鸿蒙相机、存储权限动态申请;
- 封装全局二维码扫码组件,实现相机预览、扫码识别结果回调;
- 搭建智能存取件页面完整布局,集成扫码入口、寄存入口双功能;
- 开发物品寄存表单,包含物品类型、寄存时长、联系方式输入项;
- 编写智能时长计费算法,按小时阶梯收费,普通/会员差异化计价;
- 开发驿站详情页面,展示网点完整信息、营业时间、评分、服务介绍;
- 实现列表点击跳转详情,路由传参携带驿站数据;
- 接入shared_preferences,实现常用驿站本地缓存持久化;
- 封装全局自定义弹窗,用于寄存确认、扫码结果提示;
- 整理Day3开发高频报错问题,逐一分析原因+给出完整解决方案。
二、版块1:鸿蒙动态权限配置(相机+存储)
文字讲解
扫码功能必须调用手机相机,鸿蒙系统不会默认授权,必须手动动态申请相机、存储权限。
我们封装一个通用权限请求工具类,后续扫码、相册、定位都可以复用,不用重复写权限申请代码,符合项目规范化开发。
Future<bool> requestCameraPerm() async {
final status = await Permission.camera.request();
return status.isGranted;
}
三、版块2:封装全局二维码扫码核心组件
文字讲解
借助之前引入的qr_code_scanner库,封装独立扫码页面。
打开相机实时预览,自动识别二维码内容,识别成功后自动返回结果、关闭相机,避免后台持续耗电;同时适配鸿蒙相机比例,预览界面不变形、不拉伸。
class QrScanPage extends StatefulWidget {
const QrScanPage({super.key});
State<QrScanPage> createState() => _QrScanPageState();
}
void onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
Get.back(result: scanData.code);
});
}
四、版块3:存取件页面布局重构(扫码+寄存双入口)
文字讲解
重构智能存取件页面,去掉空白骨架,做成两大功能入口:「扫码开箱」和「物品寄存」。
采用上下卡片布局,圆角阴影统一风格,适配鸿蒙多端尺寸,点击对应入口分别跳转扫码页、寄存表单页,逻辑分区清晰,用户交互直观。
body: Column(
children: [
buildFuncCard("扫码开箱", Icons.qr_code),
buildFuncCard("物品寄存", Icons.add_box),
],
)
五、版块4:创建寄存表单页面&输入控件
文字讲解
新建寄存表单页面,包含三项核心输入:物品类型选择、寄存时长输入、手机号录入。
使用TextField和下拉选择器组合,输入框适配屏幕宽度,键盘弹出自动上推页面,不会遮挡输入框,完美适配鸿蒙手机小屏设备。
String? itemType;
TextEditingController timeCtrl = TextEditingController();
TextEditingController phoneCtrl = TextEditingController();
六、版块5:核心业务——阶梯时长计费算法

文字讲解
这是本项目含金量最高的业务逻辑之一:按寄存时长阶梯计费,同时区分普通用户和会员用户。
规则:04小时基础价,412小时加价,超过12小时按单日计费;会员享受8折优惠,算法独立封装,后期修改价格规则只改这一处即可。
double calcFee(int hour, bool isMember) {
double base = hour <= 4 ? 3 : hour <= 12 ? 6 : 10;
return isMember ? base * 0.8 : base;
}
七、版块6:驿站详情实体传参&详情页搭建
文字讲解
点击首页驿站列表卡片,通过GetX路由把当前驿站实体模型传递到详情页。
详情页展示网点名称、所在区域、营业时间、评分、距离、服务简介,布局采用图文组合,信息层级分明,UI简约商务风。
final StationModel model = Get.arguments;
Text(model.name, style: TextStyle(fontSize:18.sp,fontWeight:FontWeight.bold)),
Text("营业时间:${model.time}",style: TextStyle(fontSize:14.sp))
八、版块7:常用驿站本地缓存持久化
文字讲解
利用shared_preferences把用户常去的驿站名称、地址保存到本地。
退出APP、重启鸿蒙设备后,再次进入仍能读取历史常用驿站,不用重新搜索,提升用户体验,也是商业项目标配功能。
Future<void> saveRecentStation(String name) async {
final sp = await SharedPreferences.getInstance();
await sp.setString('recent_station', name);
}
九、版块8:封装全局自定义确认弹窗
文字讲解
系统默认弹窗样式单调,我们自己封装全局通用弹窗,用于寄存确认、扫码结果提示、操作确认。
统一圆角、按钮配色、文字样式,全局任意页面可直接调用,不用重复写AlertDialog代码。
void showCommonDialog(String title, VoidCallback onConfirm) {
Get.dialog(AlertDialog(
title: Text(title),
actions: [TextButton(onPressed:onConfirm,child:Text("确认"))],
));
}
十、版块9:首页增加常用驿站历史记录模块
文字讲解
在首页顶部新增「常用驿站」模块,读取本地缓存数据,有记录则展示历史网点,无记录则显示暂无浏览记录。
配合缓存功能形成完整闭环,用户可以快速进入常去驿站详情,提升APP实用性。
Future<String?> getRecentStation() async {
final sp = await SharedPreferences.getInstance();
return sp.getString('recent_station');
}
十一、版块10:Day3开发新手高频问题 口语化详解
问题1:扫码页面打开黑屏、无法启动相机?
解答:99%是权限没申请成功,首先确认已经调用相机权限请求;鸿蒙真机需要手动在设置给APP开启相机权限;模拟器部分不支持相机,建议用真机测试。
问题2:路由传参到详情页,获取参数为null?
解答:跳转要用Get.to(页面,arguments:实体);接收页面必须在build外定义Get.arguments;名字拼写、页面路由不匹配也会导致拿不到数据。
问题3:计费算法计算金额不准、会员折扣不生效?
解答:判断会员状态要从AuthController实时获取;数值类型不要混用int和double;阶梯条件判断顺序不能颠倒,否则计价逻辑错乱。
问题4:本地缓存保存成功,重启APP读不到数据?
解答:保存和读取的key字符串必须完全一致,不能大小写有差异;异步方法要加async/await,不要同步直接取值;确保没有清空缓存的代码误执行。
问题5:表单页面键盘弹出遮挡输入框?
解答:页面外层嵌套SingleChildScrollView;不要固定高度,全部用自适应.w/.h单位;鸿蒙小屏设备优先适配布局,避免硬编码尺寸。
十二、Day3 开发总结
今天Day3完成了项目核心业务功能闭环开发,彻底从页面骨架迈入可交互、可商用的真实逻辑层面:
- 完成鸿蒙相机、存储动态权限封装,为扫码、相册功能打好权限基础;
- 封装独立二维码扫码组件,实现自动识别、结果回调、关闭相机逻辑;
- 重构存取件页面,打造扫码开箱、物品寄存两大核心功能入口;
- 搭建完整寄存表单,支持类型选择、时长与手机号录入;
- 编写高阶阶梯计费算法,实现普通/会员差异化计价,业务逻辑饱满;
- 开发驿站详情页,实现列表点击路由传参、完整信息展示;
- 接入本地缓存,实现常用驿站持久化存储,重启不丢失;
- 封装全局自定义弹窗,统一APP弹窗样式,代码可全局复用;
- 首页新增常用驿站模块,读取本地历史记录,优化用户体验;
- 汇总新手开发高频问题,给出原因和落地解决方法,轻松避坑。
整个项目现在已经具备扫码、寄存、计费、详情、缓存五大真实商业能力,完全脱离校园玩具级项目,架构规范、逻辑严谨、技术点丰富,毕设答辩、作品集展示完全够用。
十三、下期Day4预告
Day4将开发:订单生成与订单列表、寄存记录入库、订单状态管理(待取件/已完成/超时)、个人中心我的订单页面、会员中心UI与权益展示、全局交互细节优化。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)