You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

697 lines
48 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 巡检管理
> 模块编码inspection
> 端侧Web + 小程序(双端)
> 关联文档01-模块划分 §3.2 / 02-功能清单-物业公司 §2 / 03-业务流转逻辑-物业公司 §2 / 05-接口规范 §9.2 / 06-项目技术要求 §4.4
> 强制规范遵循 `07-前端界面开发规范.md`
## 功能概览
| 项目 | 说明 |
|------|------|
| 菜单名称 | 巡检管理 |
| 子菜单 | 巡检计划管理、巡检任务看板、巡检记录查询、异常处理跟踪、巡检区域管理、数据补录 |
| 功能编号 | PR-I-01 ~ PR-I-07 |
| 权限编码前缀 | inspection:plan:* / inspection:task:* / inspection:area:* / inspection:supplement:* |
---
## 页面1巡检计划管理页
**页面编号**PR-I-01-P01
**端侧归属**Web专属
**页面路径**/inspection/plans
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 巡检管理 > 巡检计划管理 │
├──────────────────────────────────────────────────────────────────┤
│ [查询条件区] │
│ 计划名称[____] 状态[▼] 巡检类型[▼] 负责班组[▼] [查询] [重置] │
├──────────────────────────────────────────────────────────────────┤
│ [操作栏] [新增计划] │
├──────────────────────────────────────────────────────────────────┤
│ [列表区] │
│ 序号 | 计划名称 | 巡检类型 | 频次 | 负责班组 | 巡检人员 | 状态 | 操作│
│ 1 | 门诊楼日常| 日常 | 每日 | 巡检一班 | 张三,李四| 启用 | 编辑│
│ 2 | 空调专项 | 专项 | 每周 | 巡检二班 | 王五 | 停用 | 编辑│
├──────────────────────────────────────────────────────────────────┤
│ [分页] 共25条 每页[20▼] < 1 2 > │
└──────────────────────────────────────────────────────────────────┘
```
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 计划名称 | 文本输入 | 否 | — | 模糊匹配 |
| 状态 | 下拉单选 | 否 | 全部 | 启用/停用 |
| 巡检类型 | 下拉单选 | 否 | 全部 | 数据来源:字典管理-巡检类型 |
| 负责班组 | 下拉单选 | 否 | 全部 | 数据来源:组织架构-班组 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 序号 | 60px | — | 自增 |
| 2 | 计划名称 | 160px | 是 | — |
| 3 | 巡检类型 | 80px | 否 | 标签样式 |
| 4 | 频次 | 80px | 否 | 每日/每周/每月/自定义 |
| 5 | 负责班组 | 100px | 是 | — |
| 6 | 巡检人员 | 150px | 否 | 显示人员列表 |
| 7 | 巡检区域 | 150px | 否 | 简略显示区域 |
| 8 | 状态 | 80px | 是 | 启用/停用 |
| 9 | 操作 | 100px | — | 编辑/停用 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 新增计划 | inspection:plan:create | 操作栏 | 始终 | 跳转新增页 |
| 编辑 | inspection:plan:update | 行操作 | 始终 | — |
| 启用/停用 | inspection:plan:update | 行操作 | 始终 | 停用后不再生成任务 |
### 表单字段(新增/编辑页)
| 字段名 | 控件类型 | 必填 | 默认值 | 数据来源 | 校验规则 |
|--------|----------|------|--------|----------|----------|
| 计划名称 | 文本输入 | 是 | — | 自填 | 最大50字同租户内唯一 |
| 巡检类型 | 下拉单选 | 是 | — | 字典管理-巡检类型 | — |
| 巡检区域 | 级联多选 | 是 | — | 区域五级架构 | 至少选一个 |
| 巡检设备 | 下拉多选 | 否 | — | 区域关联设备 | 可选,不选则巡检所有 |
| 频次 | 下拉单选 | 是 | — | 固定选项 | 每日/每周/每月/自定义 |
| 自定义cron | 文本输入 | 条件 | — | 自填 | 频次=自定义时必填 |
| 负责班组 | 下拉单选 | 是 | — | 组织架构-班组 | — |
| 巡检人员 | 下拉多选 | 是 | — | 班组内人员 | 至少选一个 |
| 巡检清单 | 下拉多选 | 是 | — | 巡检清单模板 | 至少选一个检查项 |
| 生效日期 | 日期选择 | 是 | — | 自填 | 不早于当前日期 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 列表查询 | /api/v1/inspection-plans | GET | 分页查询 |
| 新增 | /api/v1/inspection-plans | POST | — |
| 编辑 | /api/v1/inspection-plans/{id} | PUT | — |
| 启用/停用 | /api/v1/inspection-plans/{id}/toggle-status | PUT | — |
### 交互流程要求
1. **页面加载流程**:进入页面 → 并行调用列表查询API GET /api/v1/inspection-plans 和下拉选项数据(巡检类型字典、班组列表)→ 渲染表格和筛选条件默认按序号升序排列加载第一页数据每页20条
2. **查询/筛选交互流程**:填写计划名称/选择状态/选择巡检类型/选择负责班组 → 点击[查询] → 携带筛选参数重新请求第1页 → 点击[重置]清空条件并重新加载;计划名称输入框支持回车触发查询
3. **表单填写与提交流程**:点击[新增计划] → 跳转新增页面或打开弹窗 → 填写计划名称、巡检类型、巡检区域级联多选、巡检设备、频次自定义时填cron表达式、负责班组、巡检人员班组内多选、巡检清单、生效日期 → 前端校验通过 → 调用新增API → 成功后跳回列表并刷新
4. **弹窗/抽屉交互流程**编辑弹窗宽度600px回填当前计划数据选择负责班组后联动加载班组内人员列表频次选择"自定义"时显示cron表达式输入框
5. **行内操作流程**:点击[编辑] → 弹窗回填计划数据 → 修改后提交 → 刷新列表;点击[停用] → 二次确认"停用后将不再自动生成巡检任务,确认停用?" → 确认后调用toggle-status API → 刷新该行状态
6. **异常与错误处理**:计划名称重复提示"该计划名称已存在"cron表达式格式错误提示"请输入有效的cron表达式";生效日期早于当前日期提示"生效日期不能早于今天"API请求失败显示ElMessage.error
7. **联动/级联交互**:选择负责班组后联动加载班组内人员下拉选项;巡检区域级联多选——选择项目→加载区域→选择区域→加载楼栋,逐级展开;频次=自定义时显示cron表达式输入框
8. **权限控制交互表现**:无 inspection:plan:create 权限时[新增计划]按钮隐藏;无 inspection:plan:update 权限时[编辑][停用]按钮隐藏
9. **【H1 防重复请求】**:查询按钮点击后立即 disabled + loading态API返回后恢复分页切换时 abort 上一次未完成的列表请求再发新请求;[新增]/[编辑]弹窗提交按钮 :loading + disabled 防重复提交;[停用]操作点击后该行禁用 + loading态页面加载时并行请求列表和字典数据互不阻塞。
10. **【H2 统一超时配置】**GET 列表查询超时15秒POST 新增计划超时30秒PUT 编辑/启用停用超时30秒超时自动中断 + 提示"请求超时,请稍后重试" + 按钮恢复可用;请求>3秒显示全局 ElLoading。
11. **【H3 操作确认机制】**[停用]操作前弹出 `ElMessageBox.confirm("确定停用「{计划名称}」?停用后将不再自动生成巡检任务", {type: 'warning'})` 含操作后果说明。
12. **【H4 脏数据检测】**[编辑]弹窗打开时对当前计划数据做 deep clone 作为原始快照;用户修改后 isDirty 检测;取消/关闭弹窗时若 isDirty 弹出"修改未保存,确定关闭?"确认框(含 type:'warning'[新增]弹窗同理检测是否有任何输入内容。
13. **【H8 操作结果反馈】**:新增/编辑成功 `ElMessage.success`2s→ 关闭弹窗 → silent 刷新列表;停用成功更新该行状态标签为"停用";失败 `ElMessage.error`(手动关闭)保留表单内容便于修改重试。
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 计划名称输入 | el-input | placeholder="请输入计划名称", clearable, maxlength=50 |
| 状态筛选 | el-select | placeholder="请选择状态", clearable |
| 巡检类型筛选 | el-select | placeholder="请选择巡检类型", clearable, filterable |
| 负责班组筛选 | el-select | placeholder="请选择负责班组", clearable, filterable |
| 列表 | el-table | stripe, border, :data="tableData", :max-height="calc(100vh - 280px)" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50]" |
| 新增计划按钮 | el-button | type="primary", icon="Plus" |
| 编辑按钮 | el-button | type="primary", link |
| 停用按钮 | el-button | type="warning", link |
| 状态标签 | el-tag | 启用=success / 停用=info |
| 巡检类型标签 | el-tag | type="primary", size="small" |
| 编辑弹窗 | el-dialog | title="编辑巡检计划", width="600px", :close-on-click-modal="false" |
| 计划名称 | el-input | maxlength=50, show-word-limit, placeholder="请输入计划名称" |
| 巡检类型 | el-select | placeholder="请选择巡检类型", filterable |
| 巡检区域 | el-cascader | :props="{multiple:true, checkStrictly:true, emitPath:false}", placeholder="请选择巡检区域", filterable, clearable |
| 巡检设备 | el-select | v-model="form.deviceIds", multiple, collapse-tags, placeholder="请选择巡检设备" |
| 频次 | el-select | placeholder="请选择频次" |
| 自定义cron | el-input | v-if="form.frequency==='custom'", placeholder="请输入cron表达式" |
| 负责班组 | el-select | placeholder="请选择负责班组", filterable, @change="loadStaff" |
| 巡检人员 | el-select | v-model="form.staffIds", multiple, collapse-tags, placeholder="请选择巡检人员" |
| 巡检清单 | el-select | v-model="form.checklistIds", multiple, collapse-tags, placeholder="请选择巡检清单" |
| 生效日期 | el-date-picker | type="date", value-format="YYYY-MM-DD", :disabled-date="disablePastDate" |
| 二次确认 | el-message-box | type="warning", confirmButtonText="确定", cancelButtonText="取消" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 计划名称 | 必填maxlength=50同租户内唯一 | "请输入计划名称" / "该计划名称已存在" |
| 巡检类型 | 必选 | "请选择巡检类型" |
| 巡检区域 | 必选,至少选一个 | "请选择巡检区域" |
| 频次 | 必选 | "请选择频次" |
| 自定义cron | 频次=自定义时必填cron格式校验 | "请输入cron表达式" / "cron表达式格式不正确" |
| 负责班组 | 必选 | "请选择负责班组" |
| 巡检人员 | 必选,至少选一个 | "请选择巡检人员" |
| 巡检清单 | 必选,至少选一个 | "请选择巡检清单" |
| 生效日期 | 必选,不早于当前日期 | "请选择生效日期" / "生效日期不能早于今天" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件区单行展示表格完整展示全部9列弹窗宽度600px |
| 1024-1279pxPad横屏 | 查询条件区折行两行;表格隐藏"巡检区域""巡检人员"列弹窗宽度560px |
| 768-1023pxPad竖屏 | 查询条件区垂直堆叠;表格隐藏"巡检区域""巡检人员""频次"列弹窗宽度90vw表单改为单列布局 |
---
## 页面2巡检任务看板页
**页面编号**PR-I-02-P01
**端侧归属**Web专属
**页面路径**/inspection/tasks
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 巡检管理 > 巡检任务看板 │
├──────────────────────────────────────────────────────────────────┤
│ [视图切换] 📅日历视图 📋列表视图 日期:[◀ 2026-04-16 ▶] │
├──────────────────────────────────────────────────────────────────┤
│ ── 日历视图(默认)── │
│ 1 2 3 4 5 6 7 │
│ 上午 🟢 🟢 🔴 🟢 🟡 🟢 🟢 │
│ 下午 🟢 🟡 🟢 🟢 🟢 — — │
│ 🟢=正常 🔴=异常 🟡=未执行 —=无任务 │
├──────────────────────────────────────────────────────────────────┤
│ ── 列表视图 ── │
│ 日期 | 计划名称 | 巡检人员 | 打卡时间 | 状态 | 异常数 | 操作 │
│ 04-16| 门诊楼日常| 张三 | 09:15 | 正常 | 0 | 查看 │
│ 04-16| 住院楼日常| 李四 | — | 未执行| — | — │
│ 04-15| 门诊楼日常| 张三 | 09:20 | 异常 | 2 | 查看 │
├──────────────────────────────────────────────────────────────────┤
│ [分页] 共30条 每页[20▼] < 1 2 > │
└──────────────────────────────────────────────────────────────────┘
```
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 日期 | 日期选择 | 否 | 今天 | — |
| 计划名称 | 下拉单选 | 否 | 全部 | — |
| 状态 | 下拉单选 | 否 | 全部 | 正常/异常/未执行 |
| 巡检人员 | 文本输入 | 否 | — | 模糊匹配 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 日期 | 100px | 是 | — |
| 2 | 计划名称 | 150px | 否 | — |
| 3 | 巡检人员 | 80px | 否 | — |
| 4 | 打卡时间 | 100px | 是 | 未执行显示"—" |
| 5 | 打卡方式 | 80px | 否 | 蓝牙/手动/补录 |
| 6 | 状态 | 80px | 是 | 正常(绿)/异常(红)/未执行(黄) |
| 7 | 异常数 | 70px | 否 | 点击查看异常详情 |
| 8 | 操作 | 80px | — | 查看 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 任务列表 | /api/v1/inspection-tasks | GET | 分页查询 |
| 日历数据 | /api/v1/inspection-tasks/calendar | GET | 按月返回日历数据 |
### 交互流程要求
1. **页面加载流程**:进入页面 → 默认日期为今天,视图为日历视图 → 并行调用任务列表API和日历数据API → 渲染日历视图(按月展示每日上午/下午巡检状态),列表视图渲染任务表格
2. **查询/筛选交互流程**:切换日期(点击左右箭头)→ 重新请求日历/列表数据;选择计划名称/状态/输入巡检人员 → 点击[查询] → 重新加载数据;切换日历/列表视图时无需重新请求(数据共用)
3. **表单填写与提交流程**:本页无表单提交操作,仅查询展示
4. **弹窗/抽屉交互流程**:点击日历某日某时段 → 弹出该时段巡检任务列表弹窗展示具体任务详情弹窗宽度500px
5. **行内操作流程**:列表视图点击[查看] → 跳转巡检记录详情页;异常数>0时点击异常数 → 跳转异常处理跟踪页(带筛选条件)
6. **异常与错误处理**:日历数据加载失败时日历区显示"加载失败,点击重试"列表数据为空时显示ElEmpty"暂无巡检任务"网络异常提示ElMessage.error
7. **联动/级联交互**:日历视图与列表视图数据联动,切换视图不重新请求;日期切换后日历和列表同步刷新
8. **权限控制交互表现**:无 inspection:task:view 权限时[查看]按钮隐藏,仅展示基本信息
9. **【H1 防重复请求(轻量)】**日期切换左右箭头时防抖300ms后发起请求避免快速连续点击产生冗余请求查询按钮点击后 disabled + loading态日历数据和列表数据并行加载互不阻塞视图切换日历/列表)无需重新请求。
10. **【H2 统一超时配置】**GET 任务列表/日历数据API超时15秒超时中断 + 日历区显示"加载失败,点击重试" + 列表区显示 ElEmpty 占位;>3秒的请求在各自区域内显示局部 loading 而非全屏遮罩。
11. **【H8 操作结果反馈】**数据加载完成无额外toast提示静默渲染加载失败 ElMessage.error("数据加载失败,请检查网络")(手动关闭);日历某日点击弹出详情弹窗失败时弹窗内展示错误占位。
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 视图切换 | el-radio-group + el-radio-button | v-model="viewMode", size="default" |
| 日期导航 | 自定义组件 | 左右箭头+日期显示,@prev/@next事件 |
| 日历视图 | 自定义日历组件 | 按月渲染,每日分上午/下午格子,颜色标识状态 |
| 列表视图 | el-table | stripe, border, :data="taskList" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50]" |
| 状态标签 | el-tag | 正常=success / 异常=danger / 未执行=warning |
| 日期筛选 | el-date-picker | type="date", value-format="YYYY-MM-DD" |
| 计划名称 | el-select | clearable, placeholder="全部计划" |
| 状态筛选 | el-select | clearable, placeholder="全部状态" |
| 巡检人员 | el-input | clearable, maxlength=20, placeholder="输入巡检人员" |
| 查看按钮 | el-button | type="primary", link |
| 异常数链接 | el-link | type="danger", @click="viewAbnormals" |
| 日历详情弹窗 | el-dialog | title="巡检任务详情", width="500px" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 巡检人员 | 非必填maxlength=20 | — |
| 状态 | 非必填,枚举值 | — |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 日历视图完整展示,列表视图全部列展示 |
| 1024-1279pxPad横屏 | 日历视图字号略减,列表视图隐藏"打卡方式"列 |
| 768-1023pxPad竖屏 | 日历视图改为简化周视图仅显示本周7天列表视图隐藏"打卡方式""计划名称"列,查询条件垂直堆叠 |
---
## 页面3巡检记录查询页
**页面编号**PR-I-03-P01
**端侧归属**Web专属
**页面路径**/inspection/records
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 巡检人员 | 文本输入 | 否 | — | 模糊匹配 |
| 日期范围 | 日期范围 | 否 | — | — |
| 打卡方式 | 下拉单选 | 否 | 全部 | 蓝牙/手动/补录 |
| 结果状态 | 下拉单选 | 否 | 全部 | 全部正常/有异常 |
| 补录标记 | 下拉单选 | 否 | 全部 | 正常数据/补录数据 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 巡检人员 | 80px | 否 | — |
| 2 | 计划名称 | 150px | 否 | — |
| 3 | 巡检区域 | 150px | 否 | — |
| 4 | 打卡时间 | 140px | 是 | 默认倒序 |
| 5 | 打卡方式 | 80px | 否 | 蓝牙(蓝)/手动(灰)/补录(橙) |
| 6 | 检查项数 | 70px | 否 | — |
| 7 | 异常数 | 70px | 否 | — |
| 8 | 补录标记 | 70px | 否 | 补录显示"补录"标签+原因 |
| 9 | 操作 | 120px | — | 查看详情/查看异常 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 查看详情 | inspection:task:view | 行操作 | 始终 | 跳转记录详情 |
| 查看异常 | inspection:task:view | 行操作 | 异常数>0 | 跳转异常列表 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 记录列表 | /api/v1/inspection-records | GET | 分页查询 |
| 记录详情 | /api/v1/inspection-records/{id} | GET | 含打卡信息+检查项结果+照片 |
### 交互流程要求
1. **页面加载流程**:进入页面 → 默认查询条件为空 → 调用记录列表API GET /api/v1/inspection-records → 渲染表格默认按打卡时间倒序排列每页20条
2. **查询/筛选交互流程**:输入巡检人员/选择日期范围/选择打卡方式/选择结果状态/选择补录标记 → 点击[查询] → 携带筛选参数重新请求第1页 → 点击[重置]清空条件并重新加载
3. **表单填写与提交流程**:本页无表单提交操作,仅查询展示
4. **弹窗/抽屉交互流程**:点击[查看详情] → 调用记录详情API → 弹窗展示完整巡检记录打卡信息、检查项结果、照片弹窗宽度700px使用el-tabs分为"打卡信息""检查项""照片"三个标签页
5. **行内操作流程**:点击[查看异常](异常数>0时显示→ 跳转异常处理跟踪页,自动带入该记录的异常筛选条件;补录标记列点击"补录"标签 → 弹出补录原因浮层
6. **异常与错误处理**列表数据为空时显示ElEmpty"暂无巡检记录";详情弹窗加载失败提示"记录详情加载失败"API请求失败显示ElMessage.error
7. **联动/级联交互**:打卡方式列根据值显示不同颜色标签(蓝牙-蓝/手动-灰/补录-橙);补录标记与打卡方式联动,补录方式=补录时显示补录标签
8. **权限控制交互表现**:无 inspection:task:view 权限时[查看详情][查看异常]按钮隐藏
9. **【H1 防重复请求】**:查询按钮点击后立即 disabled + loading态API返回后恢复行内[查看详情]按钮点击后该行禁用 + loading态防止重复打开弹窗分页切换 abort 上一请求再发新请求详情弹窗打开时防止同一记录重复请求详情API。
10. **【H2 统一超时配置】**GET 记录列表查询超时15秒GET 记录详情查询超时15秒超时自动中断 + 提示"请求超时..." + 按钮/弹窗恢复;>3秒显示全局 ElLoading。
11. **【H5 数据权限隔离】**:区分"暂无巡检记录"(ElEmpty)与"无权限访问"(403)403时前端拦截器统一提示"您没有权限查看巡检记录",不暴露具体数据结构。
12. **【H8 操作结果反馈】**:列表刷新静默无提示;详情弹窗加载失败弹窗内展示"记录详情加载失败,请重试"ElMessage.error 仅在主动操作失败时使用duration=0手动关闭
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 巡检人员输入 | el-input | placeholder="请输入巡检人员", clearable, maxlength=20 |
| 日期范围 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", range-separator="至" |
| 打卡方式 | el-select | clearable, placeholder="全部方式" |
| 结果状态 | el-select | clearable, placeholder="全部状态" |
| 补录标记 | el-select | clearable, placeholder="全部" |
| 列表 | el-table | stripe, border, :data="tableData" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50]" |
| 打卡方式标签 | el-tag | 蓝牙=primary / 手动=info / 补录=warning |
| 补录标记标签 | el-tag | type="warning", size="small" |
| 查看详情按钮 | el-button | type="primary", link |
| 查看异常按钮 | el-button | type="danger", link |
| 详情弹窗 | el-dialog | title="巡检记录详情", width="700px", :close-on-click-modal="true" |
| 详情标签页 | el-tabs | v-model="detailTab", type="card" |
| 打卡信息 | el-descriptions | :column="2", border |
| 检查项列表 | el-table | :data="checkItems", size="small" |
| 照片展示 | el-image | :preview-src-list="photoList", fit="cover", :lazy="true" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 巡检人员 | 非必填maxlength=20 | — |
| 日期范围 | 结束日期≥开始日期 | "结束日期不能早于开始日期" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件区水平排列表格完整展示全部9列详情弹窗宽度700px |
| 1024-1279pxPad横屏 | 查询条件区换行排列,表格隐藏"检查项数""补录标记"列详情弹窗宽度650px |
| 768-1023pxPad竖屏 | 查询条件区垂直堆叠表格仅显示巡检人员、打卡时间、状态、操作列详情弹窗宽度95vw |
---
## 页面4异常处理跟踪页
**页面编号**PR-I-04-P01
**端侧归属**Web专属
**页面路径**/inspection/abnormals
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 严重等级 | 下拉单选 | 否 | 全部 | 一般/较重/严重 |
| 处理状态 | 下拉单选 | 否 | 全部 | 待处理/已生成工单/已关闭 |
| 日期范围 | 日期范围 | 否 | — | — |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 异常编号 | 120px | 否 | — |
| 2 | 巡检记录 | 120px | 否 | 关联巡检记录 |
| 3 | 严重等级 | 80px | 是 | 一般(黄)/较重(橙)/严重(红) |
| 4 | 异常描述 | 200px | 否 | — |
| 5 | 上报人 | 80px | 否 | — |
| 6 | 上报时间 | 140px | 是 | 默认倒序 |
| 7 | 处理状态 | 100px | 否 | 待处理/已生成工单/已关闭 |
| 8 | 关联工单 | 120px | 否 | 点击跳转工单详情 |
| 9 | 操作 | 120px | — | 生成工单/查看 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 生成报修工单 | repair:list:create | 行操作 | 处理状态=待处理 | 一键生成,自动关联异常记录 |
| 查看 | inspection:task:view | 行操作 | 始终 | 查看异常详情 |
### 通知触发
| 触发操作 | 通知对象 | 通知方式 | 消息模板 | 文档来源 |
|----------|----------|----------|----------|----------|
| 异常上报 | 物业主管 | 小程序推送 | 巡检异常通知 | 01 §7.1 |
| 生成工单 | 维修人员 | 小程序推送 | 新工单通知 | 05 §5.2 (INSPECTION_ABNORMAL) |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 异常列表 | /api/v1/inspection-abnormals | GET | 分页查询 |
| 生成工单 | /api/v1/inspection-abnormals/{id}/create-order | POST | — |
### 交互流程要求
1. **页面加载流程**:进入页面 → 调用异常列表API GET /api/v1/inspection-abnormals → 渲染表格默认按上报时间倒序排列每页20条同时加载严重等级、处理状态等下拉选项
2. **查询/筛选交互流程**:选择严重等级/选择处理状态/选择日期范围 → 点击[查询] → 携带筛选参数重新请求第1页 → 点击[重置]清空条件并重新加载
3. **表单填写与提交流程**:点击[生成报修工单](处理状态=待处理时显示)→ 弹窗确认"将为此异常生成报修工单,确认?" → 确认后调用生成工单API → 成功后刷新该行状态为"已生成工单",并显示工单号
4. **弹窗/抽屉交互流程**生成工单确认弹窗宽度420px点击[查看] → 弹出异常详情弹窗,展示异常描述、照片、关联巡检记录、处理历史
5. **行内操作流程**:点击[生成报修工单] → 二次确认 → 调用API → 刷新行数据;点击[查看] → 弹窗展示详情;关联工单号可点击跳转工单详情页(新标签页)
6. **异常与错误处理**:重复生成工单提示"该异常已生成工单,不可重复操作"API请求失败显示ElMessage.error列表无数据时显示ElEmpty"暂无异常记录"
7. **联动/级联交互**:处理状态=待处理时才显示"生成报修工单"按钮;生成工单后状态自动变为"已生成工单",关联工单号可点击跳转
8. **权限控制交互表现**:无 repair:list:create 权限时"生成报修工单"按钮隐藏;无 inspection:task:view 权限时"查看"按钮隐藏
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 严重等级筛选 | el-select | clearable, placeholder="全部等级" |
| 处理状态筛选 | el-select | clearable, placeholder="全部状态" |
| 日期范围 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", range-separator="至" |
| 列表 | el-table | stripe, border, :data="tableData" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50]" |
| 严重等级标签 | el-tag | 一般=warning / 较重=danger / 严重=danger, effect="dark" |
| 处理状态标签 | el-tag | 待处理=warning / 已生成工单=success / 已关闭=info |
| 生成工单按钮 | el-button | type="primary", link, v-if="row.status==='pending'" |
| 查看按钮 | el-button | type="primary", link |
| 关联工单链接 | el-link | type="primary", @click="openOrderDetail" |
| 确认弹窗 | el-message-box | type="warning", confirmButtonText="确认生成", cancelButtonText="取消" |
| 详情弹窗 | el-dialog | title="异常详情", width="600px", :close-on-click-modal="true" |
| 详情展示 | el-descriptions | :column="2", border |
| 异常照片 | el-image | :preview-src-list="photoList", fit="cover" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 日期范围 | 结束日期≥开始日期 | "结束日期不能早于开始日期" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件区水平排列表格完整展示全部9列详情弹窗宽度600px |
| 1024-1279pxPad横屏 | 查询条件区换行排列,表格隐藏"巡检记录""异常描述"列详情弹窗宽度560px |
| 768-1023pxPad竖屏 | 查询条件区垂直堆叠表格仅显示异常编号、严重等级、处理状态、操作列详情弹窗宽度95vw |
---
## 页面5巡检区域管理页
**页面编号**PR-I-05-P01
**端侧归属**Web专属
**页面路径**/inspection/areas
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 巡检管理 > 巡检区域管理 │
├──────────────────────────────────────────────────────────────────┤
│ [操作栏] [新增区域] [批量导入] │
├──────────────────────────────────────────────────────────────────┤
│ [树形结构+列表] │
│ ┌──────────────┐ ┌──────────────────────────────────────────┐ │
│ │ 主院区 │ │ 区域:主院区 > 门诊楼 > 1层 │ │
│ │ ├ 门诊楼 │ │ 蓝牙BeaconB-001 (在线) │ │
│ │ │ ├ 1层 │ │ Beacon UUIDxxxx-xxxx-xxxx │ │
│ │ │ ├ 2层 │ │ 关联设备:灯控系统、空调系统 │ │
│ │ │ └ 3层 │ │ 巡检计划:门诊楼日常巡检 │ │
│ │ └ 住院楼 │ │ [编辑] [删除]│ │
│ └──────────────┘ └──────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
```
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 新增区域 | inspection:area:create | 操作栏 | 始终 | 弹窗 |
| 编辑 | inspection:area:update | 详情区 | 始终 | — |
| 删除 | inspection:area:delete | 详情区 | 无关联计划时 | 二次确认 |
### 表单字段(新增/编辑弹窗)
| 字段名 | 控件类型 | 必填 | 默认值 | 数据来源 | 校验规则 |
|--------|----------|------|--------|----------|----------|
| 区域名称 | 文本输入 | 是 | — | 自填 | 最大30字 |
| 上级区域 | 级联选择 | 是 | — | 区域树 | — |
| 蓝牙Beacon | 下拉单选 | 是 | — | 蓝牙设备管理(在线设备) | — |
| 关联设备 | 下拉多选 | 否 | — | 设备列表 | — |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 区域树 | /api/v1/inspection-areas/tree | GET | 树形结构 |
| 新增 | /api/v1/inspection-areas | POST | — |
| 编辑 | /api/v1/inspection-areas/{id} | PUT | — |
| 删除 | /api/v1/inspection-areas/{id} | DELETE | — |
### 交互流程要求
1. **页面加载流程**:进入页面 → 调用区域树API GET /api/v1/inspection-areas/tree → 渲染左侧树形结构 → 默认选中第一个项目节点 → 右侧展示该节点详情蓝牙Beacon信息、关联设备、巡检计划
2. **查询/筛选交互流程**:点击树形节点 → 右侧实时刷新展示选中区域详情;树形节点支持搜索过滤
3. **表单填写与提交流程**:点击[新增区域] → 弹窗表单 → 填写区域名称、选择上级区域级联、选择蓝牙Beacon、选择关联设备 → 点击确定 → 前端校验通过 → 调用新增API → 成功后关闭弹窗并刷新树形结构
4. **弹窗/抽屉交互流程**:新增/编辑弹窗宽度520px上级区域级联选择器懒加载展开点击遮罩层不关闭
5. **行内操作流程**:点击[编辑] → 弹窗回填当前区域数据 → 修改后提交 → 刷新右侧详情;点击[删除] → 二次确认"删除后不可恢复,确认删除?" → 确认后调用DELETE API → 刷新树形有关联计划的区域不可删除删除按钮置灰并Tooltip提示
6. **异常与错误处理**:区域名称重复提示"该区域名称已存在";有关联计划时删除按钮置灰并提示"该区域存在关联巡检计划,不可删除";网络异常显示全局错误提示
7. **联动/级联交互**上级区域级联选择器联动下级选项选择项目后区域选项刷新选择区域后楼栋选项刷新逐级展开选择蓝牙Beacon后展示设备在线状态
8. **权限控制交互表现**:无 inspection:area:create 权限时[新增区域]按钮隐藏;无 inspection:area:update 权限时[编辑]按钮隐藏;无 inspection:area:delete 权限时[删除]按钮隐藏
9. **【H1 防重复请求】**树形节点点击防抖200ms避免频繁切换导致右侧反复请求[新增]/[编辑]弹窗提交按钮 :loading + disabled[删除]操作点击后该节点禁用 + loading态区域树初始化加载时显示 skeleton 骨架屏。
10. **【H2 统一超时配置】**GET 区域树查询超时15秒POST 新增超时30秒PUT 编辑超时30秒DELETE 删除超时30秒超时中断 + "请求超时..." + 按钮恢复。
11. **【H3 操作确认机制】**[删除]操作前必须弹出 `ElMessageBox.confirm("确定要删除「{区域名称}」吗?删除后将不可恢复", {type: 'error'})` 使用 error 级别强调不可逆;有关联计划的区域删除按钮已置灰(由业务逻辑控制),不触发此确认框。
12. **【H4 脏数据检测】**[编辑]弹窗打开时 deep clone 当前区域数据作为快照基准isDirty 检测;取消/关闭/遮罩层点击时若 isDirty 弹出"修改未保存,确定关闭?"确认框type:'warning'[新增]弹窗同理。
13. **【H8 操作结果反馈】**:新增/编辑成功 `ElMessage.success`2s→ 关闭弹窗 → 刷新树形结构+右侧详情;删除成功 `ElMessage.success("删除成功")`2s→ 刷新树;失败 `ElMessage.error`(手动关闭)。
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 区域树 | el-tree | :data="areaTree", node-key="id", :props="{label:'name',children:'children'}", highlight-current, :expand-on-click-node="false", @node-click="handleNodeClick" |
| 新增区域按钮 | el-button | type="primary", icon="Plus" |
| 编辑按钮 | el-button | type="primary", link |
| 删除按钮 | el-button | type="danger", link, :disabled="hasPlanBind" |
| 新增/编辑弹窗 | el-dialog | :title="dialogTitle", width="520px", :close-on-click-modal="false" |
| 区域名称 | el-input | maxlength=30, show-word-limit, placeholder="请输入区域名称" |
| 上级区域 | el-cascader | :props="{checkStrictly:true, emitPath:false, value:'id', label:'name'}", placeholder="请选择上级区域", clearable, filterable |
| 蓝牙Beacon | el-select | filterable, placeholder="请选择蓝牙Beacon", clearable |
| 关联设备 | el-select | v-model="form.deviceIds", multiple, collapse-tags, placeholder="请选择关联设备" |
| 详情展示 | el-descriptions | :column="2", border |
| Beacon状态标签 | el-tag | 在线=success / 离线=danger |
| 删除确认 | el-message-box | type="warning", confirmButtonText="确认", cancelButtonText="取消" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 区域名称 | 必填maxlength=30 | "请输入区域名称" / "区域名称不能超过30个字符" |
| 上级区域 | 必填 | "请选择上级区域" |
| 蓝牙Beacon | 必填 | "请选择蓝牙Beacon" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 左侧树形面板固定宽度280px右侧详情区自适应弹窗宽度520px |
| 1024-1279pxPad横屏 | 左侧树形面板宽度缩减至220px右侧详情区自适应弹窗宽度480px |
| 768-1023pxPad竖屏 | 树形面板折叠为顶部下拉选择器详情区全宽展示弹窗宽度90vw |
---
## 页面6数据补录与补录审核页
**页面编号**PR-I-06-P01 / PR-I-07-P01
**端侧归属**Web专属
**页面路径**/inspection/supplement
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 审核状态 | 下拉单选 | 否 | 全部 | 待审核/已通过/已驳回 |
| 补录人 | 文本输入 | 否 | — | 模糊匹配 |
| 补录原因 | 下拉单选 | 否 | 全部 | 蓝牙故障/系统异常/定位失败/其他 |
| 日期范围 | 日期范围 | 否 | — | — |
### 补录数据标记规范
| 标记项 | 说明 |
|--------|------|
| is_supplement | true |
| supplement_reason | 蓝牙故障/系统异常/定位失败/其他 |
| supplement_remark | 补录详细说明 |
| supplement_audit_status | 待审核/通过/驳回 |
| supplement_auditor | 审核人ID |
| supplement_audit_time | 审核时间 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 审核 | inspection:supplement:approve | 行操作 | 审核状态=待审核 | 通过/驳回弹窗 |
| 查看 | inspection:supplement:view | 行操作 | 始终 | 查看补录详情 |
### 通知触发
| 触发操作 | 通知对象 | 通知方式 | 消息模板 | 文档来源 |
|----------|----------|----------|----------|----------|
| 审核通过 | 补录人 | 小程序推送 | 补录审核通过通知 | 03-物业公司 §2.2 |
| 审核驳回 | 补录人 | 小程序推送 | 补录审核驳回通知,需重新执行 | 03-物业公司 §2.2 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 补录列表 | /api/v1/inspection-records/supplements | GET | 分页查询 |
| 审核 | /api/v1/inspection-records/supplements/{id}/approve | POST | — |
### 交互流程要求
1. **页面加载流程**:进入页面 → 调用补录列表API GET /api/v1/inspection-records/supplements → 渲染补录数据表格默认按补录时间倒序排列每页20条
2. **查询/筛选交互流程**:选择审核状态/输入补录人/选择补录原因/选择日期范围 → 点击[查询] → 携带筛选参数重新请求第1页 → 点击[重置]清空条件并重新加载
3. **表单填写与提交流程**:本页无新增表单,补录数据由小程序端提交
4. **弹窗/抽屉交互流程**:点击[审核](审核状态=待审核时显示)→ 弹出审核弹窗,选择"通过"或"驳回",驳回时必填驳回原因 → 确认后调用审核API → 成功后关闭弹窗并刷新列表;点击[查看] → 弹出补录详情弹窗,展示补录原因、详细说明、巡检记录信息等
5. **行内操作流程**:点击[审核] → 弹窗选择通过/驳回 → 提交 → 刷新该行审核状态和审核人/审核时间;点击[查看] → 弹窗展示完整补录信息
6. **异常与错误处理**:审核已审核过的记录时提示"该记录已审核"API请求失败显示ElMessage.error列表无数据时显示ElEmpty"暂无补录记录"
7. **联动/级联交互**:审核状态筛选影响列表展示;补录原因枚举来源于系统配置(蓝牙故障/系统异常/定位失败/其他)
8. **权限控制交互表现**:无 inspection:supplement:approve 权限时[审核]按钮隐藏;无 inspection:supplement:view 权限时[查看]按钮隐藏
9. **【H1 防重复请求】**:查询按钮点击后立即 disabled + loading态API返回后恢复行内[审核]按钮点击后该行禁用 + loading态防止重复审核分页切换 abort 上一请求再发新请求。
10. **【H2 统一超时配置】**GET 补录列表查询超时15秒POST 审核操作超时30秒超时自动中断 + "请求超时,请稍后重试" + 按钮恢复可用;>3秒显示全局 ElLoading。
11. **【H3 操作确认机制】**:审核操作前弹出 `ElMessageBox.confirm("确定要「{通过/驳回}」该条补录记录吗?驳回后将通知补录人重新执行巡检", {type: 通过?'info':'warning'})`,含操作后果说明;驳回原因必填校验在确认前执行。
12. **【H5 数据权限隔离】**:区分"暂无补录记录"(ElEmpty)与"无权限访问"(403)403时前端拦截器统一提示"您没有权限查看补录数据",不展示任何记录信息。
13. **【H8 操作结果反馈】**:审核成功 `ElMessage.success("审核成功")`2s→ 关闭弹窗 → silent 刷新该行审核状态/审核人/审核时间;审核失败 `ElMessage.error`(手动关闭);网络异常提示含"重试"按钮可重新触发上次操作。
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 审核状态筛选 | el-select | clearable, placeholder="全部状态" |
| 补录人输入 | el-input | clearable, maxlength=20, placeholder="请输入补录人" |
| 补录原因筛选 | el-select | clearable, placeholder="全部原因" |
| 日期范围 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", range-separator="至" |
| 列表 | el-table | stripe, border, :data="tableData" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50]" |
| 审核状态标签 | el-tag | 待审核=warning / 已通过=success / 已驳回=danger |
| 审核按钮 | el-button | type="primary", link, v-if="row.auditStatus==='pending'" |
| 查看按钮 | el-button | type="primary", link |
| 审核弹窗 | el-dialog | title="审核补录", width="500px", :close-on-click-modal="false" |
| 审核结果 | el-radio-group | v-model="auditForm.result" |
| 驳回原因 | el-input | type="textarea", :rows="3", maxlength=200, show-word-limit, v-if="auditForm.result==='reject'" |
| 详情弹窗 | el-dialog | title="补录详情", width="600px" |
| 详情展示 | el-descriptions | :column="2", border |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 审核结果 | 必选 | "请选择审核结果" |
| 驳回原因 | 驳回时必填maxlength=200 | "请填写驳回原因" |
| 日期范围 | 结束日期≥开始日期 | "结束日期不能早于开始日期" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件区水平排列表格完整展示全部列弹窗宽度500px/600px |
| 1024-1279pxPad横屏 | 查询条件区换行排列,表格隐藏"补录时间"列弹窗宽度460px/560px |
| 768-1023pxPad竖屏 | 查询条件区垂直堆叠表格仅显示补录人、补录原因、审核状态、操作列弹窗宽度90vw |
---
## 需求追溯
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|------------|----------|----------|----------|----------|
| PR-I-01 | 巡检计划管理 | 02-物业公司 §2 / 03-物业公司 §2.1 | 计划创建→自动生成每日任务 | 巡检任务看板 |
| PR-I-02 | 巡检任务看板 | 02-物业公司 §2 / 03-物业公司 §2.1 | — | 小程序端今日巡检(MP-I-01) |
| PR-I-03 | 巡检记录查询 | 02-物业公司 §2 / 03-物业公司 §2.1 | — | 统计报表→巡检统计 |
| PR-I-04 | 异常处理跟踪 | 02-物业公司 §2 / 03-物业公司 §2.1 | 异常→一键生成报修工单 | 在线报修(工单创建) |
| PR-I-05 | 巡检区域管理 | 02-物业公司 §2 | 区域→蓝牙Beacon绑定 | 系统配置→蓝牙设备管理 |
| PR-I-06 | 数据补录 | 02-物业公司 §2 / 03-物业公司 §2.2 | 补录→审核→生效 | 小程序端异常数据补录(MP-I-06) |
| PR-I-07 | 补录审核 | 02-物业公司 §2 / 03-物业公司 §2.2 | 审核结果→通知补录人 | 操作日志→补录日志 |
## 业务规则
1. **任务自动生成**巡检计划创建后系统按频次自动生成每日巡检任务来源03-物业公司 §2.1
2. **蓝牙打卡**小程序端巡检必须连接蓝牙Beacon后才可打卡和拍照策略=REQUIRED时失败进入补录模式来源01 §9 / 06 §4.4
3. **蓝牙双模式**:策略=OPTIONAL时允许手动打卡(check_type=MANUAL)无需补录审核来源06 §4.4 / 03-物业公司 §10
4. **异常上报→工单**巡检发现异常可一键生成报修工单触发INSPECTION_ABNORMAL事件来源05 §5.2 / 03-物业公司 §2.1
5. **补录审核流程**补录数据需主管审核审核通过生效驳回需重新执行来源03-物业公司 §2.2
6. **补录数据标记**所有补录记录标记is_supplement=true补录原因、审核状态等完整记录来源03-物业公司 §2.3
7. **数据权限**主管仅看本班组数据员工仅看本人数据来源01 §1.3