1363 lines
52 KiB
Markdown
1363 lines
52 KiB
Markdown
# 运营与服务域 - 详细设计
|
||
|
||
**文档编号**: DETAIL-OPS
|
||
**版本**: v1.0
|
||
**模块**: module-wo + module-mdm(备件/能耗部分)
|
||
**生成日期**: 2026-05-18
|
||
**数据来源**: ether-pms/module-wo + module-mdm 实际代码 + REVERSE-OPS.md 反推文档
|
||
|
||
---
|
||
|
||
## 一、功能点清单
|
||
|
||
| 功能ID | 功能名称 | 优先级 | 实现状态 | 对应需求ID |
|
||
|--------|----------|--------|----------|------------|
|
||
| OPS-001 | 工单创建 | P0 | 已完成 | 02-OPERATIONS-001 |
|
||
| OPS-002 | 工单查询(分页) | P0 | 已完成 | 02-OPERATIONS-001 |
|
||
| OPS-003 | 工单详情 | P0 | 已完成 | 02-OPERATIONS-001 |
|
||
| OPS-004 | 工单更新 | P1 | 已完成 | 02-OPERATIONS-001 |
|
||
| OPS-005 | 工单删除(逻辑删除) | P1 | 已完成 | 02-OPERATIONS-001 |
|
||
| OPS-006 | 工单派单 | P0 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-007 | 工单开始执行 | P0 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-008 | 工单完成 | P0 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-009 | 工单验收 | P0 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-010 | 工单取消 | P1 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-011 | 工单挂起 | P1 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-012 | 工单恢复 | P1 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-013 | 工单退回 | P1 | 已完成 | 02-OPERATIONS-002 |
|
||
| OPS-014 | 工单统计 | P1 | 已完成 | 02-OPERATIONS-003 |
|
||
| OPS-015 | 工单明细查询 | P1 | 已完成 | 02-OPERATIONS-004 |
|
||
| OPS-016 | 工单明细批量添加 | P1 | 已完成 | 02-OPERATIONS-004 |
|
||
| OPS-017 | 维保任务创建 | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-018 | 维保任务查询 | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-019 | 维保任务分配 | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-020 | 维保任务开始执行 | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-021 | 维保任务完成(简版) | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-022 | 维保任务完成(详版) | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-023 | 维保任务验收 | P0 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-024 | 维保任务取消 | P1 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-025 | 维保任务评分 | P2 | 已完成 | 02-OPERATIONS-005 |
|
||
| OPS-026 | 维保任务统计 | P1 | 已完成 | 02-OPERATIONS-006 |
|
||
| OPS-027 | 维保计划管理 | P1 | 已完成 | 02-OPERATIONS-007 |
|
||
| OPS-028 | 巡检模板管理 | P1 | 已完成 | 02-OPERATIONS-008 |
|
||
| OPS-029 | 巡检模板复制 | P2 | 已完成 | 02-OPERATIONS-008 |
|
||
| OPS-030 | 备件CRUD | P0 | 已完成 | 02-OPERATIONS-009 |
|
||
| OPS-031 | 备件分类管理 | P1 | 已完成 | 02-OPERATIONS-009 |
|
||
| OPS-032 | 备件入库 | P0 | 已完成 | 02-OPERATIONS-010 |
|
||
| OPS-033 | 备件出库 | P0 | 已完成 | 02-OPERATIONS-010 |
|
||
| OPS-034 | 备件低库存预警 | P1 | 已完成 | 02-OPERATIONS-010 |
|
||
| OPS-035 | 备件出入库记录 | P1 | 已完成 | 02-OPERATIONS-010 |
|
||
| OPS-036 | 能源计量点管理 | P1 | 已完成 | 02-OPERATIONS-011 |
|
||
| OPS-037 | 能耗抄表记录 | P0 | 已完成 | 02-OPERATIONS-012 |
|
||
| OPS-038 | 能耗按类型统计 | P1 | 已完成 | 02-OPERATIONS-013 |
|
||
| OPS-039 | 单位面积能耗 | P2 | 已完成 | 02-OPERATIONS-013 |
|
||
| OPS-040 | 消息通知系统 | P1 | 未实现 | 02-OPERATIONS-014 |
|
||
| OPS-041 | 工单流转记录 | P2 | 未实现 | 02-OPERATIONS-015 |
|
||
| OPS-042 | SLA监控 | P2 | 未实现 | 02-OPERATIONS-016 |
|
||
| OPS-043 | 智能派单 | P3 | 未实现 | 02-OPERATIONS-017 |
|
||
|
||
---
|
||
|
||
## 二、数据结构设计
|
||
|
||
### 2.1 WorkOrder(工单)
|
||
|
||
**表名**: `ops_work_order`
|
||
**实体类**: `com.ether.pms.ops.entity.WorkOrder`
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| workNo | VARCHAR(50) | 是 | 自动生成 | 工单编号,格式: WO-YYYYMMDD-XXXX,UNIQUE |
|
||
| source | ENUM | 是 | - | 工单来源(6种) |
|
||
| type | ENUM | 是 | - | 工单类型(6种) |
|
||
| priority | ENUM | 否 | MEDIUM | 优先级(4级) |
|
||
| status | ENUM | 否 | PENDING | 工单状态(8种) |
|
||
| previousStatus | ENUM | 否 | - | 前一状态(挂起恢复用) |
|
||
| title | VARCHAR(200) | 是 | - | 工单标题 |
|
||
| description | VARCHAR(2000) | 否 | - | 工单描述 |
|
||
| projectId | UUID | 是 | - | 所属项目 |
|
||
| equipmentId | UUID | 否 | - | 关联设备 |
|
||
| spaceId | UUID | 否 | - | 关联空间 |
|
||
| planId | UUID | 否 | - | 关联维保计划 |
|
||
| triggerType | ENUM | 否 | - | 触发类型(4种) |
|
||
| assignedTo | VARCHAR(200) | 否 | - | 负责人 |
|
||
| assignedVendor | VARCHAR(200) | 否 | - | 服务商 |
|
||
| assignedDate | DATE | 否 | - | 派单日期 |
|
||
| actualStart | TIMESTAMP | 否 | - | 实际开始时间 |
|
||
| actualEnd | TIMESTAMP | 否 | - | 实际结束时间 |
|
||
| actualHours | DECIMAL(6,2) | 否 | - | 实际工时(小时) |
|
||
| faultCause | VARCHAR(2000) | 否 | - | 故障原因 |
|
||
| solution | VARCHAR(5000) | 否 | - | 解决方案 |
|
||
| result | VARCHAR(2000) | 否 | - | 处理结果 |
|
||
| laborCost | DECIMAL(12,2) | 否 | - | 人工费 |
|
||
| partsCost | DECIMAL(12,2) | 否 | - | 备件费 |
|
||
| totalCost | DECIMAL(12,2) | 否 | - | 总费用 |
|
||
| completedBy | VARCHAR(200) | 否 | - | 完成人 |
|
||
| completedDate | DATE | 否 | - | 完成日期 |
|
||
| verifiedBy | VARCHAR(200) | 否 | - | 验收人 |
|
||
| verifiedDate | DATE | 否 | - | 验收日期 |
|
||
| rating | INTEGER | 否 | - | 评分(1-5星) |
|
||
| remark | VARCHAR(1000) | 否 | - | 备注 |
|
||
| photos | JSONB | 否 | - | 照片URL列表(List\<String\>) |
|
||
| signature | VARCHAR(2000) | 否 | - | 签名 |
|
||
| isDeleted | BOOLEAN | 否 | false | 逻辑删除标记 |
|
||
| createdAt | TIMESTAMP | 是 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 是 | now() | 更新时间 |
|
||
| createdBy | VARCHAR(200) | 否 | - | 创建人 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| Source | OWNER | 业主报修 |
|
||
| | MAINTENANCE | 维保计划 |
|
||
| | INSPECTION | 巡检触发 |
|
||
| | FAULT | 故障触发 |
|
||
| | REGULATORY | 法规巡检 |
|
||
| | MANUAL | 手动创建 |
|
||
| Type | REPAIR | 维修 |
|
||
| | INSPECTION | 巡检 |
|
||
| | SECURITY | 安保 |
|
||
| | CLEANING | 保洁 |
|
||
| | PROPERTY | 物业 |
|
||
| | CONSULTATION | 咨询 |
|
||
| Priority | LOW / MEDIUM / HIGH / URGENT | 低/中/高/紧急 |
|
||
| Status | PENDING / ASSIGNED / IN_PROGRESS / SUSPENDED / RETURNED / COMPLETED / VERIFIED / CANCELLED | 见状态机 |
|
||
| TriggerType | PLAN / INSPECTION / FAULT / MANUAL | 计划/巡检/故障/手动 |
|
||
|
||
**索引**:
|
||
|
||
| 索引名 | 字段 | 用途 |
|
||
|--------|------|------|
|
||
| idx_wo_project_status | project_id, status | 项目+状态查询 |
|
||
| idx_wo_priority_status | priority, status | 优先级+状态查询 |
|
||
| idx_wo_plan_createdat | plan_id, created_at | 计划关联查询 |
|
||
| idx_wo_status_createdat | status, created_at | 状态+时间查询 |
|
||
| idx_wo_createdat_desc | created_at DESC | 时间倒序 |
|
||
|
||
### 2.2 WorkOrderItem(工单明细)
|
||
|
||
**表名**: `ops_work_order_item`
|
||
**实体类**: `com.ether.pms.ops.entity.WorkOrderItem`
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| workOrderId | UUID | 是 | - | 所属工单ID |
|
||
| itemType | ENUM | 是 | - | 明细类型(3种) |
|
||
| itemName | VARCHAR(200) | 是 | - | 明细名称 |
|
||
| quantity | DECIMAL(10,2) | 否 | 1 | 数量 |
|
||
| unit | VARCHAR(50) | 否 | - | 单位 |
|
||
| unitPrice | DECIMAL(12,2) | 否 | - | 单价 |
|
||
| totalPrice | DECIMAL(12,2) | 否 | - | 总价 |
|
||
| isNormal | BOOLEAN | 否 | - | 是否正常 |
|
||
| observation | VARCHAR(2000) | 否 | - | 观察记录 |
|
||
| suggestion | VARCHAR(2000) | 否 | - | 建议 |
|
||
| sortOrder | INTEGER | 否 | 0 | 排序序号 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| ItemType | PART | 备件 |
|
||
| | INSPECTION_ITEM | 巡检项 |
|
||
| | CHECKPOINT | 检查点 |
|
||
|
||
### 2.3 MaintenancePlan(维保计划)
|
||
|
||
**表名**: `ops_maintenance_plan`
|
||
**实体类**: `com.ether.pms.ops.entity.MaintenancePlan`
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| planCode | VARCHAR(50) | 是 | 自动生成 | 计划编码(UNIQUE) |
|
||
| planName | VARCHAR(200) | 是 | - | 计划名称 |
|
||
| planContent | VARCHAR(5000) | 否 | - | 计划内容 |
|
||
| projectId | UUID | 否 | - | 所属项目 |
|
||
| equipmentId | UUID | 是 | - | 关联设备 |
|
||
| planType | ENUM | 是 | - | 计划类型(2种) |
|
||
| cycleDays | INTEGER | 否 | - | 周期天数 |
|
||
| estimatedHours | DECIMAL(6,2) | 否 | - | 预估工时 |
|
||
| assignedVendor | VARCHAR(200) | 否 | - | 指定服务商 |
|
||
| status | ENUM | 否 | ACTIVE | 计划状态(3种) |
|
||
| lastDate | DATE | 否 | - | 上次执行日期 |
|
||
| nextDate | DATE | 否 | - | 下次执行日期 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 否 | now() | 更新时间 |
|
||
| createdBy | VARCHAR(200) | 否 | - | 创建人 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| PlanType | PREVENTIVE | 预防性维护 |
|
||
| | CORRECTIVE | 纠正性维护 |
|
||
| PlanStatus | ACTIVE | 启用 |
|
||
| | INACTIVE | 停用 |
|
||
| | SUSPENDED | 暂停 |
|
||
|
||
### 2.4 MaintenanceTask(维保任务)
|
||
|
||
**表名**: `ops_maintenance_task`
|
||
**实体类**: `com.ether.pms.ops.entity.MaintenanceTask`
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| taskNo | VARCHAR(50) | 否 | 自动生成 | 任务编号,格式: EQ-YYYYMMDD-XXXX,UNIQUE |
|
||
| planId | UUID | 否 | - | 关联维保计划ID |
|
||
| equipmentId | UUID | 是 | - | 关联设备ID |
|
||
| projectId | UUID | 否 | - | 所属项目 |
|
||
| taskType | ENUM | 否 | - | 任务类型(3种) |
|
||
| triggerType | ENUM | 否 | - | 触发类型(4种) |
|
||
| priority | ENUM | 否 | 自动判定 | 优先级(4级) |
|
||
| status | ENUM | 否 | PENDING | 任务状态(6种) |
|
||
| title | VARCHAR(200) | 否 | - | 任务标题 |
|
||
| description | VARCHAR(2000) | 否 | - | 任务描述 |
|
||
| assignedTo | VARCHAR(200) | 否 | - | 负责人 |
|
||
| assignedVendor | VARCHAR(200) | 否 | - | 服务商 |
|
||
| assignedDate | DATE | 否 | - | 派单日期 |
|
||
| actualStart | TIMESTAMP | 否 | - | 实际开始时间 |
|
||
| actualEnd | TIMESTAMP | 否 | - | 实际结束时间 |
|
||
| actualHours | DECIMAL(6,2) | 否 | - | 实际工时 |
|
||
| faultCause | VARCHAR(2000) | 否 | - | 故障原因 |
|
||
| solution | VARCHAR(5000) | 否 | - | 解决方案 |
|
||
| result | VARCHAR(2000) | 否 | - | 处理结果 |
|
||
| partsUsed | JSONB | 否 | - | 使用备件列表(List\<Map\>) |
|
||
| laborCost | DECIMAL(12,2) | 否 | - | 人工费 |
|
||
| partsCost | DECIMAL(12,2) | 否 | - | 备件费 |
|
||
| totalCost | DECIMAL(12,2) | 否 | - | 总费用 |
|
||
| completedBy | VARCHAR(200) | 否 | - | 完成人 |
|
||
| completedDate | DATE | 否 | - | 完成日期 |
|
||
| verifiedBy | VARCHAR(200) | 否 | - | 验收人 |
|
||
| verifiedDate | DATE | 否 | - | 验收日期 |
|
||
| rating | INTEGER | 否 | - | 评分(1-5) |
|
||
| remark | VARCHAR(1000) | 否 | - | 备注 |
|
||
| photos | JSONB | 否 | - | 照片URL列表 |
|
||
| signature | VARCHAR(2000) | 否 | - | 签名 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 否 | now() | 更新时间 |
|
||
| createdBy | VARCHAR(200) | 否 | - | 创建人 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| TaskType | PREVENTIVE | 预防性维护 |
|
||
| | CORRECTIVE | 纠正性维护 |
|
||
| | EMERGENCY | 紧急维修 |
|
||
| TriggerType | PLAN | 计划触发 |
|
||
| | INSPECTION | 巡检触发 |
|
||
| | FAULT | 故障触发 |
|
||
| | MANUAL | 手动创建 |
|
||
| Priority | LOW / MEDIUM / HIGH / URGENT | 低/中/高/紧急 |
|
||
| Status | PENDING / ASSIGNED / IN_PROGRESS / COMPLETED / VERIFIED / CANCELLED | 见状态机 |
|
||
|
||
**partsUsed JSONB 结构**:
|
||
|
||
```json
|
||
[
|
||
{
|
||
"partsId": "uuid",
|
||
"partsName": "备件名称",
|
||
"quantity": 2,
|
||
"unitPrice": 100.00,
|
||
"totalPrice": 200.00
|
||
}
|
||
]
|
||
```
|
||
|
||
**索引**:
|
||
|
||
| 索引名 | 字段 | 用途 |
|
||
|--------|------|------|
|
||
| idx_mt_equipment_status | equipment_id, status | 设备+状态查询 |
|
||
| idx_mt_project_status | project_id, status | 项目+状态查询 |
|
||
| idx_mt_plan_createdat | plan_id, created_at | 计划关联查询 |
|
||
| idx_mt_status_assigneddate | status, assigned_date | 状态+派单日期查询 |
|
||
|
||
### 2.5 InspectionTemplate(巡检模板)
|
||
|
||
**表名**: `ops_inspection_template`
|
||
**实体类**: `com.ether.pms.mdm.entity.InspectionTemplate`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| templateCode | VARCHAR(50) | 是 | 自动生成 | 模板编码(UNIQUE) |
|
||
| templateName | VARCHAR(200) | 是 | - | 模板名称 |
|
||
| description | VARCHAR(2000) | 否 | - | 描述 |
|
||
| projectId | UUID | 否 | - | 所属项目 |
|
||
| spaceId | UUID | 否 | - | 关联空间 |
|
||
| category | VARCHAR(50) | 否 | - | 分类 |
|
||
| status | ENUM | 否 | ACTIVE | 模板状态(2种) |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 否 | now() | 更新时间 |
|
||
| createdBy | VARCHAR(200) | 否 | - | 创建人 |
|
||
| items | List\<InspectionItem\> | - | - | 检查项列表(@Transient,非持久化) |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| TemplateStatus | ACTIVE | 启用 |
|
||
| | INACTIVE | 停用 |
|
||
|
||
### 2.6 InspectionItem(巡检项)
|
||
|
||
**表名**: `ops_inspection_item`
|
||
**实体类**: `com.ether.pms.mdm.entity.InspectionItem`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| templateId | UUID | 是 | - | 所属模板ID |
|
||
| itemName | VARCHAR(200) | 是 | - | 检查项名称 |
|
||
| description | VARCHAR(2000) | 否 | - | 描述 |
|
||
| checkMethod | VARCHAR(2000) | 否 | - | 检查方法 |
|
||
| standard | VARCHAR(2000) | 否 | - | 检查标准 |
|
||
| isMandatory | BOOLEAN | 否 | true | 是否必检 |
|
||
| isNormalRequired | BOOLEAN | 否 | true | 是否需要正常判定 |
|
||
| sortOrder | INTEGER | 否 | 0 | 排序序号 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
|
||
### 2.7 SparePart(备件)
|
||
|
||
**表名**: `ops_spare_part`
|
||
**实体类**: `com.ether.pms.mdm.entity.SparePart`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| projectId | UUID | 是 | - | 所属项目 |
|
||
| sparePartCode | VARCHAR | 是 | 自动生成 | 备件编码(UNIQUE),格式: SP+yyyyMMddHHmmss |
|
||
| sparePartName | VARCHAR | 是 | - | 备件名称 |
|
||
| categoryId | UUID | 否 | - | 分类ID |
|
||
| specification | VARCHAR(500) | 否 | - | 规格 |
|
||
| unit | VARCHAR(50) | 是 | - | 单位 |
|
||
| safeStock | INTEGER | 否 | 0 | 安全库存 |
|
||
| currentStock | INTEGER | 否 | 0 | 当前库存 |
|
||
| unitPrice | DECIMAL(10,2) | 否 | - | 单价 |
|
||
| supplier | VARCHAR(200) | 否 | - | 供应商 |
|
||
| supplierContact | VARCHAR | 否 | - | 供应商联系方式 |
|
||
| location | VARCHAR(200) | 否 | - | 存放位置 |
|
||
| remarks | VARCHAR(1000) | 否 | - | 备注 |
|
||
| status | ENUM | 是 | ACTIVE | 状态(2种) |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 否 | now() | 更新时间 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 |
|
||
|------|-----|------|
|
||
| Status | ACTIVE | 启用 |
|
||
| | INACTIVE | 停用 |
|
||
|
||
**索引**:
|
||
|
||
| 索引名 | 字段 | 用途 |
|
||
|--------|------|------|
|
||
| idx_sp_project_status | project_id, status | 项目+状态查询 |
|
||
|
||
### 2.8 SparePartCategory(备件分类)
|
||
|
||
**表名**: `ops_spare_part_category`
|
||
**实体类**: `com.ether.pms.mdm.entity.SparePartCategory`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| parentId | UUID | 否 | - | 父分类ID(支持树形结构) |
|
||
| categoryCode | VARCHAR | 是 | 自动生成 | 分类编码(UNIQUE),格式: CC+yyyyMMddHHmmss |
|
||
| categoryName | VARCHAR | 是 | - | 分类名称 |
|
||
| description | VARCHAR(500) | 否 | - | 描述 |
|
||
| sortOrder | INTEGER | 否 | - | 排序序号 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
|
||
### 2.9 SparePartRecord(备件出入库记录)
|
||
|
||
**表名**: `ops_spare_part_record`
|
||
**实体类**: `com.ether.pms.mdm.entity.SparePartRecord`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| recordCode | VARCHAR | 是 | 自动生成 | 记录编码(UNIQUE),格式: REC+类型+yyyyMMddHHmmss |
|
||
| recordType | ENUM | 是 | - | 记录类型(4种) |
|
||
| sparePartId | UUID | 是 | - | 备件ID |
|
||
| quantity | INTEGER | 是 | - | 数量 |
|
||
| balance | INTEGER | 是 | - | 操作后余额 |
|
||
| relatedOrderId | UUID | 否 | - | 关联工单ID |
|
||
| recordedBy | UUID | 否 | - | 操作人 |
|
||
| recordDate | TIMESTAMP | 否 | now() | 操作时间 |
|
||
| remarks | VARCHAR(1000) | 否 | - | 备注 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 | 说明 |
|
||
|------|-----|------|------|
|
||
| RecordType | IN | 入库 | 库存增加 |
|
||
| | OUT | 出库 | 库存减少,可关联工单 |
|
||
| | CHECK | 盘点 | 库存校准 |
|
||
| | ADJUST | 调整 | 库存调整 |
|
||
|
||
### 2.10 EnergyMeter(能源计量点)
|
||
|
||
**表名**: `ops_energy_meter`
|
||
**实体类**: `com.ether.pms.mdm.entity.EnergyMeter`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| projectId | UUID | 是 | - | 所属项目 |
|
||
| meterCode | VARCHAR | 是 | 自动生成 | 计量点编码(UNIQUE) |
|
||
| meterName | VARCHAR | 是 | - | 计量点名称 |
|
||
| energyType | ENUM | 是 | - | 能源类型(6种) |
|
||
| spaceNodeId | UUID | 否 | - | 关联空间节点 |
|
||
| installationLocation | VARCHAR | 否 | - | 安装位置 |
|
||
| ratedCapacity | DECIMAL(10,2) | 否 | - | 额定容量 |
|
||
| unitPrice | DECIMAL(10,4) | 否 | - | 单价 |
|
||
| status | ENUM | 是 | ACTIVE | 状态(2种) |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
| updatedAt | TIMESTAMP | 否 | now() | 更新时间 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 | 说明 |
|
||
|------|-----|------|------|
|
||
| EnergyType | LIGHTING | 照明插座用电 | 建筑分项能耗分类 |
|
||
| | HVAC | 空调用电 | 建筑分项能耗分类 |
|
||
| | POWER | 动力用电 | 建筑分项能耗分类 |
|
||
| | SPECIAL | 特殊用电 | 建筑分项能耗分类 |
|
||
| | WATER | 给排水 | 水耗计量 |
|
||
| | GAS | 燃气 | 气耗计量 |
|
||
| Status | ACTIVE | 启用 | 可正常抄表 |
|
||
| | INACTIVE | 停用 | 不可抄表 |
|
||
|
||
### 2.11 EnergyConsumption(能耗记录)
|
||
|
||
**表名**: `ops_energy_consumption`
|
||
**实体类**: `com.ether.pms.mdm.entity.EnergyConsumption`(位于module-mdm)
|
||
|
||
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| id | UUID | 是 | 自动生成 | 主键 |
|
||
| projectId | UUID | 是 | - | 项目ID |
|
||
| meterId | UUID | 是 | - | 计量点ID |
|
||
| consumptionDate | DATE | 是 | - | 消耗日期 |
|
||
| previousReading | DECIMAL(12,2) | 否 | - | 上次读数 |
|
||
| currentReading | DECIMAL(12,2) | 否 | - | 当前读数 |
|
||
| consumption | DECIMAL(12,2) | 是 | - | 消耗量 = currentReading - previousReading |
|
||
| amount | DECIMAL(10,2) | 否 | - | 费用 = consumption x unitPrice |
|
||
| recordedBy | UUID | 否 | - | 抄表人 |
|
||
| recordMethod | ENUM | 否 | MANUAL | 抄表方式(2种) |
|
||
| remarks | VARCHAR(1000) | 否 | - | 备注 |
|
||
| createdAt | TIMESTAMP | 否 | now() | 创建时间 |
|
||
|
||
**枚举定义**:
|
||
|
||
| 枚举 | 值 | 中文 | 说明 |
|
||
|------|-----|------|------|
|
||
| RecordMethod | MANUAL | 手动录入 | 人工抄表 |
|
||
| | IOT | IoT自动采集 | 自动采集(预留) |
|
||
|
||
**索引**:
|
||
|
||
| 索引名 | 字段 | 用途 |
|
||
|--------|------|------|
|
||
| idx_ec_meter_date | meter_id, consumption_date | 计量点+日期查询 |
|
||
| idx_ec_project_date | project_id, consumption_date | 项目+日期查询 |
|
||
|
||
### 2.12 ER关系图
|
||
|
||
```mermaid
|
||
erDiagram
|
||
MaintenancePlan ||--o{ MaintenanceTask : "1:N planId"
|
||
MaintenancePlan }o--|| Equipment : "equipmentId"
|
||
WorkOrder ||--o{ WorkOrderItem : "1:N workOrderId"
|
||
WorkOrder }o--o| MaintenancePlan : "planId"
|
||
WorkOrder }o--o| Equipment : "equipmentId"
|
||
InspectionTemplate ||--o{ InspectionItem : "1:N templateId"
|
||
SparePartCategory ||--o{ SparePart : "1:N categoryId"
|
||
SparePart ||--o{ SparePartRecord : "1:N sparePartId"
|
||
EnergyMeter ||--o{ EnergyConsumption : "1:N meterId"
|
||
|
||
WorkOrder {
|
||
UUID id PK
|
||
String workNo UK
|
||
Source source
|
||
Type type
|
||
Priority priority
|
||
Status status
|
||
Status previousStatus
|
||
UUID projectId FK
|
||
UUID equipmentId FK
|
||
UUID planId FK
|
||
}
|
||
|
||
WorkOrderItem {
|
||
UUID id PK
|
||
UUID workOrderId FK
|
||
ItemType itemType
|
||
String itemName
|
||
BigDecimal quantity
|
||
BigDecimal totalPrice
|
||
}
|
||
|
||
MaintenancePlan {
|
||
UUID id PK
|
||
String planCode UK
|
||
String planName
|
||
PlanType planType
|
||
Integer cycleDays
|
||
PlanStatus status
|
||
UUID equipmentId FK
|
||
}
|
||
|
||
MaintenanceTask {
|
||
UUID id PK
|
||
String taskNo UK
|
||
UUID planId FK
|
||
UUID equipmentId FK
|
||
TaskType taskType
|
||
TriggerType triggerType
|
||
Priority priority
|
||
Status status
|
||
}
|
||
|
||
InspectionTemplate {
|
||
UUID id PK
|
||
String templateCode UK
|
||
String templateName
|
||
String category
|
||
TemplateStatus status
|
||
}
|
||
|
||
InspectionItem {
|
||
UUID id PK
|
||
UUID templateId FK
|
||
String itemName
|
||
String checkMethod
|
||
String standard
|
||
Boolean isMandatory
|
||
}
|
||
|
||
SparePart {
|
||
UUID id PK
|
||
String sparePartCode UK
|
||
String sparePartName
|
||
UUID categoryId FK
|
||
Integer currentStock
|
||
Integer safeStock
|
||
}
|
||
|
||
SparePartRecord {
|
||
UUID id PK
|
||
String recordCode UK
|
||
RecordType recordType
|
||
UUID sparePartId FK
|
||
Integer quantity
|
||
Integer balance
|
||
UUID relatedOrderId FK
|
||
}
|
||
|
||
EnergyMeter {
|
||
UUID id PK
|
||
String meterCode UK
|
||
String meterName
|
||
EnergyType energyType
|
||
BigDecimal unitPrice
|
||
}
|
||
|
||
EnergyConsumption {
|
||
UUID id PK
|
||
UUID meterId FK
|
||
LocalDate consumptionDate
|
||
BigDecimal consumption
|
||
BigDecimal amount
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、API设计
|
||
|
||
### 3.1 WorkOrderController
|
||
|
||
**基础路径**: `/api/wo/work-orders`
|
||
**控制器类**: `com.ether.pms.ops.controller.WorkOrderController`
|
||
|
||
#### 工单 CRUD
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/` | 创建工单 | WorkOrder | ApiResponse\<WorkOrder\> | OPS-001 |
|
||
| GET | `/` | 查询工单列表(分页) | QueryParams | ApiResponse\<PageResponse\<WorkOrder\>\> | OPS-002 |
|
||
| GET | `/{id}` | 获取工单详情 | - | ApiResponse\<WorkOrder\> | OPS-003 |
|
||
| PUT | `/{id}` | 更新工单 | WorkOrder | ApiResponse\<WorkOrder\> | OPS-004 |
|
||
| DELETE | `/{id}` | 删除工单(逻辑删除) | - | ApiResponse\<Void\> | OPS-005 |
|
||
|
||
**查询参数**(GET /):
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| projectId | UUID | 否 | - | 按项目筛选 |
|
||
| equipmentId | UUID | 否 | - | 按设备筛选 |
|
||
| source | Source | 否 | - | 按来源筛选 |
|
||
| type | Type | 否 | - | 按类型筛选 |
|
||
| status | Status | 否 | - | 按状态筛选 |
|
||
| priority | Priority | 否 | - | 按优先级筛选 |
|
||
| assignedTo | String | 否 | - | 按负责人筛选 |
|
||
| keyword | String | 否 | - | 关键词搜索 |
|
||
| page | int | 否 | 0 | 页码 |
|
||
| size | int | 否 | 20 | 每页大小 |
|
||
|
||
#### 工单状态流转
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/{id}/assign` | 派单 | AssignRequest | ApiResponse\<WorkOrder\> | OPS-006 |
|
||
| POST | `/{id}/start` | 开始执行 | - | ApiResponse\<WorkOrder\> | OPS-007 |
|
||
| POST | `/{id}/complete` | 完成工单 | WorkOrder | ApiResponse\<WorkOrder\> | OPS-008 |
|
||
| POST | `/{id}/verify` | 验收工单 | VerifyRequest | ApiResponse\<WorkOrder\> | OPS-009 |
|
||
| POST | `/{id}/cancel` | 取消工单 | - | ApiResponse\<WorkOrder\> | OPS-010 |
|
||
| POST | `/{id}/suspend` | 挂起工单 | - | ApiResponse\<WorkOrder\> | OPS-011 |
|
||
| POST | `/{id}/resume` | 恢复工单 | - | ApiResponse\<WorkOrder\> | OPS-012 |
|
||
| POST | `/{id}/return` | 退回工单 | - | ApiResponse\<WorkOrder\> | OPS-013 |
|
||
|
||
**请求体定义**:
|
||
|
||
```java
|
||
// 派单请求
|
||
AssignRequest {
|
||
String assignedTo; // 负责人
|
||
String assignedVendor; // 服务商
|
||
LocalDate assignedDate; // 派单日期
|
||
}
|
||
|
||
// 验收请求
|
||
VerifyRequest {
|
||
String verifiedBy; // 验收人
|
||
String remark; // 备注
|
||
Integer rating; // 评分(1-5)
|
||
}
|
||
```
|
||
|
||
#### 工单统计与明细
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| GET | `/stats` | 工单统计 | - | ApiResponse\<WorkOrderStatsDTO\> | OPS-014 |
|
||
| GET | `/{id}/items` | 获取工单明细 | - | ApiResponse\<List\<WorkOrderItem\>\> | OPS-015 |
|
||
| POST | `/{id}/items` | 批量添加工单明细 | List\<WorkOrderItem\> | ApiResponse\<WorkOrder\> | OPS-016 |
|
||
|
||
**WorkOrderStatsDTO**:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| total | long | 工单总数 |
|
||
| pending | long | 待分配数 |
|
||
| assigned | long | 已派单数 |
|
||
| inProgress | long | 执行中数 |
|
||
| completed | long | 已完成数 |
|
||
| verified | long | 已验收数 |
|
||
| cancelled | long | 已取消数 |
|
||
| suspended | long | 已挂起数 |
|
||
| returned | long | 已退回数 |
|
||
| completedToday | long | 今日完成数 |
|
||
| createdToday | long | 今日创建数 |
|
||
| overdue | long | 逾期数 |
|
||
| bySource | Map\<String, Long\> | 按来源分布 |
|
||
| byType | Map\<String, Long\> | 按类型分布 |
|
||
| byPriority | Map\<String, Long\> | 按优先级分布 |
|
||
|
||
### 3.2 MaintenanceTaskController
|
||
|
||
**基础路径**: `/api/ops/maintenance-tasks`
|
||
**控制器类**: `com.ether.pms.ops.controller.MaintenanceTaskController`
|
||
|
||
#### 维保任务 CRUD
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/` | 创建维保任务 | MaintenanceTask | ApiResponse\<MaintenanceTask\> | OPS-017 |
|
||
| GET | `/` | 查询维保任务列表 | QueryParams | ApiResponse\<List\<MaintenanceTask\>\> | OPS-018 |
|
||
| GET | `/{id}` | 获取任务详情 | - | ApiResponse\<MaintenanceTask\> | OPS-018 |
|
||
| PUT | `/{id}` | 更新任务 | MaintenanceTask | ApiResponse\<MaintenanceTask\> | OPS-018 |
|
||
| DELETE | `/{id}` | 删除任务(逻辑删除,设为CANCELLED) | - | ApiResponse\<Void\> | OPS-024 |
|
||
|
||
**查询参数**(GET /):
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| equipmentId | UUID | 否 | 按设备筛选 |
|
||
| planId | UUID | 否 | 按计划筛选 |
|
||
| status | Status | 否 | 按状态筛选 |
|
||
| priority | Priority | 否 | 按优先级筛选 |
|
||
| assignedTo | String | 否 | 按负责人筛选 |
|
||
| overdueDate | LocalDate | 否 | 逾期截止日期 |
|
||
|
||
> 查询参数互斥优先级:equipmentId > planId > status > priority > assignedTo > overdueDate
|
||
|
||
#### 维保任务状态流转
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/{id}/assign` | 分配任务 | AssignRequest | ApiResponse\<MaintenanceTask\> | OPS-019 |
|
||
| POST | `/{id}/start` | 开始执行 | - | ApiResponse\<MaintenanceTask\> | OPS-020 |
|
||
| POST | `/{id}/complete` | 完成任务(简版) | CompleteRequest | ApiResponse\<MaintenanceTask\> | OPS-021 |
|
||
| POST | `/{id}/complete-details` | 完成任务(详版) | MaintenanceTask | ApiResponse\<MaintenanceTask\> | OPS-022 |
|
||
| POST | `/{id}/verify` | 验收任务 | VerifyRequest | ApiResponse\<MaintenanceTask\> | OPS-023 |
|
||
| POST | `/{id}/cancel` | 取消任务 | - | ApiResponse\<MaintenanceTask\> | OPS-024 |
|
||
| POST | `/{id}/rate` | 评分 | rating (query param) | ApiResponse\<MaintenanceTask\> | OPS-025 |
|
||
|
||
**请求体定义**:
|
||
|
||
```java
|
||
// 分配请求
|
||
AssignRequest {
|
||
String assignedTo;
|
||
LocalDate assignedDate;
|
||
}
|
||
|
||
// 完成请求(简版)
|
||
CompleteRequest {
|
||
String result;
|
||
BigDecimal actualHours;
|
||
BigDecimal cost;
|
||
String completedBy;
|
||
}
|
||
|
||
// 验收请求
|
||
VerifyRequest {
|
||
String verifiedBy;
|
||
String remark;
|
||
Integer rating;
|
||
}
|
||
```
|
||
|
||
#### 维保任务统计
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| GET | `/stats` | 任务统计 | - | ApiResponse\<MaintenanceTaskStatsDTO\> | OPS-026 |
|
||
|
||
**MaintenanceTaskStatsDTO**:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| total | long | 任务总数 |
|
||
| pending | long | 待分配数 |
|
||
| assigned | long | 已派单数 |
|
||
| inProgress | long | 执行中数 |
|
||
| completed | long | 已完成数 |
|
||
| verified | long | 已验收数 |
|
||
| cancelled | long | 已取消数 |
|
||
| completedToday | long | 今日完成数 |
|
||
| createdToday | long | 今日创建数 |
|
||
| overdue | long | 逾期数 |
|
||
| avgCompleteHours | BigDecimal | 平均完成工时 |
|
||
| avgRating | BigDecimal | 平均评分 |
|
||
| byPriority | Map\<String, Long\> | 按优先级分布 |
|
||
| byTriggerType | Map\<String, Long\> | 按触发类型分布 |
|
||
|
||
### 3.3 InspectionTemplateController
|
||
|
||
**基础路径**: `/api/ops/inspection-templates`
|
||
**控制器类**: `com.ether.pms.mdm.controller.InspectionTemplateController`(位于module-mdm)
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| GET | `/` | 按项目查询模板 | projectId | ApiResponse\<List\<InspectionTemplate\>\> | OPS-028 |
|
||
| POST | `/` | 创建模板 | InspectionTemplate | ApiResponse\<InspectionTemplate\> | OPS-028 |
|
||
| GET | `/{id}` | 获取模板详情 | - | ApiResponse\<InspectionTemplate\> | OPS-028 |
|
||
| PUT | `/{id}` | 更新模板 | InspectionTemplate | ApiResponse\<InspectionTemplate\> | OPS-028 |
|
||
| POST | `/{id}/copy` | 复制模板 | newName (query param) | ApiResponse\<InspectionTemplate\> | OPS-029 |
|
||
| GET | `/by-type/{equipmentType}` | 按设备类型查询 | - | ApiResponse\<List\<InspectionTemplate\>\> | OPS-028 |
|
||
|
||
### 3.4 SparePartController
|
||
|
||
**基础路径**: `/api/ops/spare-parts`
|
||
**控制器类**: `com.ether.pms.mdm.controller.SparePartController`(位于module-mdm)
|
||
|
||
#### 分类管理
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| GET | `/categories` | 获取所有分类 | - | ApiResponse\<List\<SparePartCategory\>\> | OPS-031 |
|
||
| POST | `/categories` | 创建分类 | SparePartCategory | ApiResponse\<SparePartCategory\> | OPS-031 |
|
||
|
||
#### 备件管理
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| GET | `/` | 查询备件列表 | projectId, categoryId(可选) | ApiResponse\<List\<SparePart\>\> | OPS-030 |
|
||
| GET | `/{id}` | 获取备件详情 | - | ApiResponse\<SparePart\> | OPS-030 |
|
||
| POST | `/` | 创建备件 | SparePart | ApiResponse\<SparePart\> | OPS-030 |
|
||
| PUT | `/{id}` | 更新备件 | SparePart | ApiResponse\<SparePart\> | OPS-030 |
|
||
| DELETE | `/{id}` | 删除备件(设为INACTIVE) | - | ApiResponse\<Void\> | OPS-030 |
|
||
| GET | `/low-stock` | 低库存预警 | projectId | ApiResponse\<List\<SparePart\>\> | OPS-034 |
|
||
|
||
#### 库存操作
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/in-stock` | 入库 | StockRequest | ApiResponse\<SparePartRecord\> | OPS-032 |
|
||
| POST | `/out-stock` | 出库 | OutStockRequest | ApiResponse\<SparePartRecord\> | OPS-033 |
|
||
| GET | `/{id}/records` | 获取出入库记录 | - | ApiResponse\<List\<SparePartRecord\>\> | OPS-035 |
|
||
|
||
**请求体定义**:
|
||
|
||
```java
|
||
// 入库请求
|
||
StockRequest {
|
||
@NotNull UUID sparePartId;
|
||
@NotNull Integer quantity;
|
||
UUID recordedBy;
|
||
String remarks;
|
||
}
|
||
|
||
// 出库请求
|
||
OutStockRequest {
|
||
@NotNull UUID sparePartId;
|
||
@NotNull Integer quantity;
|
||
UUID relatedOrderId; // 关联工单ID
|
||
UUID recordedBy;
|
||
String remarks;
|
||
}
|
||
```
|
||
|
||
### 3.5 EnergyController
|
||
|
||
**基础路径**: `/api/ops/energy`
|
||
**控制器类**: `com.ether.pms.mdm.controller.EnergyController`(位于module-mdm)
|
||
|
||
#### 计量点管理
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/meters` | 创建计量点 | EnergyMeter | ApiResponse\<EnergyMeter\> | OPS-036 |
|
||
| GET | `/meters` | 查询计量点 | projectId, energyType(可选) | ApiResponse\<List\<EnergyMeter\>\> | OPS-036 |
|
||
| GET | `/meters/{id}` | 获取计量点详情 | - | ApiResponse\<EnergyMeter\> | OPS-036 |
|
||
| PUT | `/meters/{id}` | 更新计量点 | EnergyMeter | ApiResponse\<EnergyMeter\> | OPS-036 |
|
||
| DELETE | `/meters/{id}` | 删除计量点 | - | ApiResponse\<Void\> | OPS-036 |
|
||
|
||
#### 能耗记录
|
||
|
||
| 方法 | 路径 | 说明 | 请求体 | 响应 | 功能ID |
|
||
|------|------|------|--------|------|--------|
|
||
| POST | `/consumption` | 抄表记录 | RecordConsumptionRequest | ApiResponse\<EnergyConsumption\> | OPS-037 |
|
||
| GET | `/consumption/{meterId}` | 获取能耗记录 | startDate, endDate(可选) | ApiResponse\<List\<EnergyConsumption\>\> | OPS-037 |
|
||
|
||
#### 能耗统计
|
||
|
||
| 方法 | 路径 | 说明 | 参数 | 响应 | 功能ID |
|
||
|------|------|------|------|------|--------|
|
||
| GET | `/statistics/by-type` | 按类型统计 | projectId, month | ApiResponse\<Map\<EnergyType, BigDecimal\>\> | OPS-038 |
|
||
| GET | `/statistics/unit-consumption` | 单位面积能耗 | projectId, month | ApiResponse\<BigDecimal\> | OPS-039 |
|
||
|
||
**请求体定义**:
|
||
|
||
```java
|
||
// 抄表请求
|
||
RecordConsumptionRequest {
|
||
@NotNull UUID meterId;
|
||
@NotNull BigDecimal currentReading;
|
||
UUID recordedBy;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、业务规则
|
||
|
||
### 4.1 工单状态机
|
||
|
||
#### 完整状态流转图
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> PENDING : 创建工单
|
||
|
||
PENDING --> ASSIGNED : 派单(assign)
|
||
PENDING --> CANCELLED : 取消(cancel)
|
||
|
||
ASSIGNED --> IN_PROGRESS : 开始执行(start)
|
||
ASSIGNED --> SUSPENDED : 挂起(suspend)
|
||
ASSIGNED --> RETURNED : 退回(return)
|
||
ASSIGNED --> CANCELLED : 取消(cancel)
|
||
|
||
IN_PROGRESS --> COMPLETED : 完成(complete)
|
||
IN_PROGRESS --> SUSPENDED : 挂起(suspend)
|
||
IN_PROGRESS --> CANCELLED : 取消(cancel)
|
||
|
||
SUSPENDED --> IN_PROGRESS : 恢复(resume)\n[默认回到IN_PROGRESS]
|
||
SUSPENDED --> ASSIGNED : 恢复(resume)\n[previousStatus=ASSIGNED时]
|
||
|
||
RETURNED --> PENDING : 退回后重新变为待分配
|
||
|
||
COMPLETED --> VERIFIED : 验收(verify)
|
||
|
||
VERIFIED --> [*]
|
||
CANCELLED --> [*]
|
||
```
|
||
|
||
#### 8种状态说明
|
||
|
||
| 状态 | 中文 | 说明 | 可转入状态 |
|
||
|------|------|------|-----------|
|
||
| PENDING | 待分配 | 工单创建后的初始状态 | ASSIGNED, CANCELLED |
|
||
| ASSIGNED | 已派单 | 已分配负责人/服务商 | IN_PROGRESS, SUSPENDED, RETURNED, CANCELLED |
|
||
| IN_PROGRESS | 执行中 | 正在处理 | COMPLETED, SUSPENDED, CANCELLED |
|
||
| SUSPENDED | 已挂起 | 暂停处理,记录前一状态 | IN_PROGRESS, ASSIGNED(取决于previousStatus) |
|
||
| RETURNED | 已退回 | 被退回重新分配 | PENDING |
|
||
| COMPLETED | 已完成 | 处理完毕 | VERIFIED |
|
||
| VERIFIED | 已验收 | 验收通过 | 终态 |
|
||
| CANCELLED | 已取消 | 工单取消 | 终态 |
|
||
|
||
#### 每个流转的前置条件与自动处理
|
||
|
||
| 当前状态 | 操作 | 目标状态 | 前置条件 | 自动处理 |
|
||
|---------|------|---------|---------|---------|
|
||
| PENDING | assign | ASSIGNED | - | 设置 assignedTo/assignedVendor/assignedDate |
|
||
| ASSIGNED | start | IN_PROGRESS | - | 设置 actualStart = now() |
|
||
| IN_PROGRESS | complete | COMPLETED | - | 设置 actualEnd = now(),自动计算 actualHours |
|
||
| COMPLETED | verify | VERIFIED | - | 设置 verifiedBy/verifiedDate/rating |
|
||
| PENDING/ASSIGNED/IN_PROGRESS | cancel | CANCELLED | status 非 COMPLETED/VERIFIED | - |
|
||
| ASSIGNED/IN_PROGRESS | suspend | SUSPENDED | - | 保存 previousStatus = 当前状态 |
|
||
| SUSPENDED | resume | previousStatus | status == SUSPENDED | 恢复到 previousStatus,默认 IN_PROGRESS |
|
||
| ASSIGNED | return | PENDING | status == ASSIGNED | 清空 assignedTo/assignedVendor/assignedDate |
|
||
|
||
#### previousStatus回溯机制
|
||
|
||
```
|
||
挂起时:
|
||
workOrder.previousStatus = workOrder.status // 保存当前状态
|
||
workOrder.status = SUSPENDED
|
||
|
||
恢复时:
|
||
targetStatus = workOrder.previousStatus != null
|
||
? workOrder.previousStatus
|
||
: IN_PROGRESS // 默认恢复到IN_PROGRESS
|
||
workOrder.previousStatus = null // 清空
|
||
workOrder.status = targetStatus
|
||
```
|
||
|
||
#### 工单编号生成规则
|
||
|
||
```
|
||
格式: WO-YYYYMMDD-XXXX
|
||
示例: WO-20260518-0001
|
||
|
||
生成算法:
|
||
1. 日期前缀: "WO-" + LocalDate.now().format("yyyyMMdd") + "-"
|
||
2. 查询当天最大编号: findMaxWorkNoByPrefix(prefix + "%")
|
||
3. 序号递增: maxWorkNo存在时取后4位+1,否则从1开始
|
||
4. 格式化: String.format("%04d", sequence)
|
||
```
|
||
|
||
#### 完成工单自动计算工时
|
||
|
||
```java
|
||
actualHours = Duration.between(actualStart, actualEnd).toMinutes() / 60.0
|
||
// 精度:保留2位小数,四舍五入
|
||
```
|
||
|
||
### 4.2 维保任务触发机制
|
||
|
||
#### 4种触发类型
|
||
|
||
| 触发类型 | 枚举值 | 说明 | 优先级自动判定 |
|
||
|---------|--------|------|---------------|
|
||
| 计划触发 | PLAN | 由维保计划周期性触发 | MEDIUM |
|
||
| 巡检触发 | INSPECTION | 巡检发现异常时触发 | HIGH |
|
||
| 故障触发 | FAULT | 设备故障时触发 | HIGH(含紧急关键词时URGENT) |
|
||
| 手动创建 | MANUAL | 人工手动创建 | MEDIUM |
|
||
|
||
#### 自动优先级判定算法
|
||
|
||
```
|
||
输入: MaintenanceTask (taskType, triggerType, title, description)
|
||
|
||
1. IF taskType == EMERGENCY
|
||
→ return URGENT
|
||
|
||
2. IF triggerType == FAULT
|
||
→ 检查 title + description 是否包含紧急关键词
|
||
→ 紧急关键词: [困人, 漏水, 停电, 火灾, 爆炸, 漏电, 冒烟, 故障停机]
|
||
→ IF 包含任一关键词 → return URGENT
|
||
→ ELSE → return HIGH
|
||
|
||
3. IF triggerType == INSPECTION
|
||
→ return HIGH
|
||
|
||
4. IF triggerType == PLAN
|
||
→ return MEDIUM
|
||
|
||
5. 默认 → return MEDIUM
|
||
```
|
||
|
||
#### 维保任务状态机
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> PENDING : 创建任务
|
||
|
||
PENDING --> ASSIGNED : 分配(assign)
|
||
PENDING --> CANCELLED : 取消(cancel)
|
||
|
||
ASSIGNED --> IN_PROGRESS : 开始执行(start)
|
||
ASSIGNED --> CANCELLED : 取消(cancel)
|
||
|
||
IN_PROGRESS --> COMPLETED : 完成(complete/complete-details)
|
||
IN_PROGRESS --> CANCELLED : 取消(cancel)
|
||
|
||
COMPLETED --> VERIFIED : 验收(verify)
|
||
|
||
VERIFIED --> [*]
|
||
CANCELLED --> [*]
|
||
```
|
||
|
||
#### 维保任务与工单状态机差异
|
||
|
||
| 差异点 | WorkOrder | MaintenanceTask |
|
||
|--------|-----------|-----------------|
|
||
| 状态数量 | 8种(含SUSPENDED/RETURNED) | 6种(无SUSPENDED/RETURNED) |
|
||
| 完成方式 | 仅一种 complete | 两种:complete(简版)+ complete-details(详版) |
|
||
| 评分方式 | 验收时评分 | 验收时评分 + 独立 rate 接口 |
|
||
| 删除行为 | 逻辑删除(isDeleted=true) | 逻辑删除(设为CANCELLED) |
|
||
| 完成后联动 | 无 | 自动更新设备维保记录 |
|
||
| 挂起/恢复 | 支持 | 不支持 |
|
||
| 退回 | 支持(ASSIGNED→PENDING) | 不支持 |
|
||
|
||
#### 维保任务完成后联动
|
||
|
||
维保任务完成(completeTaskWithDetails)时自动更新设备信息:
|
||
|
||
```
|
||
1. 更新设备维保商:
|
||
equipment.maintenanceVendor = task.assignedVendor
|
||
|
||
2. 更新下次巡检日期(仅预防性维护):
|
||
IF task.taskType == PREVENTIVE
|
||
THEN equipment.nextInspectionDate = now() + equipment.inspectionCycle
|
||
默认周期: 30天
|
||
|
||
3. 异常容错:
|
||
更新设备失败不影响工单完成(catch异常仅打印日志)
|
||
```
|
||
|
||
#### 任务编号生成规则
|
||
|
||
```
|
||
格式: EQ-YYYYMMDD-XXXX
|
||
示例: EQ-20260518-0001
|
||
|
||
生成算法: 与工单编号类似,前缀为 EQ-
|
||
```
|
||
|
||
### 4.3 巡检模板管理
|
||
|
||
**模板创建规则**:
|
||
- templateCode 自动生成(UNIQUE约束)
|
||
- 模板创建时可同时配置检查项列表(@Transient字段,需单独持久化)
|
||
- 模板状态默认为 ACTIVE
|
||
|
||
**模板复制规则**:
|
||
- 复制模板时创建新模板,名称使用传入的 newName
|
||
- 检查项同时复制到新模板
|
||
- 新模板的 templateCode 自动生成
|
||
|
||
**检查项配置**:
|
||
- InspectionItem 通过 templateId 关联模板
|
||
- isMandatory = true 的检查项为必检项,不可跳过
|
||
- isNormalRequired = true 的检查项需要判定正常/异常
|
||
- sortOrder 控制检查项的展示顺序
|
||
|
||
### 4.4 备件库存管理
|
||
|
||
#### 入库流程
|
||
|
||
```
|
||
1. 校验: quantity > 0
|
||
2. 查询备件: getSparePartById(sparePartId)
|
||
3. 更新库存: currentStock += quantity
|
||
4. 创建入库记录: RecordType=IN, balance=更新后库存
|
||
5. 生成记录编码: REC + IN + yyyyMMddHHmmss
|
||
```
|
||
|
||
#### 出库流程
|
||
|
||
```
|
||
1. 校验: quantity > 0
|
||
2. 查询备件: getSparePartById(sparePartId)
|
||
3. 校验库存: currentStock >= quantity
|
||
→ 不满足: 抛出 BusinessException("库存不足,当前库存:X,需要出库:Y")
|
||
4. 更新库存: currentStock -= quantity
|
||
5. 创建出库记录: RecordType=OUT, balance=更新后库存, relatedOrderId=关联工单
|
||
6. 生成记录编码: REC + OUT + yyyyMMddHHmmss
|
||
```
|
||
|
||
#### 低库存预警
|
||
|
||
```
|
||
预警条件: currentStock < safeStock
|
||
查询方式: sparePartRepository.findLowStockParts(projectId)
|
||
```
|
||
|
||
#### 库存余额计算
|
||
|
||
```
|
||
每次出入库操作后:
|
||
record.balance = sparePart.currentStock (操作后的库存余额)
|
||
```
|
||
|
||
#### 关联工单
|
||
|
||
- 出库时可指定 relatedOrderId 关联工单
|
||
- 用于追踪工单的备件消耗
|
||
|
||
#### 并发场景考虑
|
||
|
||
> 当前实现未使用乐观锁或悲观锁,存在并发安全问题:
|
||
|
||
| 并发场景 | 风险 | 当前处理 | 建议方案 |
|
||
|----------|------|----------|---------|
|
||
| 同时出库 | 库存超卖 | 无保护 | 添加 @Version 乐观锁或 SELECT FOR UPDATE 悲观锁 |
|
||
| 同时入库 | 库存计算错误 | 无保护 | 添加 @Version 乐观锁 |
|
||
| 并发读写 | 读到中间状态 | 无保护 | 使用数据库事务隔离级别 |
|
||
|
||
**建议并发控制方案**:
|
||
|
||
```java
|
||
// 方案1: 乐观锁(推荐)
|
||
@Version
|
||
private Long version;
|
||
|
||
// 出库时:
|
||
SparePart sp = repository.findById(id);
|
||
if (sp.getCurrentStock() < quantity) throw ...;
|
||
sp.setCurrentStock(sp.getCurrentStock() - quantity);
|
||
repository.save(sp); // version不匹配时抛出OptimisticLockException
|
||
|
||
// 方案2: 悲观锁
|
||
@Lock(LockModeType.PESSIMISTIC_WRITE)
|
||
@Query("SELECT sp FROM SparePart sp WHERE sp.id = :id")
|
||
SparePart findByIdForUpdate(@Param("id") UUID id);
|
||
```
|
||
|
||
### 4.5 能耗计量管理
|
||
|
||
#### 抄表流程
|
||
|
||
```
|
||
1. 校验计量点: meterId 存在且 status == ACTIVE
|
||
2. 获取上次抄表记录: findTopByMeterIdOrderByConsumptionDateDesc
|
||
3. 计算消耗量: consumption = currentReading - previousReading
|
||
4. 校验读数: consumption >= 0(当前读数不能小于上次读数)
|
||
5. 计算费用: amount = consumption x meter.unitPrice
|
||
6. 创建能耗记录: recordMethod=MANUAL
|
||
```
|
||
|
||
#### 消耗量计算
|
||
|
||
```
|
||
consumption = currentReading - previousReading
|
||
|
||
特殊情况:
|
||
- 首次抄表: previousReading = 0
|
||
- 读数倒退: 抛出 BusinessException("当前读数不能小于上次读数")
|
||
```
|
||
|
||
#### 费用计算
|
||
|
||
```
|
||
amount = consumption x meter.unitPrice
|
||
|
||
条件:
|
||
- meter.unitPrice 不为空
|
||
- consumption > 0
|
||
```
|
||
|
||
#### 按类型统计
|
||
|
||
```
|
||
输入: projectId, month (LocalDate)
|
||
1. 计算月份范围: startDate = month.withDayOfMonth(1), endDate = month.withDayOfMonth(length)
|
||
2. 初始化所有EnergyType为0
|
||
3. 查询项目总消耗: sumConsumptionByProjectAndDateRange
|
||
4. 当前实现: 将总消耗分配给LIGHTING类型(TODO: 应按meter.energyType汇总)
|
||
```
|
||
|
||
> 当前按类型统计实现不完整,所有消耗归入LIGHTING类型,需改为按meter.energyType分别汇总。
|
||
|
||
#### 单位面积能耗
|
||
|
||
```
|
||
输入: projectId, month
|
||
1. 获取项目所有ACTIVE状态的计量点
|
||
2. 遍历每个计量点,查询当月消耗量
|
||
3. 累加总消耗量
|
||
|
||
注意: 当前实现未除以建筑面积,仅返回总消耗量
|
||
TODO: 需要获取项目建筑面积,计算 单位面积能耗 = 总消耗量 / 建筑面积
|
||
```
|
||
|
||
### 4.6 工单明细管理
|
||
|
||
#### 3种明细类型
|
||
|
||
| 类型 | 枚举值 | 中文 | 用途 |
|
||
|------|--------|------|------|
|
||
| PART | 备件 | 记录工单使用的备件及费用 |
|
||
| INSPECTION_ITEM | 巡检项 | 记录工单的巡检检查项 |
|
||
| CHECKPOINT | 检查点 | 记录工单的关键检查点 |
|
||
|
||
#### 费用计算
|
||
|
||
```
|
||
前端计算:
|
||
item.totalPrice = item.quantity x item.unitPrice
|
||
partsCost = SUM(item.totalPrice) WHERE item.itemType == PART
|
||
totalCost = laborCost + partsCost
|
||
```
|
||
|
||
#### 批量添加
|
||
|
||
- 支持批量添加工单明细
|
||
- 受 BatchOperationValidator 限制(校验批量操作大小)
|
||
- 每条明细的 workOrderId 自动设置为当前工单ID
|
||
- sortOrder 控制明细展示顺序
|
||
|
||
---
|
||
|
||
## 五、执行约束
|
||
|
||
### 5.1 工单编号唯一性
|
||
|
||
- workNo 字段在数据库层设置 UNIQUE 约束
|
||
- 生成算法基于日期前缀+4位序号,按日期递增
|
||
- 编号格式: `WO-YYYYMMDD-XXXX`
|
||
- 同一天内序号从0001开始递增
|
||
|
||
### 5.2 任务编号唯一性
|
||
|
||
- taskNo 字段在数据库层设置 UNIQUE 约束
|
||
- 编号格式: `EQ-YYYYMMDD-XXXX`
|
||
- 生成算法与工单编号类似
|
||
|
||
### 5.3 备件库存非负约束
|
||
|
||
- 出库时校验: `currentStock >= quantity`
|
||
- 不满足时抛出 BusinessException(6104, "库存不足,当前库存:X,需要出库:Y")
|
||
- 入库数量必须 > 0,否则抛出 BusinessException(6102, "入库数量必须大于0")
|
||
- 出库数量必须 > 0,否则抛出 BusinessException(6103, "出库数量必须大于0")
|
||
|
||
### 5.4 能耗读数递增约束
|
||
|
||
- 抄表时校验: `currentReading >= previousReading`
|
||
- 不满足时抛出 BusinessException(6103, "当前读数不能小于上次读数")
|
||
- 首次抄表时 previousReading = 0
|
||
|
||
### 5.5 工单状态流转约束
|
||
|
||
- 只能按合法路径流转,非法流转抛出 RuntimeException
|
||
- COMPLETED/VERIFIED 状态不可取消
|
||
- SUSPENDED 状态只能恢复(resume),不能直接转为其他状态
|
||
- RETURNED 状态自动转为 PENDING
|
||
|
||
**合法流转矩阵**:
|
||
|
||
| 当前\目标 | PENDING | ASSIGNED | IN_PROGRESS | SUSPENDED | RETURNED | COMPLETED | VERIFIED | CANCELLED |
|
||
|----------|---------|----------|-------------|-----------|----------|-----------|----------|-----------|
|
||
| PENDING | - | V | - | - | - | - | - | V |
|
||
| ASSIGNED | - | - | V | V | V | - | - | V |
|
||
| IN_PROGRESS | - | - | - | V | - | V | - | V |
|
||
| SUSPENDED | - | V* | V* | - | - | - | - | - |
|
||
| RETURNED | V | - | - | - | - | - | - | - |
|
||
| COMPLETED | - | - | - | - | - | - | V | - |
|
||
| VERIFIED | - | - | - | - | - | - | - | - |
|
||
| CANCELLED | - | - | - | - | - | - | - | - |
|
||
|
||
> V* 表示 SUSPENDED 恢复时回到 previousStatus
|
||
|
||
### 5.6 维保计划周期约束
|
||
|
||
- cycleDays 必须 > 0(周期天数必须为正数)
|
||
- nextDate = lastDate + cycleDays(下次执行日期由周期推算)
|
||
- 计划状态变更:ACTIVE 可转为 INACTIVE 或 SUSPENDED
|
||
|
||
---
|
||
|
||
## 六、权限控制
|
||
|
||
| API路径 | 操作 | 所需权限 | 说明 |
|
||
|---------|------|----------|------|
|
||
| POST /api/wo/work-orders | 创建工单 | wo:work-order:create | 需项目级权限 |
|
||
| GET /api/wo/work-orders | 查询工单 | wo:work-order:read | 需项目级权限 |
|
||
| PUT /api/wo/work-orders/{id} | 更新工单 | wo:work-order:update | 需项目级权限 |
|
||
| DELETE /api/wo/work-orders/{id} | 删除工单 | wo:work-order:delete | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/assign | 派单 | wo:work-order:assign | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/start | 开始执行 | wo:work-order:execute | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/complete | 完成工单 | wo:work-order:execute | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/verify | 验收工单 | wo:work-order:verify | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/cancel | 取消工单 | wo:work-order:cancel | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/suspend | 挂起工单 | wo:work-order:suspend | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/resume | 恢复工单 | wo:work-order:resume | 需项目级权限 |
|
||
| POST /api/wo/work-orders/{id}/return | 退回工单 | wo:work-order:return | 需项目级权限 |
|
||
| POST /api/ops/maintenance-tasks | 创建维保任务 | ops:maintenance-task:create | 需项目级权限 |
|
||
| POST /api/ops/maintenance-tasks/{id}/assign | 分配任务 | ops:maintenance-task:assign | 需项目级权限 |
|
||
| POST /api/ops/maintenance-tasks/{id}/start | 开始执行 | ops:maintenance-task:execute | 需项目级权限 |
|
||
| POST /api/ops/maintenance-tasks/{id}/complete | 完成任务 | ops:maintenance-task:execute | 需项目级权限 |
|
||
| POST /api/ops/maintenance-tasks/{id}/verify | 验收任务 | ops:maintenance-task:verify | 需项目级权限 |
|
||
| POST /api/ops/spare-parts/in-stock | 入库 | ops:spare-part:stock-in | 需项目级权限 |
|
||
| POST /api/ops/spare-parts/out-stock | 出库 | ops:spare-part:stock-out | 需项目级权限 |
|
||
| POST /api/ops/energy/consumption | 抄表 | ops:energy:record | 需项目级权限 |
|
||
|
||
> 当前实现中权限控制尚未集成Spring Security,以上为设计预期权限矩阵。
|
||
|
||
---
|
||
|
||
## 七、例外情况处理
|
||
|
||
| 例外场景 | 触发条件 | 处理方式 | 错误码/信息 |
|
||
|----------|----------|----------|------------|
|
||
| 工单状态流转非法 | 从PENDING直接complete | 抛出RuntimeException | "只能完成进行中的工单" |
|
||
| 工单已完成后取消 | status=COMPLETED/VERIFIED时cancel | 抛出RuntimeException | "无法取消已完成的工单" |
|
||
| 挂起非ASSIGNED/IN_PROGRESS工单 | status不合法时suspend | 抛出RuntimeException | "只能挂起已派单或执行中的工单" |
|
||
| 恢复非SUSPENDED工单 | status!=SUSPENDED时resume | 抛出RuntimeException | "只能恢复已挂起的工单" |
|
||
| 退回非ASSIGNED工单 | status!=ASSIGNED时return | 抛出RuntimeException | "只能退回已派单的工单" |
|
||
| 备件库存不足 | 出库数量>当前库存 | 抛出BusinessException | 6104 "库存不足,当前库存:X,需要出库:Y" |
|
||
| 入库数量非法 | quantity <= 0 | 抛出BusinessException | 6102 "入库数量必须大于0" |
|
||
| 出库数量非法 | quantity <= 0 | 抛出BusinessException | 6103 "出库数量必须大于0" |
|
||
| 能耗读数倒退 | currentReading < previousReading | 抛出BusinessException | 6103 "当前读数不能小于上次读数" |
|
||
| 能源仪表不存在 | meterId无效 | 抛出BusinessException | 6101 "能源仪表不存在" |
|
||
| 仪表非ACTIVE状态 | 抄表时meter.status!=ACTIVE | 抛出BusinessException | 6102 "只能对ACTIVE状态的仪表进行抄表" |
|
||
| 维保计划关联设备不存在 | equipmentId无效 | 数据库外键约束 | 需添加业务校验 |
|
||
| 维保任务不存在 | taskId无效 | 抛出BusinessException | ErrorCode.NOT_FOUND "维保工单不存在" |
|
||
| 工单不存在 | workOrderId无效或已删除 | 抛出RuntimeException | "工单不存在: {id}" |
|
||
| 维保任务评分越界 | rating < 1 或 rating > 5 | 抛出BusinessException | 6006 "评分必须在1-5之间" |
|
||
| 维保任务评分状态非法 | 非COMPLETED/VERIFIED状态评分 | 抛出BusinessException | 6005 "只有已完成或已验收的工单才能评分" |
|
||
| 巡检模板被引用不能删除 | 模板被巡检记录引用 | - | 当前无校验,建议增加 |
|
||
| 备件不存在 | sparePartId无效 | 抛出BusinessException | 6101 "备件不存在" |
|
||
|
||
---
|
||
|
||
**附录:已知代码问题与改进建议**
|
||
|
||
| 问题 | 位置 | 影响 | 建议 |
|
||
|------|------|------|------|
|
||
| 备件出入库无并发控制 | SparePartServiceImpl | 高并发下可能库存超卖 | 添加 @Version 乐观锁或 SELECT FOR UPDATE |
|
||
| 能耗按类型统计实现不完整 | EnergyConsumptionServiceImpl | 所有消耗归入LIGHTING类型 | 按 meter.energyType 分别汇总 |
|
||
| 单位面积能耗未除以建筑面积 | EnergyConsumptionServiceImpl | 返回的是总消耗量而非单位面积能耗 | 获取项目建筑面积做除法 |
|
||
| 工单查询参数互斥 | WorkOrderController/MaintenanceTaskController | 多条件同时传入只生效一个 | 改为 Specification 动态查询 |
|
||
| 维保任务查询无分页 | MaintenanceTaskController | 数据量大时可能OOM | 改为分页查询 |
|
||
| 工单删除/退回使用RuntimeException | WorkOrderServiceImpl | 异常信息不够结构化 | 改为 BusinessException + ErrorCode |
|
||
| 维保任务删除实际是取消 | MaintenanceTaskServiceImpl | deleteTask 实际设置 status=CANCELLED | 命名与行为不一致,建议重命名 |
|
||
| 前后端状态枚举不一致 | maintenance.ts vs MaintenanceTask | 前端含ACCEPTED,后端含ASSIGNED/VERIFIED | 统一前后端状态定义 |
|
||
| 前端维保计划两套API | maintenance.ts + maintenance-plan.ts | 接口重复,维护困难 | 统一为一套API |
|
||
| 工单无流转记录 | WorkOrderServiceImpl | 无法追溯工单状态变更历史 | 新增 WorkOrderFlow 实体 |
|