UniApp+Vue3+SpringBoot 企业移动端:H5、小程序、Android、iOS 一套 pages 怎么兼容
🌐 文档地址:https://ruoyioffice.com
📦 源码1·GitHub:https://github.com/yuqing2026/ruoyi-office
📦 源码2·GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office
📦 源码3·Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 微信:17156169080(备注「RuoYi Office」)
一套 pages 要同时跑进浏览器、微信小程序、Android 安装包和 iOS 安装包。差的不是「再写四个首页」,而是安全区、主包体积、选择器、跨分包组件和同一条流程 Key。RuoYi Office 移动端把业务摊在工作台九宫格里,PC 发起、手机批办走同一后台。本文按能点的页面讲怎么兼容。

▲ 左上 2×2 是四端差异,左下 2×2 是工作台、同一 Key、跨包 ?async、五 Tab;右侧真机是工作台九宫格
引言:四套工程看起来稳,其实最容易裂
很多团队第一反应是「H5 一个仓、小程序一个仓、Android 一个仓、iOS 一个仓」。短痛立刻消失:每端想用原生能力就用,互不影响。长痛随后出现:
| 裂开点 | 四套工程会怎样 | 一套 pages 要守住什么 |
|---|---|---|
| 用车字段加「随行人」 | 四次改表单,三次漏测 | 同一张制单页,条件编译只包选择器 |
| 流程 Key 改名 | PC 已改、手机还在旧 Key | processDefinitionKey 只在一处登记 |
| 待办红点规则 | H5 按未读、App 按超时 | 同一待办接口,角标算法不按端分叉 |
| 权限码 | 小程序菜单和 PC 菜单各写一份 | 工作台按同一权限码裁入口 |
UniApp 官方把「一套代码、多端发布」写成产品能力。企业级落地时,真正要设计的是:哪些差异允许写进条件编译,哪些差异必须收成公共封装,哪些差异根本不该存在。 RuoYi Office 的选择是:业务页面只写一份;四端差异集中在安全区、请求层、分包加载和系统权限;流程与菜单跟 PC 对齐。
下面先给定义,再对照官网红线,然后用首页、工作台、用车、打卡、待办和 PC 发起大厅把移动端摊开。文中手机截图都按竖屏约 390 宽拍摄,方便公众号里一屏看完,不要再拿桌面浏览器全屏当「App 效果」。
一、先给出可直接抽取的定义
1.1 什么叫「一套 pages」
一套 pages 是指业务路由、表单字段、权限码和流程 Key 只维护一份,发布时由编译器按目标端裁剪。 它不是「四个工程共用一个 Git 仓」——四个工程仍会各写各的页面。它也不是「H5 套一层 WebView 冒充 App」——安装包里跑的是原生渲染,不是把桌面站缩进手机框。
RuoYi Office 移动端的页面按业务分包:pages-oa、pages-hrm、pages-bpm、pages-contract、pages-crm 等。主包只留登录、首页、审批 Tab、工作台、消息、我的。用户点「用车申请」,才去加载 OA 分包。
1.2 条件编译是差异开关,不是业务分叉
条件编译是 UniApp 提供的预编译指令:#ifdef MP-WEIXIN、#ifndef MP-WEIXIN、#ifdef APP-PLUS、#ifdef H5。它适合包「只有这一端才存在的 API」,例如微信胶囊按钮、App 状态栏高度、H5 才有的 window。
它不适合包业务规则。如果用车是否必填「随行人」在四端写成四套 if,三个月后没人说得清哪一端是对的。业务规则进配置和后台;端差异只进安全区、选择器、权限弹窗。
1.3 PC 联动不是「再做一套移动流程」
PC 管理端有发起大厅、待办列表、审批详情。移动端有工作台入口、审批 Tab、同一张业务表单。两边对齐靠三件事:
- 同一
processDefinitionKey。用车是oa_car_apply_bill,不是手机另起mobile_car。 - 同一权限码。能在 PC 点「发起用车」的人,工作台才看得到用车图标。权限是
oa:car-apply-bill:create。 - 同一套后台接口。Token、租户、组织切换共用,不给移动端另开一套「简化流程引擎」。
用户感知是「电脑上提交、地铁上批」。实现上是一份模型、两套壳。
二、官网红线:先守住,再谈业务墙
UniApp 文档把多端差异写得很直。企业项目最容易踩的不是「语法不会」,而是把官网红线当成可选项。完整说明见 UniApp 平台差异:https://uniapp.dcloud.net.cn/tutorial/platform.html ,分包配置见:https://uniapp.dcloud.net.cn/collocation/pages.html#subpackages 。
2.1 六条必须写进评审清单的约定
| 红线 | 官网含义 | 企业项目里会炸在哪 |
|---|---|---|
| 条件编译 | 按端裁剪源码,不要运行时猜平台 | 用 uni.getSystemInfoSync().uniPlatform 写一长串 if,审核包体仍带上全部分支 |
| 主包体积 | 微信小程序主包常见上限约 2MB | 把合同、商城、IoT 全塞进主包,上传失败或首屏极慢 |
| rpx | 按 750 设计稿等比,不是 px 抄 PC | 把 Ant Design 的 1440 宽布局原样搬进手机,字小到点不中 |
无 DOM / window | 小程序和 App 没有浏览器对象 | document.querySelector、new URL()、直接读 window.location |
| 分包 | 业务页放子包,主包只留启动链路 | 审批详情引用合同组件,主包间接打进合同整包 |
| iOS 隐私权限 | 定位、相册、相机要用途说明 | 打卡页一进就申请定位,审核被拒或用户直接卸 App |
rpx 按 750 设计稿:手机上 32rpx 约等于半个物理像素步进,不要把 PC 的 14px 字号直接抄过来。导航标题、底栏、九宫格图标都按 rpx。H5 在宽屏浏览器里会被 UniApp 按 750 换算拉大,所以用桌面全屏截 App,字会显得「假大」,这也是本文手机截图都锁 390 宽的原因。
没有 DOM 和 window 时,常见翻车是:
document.getElementById做锚点滚动new URL(href, window.location.origin)拼下载地址- 用
window.open打开预览
文件预览、下载、外链统一走封装方法,内部再条件编译。业务页只收 url 字符串。
这六条够挡住 80% 的「能在 H5 点、小程序白屏」。剩下 20% 是企业自己的经验:安全区、请求头、跨分包异步组件、选择器封装。
2.2 哪些差异应该存在,哪些不该
应该存在的差异:
- 小程序右上角有胶囊,首页自定义导航必须让出这块。
- App 有刘海和手势条,底栏要给
safe-area-inset-bottom。 - H5 在普通浏览器里,定位权限文案要写成「请在浏览器设置中允许」,不能写「请到系统设置打开」。
- 微信小程序对
responseType: 'json'不友好,请求层要按端裁。
不该存在的差异:
- 用车表单在小程序少两个字段。
- 待办在 App 按时间倒序、在 H5 按紧急度。
- 同一张请假单,PC 用
oa_leave,手机用leave_v2。
前一类用条件编译和封装消化;后一类直接禁止。评审时问一句:「这个 if 删掉之后,业务还成立吗?」成立就删。
三、安全区:别信 env(safe-area-inset-top) 在所有端都有值
自定义导航栏的首页,必须自己算顶部内边距。官方 CSS 变量 env(safe-area-inset-top) 在 iOS 刘海上好用,在不少 Android App 和微信小程序里会返回 0。RuoYi Office 首页不用它当唯一数据源,而是读 statusBarHeight,小程序再叠加胶囊。
const headerPaddingTop = ref(20)
function initHeaderPaddingTop() {
const systemInfo = uni.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 0
// #ifdef MP-WEIXIN
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
headerPaddingTop.value = menuButtonInfo.bottom + 8
return
// #endif
// #ifndef MP-WEIXIN
headerPaddingTop.value = statusBarHeight + 12
// #endif
}
读这段时抓住三件事:
- 小程序走胶囊底部。
getMenuButtonBoundingClientRect()给出胶囊的bottom,内容从它下面 8px 开始,问候语不会顶进胶囊。 - H5 / App 走状态栏高度。 没有胶囊,
statusBarHeight + 12就够。H5 在普通 Chrome 里状态栏高度常为 0,加 12 也不会空出一块刘海。 - 不要四端各写一套 CSS。 模板只绑
:style="{ paddingTop: headerPaddingTop + 'px' }",差异全在这一个函数。
工作台页如果仍用 padding-top: calc(env(safe-area-inset-top) + 20rpx),在部分 Android 上会贴顶。新页优先抄首页这套函数,不要混用两套算法。
四、请求层:小程序不要硬设 responseType: 'json'
企业移动端请求比演示 Demo 多两件事:双 Token 刷新、并发 401 排队。这两件事四端都要。真正按端裁的是响应类型。
export function http<T>(options: CustomRequestOptions) {
return new Promise<T>((resolve, reject) => {
uni.request({
...options,
dataType: 'json',
// #ifndef MP-WEIXIN
responseType: 'json',
// #endif
success: (res) => {
// 统一解包 code / data,401 进刷新队列
},
fail: reject,
})
})
}
微信小程序对 responseType: 'json' 的支持和 App / H5 不一致,强行带上会出现解析异常或空 data。条件编译写成「非微信才设」,比运行时判断平台更干净:编译进小程序包的代码里根本没有这行。
Token 刷新四端共用:一个 refreshing 开关、一个任务队列。第一个 401 去换 refreshToken,后续请求进队,换成功再重放。不要给 H5 单独写 axios 拦截器、给 App 再写一套 uni.request 包装——两套过期文案会让用户以为「浏览器能用、安装包不行」。
登录预填只给本地开发:账号 admin、密码 admin123,验证码按环境关闭。演示站和正式包不要把默认口令写进界面文案以外的地方。
五、分包和跨包组件:主包 2MB 不是吓你的
5.1 主包只留启动链路
RuoYi Office 把业务按域拆分包根:pages-core、pages-system、pages-infra、pages-bpm、pages-hrm、pages-oa、pages-contract、pages-asset、pages-project、pages-crm、pages-statistics、pages-iot、pages-member、pages-pay、pages-mp、pages-mall、pages-mes、pages-ai、pages-im、pages-erp、pages-wms。
用户打开 App 先看到首页。点工作台「用车申请」,才下载 pages-oa。点「考勤打卡」,才下载 pages-hrm。商城、IoT、MES 这些重模块,没权限的人永远不会去拉。
主包膨胀的常见原因不是「页面太多」,而是「审批详情把合同、招聘组件静态 import 进来」。静态 import 会把子包打进主包依赖图。
5.2 跨分包必须 ?async
审批详情在 pages-bpm,合同正文、招聘需求在别的分包。微信小程序要求跨包组件走异步化,并声明 componentPlaceholder。RuoYi Office 在详情聚合页里这样写:
import ContractChangeDetail from '@/pages-contract/change/components/detail-content.vue?async'
import ContractInfoDetail from '@/pages-contract/info/components/detail-content.vue?async'
import ContractSignDetail from '@/pages-contract/sign/components/detail-content.vue?async'
// 跨分包组件必须带 ?async,否则微信小程序找不到 componentPlaceholder
import RecruitmentOfferDetail from '@/pages-hrm/recruitment-offer/components/detail-content.vue?async'
import RecruitmentRequirementDetail from '@/pages-hrm/recruitment-requirement/components/detail-content.vue?async'
H5 开发时不加 ?async 也能跑。一打微信小程序包就会报找不到占位组件。规则记一句:跨分包的 Vue 组件,import 后面跟 ?async;同包组件保持普通 import。
选择器同样不要直接铺小程序原生 picker。日期、部门、人员走封装好的 Wot 选择器,校验规则收在 createFormSchema 里,和 PC 端 Element 风格的必填/长度规则对齐。四端 UI 库底层不同,业务页不应该看见原生 picker 的 mode 和 range。
六、真机一:首页是「人 + 待办 + 工资条」,不是导航墙
打开移动端,底栏五个 Tab:首页、审批、工作台、消息、我的。首页不承担模块超市,只回答「我是谁、我有什么要处理、这个月工资和公告是什么」。

