Skip to content

Mobile 移动端

路径:packages/mobile
技术:uni-app + Vue 3(CLI + Vite,依赖见 catalogs.mobile

下载

地址
脚手架 Mobile 安装包(Android APK)xichen_mobile.apk

TIP

APK 内置 API 地址取决于打包时的 .env.production。真机需能访问对应后端地址。

定位

  • 业务端,不做完整系统管理(用户/角色/菜单 CRUD 在 Web/Desktop)
  • 仿 uni-starter 三栏 Tab(首页 / 用户 / 我的),用户模块为真接口 CRUD 范例
  • 登录、用户中心、权限宫格对接现有 RBAC auth
  • 复用 @xichen-full-stack/types@xichen-full-stack/auth@xichen-full-stack/utils
  • HTTP 层在包内自实现(uni.request),API 路径与 @xichen-full-stack/api-client 对齐

页面结构

页面说明权限
pages/grid/indexTab 首页:Banner + RBAC 业务宫格 + 静态宫格登录
pages/list/listTab 用户列表(分页、搜索、下拉刷新)system:user:list
pages/list/search用户高级搜索(debounce)system:user:list
pages/list/detail用户详情system:user:list
pages/list/edit编辑用户system:user:update
pages/ucenter/indexTab 我的:资料、角色、退出登录
pages/ucenter/userinfo个人资料(PUT 当前用户)登录
pages/ucenter/settings设置(静态演示)登录
pages/ucenter/about关于登录
pages/common/webview内嵌 H5登录
pages/login/index登录(Xm* UI)公开
pages/ui-kit/indexUI 组件库展示登录
pages/demo/index健康检查示例system:user:list

system:user:list 时进入「用户」Tab 会显示页内无权限提示(不自动跳转),见 constants/tab-pages.ts

目录结构

text
src/
├── api/
│   ├── http.ts              # uni.request + 401 Token 刷新
│   ├── index.ts             # getApi() 单例
│   ├── token-storage.ts     # getTokenStorage() 统一读写
│   └── modules/
│       ├── auth.ts          # login / me / logout / health
│       └── system.ts        # users / roles / menus / permissions(与 api-client 路径一致)
├── composables/
│   ├── usePermission.ts
│   ├── usePageGuard.ts      # 登录 + bootstrap + 权限;accessGranted
│   ├── useRequest.ts        # loading 计数、error toast、debounce
│   └── usePageList.ts       # Tab 列表页范式
├── stores/auth.ts           # Pinia;bootstrap / refreshSession
├── constants/
│   ├── entries.ts           # 首页 RBAC 宫格 MOBILE_ENTRIES
│   ├── tab-pages.ts         # Tab 页权限映射
│   └── mock/                # Banner、静态宫格(非业务 API)
├── components/xm-*/         # Xm* 通用 UI(easycom 自动引入)
├── pages/                   # grid / list / ucenter / login / demo / ui-kit
├── utils/
│   ├── navigate.ts          # Tab 跳转、ensureLoggedIn
│   ├── list-refresh.ts      # markUserListStale / 编辑后刷新列表
│   └── user-display.ts
├── styles/theme.scss        # NC 企业色
├── static/tabbar/           # TabBar 图标
└── App.vue                  # 启动 bootstrap;前后台 refreshSession

UI 组件(Xm*)

与 Web Xc* 对应,基于 uni 内置组件,适配 微信小程序 + Android App

组件说明
xm-page页面容器
xm-list-page列表三层:操作 / 内容 / 底部
xm-card / xm-section卡片与分组
xm-button / xm-input / xm-search-bar表单控件
xm-cell / xm-cell-group列表行
xm-tag / xm-grid标签与宫格
xm-empty / xm-divider空状态与分割线
xm-banner首页轮播
xm-load-state加载 / 错误 / 重试统一态

pages.json 配置 easycom:^xm-(.*)@/components/xm-$1/xm-$1.vue
我的 → UI 组件库/pages/ui-kit/index 查看示例。

主题变量通过 src/uni.scss 注入各组件样式;vite.config.ts 中 SCSS includePaths 指向 src/,以便 @import 'styles/theme.scss' 正确解析。

TabBar 与导航

Tab路径说明
首页pages/grid/indexBanner + MOBILE_ENTRIES 权限宫格
用户pages/list/list系统用户列表(真接口)
我的pages/ucenter/index用户信息 + 退出
工具说明
goHome()switchTab 到首页
goLogin()reLaunch 登录页
ensureLoggedIn()getTokenStorage() 判断,未登录跳转
openPage(url)Tab 页 switchTab,其余 navigateTo

API 层

ts
import { getApi } from '@/api'

// 认证
await getApi().auth.login({ username, password })
await getApi().auth.me()

// 系统用户(路径与 web api-client 一致)
await getApi().system.users.list({ page: 1, pageSize: 10, keyword: 'admin' })
await getApi().system.users.get(id)
await getApi().system.users.update(id, { nickname: '新昵称' })

新增业务域:在 src/api/modules/ 增加模块,于 api/index.ts 挂到 getApi()

Composables 快速范式

页面守卫

ts
import { usePageGuard } from '@/composables/usePageGuard'

// Tab 根页:无权限时页内提示,不 redirect
const { whenReady, accessGranted } = usePageGuard({
  permission: 'system:user:list',
  redirectOnDeny: false,
})

onShow(() => {
  whenReady(() => loadData())
})
  • 默认 waitAuth: true:校验前 authStore.bootstrap()
  • accessGranted === false 时可渲染无权限空态

请求

ts
import { useRequest } from '@/composables/useRequest'

const { loading, error, run } = useRequest({ showErrorToast: true })

await run(() => getApi().auth.health())

loading 为并发计数;useDebouncedFn 可用于搜索 debounce。

Tab 列表页

ts
import { usePageList } from '@/composables/usePageList'
import { getApi } from '@/api'

const {
  list, keyword, page, total, totalPages,
  loading, error, accessGranted,
  reload, search, prevPage, nextPage,
  setupTabPageLifecycle, goHome,
} = usePageList({
  permission: 'system:user:list',
  redirectOnDeny: false,
  pageSize: 10,
  fetch: (q) => getApi().system.users.list(q),
})

setupTabPageLifecycle() // onShow 首次/stale 加载 + onPullDownRefresh

编辑成功后调用 markUserListStale()utils/list-refresh.ts),返回列表 Tab 时自动刷新。

