# xcy-mp **Repository Path**: xince-cloud/xcy-mp ## Basic Information - **Project Name**: xcy-mp - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-09 - **Last Updated**: 2026-06-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 信测云统一移动端 (xcy-uni) 基于 **uni-app + Vue3** 的检验检测一体化平台统一移动端。一套代码编译 **微信小程序 / App / H5** 多端。 客户与机构员工 **双身份合一**: 同一手机号登录后, 后端按角色返回 `userType`(`CUSTOMER` / `ORG_USER`) 与可切换的 `identities` 列表, 前端按当前身份展示对应导航与功能。 ## 技术栈 - uni-app (`@dcloudio/uni-app`, Vue3 `createSSRApp`) - pinia (登录态 / 双身份) - 仅使用 uni-app 内置组件 (view/text/button/input/scroll-view/image/navigator/picker), 不引外部 UI 库 - 自定义底部 tabbar (按角色动态渲染, 原生 tabBar 无法动态切换) ## 环境要求 - Node.js >= 16 - 微信小程序: 需 **微信开发者工具** + 自有 `appid` - App: 推荐 **HBuilderX** 打包 (云打包 / 本地打包) ## 安装 ```bash npm install ``` ## 运行 / 构建 ```bash # H5 npm run dev:h5 # 本地开发 (默认 http://localhost:5173) npm run build:h5 # 构建产物在 dist/build/h5 # 微信小程序 npm run dev:mp-weixin # 产物在 dist/dev/mp-weixin, 用微信开发者工具打开该目录 npm run build:mp-weixin # 产物在 dist/build/mp-weixin # App npm run dev:app npm run build:app ``` ### 微信小程序上传步骤 1. `npm run dev:mp-weixin` (或 build) 2. 微信开发者工具 → 导入项目 → 选择 `dist/dev/mp-weixin` (或 `dist/build/mp-weixin`) 目录 3. 在 `src/manifest.json` 的 `mp-weixin.appid` 与顶层 `appid` 填入真实小程序 appid (当前为占位空串) 4. 开发者工具内预览 / 上传 ### HBuilderX 方式 直接用 HBuilderX 打开项目根目录, 选择运行到对应平台 (浏览器 / 微信开发者工具 / 手机) 即可, 无需 npm scripts。 ## 后端契约 后端: **https://xcy-api.airoot.vip** , 接口前缀 `/api`。 请求封装见 `src/utils/request.js`: - `baseURL = 'https://xcy-api.airoot.vip/api'` (H5 本地若想走 vite 代理, 改为 `'/api'` 并在 `vite.config.js` 启用 proxy) - 自动注入 `Authorization: Bearer ` - 返回约定 `{ code, msg, data }`: `code===0` resolve `data.data`; `code!==0` toast 并 reject; HTTP 401 或业务 `code` 为 `401/1003` 清 token 并 reLaunch 登录页 核心鉴权接口: | 接口 | 方法 | 请求 | 返回 | | --- | --- | --- | --- | | `/v1/auth/unified-login` | POST | `{ phone, code }` (测试码 `123456`) | `{ token, userType, uid, orgId, identities }` | | `/v1/auth/switch-to` | POST | `{ targetType, orgId? }` | 同上 (新会话) | `identities` 元素结构: `{ type, uid, orgId, orgName, username }`。 ## 目录结构 ``` src/ ├── main.js # createApp (createSSRApp + pinia) ├── App.vue # 全局 onLaunch / 公共样式 ├── manifest.json # 多端配置 (appid 占位) ├── pages.json # 全部页面预声明 (page agent 勿改, 仅填 .vue) ├── uni.scss # 全局 SCSS 变量 ├── utils/request.js # uni.request 封装 ├── store/user.js # pinia 登录态 / 双身份 ├── components/role-tabbar.vue # 自定义角色底部 tabbar └── pages/ ├── login/index.vue # 统一登录 ├── index/index.vue # 客户首页 ├── order/create.vue # 客户下单 ├── archive/index.vue # 客户我的档案 ├── workbench/index.vue # 员工工作台 ├── scan/index.vue # 员工扫码录入 ├── audit/index.vue # 员工移动审批 └── mine/index.vue # 我的 + 身份切换 ``` ## 页面与角色导航 (自定义 tabbar) `src/components/role-tabbar.vue` 按 `userStore.userType` 动态渲染底部页签: - **客户 (CUSTOMER)**: 首页 `/pages/index/index` · 档案 `/pages/archive/index` · 我的 `/pages/mine/index` - **机构员工 (ORG_USER)**: 工作台 `/pages/workbench/index` · 扫码 `/pages/scan/index` · 审批 `/pages/audit/index` · 我的 `/pages/mine/index` ### 业务页接入 tabbar (供 page agent) 每个需要底部导航的业务页在模板底部引入 (easycom 已注册, 无需 import): ```vue ``` - `current` 传当前页路径用于高亮 - 页面根容器需留底部内边距 (建议 `padding-bottom: 140rpx`) 避免被固定 tabbar 遮挡 - 切页用 `uni.reLaunch` (这些页面非原生 tabBar 页, `uni.switchTab` 无效) — 组件内部已处理 ### 约定: page agent 互斥并行 - `src/pages.json` 已 **预声明全部 8 个页面路径**, page agent 只填对应 `.vue`, **不要改 pages.json** - 下单页 `pages/order/create` 无 tabbar (二级页, 从首页进入) ## 登录态 store (`store/user.js`) ```js import { useUserStore } from '@/store/user' const store = useUserStore() await store.login(phone, code) // 统一登录, 写 token/userType/identities await store.switchIdentity(targetType, orgId) // 切换身份, 返回新会话 store.logout() // 清登录态 store.isLogin / store.isCustomer / store.isOrgUser store.hasMultiIdentity // 是否多身份 (决定 mine 页是否展示切换) store.homePath // 当前身份首页路径 ``` 字段持久化到 uni storage (`xcy_token` / `xcy_uid` / `xcy_userType` / `xcy_orgId` / `xcy_identities`), 冷启动自动恢复。