▲ 竖屏约 390 宽。顶栏问候与组织胶囊避开状态栏;五个圆入口带待办红点;下方是公告、工资条和企业云盘,不是把全部模块堆在首页
这张图里能直接读到的产品决定:
- 组织胶囊可点。 多组织用户在手机上也能切「深圳总公司 / 研发部门」,和 PC 顶栏组织切换是同一套数据,不是移动端写死一个部门。
- 快捷入口只有五个。 待办、邮箱、考勤打卡、业务申请、请假销假。待办角标封顶 99+。更多业务进工作台,避免首页变成图标墙。
- 工资条和考核分在首页。 这是 HRM 与移动端的联动:员工打开 App 先看钱和公告,而不是先翻流程分类。
- 企业云盘切片。 首页只露「我的文件 / 共享 / 收藏」三 Tab 加最近几条,完整目录进 OA 分包。PC 云盘那棵树不原样搬进手机。
安全区算法的效果也在这张图上:问候语「您好!宇擎源码」没有顶进系统状态栏,组织胶囊也没有和微信胶囊打架。换到 H5,同一套函数只会多出 12px,不会空出一块假刘海。
七、真机二:工作台才是模块墙,权限码负责裁剪
工作台标题是「高效办公,尽在掌中」。上面是「常用」分组,用户自己钉图标;下面按流程中心、OA、HRM 等分组铺九宫格。没有权限的入口直接不渲染,不是灰掉让用户点了再报错。

