uni-app 不是用来直接开发 App 的,而是用 Vue 语法写一次代码编译出多端产物;需显式配置 manifest.json 的 name、versionName、minSdkVersion(建议21),启用自定义基座集成高德/微信 SDK,并在 pages.json 中禁用预约页下拉刷新。

直接说结论:uni-app 不是用来“开发 App”的,而是用 Vue 语法写一次代码,编译出微信小程序、H5、App 等多端产物。你要做的不是“开发 App”,而是让 uni-app 编译出能真机运行的家政预约 App(即 Android/iOS 原生包),同时确保预约核心逻辑——时段选择、师傅锁定、缓冲时间校验、支付状态联动——在 App 端不掉链子。
uni-app 编译 App 时必须改的三个配置项
很多团队卡在“小程序能跑,App 打不开”或“选不了时间”,根本原因是没动这三项:
-
manifest.json中的name、versionName、android.minSdkVersion必须显式指定,尤其minSdkVersion建议设为21(Android 5.0),低于此值会导致高德地图 SDK 初始化失败,定位和距离计算全挂; -
vue.config.js(若存在)或hbuilderx的“发行 → 原生 App-云打包”里,必须勾选“使用自定义基座”并上传已集成高德/微信 SDK 的离线打包基座,否则uni.getLocation和uni.login在 App 端返回fail: not supported; -
pages.json中所有涉及预约流程的页面(如select-time.vue、confirm-order.vue)需手动添加"enablePullDownRefresh": false,因为 App 端下拉刷新会触发页面重载,导致用户刚选好的时段被清空。
时段选择组件在 App 端失效的典型原因
uni-app 自带的 picker mode="time" 或第三方日历组件(如 u-calendar)在 App 上常出现“点不动”“跳转错日期”“缓冲时间不参与校验”等问题,本质是渲染层与原生时间控件兼容性差。
- 不要依赖
picker的默认行为,改用自定义滚动列表(scroll-view+flex时间块),每个时段块绑定data-start和data-end属性,点击后主动调用uni.showLoading并立即发请求校验冲突; - 时段数据必须从后端接口拉(如
/api/v1/worker/available-slots?workerId=123&date=2026-10-31),禁止前端硬编码“9:00-12:00”这类模板,否则无法动态叠加通勤缓冲(比如师傅距你 8km,系统需自动排除 9:00-11:30 这个窗口); - App 端获取当前定位比小程序慢 300–800ms,
uni.getLocation成功回调里必须加防抖,否则连续触发多次时段请求,后端 Redis 锁可能被误释放。
订单状态同步在 App 端容易丢的关键点
用户在 App 下单后切后台,师傅在后台改了状态(如“已接单”),App 若不主动拉取,就会一直显示“待支付”。这不是 bug,是设计缺陷。
- App 启动时必须调用
uni.getPushClientId获取设备 ID,并注册到后端消息通道(如 RabbitMQ 的 fanout exchange),不能只靠轮询/api/v1/order/status?id=xxx; - 支付成功回调(
uni.requestPayment的 success 回调)里,必须立即调用uni.hideLoading()+uni.navigateTo({url: '/pages/order/success?id=' + orderId}),且该 success 页面的onShow钩子要再次调用getOrderDetail接口,防止用户从通知栏点进来的状态陈旧; - App 端取消订单后,必须同步调用
uni.removeTabBarBadge({index: 1})清除订单 Tab 的红点,否则用户下次打开仍看到未处理提示,但实际订单已释放时段。
最易被忽略的是:App 没有小程序的 onShareAppMessage 生命周期,也就没有天然的“分享后自动更新当前页状态”机制。一旦用户把预约链接分享给家人代付,App 端必须监听 uni.onAppShow 并检查 URL 参数里的 order_id,再触发状态刷新——否则代付完成,App 还卡在“待支付”界面。











