docs: 清理微服务架构遗留文档,更新开发规范
- 删除微服务架构设计文档(PRODUCT_REQUIREMENTS.md) - 删除pending-features-spec规格文档 - 删除01-SPACE_AND_MDM.md微服务描述 - 更新DEVELOPMENT_STANDARDS.md为单体架构规范 - 更新FEATURE_LIST.md功能列表 - 更新SPACE_NODE_DESIGN.md空间设计文档
This commit is contained in:
parent
223302b725
commit
5f016436c9
|
|
@ -42,7 +42,7 @@ Ether 物业管理平台是一个全场景物业管理解决方案,包含 Web
|
||||||
## 账号
|
## 账号
|
||||||
|
|
||||||
- 用户名: admin
|
- 用户名: admin
|
||||||
- 密码: Admin123!
|
- 密码: Admin@123
|
||||||
|
|
||||||
## 项目管理
|
## 项目管理
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,6 +425,22 @@
|
||||||
| FEATURE-C103 | 访客记录查询API | ✅ 已完成 | 2026-02-10 |
|
| FEATURE-C103 | 访客记录查询API | ✅ 已完成 | 2026-02-10 |
|
||||||
| FEATURE-C104 | 前端访客管理页面 | ✅ 已完成 | 2026-02-10 |
|
| FEATURE-C104 | 前端访客管理页面 | ✅ 已完成 | 2026-02-10 |
|
||||||
|
|
||||||
|
### 7.11 非居物业设备管理增强 ✅(2026-03-23新增)
|
||||||
|
|
||||||
|
| 编号 | 特性名称 | 状态 | 完成日期 |
|
||||||
|
| ---- | -------- | ---- | -------- |
|
||||||
|
| FEATURE-C110 | 设备技术参数扩展 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C111 | 特种设备证书管理 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C112 | 预防性维护引擎-触发条件 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C113 | 预防性维护引擎-任务生成 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C114 | 预防性维护引擎-SLA管理 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C115 | 能耗监控-分项计量体系 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C116 | 能耗监控-数据分析报表 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C117 | 备件库存-库位管理 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C118 | 备件库存-采购与领用 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C119 | 设备故障预测-MTBF/MTTR分析 | ⬜ 待开发 | - |
|
||||||
|
| FEATURE-C120 | 设备点检标准库 | ⬜ 待开发 | - |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 八、特性统计
|
## 八、特性统计
|
||||||
|
|
@ -433,15 +449,15 @@
|
||||||
|
|
||||||
| 状态 | 数量 | 占比 |
|
| 状态 | 数量 | 占比 |
|
||||||
| --------- | ------- | -------- |
|
| --------- | ------- | -------- |
|
||||||
| ✅ 已完成 | 147 | 66.5% |
|
| ✅ 已完成 | 147 | 65.0% |
|
||||||
| ⬜ 待开发 | 74 | 33.5% |
|
| ⬜ 待开发 | 85 | 37.6% |
|
||||||
| ⏸️ 已暂停 | 7 | 3.2% |
|
| ⏸️ 已暂停 | 7 | 3.1% |
|
||||||
| **合计** | **221** | **100%** |
|
| **合计** | **232** | **100%** |
|
||||||
|
|
||||||
**说明**:
|
**说明**:
|
||||||
|
|
||||||
- 已完成特性:147个(77个归档 + 70个阶段特性)
|
- 已完成特性:147个(77个归档 + 70个阶段特性)
|
||||||
- 待开发特性:9个(第四阶段集成平台)+ 45个(APP端)+ 20个(前端优化改进)
|
- 待开发特性:9个(第四阶段集成平台)+ 45个(APP端)+ 20个(前端优化改进)+ 11个(非居物业增强)
|
||||||
- 已暂停特性:7个
|
- 已暂停特性:7个
|
||||||
|
|
||||||
### 8.2 按阶段统计
|
### 8.2 按阶段统计
|
||||||
|
|
@ -457,7 +473,8 @@
|
||||||
| 第五阶段 | 0 | 7 | 7 |
|
| 第五阶段 | 0 | 7 | 7 |
|
||||||
| 已完成归档 | 0 | 77 | 77 |
|
| 已完成归档 | 0 | 77 | 77 |
|
||||||
| 前端优化改进 | 20 | 0 | 20 |
|
| 前端优化改进 | 20 | 0 | 20 |
|
||||||
| **合计** | **74** | **147** | **221** |
|
| **非居物业设备增强** | **11** | **0** | **11** |
|
||||||
|
| **合计** | **85** | **147** | **232** |
|
||||||
|
|
||||||
**注**: 暂停功能 7 个不计入排期
|
**注**: 暂停功能 7 个不计入排期
|
||||||
|
|
||||||
|
|
@ -473,7 +490,8 @@
|
||||||
| 第四阶段 | 32人天 | 67人天 | 99人天 |
|
| 第四阶段 | 32人天 | 67人天 | 99人天 |
|
||||||
| 第五阶段 | 10人天 | 13人天 | 23人天 |
|
| 第五阶段 | 10人天 | 13人天 | 23人天 |
|
||||||
| 前端优化改进 | 34.5人天 | - | 34.5人天 |
|
| 前端优化改进 | 34.5人天 | - | 34.5人天 |
|
||||||
| **合计** | **213.5人天** | **204人天** | **417.5人天** |
|
| **非居物业设备增强** | **25人天** | **30人天** | **55人天** |
|
||||||
|
| **合计** | **238.5人天** | **234人天** | **472.5人天** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -581,6 +599,8 @@
|
||||||
| 2026-02-24 | 同步文档:补充设备维保管理特性(FEATURE-C090~096) | - |
|
| 2026-02-24 | 同步文档:补充设备维保管理特性(FEATURE-C090~096) | - |
|
||||||
| 2026-02-24 | 同步文档:补充访客管理特性(FEATURE-C100~104) | - |
|
| 2026-02-24 | 同步文档:补充访客管理特性(FEATURE-C100~104) | - |
|
||||||
| 2026-02-24 | 更新统计数字:已完成147个,待开发74个 | - |
|
| 2026-02-24 | 更新统计数字:已完成147个,待开发74个 | - |
|
||||||
|
| 2026-03-23 | 新增非居物业设备管理增强需求(FEATURE-C110~120) | - |
|
||||||
|
| 2026-03-23 | 更新统计数字:已完成147个,待开发85个,总计232个 | - |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,372 +0,0 @@
|
||||||
# Ether 智慧物业管理平台 - 待开发功能完善规范
|
|
||||||
|
|
||||||
## 📋 项目概述
|
|
||||||
|
|
||||||
本文档定义了待开发功能的详细实现规范,确保开发过程中不影响已完成的功能模块。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 开发目标
|
|
||||||
|
|
||||||
### 总体目标
|
|
||||||
完善6个待开发功能模块,实现前后端完整对接,并通过E2E自动化测试验证。
|
|
||||||
|
|
||||||
### 实际状态分析(更新后)
|
|
||||||
|
|
||||||
| 模块 | 前端状态 | 后端状态 | API匹配 | 实际工作量 |
|
|
||||||
|------|---------|---------|---------|-----------|
|
|
||||||
| 设备管理 | ✅ 页面完整 | ⚠️ 占位接口 | ❌ 路径不匹配 | 中(需修复API路径+实现后端) |
|
|
||||||
| 收费管理 | ✅ 页面完整 | ✅ 已完整实现 | ✅ 匹配 | 低(仅需启用前端API调用) |
|
|
||||||
| 巡检管理 | ✅ 页面完整 | ✅ 已实现 | ✅ 匹配 | 低(联调测试) |
|
|
||||||
| 工单管理 | ✅ 页面完整 | ✅ 已实现 | ✅ 匹配 | 低(联调测试) |
|
|
||||||
| 访客管理 | ✅ 页面完整 | ✅ 已实现 | ✅ 匹配 | 低(联调测试) |
|
|
||||||
| 通知管理 | ✅ 页面完整 | ✅ 已实现 | ✅ 匹配 | 低(联调测试) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚨 关键问题与解决方案
|
|
||||||
|
|
||||||
### 问题1: 设备管理 API 路径不匹配
|
|
||||||
|
|
||||||
**现状**:
|
|
||||||
- 前端 API: `/api/v1/asset/equipments` (api/asset/equipment.ts)
|
|
||||||
- 后端 API: `/api/v1/mdm/equipments` (EquipmentController.java)
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
在后端添加 `/api/v1/asset/equipments` 路径映射,保持前端不变。
|
|
||||||
|
|
||||||
### 问题2: 设备表存在两个定义
|
|
||||||
|
|
||||||
**现状**:
|
|
||||||
- `mdm_equipment` (V4迁移脚本)
|
|
||||||
- `asset_equipment` (V9迁移脚本)
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
统一使用 `mdm_equipment` 表,因为测试数据已使用该表。
|
|
||||||
|
|
||||||
### 问题3: 收费管理前端显示"开发中"
|
|
||||||
|
|
||||||
**现状**:
|
|
||||||
- 后端 FeeController 已完整实现所有功能
|
|
||||||
- 前端代码注释显示"功能开发中",API调用被禁用
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
移除前端"开发中"提示,启用API调用。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📐 技术规范
|
|
||||||
|
|
||||||
### 后端开发规范
|
|
||||||
|
|
||||||
#### 1. 服务端口分配
|
|
||||||
```
|
|
||||||
ether-gateway: 8080
|
|
||||||
ether-auth: 8081
|
|
||||||
ether-mdm: 8082
|
|
||||||
ether-ops: 8083
|
|
||||||
ether-finance: 8085
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. API路径规范
|
|
||||||
```
|
|
||||||
/api/v1/{module}/{resource}
|
|
||||||
```
|
|
||||||
- module: 模块名 (mdm, ops, finance, asset)
|
|
||||||
- resource: 资源名 (复数形式)
|
|
||||||
|
|
||||||
#### 3. 响应格式规范
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 200,
|
|
||||||
"message": "success",
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. 实体规范
|
|
||||||
- 所有实体使用UUID作为主键
|
|
||||||
- 必须包含 `createdAt` 和 `updatedAt` 字段
|
|
||||||
- 使用 `@PrePersist` 和 `@PreUpdate` 自动设置时间戳
|
|
||||||
|
|
||||||
#### 5. 数据库规范
|
|
||||||
- PostgreSQL 数据库
|
|
||||||
- 端口: 5432
|
|
||||||
- 用户名: ether
|
|
||||||
- 密码: ether123
|
|
||||||
- 表名使用下划线命名法 (snake_case)
|
|
||||||
|
|
||||||
### 前端开发规范
|
|
||||||
|
|
||||||
#### 1. 组件命名
|
|
||||||
- 组件文件: kebab-case (如 `equipment-list.vue`)
|
|
||||||
- 组件名称: PascalCase (如 `EquipmentList`)
|
|
||||||
|
|
||||||
#### 2. API调用
|
|
||||||
- 统一使用 `@/api/` 目录下的API模块
|
|
||||||
- 使用 TypeScript 类型定义
|
|
||||||
|
|
||||||
#### 3. 状态管理
|
|
||||||
- 使用 Pinia 进行状态管理
|
|
||||||
- Store 文件放置在 `@/stores/` 目录
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 功能模块详细规范
|
|
||||||
|
|
||||||
### 1. 设备管理模块 (修复API路径 + 实现后端)
|
|
||||||
|
|
||||||
#### 1.1 现有资源
|
|
||||||
|
|
||||||
**前端页面** (已存在):
|
|
||||||
- `views/mdm/equipment/index.vue` - 设备列表页面(完整)
|
|
||||||
- `views/asset/equipment-statistics/index.vue` - 设备统计页面
|
|
||||||
|
|
||||||
**数据库表** (已存在):
|
|
||||||
- `mdm_equipment` - 设备主表 (V4迁移脚本已创建)
|
|
||||||
|
|
||||||
**后端** (需完善):
|
|
||||||
- `EquipmentController.java` - 仅有占位接口
|
|
||||||
|
|
||||||
#### 1.2 需要实现的内容
|
|
||||||
|
|
||||||
**后端实现**:
|
|
||||||
|
|
||||||
1. 创建设备实体类
|
|
||||||
- 文件: `ether-mdm/src/main/java/com/ether/mdm/entity/Equipment.java`
|
|
||||||
- 映射表: `mdm_equipment`
|
|
||||||
|
|
||||||
2. 创建Repository
|
|
||||||
- 文件: `ether-mdm/src/main/java/com/ether/mdm/repository/EquipmentRepository.java`
|
|
||||||
|
|
||||||
3. 创建Service
|
|
||||||
- 文件: `ether-mdm/src/main/java/com/ether/mdm/service/EquipmentService.java`
|
|
||||||
- 文件: `ether-mdm/src/main/java/com/ether/mdm/service/impl/EquipmentServiceImpl.java`
|
|
||||||
|
|
||||||
4. 完善Controller
|
|
||||||
- 添加 `/api/v1/asset/equipments` 路径映射
|
|
||||||
- 实现完整CRUD接口
|
|
||||||
|
|
||||||
#### 1.3 API接口设计
|
|
||||||
|
|
||||||
**设备管理 API** (前端已定义,后端需实现):
|
|
||||||
|
|
||||||
| 方法 | 前端调用路径 | 后端实现路径 | 描述 |
|
|
||||||
|------|-------------|-------------|------|
|
|
||||||
| GET | /api/v1/asset/equipments | 需映射 | 获取设备列表 |
|
|
||||||
| GET | /api/v1/asset/equipments/{id} | 需映射 | 获取设备详情 |
|
|
||||||
| POST | /api/v1/asset/equipments | 需映射 | 创建设备 |
|
|
||||||
| PUT | /api/v1/asset/equipments/{id} | 需映射 | 更新设备 |
|
|
||||||
| DELETE | /api/v1/asset/equipments/{id} | 需映射 | 删除设备 |
|
|
||||||
| GET | /api/v1/asset/equipments/type/{type} | 需映射 | 按类型查询 |
|
|
||||||
| GET | /api/v1/asset/equipments/status/{status} | 需映射 | 按状态查询 |
|
|
||||||
| GET | /api/v1/asset/equipments/space-node/{spaceNodeId} | 需映射 | 按空间节点查询 |
|
|
||||||
| GET | /api/v1/asset/equipments/search | 需映射 | 搜索设备 |
|
|
||||||
| PATCH | /api/v1/asset/equipments/{id}/status | 需映射 | 更新设备状态 |
|
|
||||||
| POST | /api/v1/asset/equipments/{id}/maintenance | 需映射 | 记录保养 |
|
|
||||||
| GET | /api/v1/asset/equipments/generate-code | 需映射 | 生成设备编码 |
|
|
||||||
| GET | /api/v1/asset/equipment/qrcode/{id} | 需映射 | 获取二维码 |
|
|
||||||
| GET | /api/v1/asset/equipment/qrcode/info/{qrCode} | 需映射 | 扫码获取设备信息 |
|
|
||||||
|
|
||||||
#### 1.4 数据库表结构 (已存在)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- mdm_equipment 表已存在于 V4 迁移脚本
|
|
||||||
CREATE TABLE mdm_equipment (
|
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
project_id UUID NOT NULL,
|
|
||||||
code VARCHAR(50) NOT NULL,
|
|
||||||
name VARCHAR(100) NOT NULL,
|
|
||||||
equipment_type VARCHAR(20) NOT NULL,
|
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'NORMAL',
|
|
||||||
brand VARCHAR(50),
|
|
||||||
model VARCHAR(50),
|
|
||||||
specifications VARCHAR(500),
|
|
||||||
serial_number VARCHAR(100),
|
|
||||||
manufacturer VARCHAR(100),
|
|
||||||
supplier VARCHAR(100),
|
|
||||||
space_node_id UUID,
|
|
||||||
location_desc VARCHAR(200),
|
|
||||||
purchase_date DATE,
|
|
||||||
install_date DATE,
|
|
||||||
warranty_date DATE,
|
|
||||||
purchase_price NUMERIC(12, 2),
|
|
||||||
service_life INTEGER,
|
|
||||||
maintenance_cycle INTEGER,
|
|
||||||
last_maintenance_date DATE,
|
|
||||||
next_maintenance_date DATE,
|
|
||||||
manager_id UUID,
|
|
||||||
manager_name VARCHAR(50),
|
|
||||||
contact_phone VARCHAR(20),
|
|
||||||
images VARCHAR(1000),
|
|
||||||
manual_url VARCHAR(255),
|
|
||||||
remarks VARCHAR(500),
|
|
||||||
attributes JSONB,
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
created_by UUID,
|
|
||||||
updated_by UUID,
|
|
||||||
CONSTRAINT uk_equipment_project_code UNIQUE (project_id, code)
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. 收费管理模块 (启用前端API调用)
|
|
||||||
|
|
||||||
#### 2.1 现有资源
|
|
||||||
|
|
||||||
**前端页面** (已存在):
|
|
||||||
- `views/mdm/fee/index.vue` - 收费管理页面(完整)
|
|
||||||
|
|
||||||
**后端** (已完整实现):
|
|
||||||
- `FeeController.java` - 完整的CRUD接口
|
|
||||||
- `FeeService.java` - 完整的业务逻辑
|
|
||||||
|
|
||||||
#### 2.2 需要修改的内容
|
|
||||||
|
|
||||||
**前端修改**:
|
|
||||||
|
|
||||||
1. 移除"功能开发中"提示
|
|
||||||
- 文件: `views/mdm/fee/index.vue`
|
|
||||||
- 删除 `showFeatureTip` 相关代码
|
|
||||||
|
|
||||||
2. 启用API调用
|
|
||||||
- 文件: `views/mdm/fee/index.vue`
|
|
||||||
- 在 `fetchBills`、`fetchStatistics` 等方法中启用API调用
|
|
||||||
|
|
||||||
#### 2.3 后端已实现的API
|
|
||||||
|
|
||||||
| 方法 | 路径 | 描述 |
|
|
||||||
|------|------|------|
|
|
||||||
| GET | /api/v1/finance/fee-items | 获取收费项目列表 |
|
|
||||||
| POST | /api/v1/finance/fee-items | 创建收费项目 |
|
|
||||||
| PUT | /api/v1/finance/fee-items/{id} | 更新收费项目 |
|
|
||||||
| DELETE | /api/v1/finance/fee-items/{id} | 删除收费项目 |
|
|
||||||
| GET | /api/v1/finance/bills | 获取账单列表 |
|
|
||||||
| POST | /api/v1/finance/bills | 创建账单 |
|
|
||||||
| PUT | /api/v1/finance/bills/{id} | 更新账单 |
|
|
||||||
| DELETE | /api/v1/finance/bills/{id} | 删除账单 |
|
|
||||||
| POST | /api/v1/finance/bills/{billId}/pay | 缴费 |
|
|
||||||
| GET | /api/v1/finance/payments | 获取支付记录 |
|
|
||||||
| GET | /api/v1/finance/statistics | 统计数据 |
|
|
||||||
| GET | /api/v1/finance/statistics/today-receivable | 今日应收 |
|
|
||||||
| GET | /api/v1/finance/statistics/today-received | 今日实收 |
|
|
||||||
| GET | /api/v1/finance/statistics/pending-amount | 待收金额 |
|
|
||||||
| GET | /api/v1/finance/statistics/overdue-amount | 逾期金额 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. 巡检管理模块 (联调测试)
|
|
||||||
|
|
||||||
#### 3.1 现有资源
|
|
||||||
- 前端页面: ✅ 完整
|
|
||||||
- 后端API: ✅ 完整
|
|
||||||
- API匹配: ✅ 正确
|
|
||||||
|
|
||||||
#### 3.2 验证要点
|
|
||||||
- 巡检计划CRUD
|
|
||||||
- 巡检点管理
|
|
||||||
- 巡检任务生成与执行
|
|
||||||
- 巡检记录提交
|
|
||||||
- 统计数据准确性
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. 工单管理模块 (联调测试)
|
|
||||||
|
|
||||||
#### 4.1 现有资源
|
|
||||||
- 前端页面: ✅ 完整(含组件和单元测试)
|
|
||||||
- 后端API: ✅ 完整
|
|
||||||
- API匹配: ✅ 正确
|
|
||||||
|
|
||||||
#### 4.2 验证要点
|
|
||||||
- 工单创建流程
|
|
||||||
- 工单分配与接单
|
|
||||||
- 工单状态流转
|
|
||||||
- 工单完成与关闭
|
|
||||||
- 工单统计
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. 访客管理模块 (联调测试)
|
|
||||||
|
|
||||||
#### 5.1 现有资源
|
|
||||||
- 前端页面: ✅ 完整
|
|
||||||
- 后端API: ✅ 完整
|
|
||||||
- API匹配: ✅ 正确
|
|
||||||
|
|
||||||
#### 5.2 验证要点
|
|
||||||
- 访客预约流程
|
|
||||||
- 审批流程
|
|
||||||
- 入场/离场登记
|
|
||||||
- 黑名单管理
|
|
||||||
- 历史访客查询
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6. 通知管理模块 (联调测试)
|
|
||||||
|
|
||||||
#### 6.1 现有资源
|
|
||||||
- 前端页面: ✅ 完整
|
|
||||||
- 后端API: ✅ 完整
|
|
||||||
- API匹配: ✅ 正确
|
|
||||||
|
|
||||||
#### 6.2 验证要点
|
|
||||||
- 通知渠道配置
|
|
||||||
- 通知模板管理
|
|
||||||
- 通知规则配置
|
|
||||||
- 通知发送与接收
|
|
||||||
- 通知状态管理
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 测试规范
|
|
||||||
|
|
||||||
### E2E测试策略
|
|
||||||
|
|
||||||
#### 测试工具
|
|
||||||
- Puppeteer 浏览器自动化
|
|
||||||
- 测试脚本目录: `tests/`
|
|
||||||
|
|
||||||
#### 测试覆盖范围
|
|
||||||
1. 设备管理完整流程测试
|
|
||||||
2. 收费管理完整流程测试
|
|
||||||
3. 巡检管理流程测试
|
|
||||||
4. 工单管理流程测试
|
|
||||||
5. 访客管理流程测试
|
|
||||||
6. 通知管理流程测试
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 部署规范
|
|
||||||
|
|
||||||
### 服务启动顺序
|
|
||||||
1. PostgreSQL 数据库
|
|
||||||
2. ether-auth (8081)
|
|
||||||
3. ether-mdm (8082)
|
|
||||||
4. ether-ops (8083)
|
|
||||||
5. ether-finance (8085)
|
|
||||||
6. ether-gateway (8080)
|
|
||||||
7. ether-ui-admin (5175)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 开发注意事项
|
|
||||||
|
|
||||||
### 不影响现有功能的措施
|
|
||||||
1. 所有新代码在独立分支开发
|
|
||||||
2. 新增数据库表使用新的命名空间
|
|
||||||
3. API版本控制,不修改现有API签名
|
|
||||||
4. 前端新增页面和组件,不修改现有页面
|
|
||||||
5. 完整的回归测试
|
|
||||||
|
|
||||||
### 代码审查要点
|
|
||||||
1. 遵循项目代码规范
|
|
||||||
2. 添加必要的单元测试
|
|
||||||
3. 更新相关文档
|
|
||||||
4. 确保无安全漏洞
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*最后更新: 2026-02-20*
|
|
||||||
|
|
@ -1,737 +0,0 @@
|
||||||
# 空间与主数据领域技术方案
|
|
||||||
|
|
||||||
**领域编号**: 4.1
|
|
||||||
**微服务**: ether-mdm
|
|
||||||
**最后更新**: 2026-02-14
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 一、领域概述
|
|
||||||
|
|
||||||
### 1.1 领域职责
|
|
||||||
|
|
||||||
空间与主数据领域是 Ether 平台的物理数字孪生底座,负责管理:
|
|
||||||
|
|
||||||
- 物理空间的层级结构(园区→楼栋→楼层→房间)
|
|
||||||
- 房产明细与权属关系
|
|
||||||
- 业主信息管理
|
|
||||||
- 巡检管理(计划、任务、记录)
|
|
||||||
- 访客管理(预约、记录、黑名单)
|
|
||||||
|
|
||||||
### 1.2 核心概念
|
|
||||||
|
|
||||||
| 概念 | 说明 | 对应实体 |
|
|
||||||
| ------------ | ---------------------------- | -------------------------- |
|
|
||||||
| **空间节点** | 物理空间的抽象,支持树形结构 | SpaceNode |
|
|
||||||
| **房间详情** | 房产的具体属性信息 | RoomDetail |
|
|
||||||
| **产权** | 房产与业主的关联关系 | Ownership |
|
|
||||||
| **业主** | 房产的所有者或使用者 | Owner |
|
|
||||||
| **巡检** | 定期检查任务体系 | InspectionPlan/Task/Record |
|
|
||||||
| **访客** | 访客预约与通行管理 | VisitorAppointment/Record |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 二、领域模型
|
|
||||||
|
|
||||||
### 2.1 聚合根设计
|
|
||||||
|
|
||||||
#### SpaceNode(空间节点)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_space_node")
|
|
||||||
@Data
|
|
||||||
public class SpaceNode {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
|
|
||||||
private UUID projectId;
|
|
||||||
private String code; // 节点编码,唯一
|
|
||||||
private String name; // 节点名称
|
|
||||||
private SpaceNodeType nodeType; // PROJECT/BUILDING/FLOOR/ROOM/AREA
|
|
||||||
private SpaceNodeStatus status; // ACTIVE/INACTIVE
|
|
||||||
|
|
||||||
// 树形结构
|
|
||||||
private UUID parentId; // 父节点ID
|
|
||||||
private String treePath; // 路径: 1.2.3.4
|
|
||||||
private Integer level; // 层级: 0-4
|
|
||||||
private Integer sortOrder; // 排序
|
|
||||||
|
|
||||||
// 空间属性
|
|
||||||
private BigDecimal areaSqm; // 面积
|
|
||||||
private BigDecimal longitude; // 经度
|
|
||||||
private BigDecimal latitude; // 纬度
|
|
||||||
private String address; // 地址
|
|
||||||
|
|
||||||
// 扩展属性(JSONB)
|
|
||||||
private String attributes;
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
private UUID createdBy;
|
|
||||||
private UUID updatedBy;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**业务规则**:
|
|
||||||
|
|
||||||
- code 在同一项目下唯一
|
|
||||||
- treePath 自动生成,格式为父路径+当前ID
|
|
||||||
- 删除节点时检查是否有子节点
|
|
||||||
- 删除节点时检查是否有关联业务数据
|
|
||||||
|
|
||||||
#### RoomDetail(房间详情)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_room_detail")
|
|
||||||
@Data
|
|
||||||
public class RoomDetail {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID spaceNodeId; // 关联SpaceNode
|
|
||||||
|
|
||||||
// 房产属性
|
|
||||||
private String roomType; // 住宅/商铺/办公/仓库
|
|
||||||
private BigDecimal buildArea; // 建筑面积
|
|
||||||
private BigDecimal usableArea; // 使用面积
|
|
||||||
private String orientation; // 朝向
|
|
||||||
private Integer floor; // 所在楼层
|
|
||||||
private Integer roomCount; // 房间数
|
|
||||||
private Integer hallCount; // 厅数
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private RoomStatus status; // 空置/已售/已租/装修中
|
|
||||||
|
|
||||||
// 扩展属性
|
|
||||||
private String attributes;
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Ownership(产权信息)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_ownership")
|
|
||||||
@Data
|
|
||||||
public class Ownership {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
|
|
||||||
private UUID spaceNodeId; // 关联房产
|
|
||||||
private UUID ownerId; // 关联业主
|
|
||||||
|
|
||||||
// 产权属性
|
|
||||||
private OwnershipType type; // 产权/使用权/租赁权
|
|
||||||
private BigDecimal sharePercent; // 产权份额(0-100)
|
|
||||||
private LocalDate startDate; // 起始日期
|
|
||||||
private LocalDate endDate; // 结束日期(租赁)
|
|
||||||
|
|
||||||
// 证件信息
|
|
||||||
private String certType; // 房产证/购房合同/租赁合同
|
|
||||||
private String certNo; // 证件号码
|
|
||||||
private String certFileUrl; // 证件扫描件
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private OwnershipStatus status; // 有效/过期/注销
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Owner(业主)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_owner")
|
|
||||||
@Data
|
|
||||||
public class Owner {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID projectId;
|
|
||||||
|
|
||||||
// 基本信息
|
|
||||||
private String name;
|
|
||||||
private String phone;
|
|
||||||
private String email;
|
|
||||||
private OwnerType type; // 个人/企业
|
|
||||||
|
|
||||||
// 证件信息
|
|
||||||
private String idCardType; // 身份证/护照/营业执照
|
|
||||||
private String idCardNo;
|
|
||||||
private String idCardFileUrl;
|
|
||||||
|
|
||||||
// 企业信息
|
|
||||||
private String companyName;
|
|
||||||
private String unifiedSocialCreditCode;
|
|
||||||
|
|
||||||
// 关联账户
|
|
||||||
private UUID userId; // 关联系统用户
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private OwnerStatus status;
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 三、巡检管理
|
|
||||||
|
|
||||||
### 3.1 聚合根设计
|
|
||||||
|
|
||||||
#### InspectionPlan(巡检计划)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_inspection_plan")
|
|
||||||
@Data
|
|
||||||
public class InspectionPlan {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID projectId;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
// 巡检类型
|
|
||||||
private InspectionType type; // DAILY/REGULAR/SPECIAL
|
|
||||||
|
|
||||||
// 周期配置
|
|
||||||
private String cronExpression; // Cron表达式
|
|
||||||
private LocalTime executeTime; // 执行时间
|
|
||||||
private Integer advanceDays; // 提前生成任务天数
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private PlanStatus status; // ENABLED/DISABLED
|
|
||||||
|
|
||||||
// 关联巡检点
|
|
||||||
@OneToMany(mappedBy = "plan", cascade = CascadeType.ALL)
|
|
||||||
private List<InspectionPoint> points;
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### InspectionPoint(巡检点)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_inspection_point")
|
|
||||||
@Data
|
|
||||||
public class InspectionPoint {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID planId;
|
|
||||||
|
|
||||||
private UUID spaceNodeId; // 关联空间节点
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
private Integer sortOrder;
|
|
||||||
|
|
||||||
// 检查项(JSONB)
|
|
||||||
private String checkItems; // [{"item":"消防设施","standard":"正常","type":"BOOLEAN"}]
|
|
||||||
|
|
||||||
// 关联设备
|
|
||||||
private UUID equipmentId; // 可选,关联设备
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### InspectionTask(巡检任务)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_inspection_task")
|
|
||||||
@Data
|
|
||||||
public class InspectionTask {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID projectId;
|
|
||||||
private UUID planId;
|
|
||||||
|
|
||||||
private String taskNo; // 任务编号
|
|
||||||
private LocalDate planDate; // 计划日期
|
|
||||||
|
|
||||||
// 执行人
|
|
||||||
private UUID inspectorId;
|
|
||||||
private String inspectorName;
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private TaskStatus status; // PENDING/IN_PROGRESS/COMPLETED/OVERDUE
|
|
||||||
|
|
||||||
// 时间记录
|
|
||||||
private LocalDateTime startTime;
|
|
||||||
private LocalDateTime endTime;
|
|
||||||
|
|
||||||
// 结果
|
|
||||||
private TaskResult result; // NORMAL/ABNORMAL
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
// 关联记录
|
|
||||||
@OneToMany(mappedBy = "task")
|
|
||||||
private List<InspectionRecord> records;
|
|
||||||
|
|
||||||
// 异常处理
|
|
||||||
private UUID workOrderId; // 异常时关联的工单
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### InspectionRecord(巡检记录)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_inspection_record")
|
|
||||||
@Data
|
|
||||||
public class InspectionRecord {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID taskId;
|
|
||||||
private UUID pointId;
|
|
||||||
|
|
||||||
// 巡检结果
|
|
||||||
private String checkItem; // 检查项名称
|
|
||||||
private String standard; // 标准值
|
|
||||||
private String actualValue; // 实际值
|
|
||||||
private CheckResult result; // PASS/FAIL/NA
|
|
||||||
|
|
||||||
// 备注和图片
|
|
||||||
private String remark;
|
|
||||||
private String images;
|
|
||||||
|
|
||||||
// 定位
|
|
||||||
private BigDecimal longitude;
|
|
||||||
private BigDecimal latitude;
|
|
||||||
|
|
||||||
// 时间
|
|
||||||
private LocalDateTime checkTime;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.2 巡检流程
|
|
||||||
|
|
||||||
```
|
|
||||||
1. 创建巡检计划
|
|
||||||
↓
|
|
||||||
2. 定时生成巡检任务(每天凌晨)
|
|
||||||
↓
|
|
||||||
3. 巡检人接收任务通知
|
|
||||||
↓
|
|
||||||
4. 现场扫码签到(GPS定位校验)
|
|
||||||
↓
|
|
||||||
5. 按巡检点逐项检查
|
|
||||||
↓
|
|
||||||
6. 提交巡检结果
|
|
||||||
↓
|
|
||||||
7. 异常自动创建工单(可选)
|
|
||||||
↓
|
|
||||||
8. 任务完成
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 四、访客管理
|
|
||||||
|
|
||||||
### 4.1 聚合根设计
|
|
||||||
|
|
||||||
#### VisitorAppointment(访客预约)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_visitor_appointment")
|
|
||||||
@Data
|
|
||||||
public class VisitorAppointment {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID projectId;
|
|
||||||
|
|
||||||
// 访客信息
|
|
||||||
private String visitorName;
|
|
||||||
private String visitorPhone;
|
|
||||||
private String visitorIdCard;
|
|
||||||
private VisitorType visitorType; // VISITOR/EXPRESS/DELIVERY/MAINTENANCE
|
|
||||||
|
|
||||||
// 被访人信息
|
|
||||||
private UUID hostId;
|
|
||||||
private String hostName;
|
|
||||||
private String hostPhone;
|
|
||||||
private UUID spaceNodeId; // 访问地点
|
|
||||||
|
|
||||||
// 预约信息
|
|
||||||
private LocalDate visitDate;
|
|
||||||
private LocalTime visitTime;
|
|
||||||
private Integer duration; // 预计时长(分钟)
|
|
||||||
private String purpose;
|
|
||||||
private Integer visitorCount; // 访客人数
|
|
||||||
|
|
||||||
// 凭证
|
|
||||||
private String qrCode; // 动态二维码
|
|
||||||
private LocalDateTime qrExpireTime;
|
|
||||||
|
|
||||||
// 车牌(车辆访客)
|
|
||||||
private String plateNumber;
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private AppointmentStatus status; // PENDING/CONFIRMED/CANCELLED/COMPLETED/EXPIRED
|
|
||||||
|
|
||||||
// 审计字段
|
|
||||||
private LocalDateTime createdAt;
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
private UUID createdBy;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### VisitorAccessRecord(访客通行记录)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_visitor_access_record")
|
|
||||||
@Data
|
|
||||||
public class VisitorAccessRecord {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID appointmentId;
|
|
||||||
|
|
||||||
// 通行信息
|
|
||||||
private LocalDateTime entryTime;
|
|
||||||
private LocalDateTime exitTime;
|
|
||||||
private String entryGate; // 入口
|
|
||||||
private String exitGate; // 出口
|
|
||||||
|
|
||||||
// 验证方式
|
|
||||||
private VerifyType verifyType; // QR_CODE/ID_CARD/FACE
|
|
||||||
private String verifyCode;
|
|
||||||
|
|
||||||
// 现场照片
|
|
||||||
private String entryPhoto;
|
|
||||||
private String exitPhoto;
|
|
||||||
|
|
||||||
// 设备信息
|
|
||||||
private String deviceId; // 门禁设备ID
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private AccessStatus status; // ENTERED/EXITED
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### VisitorBlacklist(访客黑名单)
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_visitor_blacklist")
|
|
||||||
@Data
|
|
||||||
public class VisitorBlacklist {
|
|
||||||
@Id
|
|
||||||
private UUID id;
|
|
||||||
private UUID projectId;
|
|
||||||
|
|
||||||
// 访客标识(至少填一项)
|
|
||||||
private String visitorName;
|
|
||||||
private String visitorPhone;
|
|
||||||
private String visitorIdCard;
|
|
||||||
|
|
||||||
// 拉黑信息
|
|
||||||
private String reason;
|
|
||||||
private BlacklistType type; // TEMPORARY/PERMANENT
|
|
||||||
private LocalDateTime blockTime;
|
|
||||||
private LocalDateTime expireTime; // null为永久
|
|
||||||
|
|
||||||
// 操作人
|
|
||||||
private UUID operatorId;
|
|
||||||
private String operatorName;
|
|
||||||
|
|
||||||
// 状态
|
|
||||||
private BlacklistStatus status; // ACTIVE/LIFTED
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.2 访客流程
|
|
||||||
|
|
||||||
```
|
|
||||||
1. 业主发起预约(APP/小程序)
|
|
||||||
↓
|
|
||||||
2. 系统生成动态二维码
|
|
||||||
↓
|
|
||||||
3. 访客收到邀请(短信/微信)
|
|
||||||
↓
|
|
||||||
4. 访客到达现场
|
|
||||||
↓
|
|
||||||
5. 扫码/刷身份证通行
|
|
||||||
↓
|
|
||||||
6. 系统记录入场时间
|
|
||||||
↓
|
|
||||||
7. 业主收到通知
|
|
||||||
↓
|
|
||||||
8. 访客离场扫码
|
|
||||||
↓
|
|
||||||
9. 系统记录离场时间
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 五、API 接口
|
|
||||||
|
|
||||||
### 5.1 SpaceNode API
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/mdm/space-nodes")
|
|
||||||
@Tag(name = "空间节点管理")
|
|
||||||
public class SpaceNodeController {
|
|
||||||
|
|
||||||
@PostMapping
|
|
||||||
@Operation(summary = "创建空间节点")
|
|
||||||
public Result<SpaceNodeVO> create(@RequestBody @Valid SpaceNodeCreateRequest request);
|
|
||||||
|
|
||||||
@GetMapping("/tree")
|
|
||||||
@Operation(summary = "获取空间树")
|
|
||||||
public Result<List<SpaceNodeTreeVO>> tree(@RequestParam UUID projectId);
|
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
@Operation(summary = "获取节点详情")
|
|
||||||
public Result<SpaceNodeVO> getById(@PathVariable UUID id);
|
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
@Operation(summary = "更新节点")
|
|
||||||
public Result<SpaceNodeVO> update(@PathVariable UUID id,
|
|
||||||
@RequestBody @Valid SpaceNodeUpdateRequest request);
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
@Operation(summary = "删除节点")
|
|
||||||
public Result<Void> delete(@PathVariable UUID id);
|
|
||||||
|
|
||||||
@GetMapping("/{id}/children")
|
|
||||||
@Operation(summary = "获取子节点")
|
|
||||||
public Result<List<SpaceNodeVO>> getChildren(@PathVariable UUID id);
|
|
||||||
|
|
||||||
@GetMapping("/{id}/path")
|
|
||||||
@Operation(summary = "获取节点路径")
|
|
||||||
public Result<List<SpaceNodeVO>> getPath(@PathVariable UUID id);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 Inspection API
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/mdm/inspections")
|
|
||||||
@Tag(name = "巡检管理")
|
|
||||||
public class InspectionController {
|
|
||||||
|
|
||||||
// 巡检计划
|
|
||||||
@PostMapping("/plans")
|
|
||||||
@Operation(summary = "创建巡检计划")
|
|
||||||
public Result<InspectionPlanVO> createPlan(@RequestBody @Valid InspectionPlanCreateRequest request);
|
|
||||||
|
|
||||||
@GetMapping("/plans")
|
|
||||||
@Operation(summary = "分页查询计划")
|
|
||||||
public Result<Page<InspectionPlanVO>> pagePlans(InspectionPlanQueryRequest request);
|
|
||||||
|
|
||||||
// 巡检任务
|
|
||||||
@GetMapping("/tasks")
|
|
||||||
@Operation(summary = "分页查询任务")
|
|
||||||
public Result<Page<InspectionTaskVO>> pageTasks(InspectionTaskQueryRequest request);
|
|
||||||
|
|
||||||
@PostMapping("/tasks/{id}/start")
|
|
||||||
@Operation(summary = "开始巡检")
|
|
||||||
public Result<InspectionTaskVO> startTask(@PathVariable UUID id);
|
|
||||||
|
|
||||||
@PostMapping("/tasks/{id}/complete")
|
|
||||||
@Operation(summary = "完成巡检")
|
|
||||||
public Result<InspectionTaskVO> completeTask(@PathVariable UUID id,
|
|
||||||
@RequestBody InspectionCompleteRequest request);
|
|
||||||
|
|
||||||
@PostMapping("/tasks/{id}/records")
|
|
||||||
@Operation(summary = "提交巡检记录")
|
|
||||||
public Result<Void> submitRecords(@PathVariable UUID id,
|
|
||||||
@RequestBody List<InspectionRecordSubmitRequest> records);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 Visitor API
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/mdm/visitors")
|
|
||||||
@Tag(name = "访客管理")
|
|
||||||
public class VisitorController {
|
|
||||||
|
|
||||||
@PostMapping("/appointments")
|
|
||||||
@Operation(summary = "创建访客预约")
|
|
||||||
public Result<VisitorAppointmentVO> createAppointment(@RequestBody @Valid VisitorAppointmentCreateRequest request);
|
|
||||||
|
|
||||||
@GetMapping("/appointments/{id}/qr-code")
|
|
||||||
@Operation(summary = "获取访客二维码")
|
|
||||||
public Result<String> getQrCode(@PathVariable UUID id);
|
|
||||||
|
|
||||||
@PostMapping("/access/verify")
|
|
||||||
@Operation(summary = "验证访客凭证")
|
|
||||||
public Result<VisitorAccessResultVO> verifyAccess(@RequestBody VisitorVerifyRequest request);
|
|
||||||
|
|
||||||
@PostMapping("/access/entry")
|
|
||||||
@Operation(summary = "记录访客入场")
|
|
||||||
public Result<Void> recordEntry(@RequestBody VisitorEntryRequest request);
|
|
||||||
|
|
||||||
@PostMapping("/access/exit")
|
|
||||||
@Operation(summary = "记录访客离场")
|
|
||||||
public Result<Void> recordExit(@RequestBody VisitorExitRequest request);
|
|
||||||
|
|
||||||
@PostMapping("/blacklist")
|
|
||||||
@Operation(summary = "添加黑名单")
|
|
||||||
public Result<VisitorBlacklistVO> addBlacklist(@RequestBody @Valid BlacklistAddRequest request);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 六、实现状态与差异
|
|
||||||
|
|
||||||
### 6.1 实现状态
|
|
||||||
|
|
||||||
| 功能模块 | 实现状态 | 备注 |
|
|
||||||
| ------------------- | --------- | ------------------ |
|
|
||||||
| SpaceNode | 🟢 已实现 | 基础CRUD、树形查询 |
|
|
||||||
| RoomDetail | 🟢 已实现 | 基础CRUD |
|
|
||||||
| Ownership | 🟢 已实现 | 基础CRUD |
|
|
||||||
| Owner | 🟢 已实现 | 基础CRUD |
|
|
||||||
| InspectionPlan | 🟢 已实现 | 基础CRUD |
|
|
||||||
| InspectionTask | 🟢 已实现 | 含定时任务生成 |
|
|
||||||
| VisitorAppointment | 🟢 已实现 | 含二维码生成 |
|
|
||||||
| VisitorAccessRecord | 🟢 已实现 | 基础记录 |
|
|
||||||
| VisitorBlacklist | 🟢 已实现 | 基础CRUD |
|
|
||||||
|
|
||||||
### 6.2 与设计方案的差异
|
|
||||||
|
|
||||||
| 设计项 | 设计方案 | 现有实现 | 差异分析 |
|
|
||||||
| ------------ | ---------------- | ------------------ | -------------------------------------------------------- |
|
|
||||||
| **空间坐标** | PostGIS geometry | longitude/latitude | ⚠️ 移除了PostGIS依赖,简化实现 |
|
|
||||||
| **树形结构** | PostgreSQL ltree | 字符串treePath | ⚠️ 未使用ltree扩展,当前数据规模可接受 |
|
|
||||||
| **巡检归属** | ether-ops | ether-mdm | ✅ 已确认:巡检点与空间节点紧密关联,归属 ether-mdm 合理 |
|
|
||||||
| **访客归属** | ether-ops | ether-mdm | ✅ 已确认:访客与业主/空间紧密关联,归属 ether-mdm 合理 |
|
|
||||||
| **设备管理** | 曾在 ether-mdm | ether-asset | ✅ 已修正:设备相关功能已迁移至 ether-asset 服务 |
|
|
||||||
|
|
||||||
### 6.3 待改进项
|
|
||||||
|
|
||||||
| 优先级 | 改进项 | 说明 |
|
|
||||||
| ------ | ---------------- | -------------------------------------------------------- |
|
|
||||||
| P2 | 优化树形查询 | 考虑引入ltree或物化路径优化 |
|
|
||||||
| P2 | 空间搜索 | 基于经纬度的附近空间查询 |
|
|
||||||
| ~~P3~~ | ~~领域边界调整~~ | ~~评估巡检、访客是否迁移到ether-ops~~ 已确认当前归属合理 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 七、数据库表结构
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- 空间节点表
|
|
||||||
CREATE TABLE mdm_space_node (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
project_id UUID NOT NULL,
|
|
||||||
code VARCHAR(50) NOT NULL,
|
|
||||||
name VARCHAR(100) NOT NULL,
|
|
||||||
node_type VARCHAR(20) NOT NULL,
|
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
|
||||||
parent_id UUID,
|
|
||||||
tree_path VARCHAR(1000),
|
|
||||||
level INTEGER,
|
|
||||||
sort_order INTEGER DEFAULT 0,
|
|
||||||
area_sqm NUMERIC(10,2),
|
|
||||||
longitude NUMERIC(10,6),
|
|
||||||
latitude NUMERIC(10,6),
|
|
||||||
address VARCHAR(255),
|
|
||||||
description VARCHAR(500),
|
|
||||||
attributes JSONB,
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
created_by UUID,
|
|
||||||
updated_by UUID,
|
|
||||||
UNIQUE(project_id, code)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 创建索引
|
|
||||||
CREATE INDEX idx_space_node_project ON mdm_space_node(project_id);
|
|
||||||
CREATE INDEX idx_space_node_parent ON mdm_space_node(parent_id);
|
|
||||||
CREATE INDEX idx_space_node_path ON mdm_space_node(tree_path);
|
|
||||||
CREATE INDEX idx_space_node_type ON mdm_space_node(node_type);
|
|
||||||
|
|
||||||
-- 巡检计划表
|
|
||||||
CREATE TABLE mdm_inspection_plan (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
project_id UUID NOT NULL,
|
|
||||||
name VARCHAR(100) NOT NULL,
|
|
||||||
description VARCHAR(500),
|
|
||||||
type VARCHAR(20) NOT NULL,
|
|
||||||
cron_expression VARCHAR(50),
|
|
||||||
execute_time TIME,
|
|
||||||
advance_days INTEGER DEFAULT 1,
|
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'ENABLED',
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
created_by UUID,
|
|
||||||
updated_by UUID
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 巡检任务表
|
|
||||||
CREATE TABLE mdm_inspection_task (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
project_id UUID NOT NULL,
|
|
||||||
plan_id UUID NOT NULL,
|
|
||||||
task_no VARCHAR(32) NOT NULL,
|
|
||||||
plan_date DATE NOT NULL,
|
|
||||||
inspector_id UUID,
|
|
||||||
inspector_name VARCHAR(100),
|
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
|
||||||
start_time TIMESTAMP,
|
|
||||||
end_time TIMESTAMP,
|
|
||||||
result VARCHAR(20),
|
|
||||||
remark VARCHAR(500),
|
|
||||||
work_order_id UUID,
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 访客预约表
|
|
||||||
CREATE TABLE mdm_visitor_appointment (
|
|
||||||
id UUID PRIMARY KEY,
|
|
||||||
project_id UUID NOT NULL,
|
|
||||||
visitor_name VARCHAR(100) NOT NULL,
|
|
||||||
visitor_phone VARCHAR(20),
|
|
||||||
visitor_id_card VARCHAR(18),
|
|
||||||
visitor_type VARCHAR(20) NOT NULL,
|
|
||||||
host_id UUID,
|
|
||||||
host_name VARCHAR(100),
|
|
||||||
host_phone VARCHAR(20),
|
|
||||||
space_node_id UUID,
|
|
||||||
visit_date DATE NOT NULL,
|
|
||||||
visit_time TIME,
|
|
||||||
duration INTEGER,
|
|
||||||
purpose VARCHAR(200),
|
|
||||||
visitor_count INTEGER DEFAULT 1,
|
|
||||||
qr_code VARCHAR(255),
|
|
||||||
qr_expire_time TIMESTAMP,
|
|
||||||
plate_number VARCHAR(20),
|
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
created_by UUID
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**文档维护**: 本领域技术方案由 ether-mdm 服务负责人维护
|
|
||||||
|
|
@ -761,5 +761,46 @@ function saveLocation() {
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 八、开发任务清单 (2026-03-23)
|
||||||
|
|
||||||
|
### 8.1 后端任务
|
||||||
|
|
||||||
|
| 任务 | 状态 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 重构 SpaceNode 实体 | 待开发 | 按设计文档完善字段 |
|
||||||
|
| 重构 SpaceNodeType 枚举 | 待开发 | 添加 BUILDING/UNIT/ROOM 等 |
|
||||||
|
| 重构 SpaceNodeService | 待开发 | 树形结构操作 |
|
||||||
|
| 重构 SpaceNodeRepository | 待开发 | JPA 查询方法 |
|
||||||
|
| 重构 SpaceNodeController | 待开发 | RESTful API |
|
||||||
|
| 添加 DTO 类 | 待开发 | 创建/更新/响应 DTO |
|
||||||
|
| 编写单元测试 | 待开发 | TDD 模式 |
|
||||||
|
|
||||||
|
### 8.2 前端任务
|
||||||
|
|
||||||
|
| 任务 | 状态 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 创建 space.ts 类型定义 | 待开发 | TypeScript 类型 |
|
||||||
|
| 创建 space.ts API | 待开发 | API 函数 |
|
||||||
|
| 创建空间管理页面 | 待开发 | Space.vue |
|
||||||
|
| 创建空间树形组件 | 待开发 | 左侧树导航 |
|
||||||
|
| 创建空间表单组件 | 待开发 | 新增/编辑 |
|
||||||
|
| E2E 测试验证 | 待开发 | Playwright 测试 |
|
||||||
|
|
||||||
|
### 8.3 API 接口清单
|
||||||
|
|
||||||
|
| 接口 | 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 获取空间树 | GET | /api/v1/mdm/space-nodes/tree | 项目空间树 |
|
||||||
|
| 获取根节点 | GET | /api/v1/mdm/space-nodes/roots | 项目下根节点 |
|
||||||
|
| 获取节点详情 | GET | /api/v1/mdm/space-nodes/{id} | 节点详情 |
|
||||||
|
| 创建节点 | POST | /api/v1/mdm/space-nodes | 创建空间节点 |
|
||||||
|
| 更新节点 | PUT | /api/v1/mdm/space-nodes/{id} | 更新节点 |
|
||||||
|
| 删除节点 | DELETE | /api/v1/mdm/space-nodes/{id} | 删除节点 |
|
||||||
|
| 获取子节点 | GET | /api/v1/mdm/space-nodes/{id}/children | 子节点列表 |
|
||||||
|
| 批量创建 | POST | /api/v1/mdm/space-nodes/batch | 批量创建 |
|
||||||
|
| 批量导入 | POST | /api/v1/mdm/space-nodes/import | Excel导入 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
**文档版本**: v2.0
|
**文档版本**: v2.0
|
||||||
**最后更新**: 2026-02-16
|
**最后更新**: 2026-03-23
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Ether 智慧物业管理平台 - 开发规范
|
# Ether 智慧物业管理平台 - 开发规范
|
||||||
|
|
||||||
**文档版本**: v1.3
|
**文档版本**: v2.0
|
||||||
**最后更新**: 2026-02-13
|
**最后更新**: 2026-03-28
|
||||||
**适用范围**: 所有微服务模块
|
**适用范围**: ether-pms 单体应用
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -874,32 +874,7 @@ management:
|
||||||
show-details: always
|
show-details: always
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 8.3.3 网关重试配置
|
#### 8.3.3 日志配置
|
||||||
|
|
||||||
**必须配置网关重试机制**,提高服务容错能力:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
cloud:
|
|
||||||
gateway:
|
|
||||||
routes:
|
|
||||||
- id: ether-auth
|
|
||||||
uri: lb://ether-auth
|
|
||||||
predicates:
|
|
||||||
- Path=/api/v1/auth/**
|
|
||||||
filters:
|
|
||||||
- name: Retry
|
|
||||||
args:
|
|
||||||
retries: 3
|
|
||||||
statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE
|
|
||||||
methods: GET,POST
|
|
||||||
backoff:
|
|
||||||
firstBackoff: 100ms
|
|
||||||
maxBackoff: 500ms
|
|
||||||
factor: 2
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 8.3.4 日志配置
|
|
||||||
|
|
||||||
**必须配置文件日志输出**,便于问题排查:
|
**必须配置文件日志输出**,便于问题排查:
|
||||||
|
|
||||||
|
|
@ -916,274 +891,7 @@ logging:
|
||||||
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 8.3.5 服务发现配置
|
#### 8.3.4 健康检查配置
|
||||||
|
|
||||||
**必须配置 Nacos 服务发现**,支持服务动态注册:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
cloud:
|
|
||||||
nacos:
|
|
||||||
discovery:
|
|
||||||
enabled: true
|
|
||||||
server-addr: localhost:8848
|
|
||||||
namespace: dev
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 8.3.6 服务管理脚本
|
|
||||||
|
|
||||||
使用项目提供的脚本管理服务:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 健康检查
|
|
||||||
./scripts/health-check.sh
|
|
||||||
|
|
||||||
# 启动所有服务
|
|
||||||
./scripts/service-manager.sh start
|
|
||||||
|
|
||||||
# 停止所有服务
|
|
||||||
./scripts/service-manager.sh stop
|
|
||||||
|
|
||||||
# 重启所有服务
|
|
||||||
./scripts/service-manager.sh restart
|
|
||||||
|
|
||||||
# 查看服务状态
|
|
||||||
./scripts/service-manager.sh status
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.4 跨业务数据访问规范
|
|
||||||
|
|
||||||
#### 8.4.1 架构原则
|
|
||||||
|
|
||||||
Ether 项目采用 **Database-per-Service** 架构,每个微服务拥有独立的数据库:
|
|
||||||
|
|
||||||
| 数据库 | 对应服务 | 业务范围 |
|
|
||||||
| --------------- | ------------- | -------------------------------- |
|
|
||||||
| `ether_auth` | ether-auth | 用户认证、权限管理 |
|
|
||||||
| `ether_mdm` | ether-mdm | 主数据管理(项目、空间、业主等) |
|
|
||||||
| `ether_ops` | ether-ops | 运营管理(工单、巡检等) |
|
|
||||||
| `ether_finance` | ether-finance | 财务管理(收费、账单等) |
|
|
||||||
|
|
||||||
**禁止直接跨库查询**,必须通过以下方案实现跨业务数据访问。
|
|
||||||
|
|
||||||
#### 8.4.2 方案一:API 组合(推荐)
|
|
||||||
|
|
||||||
**适用场景**:实时性要求高、数据量小、调用频率低
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class WorkOrderClientServiceImpl implements WorkOrderClientService {
|
|
||||||
|
|
||||||
private final RestTemplate restTemplate;
|
|
||||||
|
|
||||||
private static final String WORK_ORDER_SERVICE_URL = "http://ether-ops/api/v1/ops/work-orders";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID createWorkOrderFromInspection(
|
|
||||||
UUID projectId,
|
|
||||||
UUID equipmentId,
|
|
||||||
String pointName,
|
|
||||||
String abnormalDesc,
|
|
||||||
String suggestion,
|
|
||||||
String photos,
|
|
||||||
UUID inspectorId,
|
|
||||||
String inspectorName) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
||||||
|
|
||||||
// 传递项目上下文
|
|
||||||
if (ProjectContextHolder.getProjectId() != null) {
|
|
||||||
headers.set("X-Project-Id", ProjectContextHolder.getProjectId().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Object> workOrderRequest = new HashMap<>();
|
|
||||||
workOrderRequest.put("orderType", "REPAIR");
|
|
||||||
workOrderRequest.put("source", "INSPECTION");
|
|
||||||
workOrderRequest.put("priority", "HIGH");
|
|
||||||
workOrderRequest.put("title", "巡检异常处理 - " + pointName);
|
|
||||||
workOrderRequest.put("description", buildDescription(pointName, abnormalDesc, suggestion));
|
|
||||||
workOrderRequest.put("equipmentId", equipmentId);
|
|
||||||
workOrderRequest.put("reporterId", inspectorId);
|
|
||||||
workOrderRequest.put("reporterName", inspectorName);
|
|
||||||
workOrderRequest.put("images", photos);
|
|
||||||
|
|
||||||
HttpEntity<Map<String, Object>> request = new HttpEntity<>(workOrderRequest, headers);
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, Object> response = restTemplate.postForObject(
|
|
||||||
WORK_ORDER_SERVICE_URL,
|
|
||||||
request,
|
|
||||||
Map.class
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response != null && response.get("data") != null) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, Object> data = (Map<String, Object>) response.get("data");
|
|
||||||
String orderId = (String) data.get("id");
|
|
||||||
log.info("成功创建巡检异常工单: {}, 巡检点: {}", orderId, pointName);
|
|
||||||
return UUID.fromString(orderId);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("创建巡检异常工单失败, 巡检点: {}", pointName, e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**配置 RestTemplate**:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@Configuration
|
|
||||||
public class RestTemplateConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@LoadBalanced
|
|
||||||
public RestTemplate restTemplate() {
|
|
||||||
return new RestTemplate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 8.4.3 方案二:事件驱动
|
|
||||||
|
|
||||||
**适用场景**:异步处理、削峰填谷、最终一致性可接受
|
|
||||||
|
|
||||||
```java
|
|
||||||
// 事件发布方
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class InspectionService {
|
|
||||||
|
|
||||||
private final RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
@Value("${ether.mq.exchange.inspection}")
|
|
||||||
private String inspectionExchange;
|
|
||||||
|
|
||||||
public void reportAbnormality(InspectionResult result) {
|
|
||||||
InspectionAbnormalEvent event = new InspectionAbnormalEvent();
|
|
||||||
event.setProjectId(result.getProjectId());
|
|
||||||
event.setEquipmentId(result.getEquipmentId());
|
|
||||||
event.setAbnormalDesc(result.getAbnormalDesc());
|
|
||||||
event.setTimestamp(LocalDateTime.now());
|
|
||||||
|
|
||||||
rabbitTemplate.convertAndSend(
|
|
||||||
inspectionExchange,
|
|
||||||
"inspection.abnormal",
|
|
||||||
event
|
|
||||||
);
|
|
||||||
|
|
||||||
log.info("发布巡检异常事件: {}", event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 事件消费方
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RabbitListener(queues = "ops.inspection.abnormal")
|
|
||||||
public class InspectionAbnormalHandler {
|
|
||||||
|
|
||||||
private final WorkOrderService workOrderService;
|
|
||||||
|
|
||||||
@RabbitHandler
|
|
||||||
public void handleAbnormalInspection(InspectionAbnormalEvent event) {
|
|
||||||
log.info("接收巡检异常事件: {}", event);
|
|
||||||
|
|
||||||
WorkOrderCreateRequest request = new WorkOrderCreateRequest();
|
|
||||||
request.setOrderType("REPAIR");
|
|
||||||
request.setSource("INSPECTION");
|
|
||||||
request.setPriority("HIGH");
|
|
||||||
request.setTitle("巡检异常处理 - " + event.getPointName());
|
|
||||||
request.setEquipmentId(event.getEquipmentId());
|
|
||||||
|
|
||||||
workOrderService.create(request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**RabbitMQ 配置**:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
rabbitmq:
|
|
||||||
host: localhost
|
|
||||||
port: 5672
|
|
||||||
username: ${MQ_USERNAME:ether}
|
|
||||||
password: ${MQ_PASSWORD:ether123}
|
|
||||||
|
|
||||||
ether:
|
|
||||||
mq:
|
|
||||||
exchange:
|
|
||||||
inspection: ether.inspection.exchange
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 8.4.4 方案三:数据冗余(慎用)
|
|
||||||
|
|
||||||
**适用场景**:高频查询、实时性要求极高、数据变更频率低
|
|
||||||
|
|
||||||
```java
|
|
||||||
// 在 MDM 服务中冗余存储用户基本信息
|
|
||||||
@Entity
|
|
||||||
@Table(name = "mdm_user_snapshot")
|
|
||||||
public class UserSnapshot {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
private UUID userId;
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private String realName;
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@LastModifiedDate
|
|
||||||
private LocalDateTime updatedAt;
|
|
||||||
|
|
||||||
// 冗余字段,通过事件同步更新
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听用户变更事件,同步更新冗余数据
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RabbitListener(queues = "mdm.user.sync")
|
|
||||||
public class UserSyncHandler {
|
|
||||||
|
|
||||||
private final UserSnapshotRepository userSnapshotRepository;
|
|
||||||
|
|
||||||
@RabbitHandler
|
|
||||||
public void handleUserChange(UserChangedEvent event) {
|
|
||||||
UserSnapshot snapshot = new UserSnapshot();
|
|
||||||
snapshot.setUserId(event.getUserId());
|
|
||||||
snapshot.setUsername(event.getUsername());
|
|
||||||
snapshot.setRealName(event.getRealName());
|
|
||||||
snapshot.setPhone(event.getPhone());
|
|
||||||
snapshot.setUpdatedAt(LocalDateTime.now());
|
|
||||||
|
|
||||||
userSnapshotRepository.save(snapshot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**注意**:数据冗余方案会增加数据一致性维护成本,**仅在高频查询场景使用**。
|
|
||||||
|
|
||||||
#### 8.4.5 方案选择指南
|
|
||||||
|
|
||||||
| 场景 | 推荐方案 | 理由 |
|
|
||||||
| ---------------------- | -------- | ------------------ |
|
|
||||||
| 低频调用、实时性要求高 | API 组合 | 简单可靠、数据实时 |
|
|
||||||
| 异步处理、批量操作 | 事件驱动 | 解耦、削峰填谷 |
|
|
||||||
| 高频查询、数据变更少 | 数据冗余 | 查询高效、减少调用 |
|
|
||||||
| 复杂报表、数据分析 | CQRS | 读写分离、独立优化 |
|
|
||||||
|
|
||||||
#### 8.4.6 禁止事项
|
|
||||||
|
|
||||||
| 禁止行为 | 原因 | 替代方案 |
|
|
||||||
| ---------------------- | ---------------------- | --------------------- |
|
|
||||||
| 直接跨库 JOIN | 破坏服务边界、耦合严重 | API 组合或事件驱动 |
|
|
||||||
| 直接访问其他服务数据库 | 安全风险、难以维护 | 通过服务 API 访问 |
|
|
||||||
| 分布式事务(XA) | 性能差、复杂度高 | 最终一致性 + 补偿机制 |
|
|
||||||
| 循环调用服务 API | 性能问题、死锁风险 | 批量接口或事件驱动 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue