Skip to content

移动端总览 ​

适用端:移动端 | 类型:机制

移动端(ainb-ui-admin-uniapp)不是「另一个后台」,而是同一套后端、同一套权限体系与租户的第二个运行时宿主:工作台 / 审批 / 消息 / 我的 + 在线表单的移动端运行时。它的工作台菜单由服务端 system_nav_node 下发,不在前端写死。

本页讲清楚三件事:这个仓库是什么混合体(unibest 骨架 + 芋道业务页)、哪些分包真的交付了哪些是编译进包但点不到的尸体、以及它与 Web 管理端能力差在哪。后面 8 页是逐层展开。

前置阅读:后端架构与模块依赖(三仓共用同一套 /admin-api)、仓库结构与改名约定(yudao → enlev 的改名规律在三仓一致)。

它解决什么问题 ​

三端共用同一套接口、同一套权限判定、同一套租户。移动端与 Web 端唯一的结构性差别是菜单来源不同:Web 端的路由由 system_menu 动态生成(见路由与权限机制),移动端的工作台由 system_nav_node 下发(见服务端驱动导航)。

移动端不走 Vite proxy

env/.env:33 的 VITE_APP_PROXY_ENABLE = false 让 vite.config.ts:231-240 产出 proxy: undefined,请求拦截器于是直接拼绝对地址(src/http/interceptor.ts:33-46)。Web 端同样直连(它的 vite.config.ts 里 server.proxy 整段是注释掉的)。所以「改后端接口,前端刷新一下就好」在这里成立;反过来,跨域问题也不能指望 dev proxy 兜。

代码在哪 ​

仓库根就是工程根,没有 monorepo。src/ 下共 30 个目录,其中 17 个是页面目录,按能不能被用户点到分成三类(目录清单与逐项职责见工程结构与约定式路由):

类别目录.vue 文件数说明
主包src/pages/284 个 tabbar 页:工作台 index、审批 bpm、消息 message、我的 user,外加 contact
已交付分包src/pages-core/24登录 / 注册 / 验证码登录 / 404 / 个人中心 / 设置 / 联系客服 / FAQ
src/pages-system/120通知、操作日志、登录日志等;只有 3 个进了导航树
src/pages-infra/62API 访问/错误日志 + 在线表单运行时 form-design/run/
src/pages-bpm/69审批中心 + 自研 form-create 渲染器 components/form-create/
src/pages-ai/86AI 对话 / 智能体
🔴 编译进包但不可达src/pages-{mes,mall,im,erp,crm,iot,wms,member,pay,mp,statistics}/1,082后端没有对应模块,导航树不建节点

支撑目录:src/http/(请求层)、src/store/(6 个 Pinia store)、src/router/(登录拦截)、src/components/(只有 dict-tag/、system-select/、yudao-ui/ 三个)、src/hooks/(5 个)、src/utils/、src/style/、src/tabbar/(自定义 tabbar)、src/api/(按后端模块分目录)、src/layouts/(只有一个空壳 default.vue)。

根目录的工程文件:vite.config.ts、uno.config.ts、pages.config.ts、manifest.config.ts、env/.env*、scripts/、vite-plugins/。

那 1,082 个文件不是「以后会用」,是正在拖累产物

后端 reactor 里只有 5 个业务模块(ainb/pom.xml:16-20:system / infra / bpm / ai / agent)。上游的支付 / 商城 / CRM / ERP / 会员 / IoT / 公众号 / IM / MES / WMS 模块已被整体删除,所以这 11 个分包的页面发不出任何有效请求。

但它们照样被编译进产物——vite.config.ts:104-121 的 subPackages 把 16 个目录全列上了。实测 H5 生产包 dist/build/h5 共 13.1 MB,其中 569 个 chunk / 6.3 MB 属于这 11 个不可达分包,接近一半。最大的单个是 pages-im-home-conversation-rtc-call-index.js 512 KB(IM 实时音视频页,连带把 livekit-client 打进产物——这也是它出现在 THIRD-PARTY-NOTICES.md 里的原因)。

复现:

bash
cd ainb-ui-admin-uniapp && pnpm build:h5
cd dist/build/h5/assets && du -sk . | awk '{printf "%.1f MB total\n",$1/1024}'
find . -name '*.js' -exec du -k {} + \
  | grep -E 'pages-(crm|erp|im|iot|mall|member|mes|mp|pay|wms|statistics)-' \
  | awk '{s+=$1;n++} END {printf "%d chunks / %.1f MB unreachable\n", n, s/1024}'

想瘦身就从 subPackages 里摘掉这 11 个目录(连带 src/api/ 下同名目录),但这是不可逆的删除,且会让将来真要接某个模块时得从上游重新捞——所以本项目选择留着,代价记在这里。

核心机制 ​

1. 它是一个混合体,两套上游的缝在工程文件里 ​

来自谁具体是什么怎么认出来
unibest 4.1.0(工程骨架)vite.config.ts 的 18 个插件链、pages.config.ts / manifest.config.ts 约定式生成、src/layouts/、src/tabbar/ 自定义 tabbar、src/router/interceptor.ts(文件头自己写着「unibest 官方维护的代码」)、docs/ 整站package.json:5-7 的 unibest-version / unibest-update-time;docs/ 里还有上游的打赏与赞助页
yudao-ui-admin-uniapp(业务页底座)src/pages-*/ 全部业务页、src/api/、src/components/yudao-ui/、src/store/{token,user,dict}.ts、src/http/ 的双 tokenpackage.json:6 的 yudao-version;src/components/yudao-ui/ 目录名刻意未改(见下)
本项目自研 ★服务端驱动导航 system_nav_node、src/pages-bpm/components/form-create/(form-create 规则模型的独立 uni-app 实现)、src/style/tokens.scss 品牌令牌 + pnpm check:color 守卫、src/pages-infra/form-design/run/ 的 rule-adapter.ts见各专页

src/components/yudao-ui/ 为什么没改名

它被两处机制引用:easycom 规则 '^yd-(.*)': '@/components/yudao-ui/yd-$1/yd-$1.vue'(pages.config.ts:16)与 YudaoUiResolver 自动导入(vite.config.ts:33-47)。改名要同时动这两处 + 56 个文件的 import + 重新生成类型声明,收益为零。目录名不代表归属变更。

2. 工作台菜单是服务端下发的 ​

登录成功后 src/store/nav.ts:31-48 拉一次 GET /system/nav-node/tree?terminal=app,持久化到本地,src/pages/index/index.ts:128-134 把它映射成工作台的三层结构(分组 → 子分组 → 导航项)。前端没有任何菜单白名单——服务端已经按当前用户的权限过滤过了(src/api/system/navNode/index.ts:6-8 的注释明说这一点)。

这条链路是本仓最重要的自研能力,单独一页讲:服务端驱动导航。

3. 与 Web 端的能力差 ​

能力Web 管理端移动端差在哪
菜单来源system_menu → 动态路由system_nav_node → 工作台卡片两套表、两个维护界面
低代码表单设计✅ 设计器(vendored src/lib/form-designer)❌ 没有设计器移动端只跑运行时
低代码表单运行时✅ src/lib/form-create(Element Plus)✅ src/pages-bpm/components/form-create/(wot-design-uni)两套独立实现,控件覆盖有缺口,见在线表单在移动端
权限判定后端 GrantDecisionEngine同一套无差异
行级数据过滤后端 FormRowFilter同一套无差异(服务端做的)
字段级权限脱敏✅⚠️ 渲染器有 API、在线表单页没调用见在线表单在移动端
公式 / 脚本 / 联动规则✅❌ 声明了但零消费者同上
门户 infra_portal✅❌移动端首页是工作台,不是门户
Agent 对话 SSE✅ fetchEventSource✅ src/http/sse.ts两套实现
单元测试59 个 vitest spec0 个见「测试」节

数据模型 ​

移动端自己不拥有任何表,它读的是后端已有的表。与它强相关的两张:

表关系详见
system_nav_node移动端专属:terminal 列现阶段只有 app 一个取值,Web 端不写这张表服务端驱动导航
infra_form_design.app_nav_node_id「这张表单发布到 App 端了吗」的唯一判据,NULL = 未发布在线表单在移动端