▲ 竖屏约 390 宽。常用区可自选;流程中心是我的流程 / 待办 / 已办 / 抄送;OA 区能看到用车、还车、用印、云盘、邮箱、会议室、用品、出差、报销、日报周报
工作台数据不是前端写死一份「App 菜单 JSON」再和 PC 对一遍。过滤逻辑是:
- 菜单项可以带
permission或permissions,任一命中才展示。 - 可以带
processDefinitionKey和createUrl/mobileCreatePath,点图标就进对应制单页。 - 仅 PC 可用的页会标
onlyPc,手机工作台不出现。 - 切 Tab 时权限用节流刷新,避免每次点「工作台」都打一轮 20 秒的权限接口。
分组在真机上至少能看到:
| 分组 | 典型入口 | 对应分包 | 和 PC 的关系 |
|---|---|---|---|
| 流程中心 | 我的流程、待办、已办、抄送 | pages-bpm | 与 PC 流程中心同一批接口 |
| OA | 用车、还车、用印、会议室、云盘、邮箱、用品、出差、报销、日报周报 | pages-oa | 与 PC 协同办公同一单据 |
| HRM | 打卡、请假、补卡、工资条 | pages-hrm | 与 PC 人事考勤同一账期 |
| 合同 / 项目 / CRM | 合同、回款、商机 | pages-contract 等 | 详情组件跨包 ?async 嵌进审批 |
「常用」为空时给「添加我常用的」,不把全部图标复制一份到顶部。用户钉的是 key,不是坐标。换手机、换 H5,常用区仍在。
八、真机三:用车制单证明「同一 Key、同一字段」
从工作台点「用车申请」,进入 /pages-oa/car/create/index。这张页不因为是手机就砍字段。车辆、出车时间、回车时间、出车地点、回车地点、随行人、用车事由、备注都在。提交按钮在底部,右侧齿轮是表单配置入口,和 PC 单据页的「可写字段」是同一套权限思想。

