这次重构的是一套已有业务基础的智慧门禁应用。
项目原本已经具备设备开门、二维码、访客、房屋和个人中心等能力,但随着功能逐渐增加,首页的信息层级变得松散,部分页面仍保留着旧版设计。更棘手的是,同一套代码在 H5 中表现正常,进入微信小程序后却出现图片空白、二维码闪动、拖动失效和底部导航重叠等问题。
所以这次工作的重点不是推翻重写,而是在保留原有业务接口和页面路由的前提下,重新整理用户体验,并逐一处理跨端差异。
先重新划分首页的主次
新版首页保留了三个主要层级:
- 顶部的社区切换
- 大面积广告内容
- 当前可操作的门禁设备
广告区域没有继续使用普通轮播组件,而是实现了一套手写堆叠卡片。
页面会同时渲染当前卡片和后方的预备卡片。用户滑动时,页面主体和主视觉区域保持固定,只有当前卡片执行飞出动画,然后由下一张卡片补位。
这种实现比普通左右轮播更接近最初设计稿里的“翻卡”感觉,同时避免了手势过程中整个页面被拖着移动。
门禁区域则做了相反的处理:卡片尺寸缩小,保留左右滑动和两侧设备预览,让用户能够快速判断前后还有其他设备。
设备卡片继续承接原有业务能力:
- 一键开门
- 按设备能力显示二维码入口
- 门禁排序
- 监控视频入口
- 设备图片和位置显示
底部导航只保留门禁和个人中心,没有在首页重复堆放个人中心已有的入口。
H5 能显示,不代表小程序也能显示
远程设备图片是这次遇到的第一个明显跨端问题。
相同的图片地址在 H5 中可以直接显示,进入微信小程序后却可能变成空白。即使关闭开发工具中的合法域名校验,问题依旧存在。
最终没有把所有图片替换成本地兜底资源,而是根据资源类型分别处理:
- 普通远程栅格图片先通过小程序图片接口解析
- 获取可用的临时文件路径后再交给组件显示
- 可以被平台直接渲染的资源继续使用原地址
- 加载确实失败时才显示通用兜底图标
这样既保留了后端设备图片,也避免 H5 和微信小程序呈现两套完全不同的视觉资源。
这里得到的经验是:开发工具里的“关闭域名校验”只能排除一类限制,不能证明远程资源已经满足小程序的解码和渲染要求。
二维码为什么会先错位再弹回来
二维码在 H5 中一直正常,但微信小程序中会先出现在弹窗之外,随后闪动并回到正确位置。
问题不在二维码内容,而在画布的生命周期。
小程序的 canvas 在弹窗布局尚未稳定时开始绘制,生成和导出过程又会触发可见区域更新。用户因此看到了二维码生成过程中的中间状态。
最后采用了双端分流方案:
- H5 继续直接渲染二维码
- 微信小程序在不可见区域生成二维码
- 生成完成后导出为临时图片
- 弹窗只显示已经完成的图片
- 弹窗高度限制在当前视口范围内
二维码不再参与弹窗初次布局,也就不会出现先错位、再回弹的过程。
这类问题如果只调整 z-index、定位或延迟时间,很容易暂时掩盖症状。真正稳定的处理方式,是不要让用户看到画布的中间生成状态。
把门禁排序拆成两个触摸区域
门禁排序页原本同时承担列表滚动、长按排序和设备开关操作,这几个行为都依赖触摸事件,很容易互相争夺手势。
实际出现过的问题包括:
- 拖动过程卡顿
- 只能向下排序,无法向上排序
- 右侧开关没有反应
- 真机无法滚动到列表底部
- 修改状态后无法保存
- 保存返回首页后仍需手动刷新
最后将每一行明确拆成两个触摸区域:
- 左侧到中间区域负责长按拖动
- 右侧区域负责页面滚动和设备显示开关
拖动距离改用视口坐标计算,避免页面滚动抵消手指向上的移动距离。目标索引也改成正负方向对称的阈值算法,不再让向上和向下拖动使用不同的取整结果。
排序和设备开关最终共用一条批量保存路径。保存成功后写入刷新标记,返回首页时重新获取设备列表,并重新校准当前设备索引和二维码能力。
这样既避免了每次点击开关都立即请求接口,也解决了“页面看起来改了,实际没有保存”的问题。
底部导航与安全区域
首页内容较多时,门禁卡片曾经与底部导航发生重叠。
这里的问题并不只是少加了一段底部间距,而是页面内容、固定导航和设备安全区域被重复计算。部分机型有底部安全区,H5 模拟器和微信开发者工具的计算结果又不完全一致。
最终处理方式是:
- 页面内容只负责预留底部空间
- 导航组件负责自身层级
- 不在多个容器中重复固定导航
- 同时兼容不同形式的安全区域变量
- 避免使用运行时窗口高度锁死整个页面
页面因此可以正常滚动,导航也能保持在交互层最上方。
认证页面也需要跨端检查
登录、注册和忘记密码页面统一了视觉结构,同时处理了几个容易被忽略的问题:
- H5 宽屏模式下输入提示文字被裁切
- 密码显示图标重复出现
- 输入内容与占位文字重叠
- 业主和管理员登录提示不明确
- 服务条款默认处于勾选状态
登录页现在会根据模式显示不同的输入提示。服务条款默认保持未勾选,即使本地保存了账号信息,也不会替用户恢复“已同意”状态。
只有用户主动操作后,协议状态才会改变。
这一点看起来只是一个布尔值,但它关系到用户是否真正表达了同意,不能为了减少一次点击而自动处理。
个人中心回归业务本身
个人中心恢复并整理了当前版本需要的功能入口,包括物业服务、人员管理、房屋管理和访客能力。
这部分没有继续增加装饰性内容,而是优先保证:
- 图标来源一致
- H5 与小程序显示一致
- 固定功能不依赖临时接口数据
- 入口名称与实际业务页面对应
- 首页与个人中心之间不重复放置相同功能
对于这类高频工具页面,清晰和稳定比视觉花样更重要。
验证比“看起来正常”更重要
跨端问题最容易出现的情况,是在一个环境中修好后,就误以为所有平台都已经正常。
这次每个关键改动都同时检查了:
- H5 页面表现
- 微信开发者工具编译结果
- 微信小程序运行效果
- 不同尺寸下的布局
- 页面返回后的数据刷新
- 触摸、滚动、长按和开关之间的冲突
项目还增加了针对当前重构的静态验收脚本,用于检查关键组件、交互入口和容易回归的实现细节。
它不能代替真机测试,但可以防止已经解决的问题在后续修改中悄悄回来。
最后的结果
这次重构没有改变后端业务边界,也没有重新发明已有的开门流程。
真正完成的是三件事:
- 重新建立首页和个人中心的信息层级
- 让 H5 与微信小程序尽可能呈现一致的结果
- 把图片、二维码、触摸排序和安全区域这些跨端问题收敛到明确的组件与流程中
回头看,最值得记录的一点是:
跨端开发中,代码复用只是起点,行为一致才是最终目标。
同一个图片地址、同一个 canvas、同一个触摸事件,在不同平台上都可能遵循不同的规则。比起不断增加局部样式和延迟,更可靠的方法仍然是找到差异发生的层级,再让每个平台走适合自己的实现路径。