本机实测(ainb-professional-init,2026-10-25):system_nav_node 共 97 行,其中 20 行存活(deleted=0)、77 行是软删墓碑;infra_form_design 41 行中 3 行绑定了 app_nav_node_id。

接口清单 ​

移动端调用的后端接口与 Web 端完全同源,没有一套「移动端专用 API」。差异只在鉴权头的拼装(见请求封装与登录态)。少数几个对移动端语义特别重的:

端点用途
GET /system/nav-node/tree?terminal=app工作台导航树(服务端已按权限过滤)
POST /system/auth/login · POST /system/auth/refresh-token双 token 登录与刷新
GET /system/auth/get-permission-info权限码集合,喂给 useAccess
GET /system/tenant/simple-list · /get-by-website登录页租户选择器
GET /infra/form-design/runtime/{code}/config在线表单运行时配置
POST /infra/file/upload上传(uni.uploadFile,走同一个拦截器)

怎么扩展 ​

加一个移动端页面的完整步骤在移动端页面开发范式——注意其中没有「注册路由」这一步:UniPages 插件自动扫描,definePage() 宏声明页面配置,而「让用户点得到」是去后台 system_nav_node 加一条记录,不是改前端文件。

其余入口:

测试 ​

🔴 本仓没有任何单元测试——全仓 .spec.ts / .test.ts 命中数为 0,package.json 里也没有 test 脚本。可用的三道检查是:

命令查什么
pnpm type-checkvue-tsc --noEmit(新克隆必须先跑一次 pnpm dev,见坑位)
pnpm lintESLint
pnpm check:color品牌色硬编码守卫,#3370ff 出现即 exit 1

不要假称这里有测试体系。作为对照,Web 仓有 59 个 vitest spec、后端 agent 模块有 2,225 个 @Test。移动端唯一的回归网是手工点 + 巡检脚本(C:\code\xpy\_evidence\,不入库)。

控件契约没有任何东西守着

src/pages-infra/form-design/run/components/rule-adapter.ts:63-72 的 UNSUPPORTED_TYPES 是手工维护的清单,没有任何测试对账。它可以静默漂移——详见在线表单在移动端。

坑与注意 ​

  • 只能 pnpm:preinstall 挂了 npx only-allow pnpm(package.json:25),用 npm / yarn 直接报错。Node ≥ 20。
  • 不能跳过 install 直接 pnpm dev:src/pages.json 与 src/manifest.json 都被 gitignore,靠 scripts/create-base-files.js 生成。
  • src/types/uni-pages.d.ts 也不入库,而 src/utils/index.ts:3 直接 import { pages, subPackages } from '@/pages.json' —— 新克隆跑 type-check 必然报找不到模块。
  • 那 11 个分包不要「顺手修好」:它们不可达是因为后端模块被删了,不是前端写错了。
  • src/uni_modules/ 是空的,只有一个 .gitkeep;别以为漏拉了子模块。

→ 本节是贴着上下文的提醒;按症状查的移动端全域清单见移动端坑位,跨端清单见坑位索引。

未证实 ​

  • 小程序 / App 端从未在本机实测过。本章所有结论基于 H5(:9000)+ 后端(:48080)实跑与源码静态阅读。build:mp-weixin 与 build:app 的产物结构、miniprogram-ci 上传、原生插件资源复制都只有源码依据。
  • dist/build/h5 的 13.1 MB 是某一次构建的快照,不是稳定值;它会随依赖版本变。要引用请按上面的命令重测。
  • 那 11 个不可达分包里,是否有页面能被直接输 URL 打开(H5 下路由是注册的,只是导航树不给入口)没有逐页验证过。已知的巡检假阳性说明「能打开」和「能用」是两回事,见移动端坑位。
  • AI 大模型 分组(system_nav_node.id=291)在库里存活但零个存活子节点,于是被 /tree 的空组剪枝规则整组剪掉。它是「本来就该没有」还是「子节点被误删」,源码里没有答案。

相关页面 ​