▲ 竖屏约 390 宽。标题「发起用车申请」;出车/回车时间已带默认值;事由和备注有 200 字计数;底栏是提交,不是 PC 那排「保存草稿 / 提交 / 取消」
流程登记在移动端菜单配置里,和 PC 模型 Key 对齐:
{
key: 'oaCarApply',
name: '用车',
icon: 'location',
iconColor: '#2563eb',
permission: 'oa:car-apply-bill:create',
processDefinitionKey: 'oa_car_apply_bill',
mobileCreatePath: '/pages-oa/car/create/index',
mobileViewComponent: 'CarApplyDetail',
}
四行不要拆开理解:
permission决定工作台看不看得到图标,也决定 PC 发起大厅这张卡片亮不亮。processDefinitionKey决定提交后进哪条 Flowable 定义。手机另起 Key,PC 待办就看不见。mobileCreatePath是手机制单路径。PC 有自己的路由,但 Key 和字段名必须对得上。mobileViewComponent是审批详情里嵌哪块业务表单。跨包时再加?async。
还车、用印、请假同一份清单。用印多一个 forceDetailTaskNames:到「申请人归还印章」节点,详情必须拉起业务表单,不能只显示流程意见。这是节点级差异,不是端级差异——PC 同样要露出归还字段。
日期时间在手机上用封装选择器,valueFormat 和后台时间戳约定对齐。不要在 H5 用浏览器原生日期框、在小程序用 mode=date、在 App 再用一个第三方日历,三套格式会把 LocalDateTime 打成字符串或数组。
九、真机四:打卡最能看见「端差异只留在系统权限」
考勤打卡页是 HRM 分包。人、部门、上班下班状态、外勤按钮都是业务,四端相同。H5 上定位被拒时,提示必须写成浏览器语言。

