每年四六级报名窗口一开,学校公共机房就开始排队,辅导员抱着 Excel 反复核对学籍信息,报名系统一崩就是半小时起步。我当时负责的信息化改造任务,就是把这套四六级报名管理系统从"人肉流水线"变成一套学生手机上能直接操作的跨端应用。技术选型最终落在 Flutter 配合鸿蒙生态的 Harmony6.0 这条路线上,前后端加起来开发周期两个月,覆盖了从资格校验、照片上传、考位锁定到在线支付、准考证下载、成绩查询的完整闭环。这篇文章不是项目介绍文档,是我把整个架构设计、核心模块落地、跨端差异处理和各种构建期踩坑过程做一次完整复盘,如果你也要做类似的校园报名、预约、抢课系统,里面很多思路可以直接拿过去用。
1. 为什么是 Flutter × Harmony6.0:一次跨端选型的完整复盘
1.1 高校报名系统的现实约束
先别急着聊技术,得说说这个系统面对的客观条件。四六级报名和一般互联网产品不一样,它有几个非常特殊的约束。
第一,用户设备极杂。在校学生的手机覆盖了安卓各品牌、iPhone 全系列,还有相当比例的鸿蒙设备。我不可能要求几百上千个学生为了报个名去装一个只在单一平台可用的 App,更不可能做三个原生版本。第二,报名时间窗口极短,通常就是三五天集中开放,而且开放瞬间会涌入大量并发请求——很多学生是定好闹钟等开闸的。第三,开发资源极其有限,我们信息化中心加上外包协助,真正写代码的人就三四个,而且很多人还得同时维护学校其他系统。第四,数据敏感度高,报名涉及学号、身份证号、照片等个人敏感信息,不能用乱七八糟的第三方平台。
把这些约束摆出来,跨端方案基本是唯一解。剩下的事情就是选哪个跨端框架。
1.2 逐个排除其他方案的判断过程
我团队内部其实先列了候选名单:纯原生三端各做一套、uni-app、React Native、Flutter。纯原生第一个被否掉,人力根本撑不住三套代码,而且维护周期会把团队拖垮。uni-app 当时也认真看了,它胜在 Vue 生态,前端同学上手快,但遇到像照片裁剪、复杂动画、多原生 SDK 联调这种需求,很多行为要回到"条件编译 + 原生插件"的老路子上,社区插件质量参差不齐,报个 bug 经常没人管。
React Native 的问题类似,虽然生态更大,但鸿蒙端的适配主要靠社区分支维护,版本跟随不稳定。Flutter 的逻辑不一样,它走的是自绘引擎路线,UI 层完全不依赖系统原生控件,所以在三端上渲染一致性最好,这对我们这种要同时维护 iOS、Android、鸿蒙的场景非常关键。另外 Dart 语言本身带 AOT 编译,性能上明显比 JS 解释型方案稳。
我们内部做了张对比表,基本一目了然:
| 技术方案 | UI 一致性 | 鸿蒙适配成熟度 | 团队上手成本 | 复杂交互支持 | 维护成本 |
|---|---|---|---|---|---|
| 三端原生 | 差(各写各的) | 原生最好 | 高 | 最好 | 三套代码,极高 |
| uni-app | 中 | 中 | 低 | 中偏弱 | 中,插件依赖多 |
| React Native | 中 | 中(社区分支) | 中 | 中 | 中高 |
| Flutter | 高(自绘引擎) | 中高(生态在推进) | 中低 | 高 | 低,一套代码 |
1.3 Harmony6.0 到底怎么跑 Flutter
很多同学以为 Flutter 在鸿蒙上能像安卓一样直接跑,这是误会。Flutter 官方对 OpenHarmony 生态的适配是逐步推进的,实际要在 Harmony6.0 的设备上跑起来,走的是 Har 包集成 的路线:把 Flutter 工程以混合工程的方式打成 Har 包,再嵌入到鸿蒙原生工程里。也就是说,鸿蒙端是一个"原生壳 + Flutter 页面"的组合架构。
这么做的好处是,报名流程的核心业务页面全部复用同一套 Flutter 代码,鸿蒙原生只负责最基础的容器加载和部分系统能力桥接。真正开发的时候,要注意几个关键点:鸿蒙 SDK 的 API Level 必须和 Flutter 适配层要求的版本匹配,否则引擎初始化直接报错;ABI 架构要确认清楚,Harmony 设备跑的是 ARM 芯片代码,打包时要带对应 so 库;还有权限模型,鸿蒙的权限声明和 Android 不在同一个地方,不能想当然地移植。
我当时的判断是,这套组合可能不是最优雅的方案,但它是当时投入产出比最高的方案。后面所有核心流程,都是在 Flutter 层完成的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统整体架构:从报名到发证的全链路设计
2.1 业务流程梳理
大学里很多系统的逻辑并不复杂,但流程长、状态多、参与角色杂,四六级报名系统就是典型。我从用户端和管理端两条线把流程捋清楚,这一张图基本决定了后面所有接口设计。
用户端流程:学号密码或手机号验证码登录 → 进入报名页,系统校验四六级报考资格(学籍状态、年级限制、上次考试成绩等)→ 填写个人信息并上传近期证件照 → 选择笔试考区/考场批次 → 生成待支付报名单,锁定考位 → 在线支付报名费 → 支付成功,报名完成 → 考前下载准考证 → 考后查询成绩。
管理端流程:创建考试批次,配置报名起止时间、开放年级、考区容量和费用标准 → 审核学生上传的照片和报名信息 → 管理考位池,处理退报释放名额 → 导出报名数据,按考试院格式上报 → 录入成绩并分批发布。
这里面有过两个小设计决策值得说。一是我们把"选考区和选考位"拆开了,考区是学生选的,具体座位号是系统按顺序分配的,这样既满足学生离家近的诉求,又避免抢座位的并发风暴。二是照片审核没有做成人工逐张审,而是"前端规范压缩 + 后端机器校验 + 异常照片人工抽检"三层处理,人工只处理机器识别不了的特例。
2.2 前后端接口契约与状态机设计
报名系统最容易出错的地方是状态管理。一份报名单,从草稿到最后完成,中间会经历非常多状态流转。我们必须把这套状态机在设计阶段就定死,否则后面客户端和服务端各写各的判断逻辑,早晚出 bug。
我们定的核心状态机:
DRAFT:用户填写了信息但没提交,此时不占考位SEAT_HOLD:用户提交报名单,考位被预占,进入付款等待期PAID:支付成功,报名正式生效REJECTED:审核不通过,学生需修改后重新提交CANCELLED:用户主动退报或超时未支付,考位释放COMPLETED:考试结束,成绩发布后归档
接口层
