离线优先的工地应用:我们如何设计 Şantiyepro
如何设计一款能在没有网络的工地上运行的应用?以拥有 56 个模块的 Şantiyepro 为例,谈离线优先架构、同步和测试。

Şantiyepro 是我们为建筑行业开发的自有工地管理应用。从考勤到现金和往来账,从施工记录到进度款、混凝土跟踪和职业安全健康(İSG),它共有 56 个模块;运行在 Android 和 iOS 上,还有一个供电脑端访问的 WebPanel。这款产品最突出的特点,是可以完全离线运行。我是 Berke Özyaşar,在这篇文章中介绍做出这一决定的原因,以及开发离线优先应用时需要注意的事项。
在工地上,网络不是理所当然的
对于在办公室里使用的软件,网络几乎总是在线的。工地却不是这样。在地下室、钢筋混凝土剪力墙之间、城外的场地上或新开发的居住区里,移动数据信号很弱,甚至完全没有。如果工长在一天结束时想录入考勤,应用却提示“连接错误”,这条记录要么回到纸上,要么干脆不录了。这正是一线应用没人用的最常见原因之一。
因此,Şantiyepro 的基本原则是:应用无需联网即可完整运行,数据先保存在手机上。录入记录、生成报表或查看历史都不需要网络。当团队需要协同工作时,再启用基于角色的云端同步。
离线优先与“离线支持”的区别
很多应用都提供“离线支持”:断网时显示最后一次看到的数据,或许还会把几个操作放进队列。离线优先则恰恰相反:应用的主要数据源是设备上的本地数据库,服务器只是同步目标。这一区别会影响架构的每一层:
- 页面从本地数据库读取,而不是从网络读取;因此无论有没有网络,打开速度都一样。
- 每条记录在设备上创建的那一刻即生效,不必等待服务器确认。
- 记录 ID 必须在设备上生成且全局唯一,而不是向服务器申请;否则在两台设备上同时创建的记录就会冲突。
- 考勤汇总、现金余额等报表和计算必须能在设备上完成。
同步:最难的部分
如果只有一个人使用,数据保存在手机上就够了。但当工地负责人、技术办公室和财务都想看到同一份数据时,就需要同步。在离线优先系统中设计同步时,需要回答这些问题:
- 要发送什么?需要跟踪自上次同步以来发生变化的记录。给每次变更打上时间戳或版本号,就可以只发送差异部分。
- 发生冲突怎么办?如果两个人在离线状态下修改了同一条记录,以谁为准?对很多类型的记录来说,以最后写入者为准就够了。但对于现金和往来账流水这样的财务记录,与其修改已有记录,不如新增一笔流水,这样安全得多;如此一来不会产生冲突,而是形成两条独立记录,余额也始终可以根据流水重新计算。
- 谁能看到什么?Şantiyepro 的同步是基于角色的。工长和公司老板能看到的数据并不相同;每台设备上只应下载该用户有权查看的数据。
- 删除如何传播?要让在离线设备上删除的记录也从其他设备上删除,就不能物理删除记录,而应将其标记为已删除。
- 大文件:施工记录中的照片比文本数据大得多。把它们放进单独的队列,在网络条件合适时再上传,就不会拖慢记录的同步。
一线的可信度:签名、位置和时间
在工地上,记录是何时、何地录入的很重要;一份现场记录、一张交接单或一次职业安全检查,事后不应成为争议的焦点。在 Şantiyepro 中,电子签名会连同 GPS 坐标和时间戳一起保存。离线运行在这里有个细节:即使没有网络,也能从手机 GPS 获取位置,但设备时间可以被用户修改。对于这类记录,除了设备时间之外,再保存同步时的服务器时间,对事后核查很有帮助。
让 56 个模块保持可管理
考勤、现金、往来账、支票跟踪、施工、内部调拨、混凝土浇筑和钢筋跟踪、采购、进度款、质量控制、职业安全……Şantiyepro 的覆盖面很广,因为工地上的各项工作并不是彼此割裂的。在如此庞大的产品中,如果每个模块都像一个独立应用那样运作,维护将无从谈起。模块之间需要共享一套公共底层:同一个本地数据层、同一套同步逻辑、同一个权限模型、同一套报表和导出工具。这样,新增一个模块就不是从零开始写一个功能,而是在这套底层之上增加新的数据类型和页面。
产品的用户也多种多样:承包商、住宅开发商、工程师、职业安全专员、技术员和工长。每类人都会高频使用应用的不同部分。根据角色和需求让菜单和主屏幕保持简洁,对于不让 56 个模块淹没用户非常重要。
测试:飞行模式是你最好的朋友
测试离线优先应用最有效的方法,就是真的在断网状态下使用它。这类应用的测试清单中一定要包括:
- 在飞行模式下录入一整天的数据,然后打开网络,观察同步过程
- 在两台设备上离线修改同一条记录,检查冲突处理行为
- 在同步进行到一半时断开网络,查看数据是否依然一致
- 更新应用,验证本地数据库的结构变更能在不破坏现有数据的前提下完成
- 在老旧和存储空间不足的设备上,用大量记录和照片测试性能
最后一项尤其重要:Şantiyepro 支持 Android 8.0 及以上版本,而一线使用的手机并不都是新机型。
数据留在用户手中
离线优先还有一个非技术性的好处:数据留在用户的手机上。工地现金、分包商付款和往来账都是敏感信息。Şantiyepro 的免费套餐可以从一个工地开始使用;当团队需要协同工作时,再启用云端同步。这样,这款产品既适合单打独斗的小承包商,也适合人员众多的团队。
发布与版本节奏
Şantiyepro 已在 Google Play 和 App Store 上架。我们大约每 45 天更新一次产品。在离线优先应用中,每个版本都必须安全地迁移设备上的现有数据,因此稳定、可预期的节奏非常重要。
结论
如果您在为一线工作人员开发软件,就要把网络连接看作锦上添花,而不是理所当然。离线优先架构需要更多的设计投入,但它能给用户一个在任何条件下都能工作的工具。如果您在构思类似的一线应用或 SaaS 产品,可以在 SaaS 产品开发和移动应用开发页面了解我的工作方式。