▲ 竖屏约 390 宽。上班 08:00 / 下班 17:00 显示未打卡;中心是外勤打卡;底栏提示「定位权限被拒绝,请在浏览器设置中允许定位」——这是 H5 文案,不是 iOS 系统设置文案
把这张图当成多端兼容的反例教材也行:
| 端 | 定位权限怎么要 | 失败文案该怎么写 |
|---|---|---|
| H5 | 浏览器 Geolocation | 请在浏览器设置中允许定位 |
| 微信小程序 | scope.userLocation,要用途说明 | 请在小程序设置中打开位置 |
| Android App | 运行时权限 + 厂商后台限制 | 请到系统设置允许位置信息 |
| iOS App | Info.plist 用途字符串,审核看文案 | 请到系统设置允许位置信息 |
业务按钮「外勤打卡」不按端改名,围栏半径不按端改规则。变的只有申请权限的 API 和失败提示。官网要求 iOS 写清用途;企业项目还要多写一句:打卡页不要一进就弹权限,等用户点按钮再申请。先弹后看页面,卸载率比少一次定位高得多。
PC 考勤页管规则、班次、补卡审批。手机管到点、到围栏、外勤说明。不要让手机变成「缩小版排班表」。
十、真机五:待办列表只留一张,办理仍回同一详情
底栏「审批」进的是待办。这一屏是本文唯一一张列表。字段要让人在地铁上判断「要不要点进去」,不要把 PC 待办的二十列搬过来。

▲ 竖屏约 390 宽。审批 Tab 下列待办卡片;点进去是和 PC 同一流程实例的详情,不是手机专属流程图
列表页承担的职责只有:
- 过滤:待办 / 已办 / 抄送,不要和「我的流程」混成一个无限滚动。
- 识别:标题、发起人、到达时间、紧急度。
- 跳转:带上流程实例 ID 和任务 ID,打开详情。
详情页才是办理。底栏通过、拒绝、退回、转办从任务操作接口来,不在列表上做「滑动通过」。PC 批量通过是管理端能力,手机默认一单一办,避免误触。业务表单嵌在详情中段,用车、用印、请假走各自的 mobileViewComponent。合同、招聘这类跨包组件带 ?async。
用户在 PC 发起大厅提交的用车,会出现在手机待办里。反向也成立:手机提交的请假,PC 待办能办。检验标准不是「两端都有待办菜单」,而是同一条实例 ID 在两端能打开同一组字段。
底栏「我的」承担账号、组织、设置,不承担业务墙。头像、部门、退出登录、双 Token 清理都在这里。换手机重装后,常用工作台图标跟账号走,不跟安装包走。

▲ 竖屏约 390 宽。头像与组织在「我的」;「切换组织」回写与首页胶囊同一上下文;退出登录清双 Token。通讯录、文件助手是入口,不是第二套工作台
十一、PC 发起大厅:联动一眼就能对上
移动端讲完,补一张 PC。发起大厅按分类摊卡片,用车、请假、用印和手机工作台是同一批模型。电脑上字段多、附件好传;手机上字段不少、操作键更大。

