# 风控品控管理系统 — 移动端(uniapp)
**uniapp 3.x** | **Vue 3.4** | **TypeScript 5** | **Vite 5**
巡检打卡 · 隐患排查 · 风险管控
---
## 一、项目简介
本仓库是 **风控品控管理系统** 的移动端(uniapp)项目,基于 DCloud 官方 Vue3 + Vite 模板深度定制。
### 已实现模块
| 模块 | 路由 | 状态 |
|---|---|---|
| 工作台首页 | `/pages/index/index` | ✅ |
| 巡检任务列表 | `/pages/inspection/list/index` | ✅ |
| 巡检打卡 | `/pages/inspection/check/index` | ✅ |
| 扫码打卡 | `/pages/inspection/scan/index` | ✅ |
> 仅 H5 端已验证可运行;APP / 微信小程序端需要真机调试。
---
## 二、技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| uniapp | 3.x | 跨端框架(iOS / Android / H5 / 微信小程序 / 抖音小程序) |
| Vue | 3.4 | Composition API |
| TypeScript | 5.x | 类型系统 |
| Vite | 5.x | 构建工具 |
| Sass | 1.69 | SCSS 预处理器 |
> **不使用 uView 等第三方组件库**,所有 UI 元素手写 + SCSS 实现,便于定制和体积优化。
---
## 三、项目结构
```
uniapp/
├── src/
│ ├── api/ # API 接口层
│ │ └── inspection.ts # 巡检相关接口(列表、详情、提交、扫码校验)
│ │
│ ├── types/ # 全局类型声明
│ │ └── inspection.ts # InspectionTask / InspectionItem / Payload 等
│ │
│ ├── utils/ # 工具类
│ │ └── location.ts # 位置工具(Haversine 距离 / 授权)
│ │
│ ├── static/
│ │ └── styles/
│ │ ├── variables.scss # 颜色/间距/字号/圆角变量
│ │ └── common.scss # 通用工具类(flex / tag / btn / 间距)
│ │
│ ├── components/ # 业务组件(easycom 自动注册)
│ │
│ ├── pages/ # 页面
│ │ ├── index/index.vue # 首页(入口)
│ │ └── inspection/
│ │ ├── list/index.vue # 巡检任务列表
│ │ ├── check/index.vue # 巡检打卡
│ │ └── scan/index.vue # 扫码中间页
│ │
│ ├── App.vue # 根组件
│ ├── main.ts # 入口
│ ├── pages.json # 路由与 tabBar 配置(uniapp 必需)
│ └── manifest.json # 应用配置(uniapp 必需)
│
├── index.html # H5 入口
├── vite.config.ts
├── tsconfig.json
├── package.json
└── README.md
```
---
## 四、核心页面
### 4.1 巡检任务列表
**功能**:
- 顶部 Tab 切换:全部 / 未打卡 / 已打卡
- 右上角筛选按钮(按巡检类型)
- 卡片列表显示 8 个字段:任务名称、巡检类型、打卡方式、门店、打卡地点、任务完成时间、实际打卡时间(仅已打卡)、打卡结果(仅已打卡)
- 状态标签颜色:已打卡 = 绿色,未打卡 = 橙色,已过期 = 灰色
- 结果标签颜色:正常 = 绿色,异常 = 橙色
- 操作按钮:未打卡 → 「前去打卡」(蓝色),已打卡 → 「查看详情」(默认色)
- 下拉刷新 + 上拉加载更多
**跳转逻辑**:
```ts
if (punchType === 'NORMAL') {
// 常规打卡:直接跳到打卡页
navigateTo('/pages/inspection/check/index?taskId=' + id)
} else if (punchType === 'SCAN') {
// 扫码打卡:先跳到扫码页
navigateTo('/pages/inspection/scan/index?taskId=' + id)
}
```
### 4.2 扫码中间页
**功能**:
- 拉起摄像头(仅 APP / 微信小程序原生支持,H5 退化为手动输入)
- 调用 `uni.scanCode` 识别二维码
- 校验顺序:
1. 二维码与任务绑定关系(`/risk/inspectionTask/verifyQr`)
2. 当前位置与点位距离 ≤ X 米(X 取自系统配置 `scan_limit_meter`,默认 100 米)
3. 校验通过后跳到打卡页
- 顶部/底部/左右黑色遮罩 + 4 个角的蓝色边框 + 上下扫描动画线
**距离计算**:`utils/location.ts` 中 `calculateDistance()` 使用 Haversine 公式。
### 4.3 巡检打卡页
**功能**:
- 顶部只读:巡检名称、巡检位置(含 📍 icon)
- 巡检项目卡片(多个):
- 项目大类(蓝色背景小标签)
- 巡检内容
- 巡检标准
- 检查结果:正常 / 异常 按钮(二选一,可取消)
- 异常时显示异常原因输入框(必填,maxlength=200)
- 「是否需要拍照」项才显示现场照片上传区(支持多张,可删除)
- 底部「提交打卡」按钮:固定底部,蓝色,高度 88rpx
**校验逻辑**(提交前):
1. 每个项目必须选择正常/异常
2. 选择异常时必须填写原因
3. 「是否需要拍照」项必须上传至少 1 张照片
4. 获取当前位置(用于考勤记录)
**成功弹窗**:
- 半透明遮罩 + 居中卡片
- 绿色 ✓ 图标 + "提交成功"标题 + "巡检结果已成功保存"副标题
- 蓝色 "返回巡检列表"按钮,点击后回退并强制刷新列表
### 4.4 只读模式
点击「查看详情」进入打卡页时携带 `?readonly=1`:
- 所有选择按钮 disabled
- 照片区不显示删除 ×
- 底部无「提交打卡」按钮
- 用户只能查看,不可修改
---
## 五、跨端适配
| 平台 | 支持情况 | 备注 |
|---|---|---|
| H5 | ✅ 完整 | 浏览器 + 移动端 H5 |
| Android | ✅ | 需自定义基座 / 真机调试 |
| iOS | ✅ | 需 Apple 证书 |
| 微信小程序 | ✅ | 需在 manifest.json 填入 appid |
| 抖音/支付宝小程序 | ⚠️ | 可能需调整 API |
**扫码 API 限制**:
- `uni.scanCode` 在 H5 端无法直接拉起摄像头
- 解决方案:H5 端点击「前去打卡」扫码任务时,自动跳到「手动输入」弹窗
---
## 六、本地开发
### 环境要求
- Node.js 18+(推荐 20 LTS)
- npm 9+ 或 pnpm 8+
- HBuilderX(推荐,IDE 自带真机调试)或 VSCode + 命令行
### 安装与运行
```bash
# 1. 安装依赖
npm install --registry=https://registry.npmmirror.com
# 2. 启动 H5 开发服务器(默认 :9000)
npm run dev:h5
# 3. 启动微信小程序(需在 manifest.json 填入 appid)
npm run dev:mp-weixin
# 4. 生产构建
npm run build:h5 # H5 静态资源输出到 dist/
npm run build:mp-weixin # 微信小程序输出到 dist/dev/mp-weixin
```
### 浏览器访问
启动后访问 `http://127.0.0.1:9000/`,按 F12 切到移动端模拟器(iPhone 14 Pro 390×844)体验。
### 后端联调
`vite.config.ts` 中已配置代理:
```ts
proxy: {
'/dev-api': {
target: 'http://127.0.0.1:8080', // RuoYi-Vue-Plus 后端
changeOrigin: true
}
}
```
确保后端 [http://127.0.0.1:8080](http://127.0.0.1:8080) 已启动且:
- 已实现 `GET /risk/inspectionTask/mobileList`
- 已实现 `GET /risk/inspectionTask/{id}`
- 已实现 `POST /risk/inspectionRecord/punch`
- 已实现 `POST /risk/inspectionTask/verifyQr`
> **演示模式**:未连接后端时,`loadDetail()` 与 `listInspectionTasks()` 会自动 fallback 到 mock 数据(消防设备、电气安全、通道畅通 3 个示例项目)。
---
## 七、API 对接规范
所有接口统一走 RuoYi-Vue-Plus 后端,基础路径 `/dev-api`(开发)/ `/prod-api`(生产):
```ts
// 列表
GET /risk/inspectionTask/mobileList?status=ALL&pageNo=1&pageSize=10
Response: {
code: 200,
msg: 'ok',
data: {
total: 3,
rows: InspectionTask[],
pageNum: 1,
pageSize: 10
}
}
// 详情
GET /risk/inspectionTask/{id}
Response: { code: 200, data: InspectionTask }
// 校验二维码
POST /risk/inspectionTask/verifyQr
Body: { taskId: number, qrContent: string }
Response: { code: 200, data: { valid: boolean } }
// 提交打卡
POST /risk/inspectionRecord/punch
Body: {
taskId: number,
longitude: number,
latitude: number,
punchType: 'NORMAL' | 'SCAN',
items: Array<{ itemId, result, reason?, photos? }>
}
Response: { code: 200, data: { punchId: number } }
```
---
## 八、构建与部署
### H5 部署
```bash
npm run build:h5
# 输出至 dist/ 目录
```
Nginx 配置示例:
```nginx
server {
listen 80;
server_name m.example.com;
root /var/www/risk-mobile/dist/build/h5;
index index.html;
location / { try_files $uri $uri/ /index.html; }
location /prod-api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
}
}
```
### APP 打包
使用 HBuilderX 打开项目 → 发行 → 原生 APP-云打包,上传证书后生成 apk / ipa。
### 微信小程序
```bash
npm run build:mp-weixin
# 用微信开发者工具导入 dist/dev/mp-weixin
```
---
## 九、配套仓库
| 端 | 仓库 |
|---|---|
| 后端 | http://134.175.81.27:3000/yangjingjing/risk_control_platform.git |
| PC Web 前端 | http://134.175.81.27:3000/yangjingjing/risk_control_platform_ui.git |
| 移动端(本仓) | http://134.175.81.27:3000/yangjingjing/risk_control_platform_app.git |
---
## 十、版本历史
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.0.0 | 2026-06 | 巡检模块首版上线(列表 + 打卡 + 扫码) |