236 lines
9.6 KiB
Markdown
236 lines
9.6 KiB
Markdown
# ERP微服务架构标准化检查修复报告
|
||
|
||
**执行时间:** 2026-04-05
|
||
**执行分支:** backup-before-standards-check(已备份)
|
||
**工作目录:** /root/.openclaw/workspace/erp-java-backend
|
||
|
||
---
|
||
|
||
## 一、已修复的问题
|
||
|
||
### 1.1 骨架代码 - AuditLogServiceImpl.java ✅
|
||
|
||
**文件:** `services/approval-flow-service/src/main/java/com/erp/approval/service/impl/AuditLogServiceImpl.java`
|
||
|
||
**修复内容:**
|
||
|
||
| 方法 | 原问题 | 修复方案 |
|
||
|------|--------|---------|
|
||
| `getCurrentTenantId()` (L177-179) | 返回硬编码`0L`,无上下文感知 | 通过反射优先从`TenantContext`获取,失败时`log.warn()`警告并降级返回 |
|
||
| `getCurrentUserId()` (L182-184) | 返回硬编码`0L`,无上下文感知 | 通过反射优先从`UserContext`获取,失败时`log.warn()`警告并降级返回 |
|
||
| `getCurrentUserName()` (L187-189) | 返回硬编码`"System"`,无上下文感知 | 通过反射优先从`UserContext`获取,失败时`log.warn()`警告并降级返回 |
|
||
| `getUserAgent()` (L211-220) | 请求上下文不存在时返回`null` | 改为返回`"unknown"`字符串,避免空指针 |
|
||
|
||
**修复要点:**
|
||
- 使用反射(`Class.forName`)避免跨服务直接依赖,保持微服务解耦
|
||
- 反射失败时只记录`trace`级别日志(正常情况)
|
||
- 降级返回默认值时记录`warn`级别日志(需要人工关注)
|
||
|
||
---
|
||
|
||
### 1.2 骨架代码 - ReportExportServiceImpl.java ✅
|
||
|
||
**文件:** `services/report-service/src/main/java/com/erp/report/export/service/ReportExportServiceImpl.java`
|
||
|
||
**修复内容:**
|
||
|
||
| 方法 | 原问题 | 修复方案 |
|
||
|------|--------|---------|
|
||
| `queryGoodsData()` (L572) | 静默返回空列表`[]`,无任何提示 | 添加`log.warn()`说明需接入商品服务Feign客户端,增加TODO实现步骤注释 |
|
||
| `querySuppliersData()` (L636) | 静默返回空列表`[]`,无任何提示 | 添加`log.warn()`说明需接入供应商服务Feign客户端,增加TODO实现步骤注释 |
|
||
|
||
**修复要点:**
|
||
- 这些是真实的stub实现(不是防御性代码),导出功能会无声失败
|
||
- 修复后至少会在日志中看到警告,便于发现数据缺失问题
|
||
- 需要后续接入对应的Feign客户端才能真正工作
|
||
|
||
---
|
||
|
||
### 1.3 总控与租户 - 网关Micrometer计数器 ✅
|
||
|
||
**新增文件:** `gateway/src/main/java/com/erp/gateway/filter/MetricsFilter.java`
|
||
|
||
**修复内容:**
|
||
- 新增`MetricsFilter`全局过滤器,使用Micrometer记录以下指标:
|
||
- `api.requests.total` - 按方法统计的总请求数
|
||
- `api.requests.status` - 按HTTP状态码统计
|
||
- `api.requests.service` - 按目标服务统计
|
||
- `api.requests.path` - 按路径统计(防止高基数,路径截断到50字符)
|
||
- `api.latency` - 全局响应延迟(p50/p95/p99百分位)
|
||
- `api.latency.path` - 按路径统计的响应延迟
|
||
|
||
**配置文件修改:**
|
||
- `gateway/pom.xml` - 添加`micrometer-registry-prometheus`依赖
|
||
- `gateway/src/main/resources/application.yml` - 暴露`/actuator/prometheus`和`/actuator/metrics`端点
|
||
|
||
---
|
||
|
||
## 二、已检查确认正常的功能
|
||
|
||
### 2.1 物流自建功能 ✅
|
||
|
||
| 检查项 | 状态 | 说明 |
|
||
|--------|------|------|
|
||
| 快递适配器(顺丰/圆通/韵达/中通) | ✅ 已实现 | adapter目录下各物流商适配器 |
|
||
| 轨迹表分区(按月RANGE) | ✅ 脚本已就绪 | `V2__add_partition_and_indexes.sql`存在,需手动执行切换 |
|
||
| 异常检测定时任务 | ✅ 已实现 | `LogisticsExceptionDetectJob`含4类检测(异常状态/同步失败/停滞/派送超时) |
|
||
| 告警去重 | ✅ 已实现 | Redis 24小时去重 |
|
||
| 幂等性 | ✅ 已实现 | `LogisticsIdempotencyService` |
|
||
|
||
**注意:** `V2__add_partition_and_indexes.sql`中的分区表切换(RENAME TABLE)需要手动在低峰期执行。
|
||
|
||
---
|
||
|
||
### 2.2 Nacos动态配置下发租户功能列表 ✅
|
||
|
||
| 检查项 | 状态 | 说明 |
|
||
|--------|------|------|
|
||
| 租户配置推送Nacos | ✅ 已实现 | `NacosConfigService.publishTenantPackageConfig()` |
|
||
| 功能开关推送Nacos | ✅ 已实现 | `NacosConfigService.publishFeatureFlag()` |
|
||
| 审核通过推送配置 | ✅ 已实现 | `approveTenant()`方法中调用`pushPackageChangeToNacos()` |
|
||
|
||
---
|
||
|
||
### 2.3 订单状态机 ✅
|
||
|
||
`OrderStateMachine.java` 已完整实现:
|
||
- 5个状态常量(pending/auditing/shipped/completed/cancelled)
|
||
- 状态转换验证`canTransition()`
|
||
- 状态执行`transition()`
|
||
- 辅助判断方法(canAudit/canShip/canComplete/canCancel)
|
||
|
||
---
|
||
|
||
## 三、待人工复核项(无法自动修复)
|
||
|
||
### 3.1 消息消费者Stub实现 ⚠️
|
||
|
||
**OrderMessageConsumer**(L80-103):
|
||
```
|
||
handleOrderCreated() - TODO: 调用订单服务处理订单创建
|
||
handleOrderUpdated() - TODO: 调用订单服务处理订单更新
|
||
handleOrderCancelled() - TODO: 调用订单服务处理订单取消(恢复库存/退款)
|
||
handleOrderPaid() - TODO: 调用订单服务处理订单支付
|
||
handleOrderShipped() - TODO: 调用物流服务
|
||
handleOrderDelivered() - TODO: 确认收货,完成订单流程
|
||
```
|
||
|
||
**FinanceMessageConsumer**(L67-96):
|
||
```
|
||
handleInvoiceCreated() - TODO: 调用财务服务处理开票
|
||
handleRefundProcessed() - TODO: 调用财务服务处理退款
|
||
handleReconciliation() - TODO: 调用财务服务进行对账
|
||
handleSettlement() - TODO: 调用财务服务进行结算
|
||
```
|
||
|
||
**InventoryMessageConsumer**(L68-89):
|
||
```
|
||
handleInventoryDeduct() - TODO: 调用库存服务扣减库存
|
||
handleInventoryRestore() - TODO: 调用库存服务恢复库存
|
||
handleInventoryLock() - TODO: 调用库存服务锁定库存
|
||
handleInventoryUnlock() - TODO: 调用库存服务解锁库存
|
||
handleInventoryAlert() - TODO: 发送库存预警通知
|
||
```
|
||
|
||
**影响:** 这些是RocketMQ消息的最终处理入口,当前实现只记录日志,消息会被消费但不执行任何业务操作。
|
||
|
||
---
|
||
|
||
### 3.2 消息消费者缺少业务级幂等键 ⚠️
|
||
|
||
**问题:** `BaseRocketMQConsumer`使用`messageExt.getMsgId()`(RocketMQ生成的broker消息ID)作为消息标识,但这不是业务级幂等键。
|
||
|
||
**建议修复方案:** 在`OrderMessage`/`FinanceMessage`/`InventoryMessage`中提取业务ID(如orderId + eventType)作为Redis去重键,而非使用RocketMQ的msgId。
|
||
|
||
---
|
||
|
||
### 3.3 平台同步服务Stub ⚠️
|
||
|
||
**文件:** `services/platform-sync-service/.../PlatformSyncServiceImpl.java`
|
||
```
|
||
syncOrderToPlatform() - TODO: 实现各平台API适配器,调用实际平台接口
|
||
pullOrdersFromPlatform() - TODO: 实现各平台API适配器,拉取实际订单数据
|
||
```
|
||
|
||
---
|
||
|
||
### 3.4 对账服务Stub ⚠️
|
||
|
||
**文件:** `services/reconciliation-service/.../ReconciliationServiceImpl.java`
|
||
```
|
||
getStatistics() - TODO: 实现完整的统计逻辑 (L564)
|
||
getDifferenceTrend() - TODO: 实现差异趋势统计 (L612)
|
||
getWeeklyReconciliation() - TODO: 实现周对账 (L640)
|
||
getMonthlyReconciliation() - TODO: 实现月对账 (L646)
|
||
fetchPlatformOrders() - TODO: 实现真实的平台订单获取逻辑 (L664)
|
||
fetchInternalOrders() - TODO: 实现真实的内部订单获取逻辑 (L674)
|
||
```
|
||
|
||
---
|
||
|
||
### 3.5 通知服务Stub ⚠️
|
||
|
||
**文件:** `services/notification-service/.../NotificationServiceImpl.java`
|
||
```
|
||
sendEmail() - TODO: 实现真实的邮件发送(接入SendGrid/阿里云邮件)(L106)
|
||
sendSms() - TODO: 实现真实的短信发送(接入阿里云/腾讯云短信)(L125)
|
||
```
|
||
|
||
当前为模拟实现,只记录日志,不实际发送。
|
||
|
||
---
|
||
|
||
### 3.6 事务边界问题 ⚠️(需人工确认)
|
||
|
||
**潜在风险点:** 检查了`OrderServiceImpl`中的`@Transactional`方法,未发现Feign调用被事务包裹的情况。但建议在以下场景中确认:
|
||
- 所有涉及跨服务调用的方法
|
||
- 任何在`@Transactional`方法内部的`FeignClient`调用
|
||
|
||
建议:使用`TransactionTemplate`编程式事务,将Feign调用放在事务外。
|
||
|
||
---
|
||
|
||
## 四、部署标准化清单
|
||
|
||
### 4.1 立即执行(代码已修复)
|
||
|
||
| 序号 | 操作 | 文件 |
|
||
|------|------|------|
|
||
| 1 | 重新编译approval-flow-service | AuditLogServiceImpl.java |
|
||
| 2 | 重新编译report-service | ReportExportServiceImpl.java |
|
||
| 3 | 重新编译gateway | MetricsFilter.java, application.yml, pom.xml |
|
||
| 4 | 部署后验证日志 | 检查是否有"无法获取当前租户上下文"警告 |
|
||
|
||
### 4.2 人工执行(需停机窗口)
|
||
|
||
| 序号 | 操作 | 说明 |
|
||
|------|------|------|
|
||
| 1 | 执行物流轨迹表分区切换 | `V2__add_partition_and_indexes.sql`中的RENAME TABLE步骤 |
|
||
| 2 | Prometheus配置 | 确认`/actuator/prometheus`端点可访问 |
|
||
| 3 | 接入商品/供应商服务Feign客户端 | 修复ReportExportServiceImpl的stub |
|
||
| 4 | 接入消息消费者真实实现 | Order/Finance/Inventory MessageConsumer |
|
||
| 5 | 接入邮件/短信服务商 | NotificationServiceImpl |
|
||
| 6 | 接入平台API适配器 | PlatformSyncServiceImpl |
|
||
|
||
---
|
||
|
||
## 五、文件变更摘要
|
||
|
||
```
|
||
gateway/pom.xml | +8 行
|
||
gateway/src/main/resources/application.yml | +10 行
|
||
.../approval/service/impl/AuditLogServiceImpl.java | ±47 行(重构3个stub方法+修复getUserAgent)
|
||
.../export/service/ReportExportServiceImpl.java | +14 行(2个stub方法增加warn日志)
|
||
gateway/src/main/java/com/erp/gateway/filter/MetricsFilter.java | 新增(+185行)
|
||
```
|
||
|
||
---
|
||
|
||
## 六、结论
|
||
|
||
✅ **已修复:4项** - 骨架代码stub、日志完善、网关指标收集
|
||
✅ **已确认正常:3项** - 物流功能、Nacos配置、订单状态机
|
||
⚠️ **待人工复核:6项** - 消息消费者stub、平台同步、对账服务、通知服务、事务边界、物流分区切换
|
||
|
||
**建议优先处理:** 消息消费者stub实现(直接影响业务)和物流轨迹表分区切换(数据增长后会遇到性能问题)。
|