▲ PC 1440 宽。发起大厅按流程分类铺卡片;点用车进 PC 制单,提交后手机待办能办。权限码和 Key 与上一节菜单配置同一行
对照关系可以写成验收表:
| 动作 | PC | 手机 | 必须相同 |
|---|---|---|---|
| 发起用车 | 发起大厅卡片 | 工作台「用车申请」 | oa_car_apply_bill + oa:car-apply-bill:create |
| 办待办 | 待办列表 → 详情 | 审批 Tab → 详情 | 实例 ID、任务 ID、字段权限 |
| 看公告 / 工资条 | 工作台卡片 | 首页卡片 | 同一公告 ID、同一薪资账期 |
| 切组织 | 顶栏组织 | 首页组织胶囊 | 同一访问租户 / 部门上下文 |
| 传附件 | 上传组件 | 封装上传 | 同一文件配置主存储器(见同期文件配置文) |
「PC 发起 / 手机批」不是口号。产品经理验收时带上两个窗口:左边电脑提交,右边手机刷待办。Key 不一致,右边永远是空的。
十二、四端对照:把差异收成一张表
前面的代码和截图可以收成评审用的对照。打印这一张,比再写一篇「架构总览」有用。
| 主题 | H5 | 微信小程序 | Android App | iOS App |
|---|---|---|---|---|
| 顶部避让 | 状态栏常为 0,+12 即可 | 胶囊 bottom + 8 | statusBarHeight + 12 | 刘海走状态栏高度,不要只信 CSS env |
| 底部避让 | 无手势条 | 无 Home Indicator | 部分全面屏要底 padding | safe-area-inset-bottom |
| 请求 | 可设 responseType: 'json' | 不要设这行 | 同 H5 | 同 H5 |
| 包体 | 无 2MB 主包 | 主包控制、业务分包 | 安装包另算资源 | 安装包 + 隐私清单 |
| 选择器 | 封装组件 | 同左,禁止原生 picker 铺业务 | 同左 | 同左 |
| 定位文案 | 浏览器设置 | 小程序设置 | 系统设置 | 系统设置 + 用途字符串 |
| 跨包组件 | 普通 import 也能跑 | 必须 ?async | 跟随小程序策略更稳 | 同左 |
| 业务 Key | 与 PC 相同 | 与 PC 相同 | 与 PC 相同 | 与 PC 相同 |
表里最后一行是唯一全绿的行。它不是技术细节,是产品底线。
十三、设计取舍:我们故意没做的三件事
13.1 不为小程序再做「轻量首页」
有人建议小程序只留待办和打卡,把云盘、合同藏起来。短期包体更小。长期会变成「小程序一套信息架构、App 一套信息架构」,权限和培训都要讲两遍。RuoYi Office 选择同一套五 Tab + 工作台裁剪:没权限的人本来就看不到商城和 IoT,主包不会因为菜单项多而变大。变大的是用户点进去才下载的分包。
13.2 不把桌面 H5 当成 App 截图
桌面浏览器 1440 宽打开移动端 H5,页面是通栏的,底栏会拉得很长。那不是用户手里的 App。对外写文章、做手册、做公众号,截图视口用 390×844。读者对「这是不是手机」的判断发生在 0.3 秒,用错尺寸,正文写得再细也像在看后台。
13.3 不在条件编译里写工资条规则
工资条掩码、考核分入口、公告类型,全部走后台和权限。#ifdef 里只允许出现胶囊、状态栏、responseType、系统权限。看见 #ifdef MP-WEIXIN 后面跟着「本月应发」,就是设计已经漏了。
十四、模块怎么摊开,读者才能带走
工作台不是装饰。按域记住这些入口,本地或演示站都能点:
| 域 | 手机从哪进 | 典型页 | 和 PC 联动的一句 |
|---|---|---|---|
| 流程 | 底栏审批 / 工作台流程中心 | 待办、已办、抄送 | 同一实例两端办理 |
| OA | 工作台 OA 分组 | 用车、用印、会议室、云盘、邮箱 | PC 发起大厅同一卡片 |
| HRM | 首页快捷入口 + 工作台 | 打卡、请假、工资条 | 班次规则在 PC,动作在手机 |
| 合同项目 | 工作台对应分组 | 合同详情嵌审批 | 跨包 ?async |
| 消息 | 底栏消息 | 站内信 / IM | 红点与 PC 顶栏铃铛同一未读口径 |
| 我的 | 底栏我的 | 资料、组织、设置 | 退出登录清双 Token |
演示站移动端入口:https://ruoyioffice.com/app/ 。PC 管理端:https://ruoyioffice.com/web/ 。账号都是 admin / admin123。两头同时打开,比只看一张架构图快。
十五、常见误区
误区 1:H5 能跑就等于四端能发。
H5 有 window、有 DOM、没有 2MB 主包。小程序白屏的第一嫌疑是静态跨包 import 和 document。
误区 2:安全区用一行 CSS 就能通吃。
env(safe-area-inset-top) 在 Android / 小程序经常是 0。自定义导航必须读 statusBarHeight,微信再读胶囊。
误区 3:手机表单可以少字段。
字段可以换布局,不能换语义。用车少了「随行人」,PC 打印单和手机详情会对不上。
误区 4:每端一个流程 Key 更好维护。
相反。待办中心、抄送、催办、统计全部按 Key 聚合。Key 分叉等于流程中心裂成两套。
误区 5:原生 picker 更「像小程序」。
像不像是皮肤,校验和回填才是业务。封装选择器能对齐 PC 的必填和格式,原生 picker 对不齐时间戳。
十六、FAQ
UniApp 企业级应用怎么同时兼容 H5、微信小程序、Android 和 iOS?
业务 pages、权限码、流程 Key 只维护一份;用条件编译处理安全区、请求响应类型和系统权限;用分包控制微信主包体积;跨分包组件加 ?async。不要为四端复制四套表单。
微信小程序主包超 2MB 该先拆什么?
先拆业务分包,不要先压缩图片应付。主包只留登录和五个 Tab。合同、商城、IoT、MES 进子包。审批详情引用其它域组件时改成 ?async,避免子包被打进主包。
为什么 Android 上首页会顶到状态栏?
自定义导航时 env(safe-area-inset-top) 常为 0。用 uni.getSystemInfoSync().statusBarHeight 计算 paddingTop。微信小程序还要加胶囊底部间距。
PC 提交的流程,手机待办为什么是空的?
先对 processDefinitionKey 和发起权限码。手机菜单如果写成另一个 Key,或权限码只授给 PC 菜单,待办接口按当前人过滤后就是空。不要先怀疑 Token。
打卡在 H5 提示「请在浏览器设置中允许」,装 App 还会一样吗?
不会。文案按端写。App 走系统定位权限,iOS 还要在隐私清单写用途。围栏半径和班次规则四端相同,变的只是申请权限的方式和失败提示。
十七、本地怎么跑起来对照
- 后端按仓库文档启动,管理端 API 默认
48080,前缀/admin-api。 - PC:在前端工程执行
pnpm dev:antd,浏览器打开本地管理端,进「发起流程」对照用车卡片。 - 移动端 H5:在 UniApp 工程执行
pnpm dev,本地一般是http://127.0.0.1:9000/,hash 路由形如#/pages/index/index。 - 微信小程序:用微信开发者工具导入 UniApp 编译产物,重点看主包体积和跨包组件。
- App:HBuilderX 云打包或本地自定义基座。iOS 先填定位/相册用途,再测打卡。
登录账号与演示站相同:admin / admin123。本地开发可预填,验证码按环境关闭。真机或开发者工具里把宽度收成手机竖屏,再判断布局——通栏 H5 不能当验收截图。
公网对照:
- 文档与产品:https://ruoyioffice.com
- PC 演示:https://ruoyioffice.com/web/
- 移动端 H5:https://ruoyioffice.com/app/
十八、结语
多端兼容的难度不在「UniApp 会不会编译」,而在企业自己有没有把差异分级。官网已经划了条件编译、主包、rpx、无 DOM、分包、iOS 隐私。RuoYi Office 补上的是安全区算法、请求层裁剪、跨包 ?async、Wot 选择器,以及和工作台、用车、打卡、待办绑在同一条流程 Key 上的产品墙。
读者能带走的只有三句:业务不要按端分叉;差异写进编译指令和封装;PC 与手机对 Key,不对「像不像原生」。首页问候能避开胶囊,工作台九宫格能按权限裁,用车字段能和发起大厅对上,这套 pages 才算兼容完成,而不是仅仅「四个平台都能点开登录页」。
附件上传在手机上同样只打一个封装入口。字节落到本地磁盘还是 S3,由基础设施「文件配置」的主配置决定,不在用车页写盘符。同期文件配置一文把这颗旋钮拆开了。
相关阅读:同目录下「一套后端,三端联动」「PC+APP 双端考勤打卡」「企业级移动审批详情」——那些文章讲架构总览或单页详情,本文只把四端差异和能点的模块墙摊开。
💡 想要体验 RuoYi Office 的强大功能?
🌐 在线演示:https://ruoyioffice.com/web/(账号 admin / admin123)
📦 源码仓库:GitHub:https://github.com/yuqing2026/ruoyi-office | GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office | Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 技术咨询:添加微信 17156169080,备注「RuoYi Office」
⭐ 如果觉得不错,请给个 Star 支持一下!
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/zhouzhongyan/article/details/164341211




