ether-docs/_archive/domains-old/REVERSE-MDM.md

1159 lines
49 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ether 主数据域MDM功能详细设计文档
**版本**: v1.0(反推自代码)
**生成日期**: 2026-04-23
**数据来源**: module-mdm 实际代码反推
**代码路径**: `ether-pms/module-mdm`
---
## 一、领域概述
### 1.1 领域职责
主数据域Master Data Management是 Ether 系统的基础数据层,负责管理物业项目全生命周期的核心主数据,为所有业务域(工单、收费、巡检、维保等)提供统一的数据基座。
核心职责:
- **项目管理**:项目创建、状态流转、成员管理、功能配置
- **空间节点管理**:统一空间体系,树形结构管理楼栋/单元/房间/车位/设备房等
- **巡检标准管理**:巡检标准项库、巡检模板管理
- **巡检记录管理**:设备巡检记录、巡检结果跟踪
- **备件库存管理**:备件台账、分类管理、出入库操作、低库存预警
- **能耗计量管理**:计量点管理、能耗抄表记录、能耗统计分析
### 1.2 核心概念
| 概念 | 说明 | 对应实体 |
|------|------|----------|
| **项目** | 物业管理的基本单元,所有业务数据的归属 | Project |
| **空间节点** | 统一的空间体系,支持树形层级 | SpaceNode |
| **项目配置** | 项目级别的功能开关 | ProjectConfig |
| **项目统计** | 项目维度的汇总统计 | ProjectStatistics |
| **状态历史** | 项目状态变更记录 | ProjectStatusHistory |
| **巡检标准项** | 设备巡检的检查标准库 | InspectionItem |
| **巡检模板** | 按设备类型组织的巡检检查项集合 | InspectionTemplate |
| **巡检记录** | 实际巡检执行记录 | InspectionRecord |
| **备件** | 维修用备品备件 | SparePart |
| **备件分类** | 备件的分类体系 | SparePartCategory |
| **备件记录** | 备件出入库流水 | SparePartRecord |
| **计量点** | 能源计量仪表 | EnergyMeter |
| **能耗记录** | 能源消耗抄表记录 | EnergyConsumption |
### 1.3 领域边界
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 主数据域MDM边界 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 项目管理 │ │ 空间节点 │ │ 巡检标准 │ │ 备件库存 │ │ 能耗计量 │ │
│ │ Project │ │SpaceNode │ │InspectItem│ │SparePart │ │ Energy │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 项目配置 │ │ 设备扩展 │ │ 巡检模板 │ │ 备件分类 │ │ 计量点 │ │
│ │ Config │ │Equipment │ │ Template │ │ Category │ │ Meter │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────┤
│ 依赖关系: │
│ - 所有实体均以 projectId 为核心维度 │
│ - SpaceNode 是空间基座,设备/计量点/巡检均关联空间节点 │
│ - 巡检模板引用巡检标准项 │
│ - 备件记录关联备件和工单 │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 二、数据结构设计
### 2.1 实体总览
| # | 实体 | 表名 | 模块 | 说明 |
|---|------|------|------|------|
| 1 | Project | mdm_project | 项目管理 | 项目基础信息 |
| 2 | ProjectConfig | mdm_project_config | 项目管理 | 项目功能配置 |
| 3 | ProjectStatistics | mdm_project_statistics | 项目管理 | 项目统计快照 |
| 4 | ProjectStatusHistory | mdm_project_status_history | 项目管理 | 状态变更历史 |
| 5 | SpaceNode | mdm_space_node | 空间管理 | 统一空间节点(含设备扩展) |
| 6 | InspectionItem | mdm_inspection_item | 巡检标准 | 巡检标准项 |
| 7 | InspectionTemplate | ops_inspection_template | 巡检模板 | 巡检检查模板 |
| 8 | InspectionRecord | mdm_inspection_record | 巡检记录 | 巡检执行记录 |
| 9 | SparePart | ops_spare_part | 备件管理 | 备件台账 |
| 10 | SparePartCategory | ops_spare_part_category | 备件管理 | 备件分类 |
| 11 | SparePartRecord | ops_spare_part_record | 备件管理 | 出入库记录 |
| 12 | EnergyMeter | ops_energy_meter | 能耗管理 | 计量点 |
| 13 | EnergyConsumption | ops_energy_consumption | 能耗管理 | 能耗记录 |
### 2.2 Project项目
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键,自动生成 |
| code | String(50) | 是 | 项目编码,唯一,正则 `^[a-zA-Z0-9_-]+$`2-50位 |
| name | String(100) | 是 | 项目名称2-100位 |
| description | String(500) | 否 | 项目描述 |
| address | String(100) | 否 | 项目地址 |
| projectType | Enum(ProjectType) | 否 | 项目类型,默认 RESIDENTIAL |
| province | String(50) | 否 | 省 |
| city | String(50) | 否 | 市 |
| district | String(50) | 否 | 区 |
| longitude | Double | 否 | 经度 |
| latitude | Double | 否 | 纬度 |
| status | String(20) | 是 | 项目状态,默认 ACTIVE |
| buildingCount | Integer | 否 | 楼栋数 |
| unitCount | Integer | 否 | 单元数 |
| roomCount | Integer | 否 | 房间数 |
| floorCount | Integer | 否 | 楼层数 |
| logo | String(200) | 否 | 项目Logo |
| contact | String(200) | 否 | 联系人 |
| contactPhone | String(20) | 否 | 联系电话,正则 `^1[3-9]\d{9}$` |
| createdAt | LocalDateTime | 是 | 创建时间,自动填充 |
| updatedAt | LocalDateTime | 是 | 更新时间,自动填充 |
**枚举ProjectType**
| 值 | 描述 |
|----|------|
| RESIDENTIAL | 住宅 |
| OFFICE | 办公 |
| INDUSTRIAL_PARK | 产业园区 |
**项目状态值String类型非枚举**
| 值 | 描述 | 前端颜色 |
|----|------|----------|
| ACTIVE | 正常 | success |
| DISABLED | 禁用 | error |
| PENDING | 待审核 | warning |
| ARCHIVED | 已归档 | default |
### 2.3 ProjectConfig项目配置
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| id | UUID | 是 | - | 主键 |
| projectId | UUID | 是 | - | 项目ID唯一 |
| enableReservation | Boolean | 否 | false | 预约功能 |
| enableVisitor | Boolean | 否 | false | 访客功能 |
| enableComplaint | Boolean | 否 | true | 投诉功能 |
| enablePayment | Boolean | 否 | false | 缴费功能 |
| enableAnnouncement | Boolean | 否 | true | 公告功能 |
| enableSurvey | Boolean | 否 | false | 问卷功能 |
| enableVote | Boolean | 否 | false | 投票功能 |
| enableMaintenance | Boolean | 否 | true | 报修功能 |
| enableAsset | Boolean | 否 | false | 资产功能 |
| customConfig | String(5000) | 否 | - | 自定义配置JSON |
| createdAt | LocalDateTime | - | 自动 | 创建时间 |
| updatedAt | LocalDateTime | - | 自动 | 更新时间 |
### 2.4 ProjectStatistics项目统计
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| id | UUID | - | 主键 |
| projectId | UUID | - | 项目ID唯一 |
| memberCount | Integer | 0 | 成员数 |
| buildingCount | Integer | 0 | 楼栋数 |
| unitCount | Integer | 0 | 单元数 |
| roomCount | Integer | 0 | 房间数 |
| ownerCount | Integer | 0 | 业主数 |
| tenantCount | Integer | 0 | 租户数 |
| lastSyncedAt | LocalDateTime | - | 最后同步时间 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
| updatedAt | LocalDateTime | 自动 | 更新时间 |
### 2.5 ProjectStatusHistory状态变更历史
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID |
| fromStatus | String(20) | 否 | 原状态 |
| toStatus | String(20) | 是 | 新状态 |
| reason | String(500) | 否 | 变更原因 |
| operatorId | UUID | 否 | 操作人ID |
| operatorName | String(50) | 否 | 操作人姓名 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
### 2.6 SpaceNode空间节点— 核心实体
SpaceNode 是 MDM 域最复杂的实体,采用统一空间模型 + 设备扩展字段的设计。
#### 2.6.1 基础字段
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID注意列名为 project_code |
| name | String(100) | 是 | 节点名称1-100位 |
| fullName | String(500) | 否 | 全路径名称 |
| shortName | String(50) | 否 | 简称 |
| nodeCategory | Enum(NodeCategory) | 是 | 节点大类 |
| nodeType | Enum(NodeType) | 是 | 节点类型 |
| usageType | String(30) | 否 | 用途类型 |
| parentId | UUID | 否 | 父节点ID |
| treePath | String(1000) | 否 | 物理路径 id.id.id |
| treePathName | String(1000) | 否 | 名称路径 项目/楼栋/单元/房间 |
| level | Integer | 否 | 层级深度默认0 |
| sortOrder | Integer | 否 | 排序号默认0 |
| status | String(20) | 否 | 状态,默认 ACTIVE |
| deliveryStatus | String(20) | 否 | 交付状态 |
| decorationStatus | String(20) | 否 | 装修状态 |
#### 2.6.2 面积信息
| 字段 | 类型 | 说明 |
|------|------|------|
| buildingArea | BigDecimal(10,2) | 建筑面积(㎡) |
| usableArea | BigDecimal(10,2) | 使用面积(㎡) |
| sharedArea | BigDecimal(10,2) | 公摊面积(㎡) |
| landArea | BigDecimal(10,2) | 占地面积(㎡) |
#### 2.6.3 地理信息
| 字段 | 类型 | 说明 |
|------|------|------|
| longitude | BigDecimal(10) | 经度 |
| latitude | BigDecimal(10) | 纬度 |
| altitude | BigDecimal(8,2) | 海拔 |
| floorNumber | Integer | 楼层号(正数地上,负数地下) |
#### 2.6.4 地址信息
| 字段 | 类型 | 说明 |
|------|------|------|
| province | String(50) | 省 |
| city | String(50) | 市 |
| district | String(50) | 区 |
| street | String(100) | 街道 |
| address | String(255) | 详细地址 |
#### 2.6.5 扩展属性
| 字段 | 类型 | 说明 |
|------|------|------|
| attributes | String(2000) | 类型特定属性JSON格式 |
#### 2.6.6 设备扩展字段isEquipment=true 时使用)
| 字段 | 类型 | 说明 |
|------|------|------|
| isEquipment | Boolean | 是否为设备节点默认false |
| designLifeYears | Integer | 设计寿命(年) |
| ratedPower | BigDecimal(10,2) | 额定功率 |
| ratedVoltage | BigDecimal(10,2) | 额定电压 |
| ratedCurrent | BigDecimal(10,2) | 额定电流 |
| maintenanceVendor | String(100) | 维保厂商 |
| maintenanceVendorContact | String(50) | 维保联系人 |
| maintenanceVendorPhone | String(20) | 维保电话 |
| maintenanceContractNo | String(50) | 维保合同号 |
| maintenanceContractStart | LocalDate | 合同开始日期 |
| maintenanceContractEnd | LocalDate | 合同结束日期 |
| specialEquipmentType | String(50) | 特种设备类型 |
| specialEquipmentCert | String(100) | 特种设备证书 |
| inspectionCycle | Integer | 巡检周期(天) |
| nextInspectionDate | LocalDate | 下次年检日期 |
| lastInspectionDate | LocalDate | 上次年检日期 |
| lastInspectionResult | String(20) | 上次年检结果 |
| commonSpareParts | String(2000) | 常用备件(JSON) |
| energyConsumptionStandard | BigDecimal(12,2) | 能耗标准 |
| installationEnvironment | String(50) | 安装环境 |
| protectionLevel | String(20) | 防护等级 |
#### 2.6.7 系统字段
| 字段 | 类型 | 说明 |
|------|------|------|
| createdAt | LocalDateTime | 创建时间 |
| updatedAt | LocalDateTime | 更新时间 |
| createdBy | UUID | 创建人 |
| updatedBy | UUID | 更新人 |
| isDeleted | Boolean | 软删除标记默认false |
#### 2.6.8 NodeCategory 枚举(节点大类)
| 值 | 描述 |
|----|------|
| BUILDING | 建筑空间 |
| PARKING | 停车空间 |
| FACILITY | 设施空间 |
| AREA | 区域空间 |
#### 2.6.9 NodeType 枚举(节点类型)— 含分类和层级
| 值 | 描述 | 所属大类 | 层级序号 |
|----|------|----------|----------|
| BUILDING | 楼栋 | BUILDING | 1 |
| UNIT | 单元 | BUILDING | 2 |
| FLOOR | 楼层 | BUILDING | 3 |
| ROOM | 房间 | BUILDING | 4 |
| SHOP | 商铺 | BUILDING | 2 |
| GARAGE | 车库 | PARKING | 1 |
| PARKING_AREA | 停车区域 | PARKING | 2 |
| PARKING_SPACE | 车位 | PARKING | 3 |
| EQUIPMENT_ROOM | 设备房 | FACILITY | 1 |
| PROPERTY_OFFICE | 物业用房 | FACILITY | 1 |
| SECURITY_ROOM | 门岗 | FACILITY | 1 |
| PUBLIC_ROOM | 公共用房 | FACILITY | 1 |
| PUBLIC_AREA | 公共区域 | AREA | 1 |
| GREEN_AREA | 绿化区域 | AREA | 1 |
| ROAD | 道路 | AREA | 1 |
#### 2.6.10 索引设计
| 索引名 | 列 | 说明 |
|--------|-----|------|
| idx_space_node_project | project_id | 按项目查询 |
| idx_space_node_parent | parent_id | 查子节点 |
| idx_space_node_type | node_type | 按类型查询 |
| idx_space_node_tree_path | tree_path | 路径查询 |
| idx_sn_project_parent | project_id, parent_id | 项目+父节点 |
| idx_sn_project_type | project_id, node_type | 项目+类型 |
| idx_sn_project_isequipment | project_id, is_equipment | 项目+设备 |
| idx_sn_project_nextinspection | project_id, next_inspection_date | 年检预警 |
### 2.7 InspectionItem巡检标准项
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| equipmentType | String(50) | 否 | 设备类型 |
| systemType | String(50) | 否 | 系统类型 |
| itemName | String(200) | 是 | 检查项名称 |
| checkMethod | String(200) | 否 | 检查方法 |
| standardValue | String(100) | 否 | 标准值 |
| isRequired | Boolean | 否 | 是否必检默认true |
| remark | String(500) | 否 | 备注 |
| sortOrder | Integer | 否 | 排序号 |
| status | Enum(Status) | 否 | 状态默认ACTIVE |
| createdAt | LocalDateTime | 自动 | 创建时间 |
| updatedAt | LocalDateTime | 自动 | 更新时间 |
**枚举Status**
| 值 | 描述 |
|----|------|
| ACTIVE | 启用 |
| INACTIVE | 停用 |
### 2.8 InspectionTemplate巡检模板
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID |
| templateCode | String | 是 | 模板编码,唯一 |
| templateName | String | 是 | 模板名称 |
| equipmentType | String | 是 | 设备类型 |
| inspectionItems | String(5000) | 否 | 检查项(JSON) |
| estimatedDuration | Integer | 否 | 预计耗时(分钟) |
| status | Enum(Status) | 否 | 状态默认ACTIVE |
| version | Integer | 否 | 版本号默认1 |
| createdBy | String | 否 | 创建人 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
| updatedAt | LocalDateTime | 自动 | 更新时间 |
### 2.9 InspectionRecord巡检记录
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| planId | UUID | 否 | 巡检计划ID |
| equipmentId | UUID | 是 | 设备ID |
| inspectionDate | LocalDate | 是 | 巡检日期 |
| inspector | String(200) | 是 | 巡检人 |
| status | Enum(CheckStatus) | 否 | 检查状态默认NORMAL |
| checkInTime | LocalDateTime | 否 | 签到时间 |
| checkInLocation | String(100) | 否 | 签到位置 |
| checkInPhoto | String(200) | 否 | 签到照片 |
| items | JSONB | 否 | 检查项结果列表 |
| problems | JSONB | 否 | 异常问题列表 |
| completed | Boolean | 否 | 是否完成默认false |
| completedTime | LocalDateTime | 否 | 完成时间 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
**枚举CheckStatus**
| 值 | 描述 |
|----|------|
| NORMAL | 正常 |
| WARNING | 预警 |
| ABNORMAL | 异常 |
**items JSONB 结构示例**
```json
[
{ "itemId": "uuid", "itemName": "检查项", "value": "实测值", "result": "PASS/FAIL", "remark": "备注" }
]
```
**problems JSONB 结构示例**
```json
[
{ "desc": "问题描述", "photo": "照片URL", "severity": "LOW/MEDIUM/HIGH" }
]
```
**索引设计**
| 索引名 | 列 |
|--------|-----|
| idx_ir_equipment_date | equipment_id, inspection_date |
| idx_ir_inspectiondate | inspection_date |
### 2.10 SparePart备件
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID |
| sparePartCode | String | 是 | 备件编码,唯一 |
| sparePartName | String | 是 | 备件名称 |
| categoryId | UUID | 否 | 分类ID |
| specification | String(500) | 否 | 规格型号 |
| unit | String(50) | 是 | 计量单位 |
| safeStock | Integer | 否 | 安全库存默认0 |
| currentStock | Integer | 否 | 当前库存默认0 |
| unitPrice | BigDecimal(10,2) | 否 | 单价 |
| supplier | String(200) | 否 | 供应商 |
| supplierContact | String | 否 | 供应商联系方式 |
| location | String(200) | 否 | 存放位置 |
| remarks | String(1000) | 否 | 备注 |
| status | Enum(Status) | 否 | 状态默认ACTIVE |
| createdAt | LocalDateTime | 自动 | 创建时间 |
| updatedAt | LocalDateTime | 自动 | 更新时间 |
**枚举Status**
| 值 | 描述 |
|----|------|
| ACTIVE | 启用 |
| INACTIVE | 停用 |
**索引**`idx_sp_project_status(project_id, status)`
### 2.11 SparePartCategory备件分类
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| parentId | UUID | 否 | 父分类ID支持树形 |
| categoryCode | String | 是 | 分类编码,唯一 |
| categoryName | String | 是 | 分类名称 |
| description | String(500) | 否 | 描述 |
| sortOrder | Integer | 否 | 排序号 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
### 2.12 SparePartRecord备件出入库记录
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| recordCode | String | 是 | 记录编码,唯一 |
| recordType | Enum(RecordType) | 是 | 记录类型 |
| sparePartId | UUID | 是 | 备件ID |
| quantity | Integer | 是 | 数量 |
| balance | Integer | 是 | 余额(操作后库存) |
| relatedOrderId | UUID | 否 | 关联工单ID |
| recordedBy | UUID | 否 | 操作人ID |
| recordDate | LocalDateTime | 否 | 操作时间,默认当前 |
| remarks | String(1000) | 否 | 备注 |
**枚举RecordType**
| 值 | 描述 |
|----|------|
| IN | 入库 |
| OUT | 出库 |
| CHECK | 盘点 |
| ADJUST | 调整 |
### 2.13 EnergyMeter计量点
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID |
| meterCode | String | 是 | 计量点编码,唯一 |
| meterName | String | 是 | 计量点名称 |
| energyType | Enum(EnergyType) | 是 | 能源类型 |
| spaceNodeId | UUID | 否 | 关联空间节点 |
| installationLocation | String | 否 | 安装位置 |
| ratedCapacity | BigDecimal(10,2) | 否 | 额定容量 |
| unitPrice | BigDecimal(10,4) | 否 | 单价 |
| status | Enum(Status) | 否 | 状态默认ACTIVE |
| createdAt | LocalDateTime | 自动 | 创建时间 |
| updatedAt | LocalDateTime | 自动 | 更新时间 |
**枚举EnergyType**
| 值 | 描述 |
|----|------|
| LIGHTING | 照明插座用电 |
| HVAC | 空调用电 |
| POWER | 动力用电 |
| SPECIAL | 特殊用电 |
| WATER | 给排水 |
| GAS | 燃气 |
### 2.14 EnergyConsumption能耗记录
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | UUID | 是 | 主键 |
| projectId | UUID | 是 | 项目ID |
| meterId | UUID | 是 | 计量点ID |
| consumptionDate | LocalDate | 是 | 消耗日期 |
| previousReading | BigDecimal(12,2) | 否 | 上次读数 |
| currentReading | BigDecimal(12,2) | 否 | 本次读数 |
| consumption | BigDecimal(12,2) | 是 | 消耗量 |
| amount | BigDecimal(10,2) | 否 | 金额 |
| recordedBy | UUID | 否 | 记录人 |
| recordMethod | Enum(RecordMethod) | 否 | 记录方式默认MANUAL |
| remarks | String(1000) | 否 | 备注 |
| createdAt | LocalDateTime | 自动 | 创建时间 |
**枚举RecordMethod**
| 值 | 描述 |
|----|------|
| MANUAL | 手动录入 |
| IOT | IoT自动采集 |
**索引**
| 索引名 | 列 |
|--------|-----|
| idx_ec_meter_date | meter_id, consumption_date |
| idx_ec_project_date | project_id, consumption_date |
### 2.15 实体关系图
```
Project (1) ──→ (N) SpaceNode 通过 projectId 关联
Project (1) ──→ (1) ProjectConfig 通过 projectId 唯一关联
Project (1) ──→ (1) ProjectStatistics 通过 projectId 唯一关联
Project (1) ──→ (N) ProjectStatusHistory 通过 projectId 关联
SpaceNode (1) ──→ (N) SpaceNode 通过 parentId 自关联(树形)
SpaceNode (1) ──→ (0..1) Equipment 通过 isEquipment 标记(设备扩展字段)
EnergyMeter (1) ──→ (N) EnergyConsumption 通过 meterId 关联
EnergyMeter ──→ SpaceNode 通过 spaceNodeId 关联
SparePartCategory (1) ──→ (N) SparePartCategory 通过 parentId 自关联(树形)
SparePartCategory (1) ──→ (N) SparePart 通过 categoryId 关联
SparePart (1) ──→ (N) SparePartRecord 通过 sparePartId 关联
InspectionItem ──→ InspectionTemplate 通过 equipmentType 逻辑关联
InspectionTemplate ──→ InspectionRecord 通过 planId 逻辑关联
InspectionRecord ──→ SpaceNode(Equipment) 通过 equipmentId 关联
```
---
## 三、API接口设计
### 3.1 ProjectController — `/api/mdm/projects`
| 编号 | 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|------|----------|
| PM-001 | GET | / | 分页查询项目列表 | keyword, status, page, size, sortBy, sortDirection |
| PM-010 | GET | /selector | 获取项目选择器列表 | - |
| PM-005 | GET | /generate-code | 生成项目编码 | - |
| - | GET | /{id} | 按ID查询项目 | id(Path) |
| - | GET | /code/{code} | 按编码查询项目 | code(Path) |
| - | POST | / | 创建项目 | Project(Body) |
| - | PUT | /{id} | 更新项目 | id(Path), Project(Body) |
| - | DELETE | /{id} | 删除项目 | id(Path) |
| PM-003 | GET | /{id}/members | 获取项目成员列表 | id(Path), page, size |
| PM-003 | POST | /{id}/members | 添加项目成员 | id(Path), AddMemberRequest(Body) |
| PM-003 | DELETE | /{id}/members/{memberId} | 移除项目成员 | id(Path), memberId(Path) |
| PM-002 | GET | /{id}/statistics | 获取项目统计数据 | id(Path) |
| PM-006 | PUT | /{id}/status | 变更项目状态 | id(Path), ChangeStatusRequest(Body) |
| PM-008 | GET | /{id}/config | 获取项目配置 | id(Path) |
| PM-008 | PUT | /{id}/config | 更新项目配置 | id(Path), ProjectConfigDTO(Body) |
| PM-009 | GET | /{projectId}/delete-check | 项目删除前检查 | projectId(Path) |
**关键DTO**
```typescript
// ProjectQueryRequest
{ keyword?: string; status?: string; page?: number; size?: number; sortBy?: string; sortDirection?: string }
// ChangeStatusRequest
{ status: string; reason?: string }
// AddMemberRequest
{ userIds: string[]; roleInProject: string }
// ProjectDeleteCheckVO
{ canDelete: boolean; reason?: string; statistics: ProjectDeleteStatistics }
```
### 3.2 SpaceNodeController — `/api/mdm/space-nodes`
| 编号 | 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|------|----------|
| - | GET | / | 分页查询空间节点 | page, size |
| - | GET | /{id} | 查询节点详情 | id(Path) |
| - | GET | /project/{projectId} | 按项目查询节点列表 | projectId(Path) |
| - | GET | /project/{projectId}/tree | 获取项目空间树 | projectId(Path) |
| - | GET | /project/{projectId}/roots | 获取项目根节点 | projectId(Path) |
| - | GET | /project/{projectId}/type/{nodeType} | 按项目+类型查询 | projectId(Path), nodeType(Path) |
| - | GET | /parent/{parentId}/children | 获取子节点列表 | parentId(Path) |
| - | POST | / | 创建空间节点 | SpaceNodeCreateDTO(Body) |
| - | POST | /batch | 批量创建节点 | List\<SpaceNodeCreateDTO\>(Body) |
| - | PUT | /{id} | 更新节点 | id(Path), SpaceNodeUpdateDTO(Body) |
| - | DELETE | /{id} | 删除节点 | id(Path) |
| - | GET | /{id}/delete-check | 删除前检查 | id(Path) |
| - | DELETE | /{id}/cascade | 级联删除(含子节点) | id(Path) |
| - | GET | /{id}/equipment | 获取设备详情 | id(Path) |
| - | GET | /equipment | 获取设备列表 | projectId(Param) |
| - | GET | /special-equipment | 获取特种设备列表 | projectId(Param) |
| - | GET | /expiring-inspection | 获取即将年检设备 | projectId(Param), daysAhead(默认90) |
| - | POST | /equipment | 创建设备 | EquipmentCreateDTO(Body) |
| - | POST | /equipment/batch | 批量创建设备 | List\<EquipmentCreateDTO\>(Body) |
| - | POST | /equipment/import | Excel导入设备 | file(Multipart), projectId(Param) |
| - | GET | /{buildingId}/floor-info | 获取楼栋楼层信息 | buildingId(Path) |
| - | GET | /debug/floor-numbers | 调试:检查房间楼层号 | projectId(Param) |
**关键DTO**
```typescript
// SpaceNodeCreateDTO / SpaceNodeUpdateForm
{ projectId, name, nodeCategory, nodeType, parentId?, buildingArea?, ... }
// SpaceNodeTreeDTO extends SpaceNode
{ ...SpaceNode, children: SpaceNodeTreeDTO[] }
// SpaceNodeDeleteCheckDTO
{ nodeId, nodeName, childCount, childTypeCount, totalDescendantCount }
// EquipmentCreateDTO
{ projectId, name, nodeType, parentId?, ...设备扩展字段 }
// FloorInfoVO
{ buildingId, buildingName, totalFloors, undergroundFloors, floors: FloorDetailVO[] }
```
### 3.3 InspectionItemController — `/api/mdm/inspection-items`
| 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|----------|
| POST | / | 创建巡检标准项 | InspectionItem(Body) |
| GET | / | 查询巡检标准项列表 | equipmentType?, systemType?, activeOnly? |
| GET | /{id} | 获取标准项详情 | id(Path) |
| PUT | /{id} | 更新标准项 | id(Path), InspectionItem(Body) |
| DELETE | /{id} | 删除标准项 | id(Path) |
**查询逻辑**activeOnly=true → 仅启用项equipmentType+systemType → 双条件过滤equipmentType → 单条件过滤systemType → 系统类型过滤;无参数 → 全部。
### 3.4 InspectionTemplateController — `/api/ops/inspection-templates`
| 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|----------|
| GET | / | 获取项目模板列表 | projectId(Param) |
| POST | / | 创建模板 | InspectionTemplate(Body) |
| GET | /{id} | 获取模板详情 | id(Path) |
| PUT | /{id} | 更新模板 | id(Path), InspectionTemplate(Body) |
| POST | /{id}/copy | 复制模板 | id(Path), newName(Param) |
| GET | /by-type/{equipmentType} | 按设备类型查模板 | equipmentType(Path) |
### 3.5 InspectionRecordController — `/api/mdm/inspection-records`
| 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|----------|
| POST | / | 创建巡检记录 | InspectionRecord(Body) |
| GET | / | 查询巡检记录列表 | equipmentId?, planId?, inspector?, status?, startDate?, endDate? |
| GET | /{id} | 获取记录详情 | id(Path) |
| PUT | /{id} | 更新记录 | id(Path), InspectionRecord(Body) |
| DELETE | /{id} | 删除记录 | id(Path) |
| POST | /{id}/complete | 完成巡检记录 | id(Path) |
**查询逻辑**equipmentId+日期范围 → 设备+日期equipmentId → 设备planId → 计划inspector → 巡检人status → 状态;日期范围 → 时间段;无参数 → 全部。
### 3.6 SparePartController — `/api/ops/spare-parts`
| 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|----------|
| GET | /categories | 获取分类列表 | - |
| POST | /categories | 创建分类 | SparePartCategory(Body) |
| GET | / | 获取备件列表 | projectId(Param), categoryId? |
| GET | /{id} | 获取备件详情 | id(Path) |
| POST | / | 创建备件 | SparePart(Body) |
| PUT | /{id} | 更新备件 | id(Path), SparePart(Body) |
| DELETE | /{id} | 删除备件 | id(Path) |
| GET | /low-stock | 获取低库存备件 | projectId(Param) |
| POST | /in-stock | 入库操作 | StockRequest(Body) |
| POST | /out-stock | 出库操作 | OutStockRequest(Body) |
| GET | /{id}/records | 获取备件出入库记录 | id(Path) |
**关键请求体**
```typescript
// StockRequest
{ sparePartId: UUID; quantity: Integer; recordedBy?: UUID; remarks?: String }
// OutStockRequest
{ sparePartId: UUID; quantity: Integer; relatedOrderId?: UUID; recordedBy?: UUID; remarks?: String }
```
### 3.7 EnergyController — `/api/ops/energy`
| 方法 | 路径 | 说明 | 请求参数 |
|------|------|------|----------|
| POST | /meters | 创建计量点 | EnergyMeter(Body) |
| GET | /meters | 获取计量点列表 | projectId(Param), energyType? |
| GET | /meters/{id} | 获取计量点详情 | id(Path) |
| PUT | /meters/{id} | 更新计量点 | id(Path), EnergyMeter(Body) |
| DELETE | /meters/{id} | 删除计量点 | id(Path) |
| POST | /consumption | 录入能耗记录 | RecordConsumptionRequest(Body) |
| GET | /consumption/{meterId} | 获取能耗记录 | meterId(Path), startDate?, endDate? |
| GET | /statistics/by-type | 按类型统计能耗 | projectId(Param), month(Param) |
| GET | /statistics/unit-consumption | 单位面积能耗 | projectId(Param), month(Param) |
**关键请求体**
```typescript
// RecordConsumptionRequest
{ meterId: UUID; currentReading: BigDecimal; recordedBy?: UUID }
```
---
## 四、业务规则
### 4.1 空间节点树形管理
#### 4.1.1 树形结构规则
```
项目 (Project)
├── 楼栋 (BUILDING) ← NodeCategory.BUILDING, order=1
│ ├── 单元 (UNIT) ← NodeCategory.BUILDING, order=2
│ │ ├── 楼层 (FLOOR) ← NodeCategory.BUILDING, order=3
│ │ │ └── 房间 (ROOM) ← NodeCategory.BUILDING, order=4
│ │ └── 房间 (ROOM) ← 可跳过楼层直接挂房间
│ └── 公共用房 (PUBLIC_ROOM)
├── 商铺 (SHOP) ← NodeCategory.BUILDING, order=2直接挂在项目下
├── 车库 (GARAGE) ← NodeCategory.PARKING, order=1
│ ├── 停车区域 (PARKING_AREA) ← NodeCategory.PARKING, order=2
│ │ └── 车位 (PARKING_SPACE) ← NodeCategory.PARKING, order=3
├── 设备房 (EQUIPMENT_ROOM) ← NodeCategory.FACILITY, order=1
├── 物业用房 (PROPERTY_OFFICE)
├── 门岗 (SECURITY_ROOM)
├── 公共区域 (PUBLIC_AREA) ← NodeCategory.AREA, order=1
├── 绿化区域 (GREEN_AREA)
└── 道路 (ROAD)
```
#### 4.1.2 树形路径维护
- **treePath**:物理路径,格式 `id1.id2.id3`,用于快速查询所有子孙节点
- **treePathName**:名称路径,格式 `项目/楼栋/单元/房间`,用于展示
- **level**层级深度根节点为0每层+1
- 创建/移动节点时自动维护 treePath 和 treePathName
#### 4.1.3 设备扩展模式
SpaceNode 通过 `isEquipment` 字段标记是否为设备节点。设备节点在基础空间字段之外,额外使用设备扩展字段(维保信息、巡检周期、特种设备证书等)。这种设计将设备信息嵌入空间节点,而非独立设备实体。
#### 4.1.4 删除规则
- 删除前必须调用 `delete-check` 接口检查子节点数量
- 普通删除:仅删除当前节点(有子节点时拒绝)
- 级联删除:删除当前节点及所有子孙节点
- 软删除:通过 `isDeleted` 标记,非物理删除
#### 4.1.5 批量操作
- 批量创建:通过 `batch` 接口,受 `BatchOperationValidator` 限制数量
- Excel导入设备支持 .xlsx/.xls 格式最大1000行文件类型校验
### 4.2 项目状态流转
#### 4.2.1 状态值
| 状态 | 描述 | 可流转到 |
|------|------|----------|
| PENDING | 待审核 | ACTIVE, DISABLED |
| ACTIVE | 正常 | DISABLED, ARCHIVED |
| DISABLED | 禁用 | ACTIVE, ARCHIVED |
| ARCHIVED | 已归档 | -(终态) |
#### 4.2.2 状态变更规则
- 每次状态变更必须记录 `ProjectStatusHistory`fromStatus, toStatus, reason, operatorId, operatorName
- 删除项目前必须调用 `delete-check` 检查关联数据
- 存在应收未收费用时无法删除项目
#### 4.2.3 项目成员管理
- 成员角色PROJECT_MANAGER(项目经理)、PROJECT_ADMIN(项目管理员)、OPERATION_STAFF(运营人员)、FINANCE_STAFF(财务人员)、VIEWER(查看者)
- 员工类型SECURITY(保安)、CLEANING(保洁)、GARDEN(绿化)、MAINTENANCE(维修)、CUSTOMER_SERVICE(客服)、PROJECT_STAFF(项目人员)
- 支持批量添加成员
### 4.3 巡检标准项管理
#### 4.3.1 标准项库
- 巡检标准项按 `equipmentType`(设备类型)和 `systemType`(系统类型)分类
- 每个标准项包含:检查项名称、检查方法、标准值、是否必检
- 标准项状态ACTIVE(启用)/INACTIVE(停用)
- 支持按 activeOnly=true 仅查询启用项
#### 4.3.2 巡检模板
- 模板按项目+设备类型组织
- 模板包含检查项列表JSON格式存储
- 支持模板版本管理version字段
- 支持模板复制copy接口
- 模板与标准项通过 equipmentType 逻辑关联
#### 4.3.3 巡检记录
- 记录关联设备equipmentId和计划planId
- 检查结果状态NORMAL(正常)/WARNING(预警)/ABNORMAL(异常)
- 支持签到信息(时间、位置、照片)
- 检查项结果和异常问题以JSONB存储
- 完成操作:调用 `complete` 接口标记完成
### 4.4 备件库存管理
#### 4.4.1 库存管理规则
- 每个备件有 `currentStock`(当前库存)和 `safeStock`(安全库存)
-`currentStock < safeStock` 时触发低库存预警
- 低库存查询:`low-stock` 接口返回低于安全库存的备件列表
#### 4.4.2 出入库操作
| 操作 | 说明 | 关键字段 |
|------|------|----------|
| 入库(IN) | 增加库存 | sparePartId, quantity, recordedBy, remarks |
| 出库(OUT) | 减少库存 | sparePartId, quantity, relatedOrderId, recordedBy, remarks |
| 盘点(CHECK) | 库存盘点 | sparePartId, quantity, recordedBy |
| 调整(ADJUST) | 库存调整 | sparePartId, quantity, recordedBy |
- 每次操作记录 `SparePartRecord`包含操作后余额balance
- 出库可关联工单relatedOrderId
- 出库时校验库存不能为负
#### 4.4.3 备件分类
- 支持树形分类parentId 自关联)
- 分类编码唯一
- 备件通过 categoryId 关联分类
### 4.5 能耗计量管理
#### 4.5.1 计量点管理
- 计量点按能源类型分类:照明插座用电、空调用电、动力用电、特殊用电、给排水、燃气
- 计量点关联空间节点spaceNodeId
- 计量点状态ACTIVE(启用)/INACTIVE(停用)
#### 4.5.2 能耗记录
- 抄表记录包含:上次读数、本次读数、消耗量、金额
- 消耗量 = 本次读数 - 上次读数
- 金额 = 消耗量 × 单价(计量点的 unitPrice
- 记录方式MANUAL(手动录入)/IOT(IoT自动采集)
#### 4.5.3 能耗统计
- **按类型统计**`getConsumptionByType(projectId, month)` → `Map<EnergyType, BigDecimal>`
- **单位面积能耗**`getUnitConsumption(projectId, month)` → 总能耗/总建筑面积
- 支持按日期范围查询能耗趋势
---
## 五、前端操作流程
### 5.1 项目管理流程
```
项目列表页 → 新建项目
├── 填写项目基本信息(编码、名称、类型、地址)
├── 系统自动生成项目编码generate-code
├── 创建后自动初始化 ProjectConfig默认配置
└── 跳转到项目详情
项目详情页
├── 基本信息Tab编辑项目信息
├── 成员管理Tab
│ ├── 查看成员列表(分页)
│ ├── 添加成员(从企业员工中选择)
│ └── 移除成员
├── 空间管理Tab跳转到空间节点管理
├── 统计数据Tab查看项目统计
├── 配置管理Tab功能开关配置
└── 状态管理:变更项目状态(需填写原因)
项目删除
├── 先调用 delete-check 检查关联数据
├── 有应收未收费用 → 无法删除
└── 无关联数据 → 确认删除
```
### 5.2 空间节点管理流程
```
空间管理页(左侧树 + 右侧详情)
├── 左侧树形导航
│ ├── 加载项目空间树getSpaceTree
│ ├── 点击节点 → 右侧显示详情
│ └── 展开/折叠节点
├── 右侧详情区
│ ├── 节点基本信息
│ ├── 面积信息
│ ├── 地址信息
│ └── 子节点列表(表格)
├── 新增节点
│ ├── 选择父节点
│ ├── 选择节点类型NodeType
│ ├── 自动填充 NodeCategory
│ └── 填写名称、面积等信息
├── 批量创建
│ ├── 批量创建楼栋/单元/房间
│ └── 受 BatchOperationValidator 限制
├── 设备管理
│ ├── 创建设备isEquipment=true
│ ├── 批量创建设备
│ ├── Excel导入设备
│ ├── 查看设备列表
│ ├── 查看特种设备列表
│ └── 查看即将年检设备90天内
└── 删除节点
├── 删除前检查delete-check
└── 确认删除或级联删除
```
### 5.3 巡检管理流程
```
巡检标准项管理
├── 标准项列表页
│ ├── 按设备类型/系统类型筛选
│ ├── 仅查看启用项activeOnly
│ ├── 新增标准项
│ ├── 编辑标准项
│ └── 停用/启用标准项
└── 巡检模板管理
├── 模板列表页(按项目筛选)
├── 新增模板
│ ├── 选择设备类型
│ ├── 配置检查项(从标准项库选择)
│ └── 设置预计耗时
├── 编辑模板
├── 复制模板
└── 按设备类型查模板
巡检记录管理
├── 记录列表页
│ ├── 按设备/计划/巡检人/状态/日期筛选
│ └── 查看记录详情
├── 创建巡检记录
│ ├── 选择设备
│ ├── 填写巡检日期和巡检人
│ ├── 逐项填写检查结果
│ ├── 上报异常问题
│ └── 签到(时间、位置、照片)
└── 完成巡检
└── 调用 complete 接口标记完成
```
### 5.4 备件管理流程
```
备件分类管理
├── 分类列表
├── 新增分类(支持树形层级)
└── 编辑分类
备件台账管理
├── 备件列表页
│ ├── 按项目筛选
│ ├── 按分类筛选
│ ├── 低库存预警标识
│ └── 新增/编辑/删除备件
├── 入库操作
│ ├── 选择备件
│ ├── 输入入库数量
│ └── 确认入库 → 更新 currentStock
├── 出库操作
│ ├── 选择备件
│ ├── 输入出库数量
│ ├── 可关联工单
│ └── 确认出库 → 更新 currentStock
└── 出入库记录
└── 查看备件的所有操作流水
低库存预警
└── 低库存备件列表currentStock < safeStock
```
### 5.5 能耗管理流程
```
计量点管理
├── 计量点列表页
│ ├── 按项目筛选
│ ├── 按能源类型筛选
│ └── 新增/编辑/删除计量点
└── 计量点详情
├── 关联空间节点
├── 额定容量、单价
└── 状态管理
能耗抄表
├── 录入能耗
│ ├── 选择计量点
│ ├── 输入本次读数
│ ├── 系统自动计算消耗量和金额
│ └── 选择记录方式(手动/IoT
└── 能耗记录查询
├── 按计量点查询
└── 按日期范围查询
能耗统计
├── 按类型统计
│ └── 指定月份各能源类型消耗量
└── 单位面积能耗
└── 总能耗/总建筑面积
```
---
## 六、与原需求文档 02-SPACE_NODE_DESIGN.md 的差异对比
### 6.1 数据模型差异
| 对比项 | 原需求文档设计 | 实际代码实现 | 差异分析 |
|--------|---------------|-------------|----------|
| **API路径前缀** | `/api/v1/mdm/space-nodes` | `/api/mdm/space-nodes` | 去掉了v1版本号 |
| **code字段** | 有 `code` 列,`UNIQUE(project_id, code)` | 无 `code` 列,列名 `project_code` 实际存 projectId | 原设计的空间编码未实现project_code 列名与实际存储不匹配 |
| **PostGIS字段** | `location GEOMETRY(Point)`, `boundary GEOMETRY(Polygon)` | 无PostGIS字段 | 地图服务未实现,仅保留经纬度数值字段 |
| **attributes字段** | JSONB类型 | String(2000) | 降级为字符串存储JSON未使用PostgreSQL JSONB |
| **设备扩展字段** | 未设计(设备独立为 asset_equipment 表) | SpaceNode 内嵌设备扩展字段 | 实际采用"空间+设备"混合模型isEquipment标记 |
| **NodeType枚举** | 无 PUBLIC_ROOM | 增加 PUBLIC_ROOM(公共用房) | 实际增加了公共用房类型 |
| **删除方式** | 未明确 | 软删除isDeleted字段 | 实际采用软删除 |
| **唯一约束** | `UNIQUE(project_id, code)` | 无唯一约束 | 空间编码唯一性未在数据库层面约束 |
| **索引** | GIST空间索引、GIN属性索引 | 普通B-tree索引 | 无空间索引和JSON索引 |
### 6.2 API接口差异
| 对比项 | 原需求文档设计 | 实际代码实现 | 差异分析 |
|--------|---------------|-------------|----------|
| **树形查询** | `GET /tree` 全局树 | `GET /project/{projectId}/tree` 按项目 | 实际按项目维度查询,更合理 |
| **祖先节点** | `GET /{id}/ancestors` | 未实现 | 祖先链查询缺失 |
| **子孙节点** | `GET /{id}/descendants` | 未实现 | 可通过 treePath LIKE 查询替代 |
| **移动节点** | `PUT /{id}/move` | 未实现 | 节点移动功能缺失 |
| **类型快捷查询** | `/buildings`, `/rooms`, `/parking-spaces`, `/shops` | `GET /project/{projectId}/type/{nodeType}` | 统一为按类型查询,更通用 |
| **批量更新** | `PUT /batch` | 未实现 | 仅支持批量创建 |
| **批量删除** | `DELETE /batch` | 未实现 | 仅支持单个/级联删除 |
| **导入模板下载** | `GET /export/template` | 未实现 | 无模板下载接口 |
| **数据导出** | `GET /export` | 未实现 | 无导出功能 |
| **地图相关** | `/map/markers`, `/map/boundaries`, `/{id}/location`, `/{id}/boundary` | 未实现 | 地图服务完全未实现 |
| **统计分析** | `/statistics`, `/statistics/by-type`, `/statistics/by-status` | 未实现 | 空间统计接口缺失 |
| **删除前检查** | 未设计 | `GET /{id}/delete-check` | 实际增加了安全检查 |
| **级联删除** | 未设计 | `DELETE /{id}/cascade` | 实际增加了级联删除 |
| **设备管理** | 未设计(设备独立模块) | 设备CRUD集成在SpaceNodeController | 空间与设备管理合并 |
| **Excel导入** | 空间节点导入 | 仅设备导入 | 空间节点批量导入未实现 |
| **楼层信息** | 未设计 | `GET /{buildingId}/floor-info` | 实际增加了楼栋楼层信息接口 |
### 6.3 前端差异
| 对比项 | 原需求文档设计 | 实际代码实现 | 差异分析 |
|--------|---------------|-------------|----------|
| **地图模式** | 高德地图集成,支持标注/绘制/路径 | 未实现 | 地图功能完全未开发 |
| **MapEditor组件** | AMap SDK集成 | 未实现 | - |
| **空间编码** | 自动生成空间编码规则 | 未实现 | SpaceNode无code字段 |
| **批量创建房间** | 支持 startFloor/endFloor/roomsPerFloor 模板 | 仅支持 DTO 列表批量创建 | 智能批量创建未实现 |
### 6.4 业务规则差异
| 对比项 | 原需求文档设计 | 实际代码实现 | 差异分析 |
|--------|---------------|-------------|----------|
| **设备模型** | 独立 Equipment 实体asset_equipment表 | SpaceNode 内嵌设备扩展字段 | 两种模型并存module-mdm 用 SpaceNode 扩展module-asset 用独立 Equipment |
| **项目统计** | 数据库视图实时计算 | ProjectStatistics 实体快照 | 实际采用快照模式,需手动同步 |
| **空间编码** | 自动生成编码规则 | 未实现 | 无自动编码机制 |
| **PostGIS** | 空间查询(范围搜索、距离计算) | 未使用 | 无空间数据库能力 |
### 6.5 差异总结
| 类别 | 已实现 | 部分实现 | 未实现 |
|------|--------|----------|--------|
| **数据模型** | 基础字段、树形结构、NodeType枚举 | 设备扩展字段(混合模型) | PostGIS、JSONB、空间编码 |
| **API接口** | 基础CRUD、树形查询、设备管理 | 批量操作 | 地图服务、统计分析、导入导出 |
| **前端** | 树形导航、表单编辑 | - | 地图模式、智能批量创建 |
| **业务规则** | 删除检查、级联删除 | - | 空间编码、空间查询 |
---
## 附录A服务层接口清单
| 服务 | 关键方法 |
|------|----------|
| ProjectService | create, update, delete, findById, findByCode, queryProjects, getSelectorList, generateCode, changeStatus, checkProjectDelete |
| ProjectMemberService | getMembers, addMembers, removeMember |
| ProjectConfigService | getConfig, updateConfig |
| ProjectStatisticsService | getStatistics |
| SpaceNodeService | create, batchCreate, update, delete, deleteWithChildren, findById, findByProjectId, getTreeByProjectId, findRootsByProjectId, findChildren, findByProjectIdAndNodeType, checkDeleteInfo, getEquipmentById, getEquipmentList, getSpecialEquipmentList, getExpiringInspectionEquipment, createEquipment, batchCreateEquipment, importEquipmentFromExcel, getBuildingFloorInfo |
| InspectionItemService | createItem, getItemById, updateItem, deleteItem, getAllItems, getActiveItems, getItemsByEquipmentType, getItemsBySystemType, getItemsByEquipmentTypeAndSystemType |
| InspectionTemplateService | createTemplate, getTemplateById, updateTemplate, getTemplatesByProject, getTemplatesByType, copyTemplate |
| InspectionRecordService | createRecord, getRecordById, updateRecord, deleteRecord, completeRecord, getAllRecords, getRecordsByEquipment, getRecordsByEquipmentAndDateRange, getRecordsByPlan, getRecordsByInspector, getRecordsByStatus, getRecordsByDateRange |
| SparePartService | createSparePart, getSparePartById, updateSparePart, deleteSparePart, getSparePartsByProject, getSparePartsByCategory, getLowStockParts, inStock, outStock, getSparePartRecords, getCategories, createCategory |
| EnergyMeterService | createMeter, getMeterById, updateMeter, deleteMeter, getMetersByProject, getMetersByType |
| EnergyConsumptionService | recordConsumption, getConsumptionByMeter, getConsumptionByMeterAndDateRange, getConsumptionByType, getUnitConsumption |
---
## 附录B前端API文件对照
| 前端文件 | 对应后端Controller | 说明 |
|----------|-------------------|------|
| `src/api/project.ts` | ProjectController | 项目CRUD、成员、配置、统计 |
| `src/api/space.ts` | SpaceNodeController | 空间节点CRUD、树形查询 |
| `src/api/inspection-item.ts` | InspectionItemController | 巡检标准项CRUD |
| `src/api/inspection-template.ts` | InspectionTemplateController | 巡检模板CRUD |
| `src/api/inspection-record.ts` | InspectionRecordController | 巡检记录CRUD |
| `src/api/sparepart.ts` | SparePartController | 备件CRUD、出入库 |
| `src/api/energy.ts` | EnergyController | 计量点CRUD、能耗记录 |
| `src/api/maintenance-plan.ts` | - | 维保计划(独立模块) |
| `src/types/project.ts` | - | 项目相关类型定义 |
| `src/types/space.ts` | - | 空间节点类型定义 |
---
**文档生成说明**:本文档基于 `ether-pms/module-mdm` 模块的实际代码反推生成涵盖13个实体、7个控制器、11个服务接口的完整分析。所有字段、枚举、API端点均来源于实际代码与原需求文档的差异已在第六章详细对比。