21 KiB
21 KiB
巡检管理模块重构规格文档
1. 概述
1.1 背景
当前巡检管理模块存在以下问题需要重构:
- 巡检点管理不够独立,缺少批量创建和二维码/NFC支持
- 巡检计划缺少路径编排功能
- 缺少执行人排班管理
- 任务详情缺少路径比对和问题标记
1.2 目标
- 完善巡检点管理功能,支持批量创建、二维码生成、NFC写入
- 实现巡检计划路径编排,支持巡检点顺序和间隔时间设置
- 增加执行人排班管理,支持按周循环排班
- 完善任务详情,支持路径比对和问题标记
- 支持巡检计划复制功能
2. 功能需求
2.1 巡检点管理(独立Tab页)
2.1.1 批量创建巡检点
需求描述:支持批量创建多个巡检点,采用混合模式。
交互设计:
- 提供表格形式的批量创建界面
- 支持手动输入每个巡检点名称
- 支持自动编号功能:输入前缀+起始编号,系统自动生成如"巡检点-001、巡检点-002..."
- 支持混合模式:空白行可自动填充编号
数据结构:
interface BatchCreateInspectionPointRequest {
points: Array<{
name: string; // 巡检点名称
location?: string; // 位置描述
type: string; // 巡检点类型
spaceNodeId?: string; // 关联空间节点
longitude?: number; // 经度
latitude?: number; // 纬度
}>;
autoNumbering?: {
enabled: boolean;
prefix: string; // 名称前缀
startNumber: number; // 起始编号
padding: number; // 编号位数,如3表示001
};
}
2.1.2 二维码生成
需求描述:每个巡检点可生成唯一二维码,存储完整信息。
二维码内容(JSON格式):
{
"type": "INSPECTION_POINT",
"id": "uuid",
"code": "PT202502200001",
"name": "巡检点名称",
"projectId": "project-uuid",
"location": "位置描述",
"createdAt": "2025-02-20T10:00:00Z",
"signature": "数字签名(可选,用于防伪)"
}
功能要求:
- 支持单个巡检点二维码生成和下载
- 支持批量生成二维码(ZIP打包下载)
- 二维码格式:QR Code,尺寸可配置(默认200x200px)
- 支持打印模板:A4纸每页10个二维码
2.1.3 NFC写入
需求描述:支持将巡检点信息写入NFC贴片。
NFC数据格式:
- 使用NDEF格式存储
- 存储与二维码相同的JSON数据
- 支持手机NFC功能写入(待定具体实现)
功能要求:
- 提供NFC写入界面(Web NFC API或移动端App)
- 支持批量写入模式
- 记录NFC标签ID用于验证
2.2 巡检计划路径编排
2.2.1 路径编排功能
需求描述:将已录入的巡检点进行先后顺序编排,形成巡检路径。
数据结构:
interface InspectionPathPoint {
pointId: string; // 巡检点ID
pointName: string; // 巡检点名称
pointCode: string; // 巡检点编码
order: number; // 顺序号
minIntervalMinutes: number; // 与上一个巡检点的最小间隔时间(分钟)
estimatedMinutes: number; // 预计停留时间(分钟)
location?: string; // 位置描述
}
interface InspectionPath {
id: string;
planId: string;
points: InspectionPathPoint[];
totalEstimatedMinutes: number; // 总预计时间
createdAt: string;
updatedAt: string;
}
交互设计:
- 提供拖拽排序界面
- 左侧显示可选巡检点列表
- 右侧显示已选巡检点路径
- 支持设置每个巡检点的最小间隔时间
- 实时显示总预计时间
2.2.2 最小间隔时间
需求描述:设置相邻巡检点之间的最小到达时间间隔。
业务规则:
- 从上一个巡检点打卡到下一个巡检点打卡的最小时间差
- 如果实际间隔小于设置值,标记为"时间间隔不足"问题
- 可设置默认值(如5分钟),也可单独设置每个点
2.3 巡检计划周期设置
2.3.1 多种周期类型
需求描述:支持多种巡检周期类型。
周期类型:
- 每日(DAILY)
- 每周(WEEKLY)- 可指定星期几
- 每两周(BIWEEKLY)
- 每月(MONTHLY)- 可指定日期
- 每季度(QUARTERLY)
- 每半年(SEMIANNUAL)
- 每年(YEARLY)
2.3.2 周期内最少完成次数
需求描述:设置每个周期内需要完成的最少巡检次数。
数据结构:
interface InspectionPlanCycle {
cycle: string; // 周期类型
cycleDay?: number; // 执行日期(如每月几号)
cycleDays?: number[]; // 执行日期数组(如每周几)
executeTime: string; // 执行时间(HH:mm)
minCompletionsPerCycle: number; // 周期内最少完成次数
endDate?: string; // 计划结束日期
}
2.4 巡检计划负责人和执行人
2.4.1 角色定义
负责人:
- 管理巡检计划
- 监督巡检任务完成情况
- 查看巡检报告和统计数据
- 调整计划和排班
执行人:
- 完成巡检任务
- 扫码打卡
- 上报巡检问题
2.4.2 人员选择器
需求描述:选择负责人和执行人时,只能选择符合条件的人员。
筛选条件:
- 本部门及下级部门的人员
- 具备本项目执行巡检任务权限的人员
数据结构:
interface InspectionPlanPersonnel {
planId: string;
managerId: string; // 负责人ID
managerName: string; // 负责人姓名
executorIds: string[]; // 执行人ID列表
executorNames: string[]; // 执行人姓名列表
}
2.5 执行人排班管理
2.5.1 按周循环排班
需求描述:为多个执行人设置按周循环的排班。
数据结构:
interface InspectionSchedule {
id: string;
planId: string;
weekSchedules: WeekSchedule[];
createdAt: string;
updatedAt: string;
}
interface WeekSchedule {
dayOfWeek: number; // 1-7 表示周一到周日
executorId: string; // 执行人ID
executorName: string; // 执行人姓名
timeSlot?: string; // 时间段(可选)
}
业务规则:
- 每天可指定一个执行人
- 未指定的日期默认由所有执行人轮流
- 只要求多人里有一人完成任务即可标记完成
2.5.2 任务完成判定
需求描述:多执行人情况下,只要有一人完成即标记任务完成。
判定逻辑:
- 根据排班表确定当天执行人
- 当天执行人扫码打卡完成巡检
- 系统自动标记任务为完成状态
- 记录实际执行人信息
2.6 任务详情路径比对
2.6.1 时间线对比展示
需求描述:在任务详情中展示计划路径与实际路径的对比。
数据结构:
interface InspectionTaskPath {
taskId: string;
plannedPath: PlannedPathPoint[];
actualPath: ActualPathPoint[];
issues: PathIssue[];
summary: TaskSummary;
}
interface PlannedPathPoint {
order: number;
pointId: string;
pointName: string;
minIntervalMinutes: number;
estimatedMinutes: number;
}
interface ActualPathPoint {
order: number;
pointId: string;
pointName: string;
scannedAt: string; // 扫码时间
scannedBy: string; // 扫码人
scannedByName: string;
intervalFromPrevious: number; // 与上一个点的实际间隔(分钟)
issues?: string[]; // 问题列表
}
interface PathIssue {
type: 'ORDER_ERROR' | 'TIME_INTERVAL_ERROR' | 'POINT_SKIPPED' | 'INSPECTION_ISSUE';
severity: 'WARNING' | 'ERROR';
pointId?: string;
pointName?: string;
description: string;
details?: any;
}
interface TaskSummary {
totalPoints: number;
completedPoints: number;
skippedPoints: number;
orderErrors: number;
timeIntervalErrors: number;
inspectionIssues: number;
startedAt: string;
completedAt: string;
totalDuration: number; // 总耗时(分钟)
}
交互设计:
- 使用时间线组件展示
- 计划路径用虚线表示
- 实际路径用实线表示
- 问题点用红色标记
- 点击节点显示详细信息
2.6.2 问题标记
需求描述:标记路径问题和巡检问题。
问题类型:
-
路径问题:
- 顺序错误(ORDER_ERROR):未按计划顺序巡检
- 时间间隔不足(TIME_INTERVAL_ERROR):两点之间时间过短
- 巡检点跳过(POINT_SKIPPED):未巡检计划中的点
-
巡检问题:
- 设备故障
- 环境异常
- 安全隐患
- 其他问题
问题展示:
- 在任务详情顶部显示问题简报
- 问题点用不同颜色标记
- 支持查看问题详情和照片
2.7 巡检计划复制
2.7.1 复制功能
需求描述:支持复制巡检计划,创建新计划。
复制内容:
- 计划基本信息(名称需修改)
- 巡检点路径
- 执行人设置
- 排班配置
不复制内容:
- 计划ID
- 创建时间
- 已生成的任务
API设计:
POST /api/v1/ops/inspection/plans/{id}/copy
Request: {
name: string; // 新计划名称
startDate?: string; // 新计划开始日期
endDate?: string; // 新计划结束日期
}
Response: InspectionPlan
3. 数据库设计
3.1 新增表
3.1.1 巡检路径表 (ops_inspection_path)
CREATE TABLE ops_inspection_path (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL,
plan_id UUID NOT NULL,
name VARCHAR(100),
description VARCHAR(500),
total_estimated_minutes INTEGER DEFAULT 0,
enabled BOOLEAN NOT NULL DEFAULT true,
version BIGINT DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by UUID,
updated_by UUID,
CONSTRAINT fk_path_plan FOREIGN KEY (plan_id) REFERENCES ops_inspection_plan(id) ON DELETE CASCADE
);
CREATE INDEX idx_path_project ON ops_inspection_path(project_id);
CREATE INDEX idx_path_plan ON ops_inspection_path(plan_id);
3.1.2 巡检路径点表 (ops_inspection_path_point)
CREATE TABLE ops_inspection_path_point (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
path_id UUID NOT NULL,
point_id UUID NOT NULL,
point_order INTEGER NOT NULL,
min_interval_minutes INTEGER DEFAULT 5,
estimated_minutes INTEGER DEFAULT 5,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_point_path FOREIGN KEY (path_id) REFERENCES ops_inspection_path(id) ON DELETE CASCADE,
CONSTRAINT fk_point_inspection FOREIGN KEY (point_id) REFERENCES ops_inspection_point(id)
);
CREATE INDEX idx_path_point_path ON ops_inspection_path_point(path_id);
CREATE INDEX idx_path_point_order ON ops_inspection_path_point(path_id, point_order);
3.1.3 执行人排班表 (ops_inspection_schedule)
CREATE TABLE ops_inspection_schedule (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL,
plan_id UUID NOT NULL,
executor_id UUID NOT NULL,
executor_name VARCHAR(100),
day_of_week INTEGER NOT NULL CHECK (day_of_week BETWEEN 1 AND 7),
time_slot VARCHAR(50),
enabled BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by UUID,
updated_by UUID,
CONSTRAINT fk_schedule_plan FOREIGN KEY (plan_id) REFERENCES ops_inspection_plan(id) ON DELETE CASCADE
);
CREATE INDEX idx_schedule_project ON ops_inspection_schedule(project_id);
CREATE INDEX idx_schedule_plan ON ops_inspection_schedule(plan_id);
CREATE INDEX idx_schedule_day ON ops_inspection_schedule(plan_id, day_of_week);
3.1.4 任务打卡记录表 (ops_inspection_checkin)
CREATE TABLE ops_inspection_checkin (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL,
task_id UUID NOT NULL,
point_id UUID NOT NULL,
point_order INTEGER,
checkin_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
checkin_type VARCHAR(20) NOT NULL, -- QR_CODE, NFC
executor_id UUID NOT NULL,
executor_name VARCHAR(100),
longitude DECIMAL(10, 7),
latitude DECIMAL(10, 7),
location_verified BOOLEAN DEFAULT false,
issues JSONB,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_checkin_task FOREIGN KEY (task_id) REFERENCES ops_inspection_task(id) ON DELETE CASCADE,
CONSTRAINT fk_checkin_point FOREIGN KEY (point_id) REFERENCES ops_inspection_point(id)
);
CREATE INDEX idx_checkin_project ON ops_inspection_checkin(project_id);
CREATE INDEX idx_checkin_task ON ops_inspection_checkin(task_id);
CREATE INDEX idx_checkin_point ON ops_inspection_checkin(point_id);
CREATE INDEX idx_checkin_time ON ops_inspection_checkin(checkin_time);
3.2 修改表
3.2.1 巡检计划表 (ops_inspection_plan)
ALTER TABLE ops_inspection_plan ADD COLUMN IF NOT EXISTS min_completions_per_cycle INTEGER DEFAULT 1;
ALTER TABLE ops_inspection_plan ADD COLUMN IF NOT EXISTS executor_ids JSONB;
ALTER TABLE ops_inspection_plan ADD COLUMN IF NOT EXISTS executor_names JSONB;
ALTER TABLE ops_inspection_plan ADD COLUMN IF NOT EXISTS path_id UUID;
3.2.2 巡检点表 (ops_inspection_point)
ALTER TABLE ops_inspection_point ADD COLUMN IF NOT EXISTS qr_data JSONB;
ALTER TABLE ops_inspection_point ADD COLUMN IF NOT EXISTS nfc_data JSONB;
3.2.3 巡检任务表 (ops_inspection_task)
ALTER TABLE ops_inspection_task ADD COLUMN IF NOT EXISTS path_id UUID;
ALTER TABLE ops_inspection_task ADD COLUMN IF NOT EXISTS planned_path JSONB;
ALTER TABLE ops_inspection_task ADD COLUMN IF NOT EXISTS actual_path JSONB;
ALTER TABLE ops_inspection_task ADD COLUMN IF NOT EXISTS path_issues JSONB;
ALTER TABLE ops_inspection_task ADD COLUMN IF NOT EXISTS task_summary JSONB;
4. API设计
4.1 巡检点管理API
4.1.1 批量创建巡检点
POST /api/v1/ops/inspection/points/batch
Request: BatchCreateInspectionPointRequest
Response: InspectionPoint[]
4.1.2 生成二维码
POST /api/v1/ops/inspection/points/{id}/generate-qrcode
Response: { qrCode: string, qrData: string, qrImage: string }
4.1.3 批量生成二维码
POST /api/v1/ops/inspection/points/batch-qrcode
Request: { pointIds: string[] }
Response: { downloadUrl: string }
4.1.4 NFC写入准备
GET /api/v1/ops/inspection/points/{id}/nfc-data
Response: { nfcData: string, pointId: string, pointName: string }
4.2 巡检路径API
4.2.1 创建巡检路径
POST /api/v1/ops/inspection/plans/{planId}/path
Request: {
name: string;
points: Array<{
pointId: string;
minIntervalMinutes: number;
estimatedMinutes: number;
}>;
}
Response: InspectionPath
4.2.2 更新巡检路径
PUT /api/v1/ops/inspection/plans/{planId}/path
Request: {
name: string;
points: Array<{
pointId: string;
minIntervalMinutes: number;
estimatedMinutes: number;
}>;
}
Response: InspectionPath
4.2.3 获取巡检路径
GET /api/v1/ops/inspection/plans/{planId}/path
Response: InspectionPath
4.3 排班管理API
4.3.1 设置排班
POST /api/v1/ops/inspection/plans/{planId}/schedule
Request: {
schedules: Array<{
dayOfWeek: number;
executorId: string;
executorName: string;
timeSlot?: string;
}>;
}
Response: InspectionSchedule[]
4.3.2 获取排班
GET /api/v1/ops/inspection/plans/{planId}/schedule
Response: InspectionSchedule[]
4.4 打卡API
4.4.1 扫码打卡
POST /api/v1/ops/inspection/checkin
Request: {
taskId: string;
qrCode?: string;
nfcTag?: string;
longitude?: number;
latitude?: number;
}
Response: InspectionCheckin
4.4.2 获取打卡记录
GET /api/v1/ops/inspection/tasks/{taskId}/checkins
Response: InspectionCheckin[]
4.5 任务路径比对API
4.5.1 获取任务路径比对
GET /api/v1/ops/inspection/tasks/{taskId}/path-comparison
Response: InspectionTaskPath
4.6 计划复制API
4.6.1 复制计划
POST /api/v1/ops/inspection/plans/{id}/copy
Request: {
name: string;
startDate?: string;
endDate?: string;
}
Response: InspectionPlan
5. 前端页面设计
5.1 巡检点管理页面
5.1.1 页面结构
巡检点管理
├── 搜索栏
│ ├── 关键词搜索
│ ├── 类型筛选
│ └── 状态筛选
├── 操作栏
│ ├── 新增巡检点
│ ├── 批量创建
│ └── 批量生成二维码
├── 数据表格
│ ├── 巡检点编码
│ ├── 巡检点名称
│ ├── 类型
│ ├── 位置
│ ├── 二维码
│ ├── NFC状态
│ ├── 状态
│ └── 操作
└── 批量创建弹窗
├── 表格形式输入
├── 自动编号设置
└── 导入功能
5.1.2 二维码弹窗
二维码详情
├── 巡检点信息
├── 二维码图片
├── 下载按钮
└── 打印按钮
5.2 巡检计划页面
5.2.1 页面结构
巡检计划
├── 搜索栏
├── 操作栏
│ ├── 新增计划
│ └── 生成任务
├── 数据表格
│ ├── 计划编码
│ ├── 计划名称
│ ├── 类型
│ ├── 周期
│ ├── 最少完成次数
│ ├── 负责人
│ ├── 执行人数
│ ├── 状态
│ └── 操作
└── 计划详情/编辑弹窗
├── 基本信息 Tab
├── 巡检路径 Tab
├── 执行人 Tab
└── 排班管理 Tab
5.2.2 路径编排界面
路径编排
├── 左侧:可选巡检点列表
│ ├── 搜索
│ └── 巡检点列表(可拖拽)
├── 右侧:已选巡检点路径
│ ├── 路径列表(可拖拽排序)
│ ├── 每个点设置间隔时间
│ └── 总预计时间显示
└── 操作按钮
├── 保存
└── 重置
5.2.3 排班管理界面
排班管理
├── 周视图
│ ├── 周一至周日
│ └── 每天显示执行人
├── 执行人列表
│ └── 勾选参与排班的人员
└── 快速排班
├── 轮流排班
└── 指定排班
5.3 任务详情页面
5.3.1 页面结构
任务详情
├── 任务简报
│ ├── 任务状态
│ ├── 完成进度
│ └── 问题摘要
├── 路径比对
│ ├── 时间线视图
│ ├── 计划路径(虚线)
│ ├── 实际路径(实线)
│ └── 问题标记(红色)
├── 打卡记录列表
│ ├── 序号
│ ├── 巡检点
│ ├── 打卡时间
│ ├── 执行人
│ ├── 间隔时间
│ └── 状态
└── 问题详情
├── 问题描述
├── 问题照片
└── 处理状态
6. 开发任务
6.1 后端开发任务
-
数据库变更
- 创建新表
- 修改现有表结构
- 编写数据迁移脚本
-
实体和Repository
- 创建InspectionPath实体
- 创建InspectionPathPoint实体
- 创建InspectionSchedule实体
- 创建InspectionCheckin实体
- 修改InspectionPlan实体
- 修改InspectionPoint实体
- 修改InspectionTask实体
-
Service层
- 实现批量创建巡检点服务
- 实现二维码生成服务
- 实现NFC数据准备服务
- 实现路径编排服务
- 实现排班管理服务
- 实现打卡服务
- 实现路径比对服务
- 实现计划复制服务
-
Controller层
- 实现巡检点批量API
- 实现二维码API
- 实现NFC API
- 实现路径API
- 实现排班API
- 实现打卡API
- 实现路径比对API
- 实现计划复制API
6.2 前端开发任务
-
巡检点管理页面
- 实现批量创建组件
- 实现二维码生成和显示
- 实现NFC写入界面
-
巡检计划页面
- 实现路径编排组件
- 实现执行人选择器
- 实现排班管理组件
-
任务详情页面
- 实现时间线对比组件
- 实现问题标记展示
- 实现简报组件
-
API集成
- 集成所有新增API
6.3 测试任务
-
单元测试
- 后端Service层测试
- 前端组件测试
-
集成测试
- API集成测试
- 业务流程测试
-
E2E测试
- 巡检点批量创建流程
- 路径编排流程
- 排班管理流程
- 打卡流程
- 路径比对流程
7. 风险和注意事项
7.1 技术风险
- NFC写入:Web NFC API支持有限,可能需要移动端App支持
- 二维码批量生成:大量二维码生成可能影响性能,需要异步处理
- 路径比对算法:需要考虑各种边界情况
7.2 业务风险
- 排班冲突:同一执行人可能被分配到多个计划
- 路径变更:计划执行中修改路径需要处理已生成任务
- 数据迁移:现有数据需要兼容新结构
7.3 注意事项
- 保持向后兼容性
- 做好数据备份
- 分阶段上线
- 充分测试边界情况