1. 项目背景与整体设计思路
1.1 为什么在HarmonyOS 6.0上选择Flutter
做新生宿舍管理系统这个项目之前,我其实纠结过一阵子技术选型。HarmonyOS 6.0发布之后,官方主推的还是ArkTS和ArkUI这套原生方案,社区里关于"鸿蒙到底能不能跑Flutter"的讨论也一直没停过。但实际考察下来,Flutter在鸿蒙生态的适配已经比前两年成熟太多——OpenHarmony的Flutter适配分支从早期只能跑通Demo,到现在已经能支撑完整的商业应用落地。
我选择Flutter的一个核心原因是团队里大部分人熟悉Dart,而新生宿舍管理这种系统,本质上是一个典型的"中后台管理+移动端上报"组合场景,涉及学工部管理端、宿管员端、新生移动端三个角色,需要跨端复用。如果完全用ArkTS从零开发,三个端的代码没法共享,排期压力会成倍放大。而Flutter不管是写移动端还是鸿蒙端,UI层逻辑、状态管理、网络层都能复用同一套Dart代码,后端只需要提供标准RESTful API对接就行。
另一个必须考虑的现实问题是,宿舍管理系统的使用场景集中在每年9月新生入学报到前后的两三周内,属于典型的"波峰式"高并发访问。9月初的报到高峰期,家长和新生同时登录查询宿舍信息、办理入住、上报设施维修,请求量可能是平时的一百倍。这就要求前端的渲染效率、后端的响应能力都要扛得住瞬时压力,Flutter自带的Skia渲染引擎在列表滚动和大量卡片渲染场景下的表现,比基于WebView的跨端方案要稳定得多。
1.2 系统的三个核心角色与需求提炼
DormOne的目标用户是高校后勤管理场景里的三类人。新生和家长最关心的是:分到哪个宿舍楼、哪个床位,宿舍里有没有空调、独卫、阳台,室友是谁,入住流程怎么走。宿管员关心的是:今天哪些新生来报到了,哪些床位还空着,哪些宿舍设施报修了、维修进度如何。学工部管理层关心的则是:全校宿舍的入住率实时数据、各楼栋的空闲床位分布、新生入住进度统计,以及异常情况预警。
这三类需求落到系统设计上,就变成了一条清晰的链路。新生端负责"查询与报到"——查宿舍、绑定床位、在线报到、提交报修;宿管员端负责"核验与处理"——扫码确认入住、管理退宿换宿、跟进维修工单;管理端负责"数据总览与配置"——楼栋管理、房间管理、床位分配策略配置、入住进度大屏。三端的数据全部收敛到同一个后端,通过统一的权限模型做角色隔离。
我还为系统预设了一个消息推送链路:新生绑定床位后,宿管员可以在后台一键推送"宿舍入住指南"或"报到日路线指引",宿管员端也能实时收到新生的报修通知。这条链路在后面的架构设计中会谈到,因为消息推送在鸿蒙环境下的实现和Android有区别,值得单独说。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心系统架构与分层设计
2.1 整体架构拓扑与数据流向
DormOne采用的是主流的"客户端-服务端"三层架构,但在鸿蒙、Android、iOS多端适配的基础上,我专门加了一层轻量级的BFF(Backend for Frontend)聚合层,用来处理三端请求格式差异、数据裁剪和权限校验,避免客户端直接面对过于细粒度的微服务接口。
text复制Flutter客户端(鸿蒙 / Android / iOS)
│
▼
HarmonyOS网络权限适配层(ohos_permission + http)
│
▼
BFF聚合层(鉴权 + 路由 + 数据裁剪)
│
▼
业务服务层(宿舍分配 / 报修工单 / 用户中心 / 消息推送)
│
▼
数据访问层(MyBatis-Plus + MySQL + Redis)
这里要说一下为什么需要BFF层。宿舍管理系统虽然业务不算复杂,但三端对接口数据的诉求差异其实挺明显的:新生端首页需要卡片化的宿舍摘要数据、宿管员端需要列表化的床位状态数据、管理端需要的是聚合统计类数据。如果把所有字段一股脑返回给客户端,不仅浪费流量,还会让前端做大量无谓的数据拼装。BFF层按端裁剪响应字段,实测下来接口平均响应体从原来的86KB降到了31KB,移动端弱网环境下体感提升非常明显。
数据流向这条链路上,我做了一个有意思的取舍——宿舍分配这种核心写操作走的是同步事务,但报修工单的状态流转走的是异步事件。后面讲数据结构时我会解释为什么这么设计,简单来说就是:宿舍分配一旦出错会引发连锁投诉,必须强一致;而报修状态只是流程通知,容忍短暂延迟,异步化能避免高峰期数据库连接池被打满。
2.2 Flutter端的模块划分与状态管理
Flutter端的代码结构完全按照业务模块来组织,没有用传统的"按类型分层"(即把所有models放一个目录、所有pages放一个目录),因为那种结构在项目膨胀后维护起来非常痛苦。我的做法是"按特性划分",每个业务模块自带数据模型、页面、状态管理和服务接口。
text复制lib/
├── core/ # 基础能力:网络、路由、主题、工具类
├── modules/
│ ├── auth/ # 登录注册、权限管理
│ ├── dormitory/ # 宿舍查询、床位分配展示
│ ├── checkin/ # 新生报到、扫码入住
│ ├── repair/ # 报修工单、维修进度
│ ├── message/ # 站内信、推送通知
│ └── dashboard/ # 管理端数据大屏
├── shared/ # 跨模块共享组件与工具
└── main.dart
状态管理选型上,我最终用的是Provider + ChangeNotifier的组合,而不是Bloc或GetX。原因有三个:第一,宿舍管理系统的状态流是典型的"树形下发"结构——登录态是全局的,但宿舍列表、报修工单这类业务状态是局部的,Provider在这种场景下比Bloc轻得多;第二,团队里新人对Provider的上手成本极低,代码review时一眼就能看懂依赖关系;第三,鸿蒙适配分支对Provider系库兼容性验证得比较充分,Bloc在鸿蒙Flutter插件上偶尔会有Stream异步回调不触发的坑。
路由这块,鸿蒙端和Android端有差异。Flutter默认的路由栈在鸿蒙上运行稳定,但涉及系统返回键时有个细节:鸿蒙的侧滑返回手势和Flutter的PopScope组件需要配合使用,否则会出现"点击返回键页面退出但手势失效"的怪异现象。后面我有一节专门讲HarmonyOS适配的坑,这里先不展开。
2.3 HarmonyOS原生能力桥接的架构方案
Flutter要调用鸿蒙的原生能力,比如推送角标、系统相册、设备信息、网络状态感知,不能直接像Android一样找MethodChannel就行——鸿蒙适配分支沿用了MethodChannel语法,但底层桥接的Host是ArkTS层的Ability。我自己封装了一个统一的PlatformBridge,把所有涉及鸿蒙原生能力的调用都收口到这一个类里。
dart复制class PlatformBridge {
static const MethodChannel _channel = MethodChannel('dormone/ohos');
static Future<String> getDeviceId() async {
return await _channel.invokeMethod('getDeviceId');
}
static Future<bool> requestPermission(String permission) async {
return await _channel.invokeMethod('requestPermiss