用户模块范例流程

text
首页宫格「用户管理」→ Tab 用户列表
  → 详情(system:user:list)
  → 编辑(system:user:update)→ 保存 → markUserListStale → 列表刷新

我的 → 个人资料 → PUT 当前用户 → refreshSession
接口方法权限
/api/v1/system/usersGETsystem:user:list
/api/v1/system/users/:idGETsystem:user:list
/api/v1/system/users/:idPUTsystem:user:update

认证与前后台

  • stores/auth.tsbootstrap() 启动恢复会话;refreshSession() App 从后台回前台时刷新 /auth/me
  • App.vueonLaunch bootstrap;后续 onShow 调用 refreshSession(跳过首次)
  • Token 统一经 getTokenStorage(),与 ensureLoggedIn() 一致

与 Web admin 的差异

Web adminMobile
vue-router 动态 addRoutepages.json 固定页面 + 入口显隐
axios + @xichen-full-stack/api-clientuni.request + 本地 getApi()
localStorage Tokenuni.setStorageSync
Element PlusXm* 自研组件

环境变量

不会读取 .env.example

.env.example 仅为模板。Vite 按模式加载 .env.development / .env.production

文件场景
.env.developmentdev:h5dev:app-android 等开发
.env.productionbuild:app-android、HBuilderX 生产打包
env
# 示例:.env.production
VITE_API_BASE_URL=http://192.168.1.12:8080
  • H5 开发可用 localhost
  • App / 真机 必须用局域网 IP 或公网域名
  • 修改 env 后须重新 build

配置入口:src/config/index.tsgetApiBaseUrl()

manifest.json

字段说明
appidDCloud 应用 ID(Android App 必填)
app-plus.distribute.android.permissions网络等权限
mp-weixin.appid微信小程序 AppID

启动

bash
pnpm --filter mobile dev:h5              # H5
pnpm --filter mobile dev:mp-weixin       # 微信小程序
pnpm --filter mobile dev:app-android     # Android 调试
pnpm --filter mobile type-check          # TS 检查

默认账号:admin / admin123

Android 打包

CLI uni build 不能直接产出可分发 APK,需配合 HBuilderX(建议与 wgt 同版本,如 5.07)。

text
1. 配置 .env.production(API 地址)
2. pnpm --filter mobile build:app-android   → dist/build/app
3. HBuilderX 打开 dist/build/app
4. 发行 → 原生 App-云打包 → Android

真机调试需 自定义调试基座,勿用标准基座 + 新版 wgt 混用。

bash
pnpm --filter mobile build:app-android
pnpm --filter mobile build:h5
pnpm --filter mobile build:mp-weixin

依赖与 catalog

mobile 使用 pnpm-workspace.yamlcatalogs.mobile(Vite 5、TS 4.9、@dcloudio/*),与 web/desktop 的 catalog 分离,不可混升。

相关文档

Xichen Full Stack 内部文档