Commit f39c6de8 by yanrui

cursor代码分析优化使用案例

parent ff613c3c
# 项目页面代码检查优化以及潜在问题处理
# 项目页面代码检查优化以及潜在问题处理
> **场景**: 针对在旧版本需求基础上进行新需求的迭代,需要理解旧版本代码的逻辑,并在其基础进行开发新版本需求。
>
> **作者**: yanrui
> **日期**: 2025-06-27
---
## 案例背景描述
在旧版本需求上进行功能迭代时,可以通过Cursor对现有代码进行以下操作:
- 分析各个方法的业务逻辑
- 增加异常捕获以及日志补全
- 发现方法中隐藏的潜在问题(NullPointException...)
- 减少代码冗余、硬编码等,提高可读性、健壮性
## 使用 Cursor 的解决过程
### 1. 问题诊断 Prompt
```
@/BerthOccupyOrderServiceImpl 梳理当前业务类中各个方法业务逻辑,优化代码,包括日志补全,异常捕获,潜在异常风险处理,提高代码可读性。分批次进行优化,并指出存在的问题,以及需要优化的建议
```
### 2. 代码分析与优化方案
#### 举例其中一个方法优化分析过程
1. addEntryApply方法
### 业务逻辑
- 创建占用工单对象,设置属性
- 通过Feign保存工单
- 保存成功后自动发起初审
### 存在问题
- 参数未校验,可能NPE
- 异常未捕获
- 日志不够详细
- approval返回值未判断
### 优化建议
- 增加参数校验
- try-catch包裹主流程
- 日志补全:入参、出参、异常
- 判断approval返回值
#### 解决方案代码
**优化前的 addEntryApply方法**
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone,
long parkId, String berthIds, String applyReason) {
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
berthOccupyOrder.setWorkOrderId(IdentifyUtils.getId());
berthOccupyOrder.setBerthIds(berthIds);
berthOccupyOrder.setOccupyType(occupyType);
berthOccupyOrder.setEntryTime(entryTime.getTime());
berthOccupyOrder.setPhone(phone);
berthOccupyOrder.setParkId(parkId);
// 在场状态:0-已离场;1-在场中;2-待入场
berthOccupyOrder.setRecordState(BerthOccupyRecordState.WAIT_ENTER.getCode());
berthOccupyOrder.setApplyReason(applyReason);
berthOccupyOrder.setD(0);
LoginUser loginUser = ReqContextParams.getLoginUser();
Long userId = Long.parseLong(loginUser.getUserId());
berthOccupyOrder.setUserId(userId);
berthOccupyOrder.setState(BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode());
log.info("占用申请创建:{}", JSON.toJSONString(berthOccupyOrder));
int i = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建条数,i={}", i);
if (i == 1) {
//处理记录
approval(berthOccupyOrder.getWorkOrderId(), BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null, BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(),null,null);
}
return berthOccupyOrder.getWorkOrderId();
}
```
**优化后的 addEntryApply方法**
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone,
long parkId, String berthIds, String applyReason) {
log.info("addEntryApply开始执行,入参:occupyType={}, entryTime={}, phone={}, parkId={}, berthIds={}, applyReason={}",
occupyType, entryTime, phone, parkId, berthIds, applyReason);
try {
// 参数校验
if (entryTime == null) {
log.warn("addEntryApply参数校验失败:entryTime为空");
throw new IllegalArgumentException("入场时间不能为空");
}
if (StringUtils.isStrTrimNull(phone)) {
log.warn("addEntryApply参数校验失败:phone为空");
throw new IllegalArgumentException("手机号不能为空");
}
if (StringUtils.isStrTrimNull(berthIds)) {
log.warn("addEntryApply参数校验失败:berthIds为空");
throw new IllegalArgumentException("泊位ID不能为空");
}
if (parkId <= 0) {
log.warn("addEntryApply参数校验失败:parkId无效,parkId={}", parkId);
throw new IllegalArgumentException("车场ID无效");
}
// 获取当前登录用户
LoginUser loginUser = ReqContextParams.getLoginUser();
if (loginUser == null || StringUtils.isStrTrimNull(loginUser.getUserId())) {
log.error("addEntryApply获取登录用户信息失败");
throw new RuntimeException("获取用户信息失败");
}
// 创建工单对象
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
berthOccupyOrder.setWorkOrderId(IdentifyUtils.getId());
berthOccupyOrder.setBerthIds(berthIds);
berthOccupyOrder.setOccupyType(occupyType);
berthOccupyOrder.setEntryTime(entryTime.getTime());
berthOccupyOrder.setPhone(phone);
berthOccupyOrder.setParkId(parkId);
// 在场状态:0-已离场;1-在场中;2-待入场
berthOccupyOrder.setRecordState(BerthOccupyRecordState.WAIT_ENTER.getCode());
berthOccupyOrder.setApplyReason(applyReason);
berthOccupyOrder.setD(0);
Long userId = Long.parseLong(loginUser.getUserId());
berthOccupyOrder.setUserId(userId);
berthOccupyOrder.setState(BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode());
log.info("占用申请创建,工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 保存工单
int saveResult = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建结果,影响行数:{}", saveResult);
if (saveResult != 1) {
log.error("占用申请创建失败,预期影响行数:1,实际影响行数:{}", saveResult);
throw new RuntimeException("占用申请创建失败");
}
// 发起初审
log.info("开始发起初审,工单ID:{}", berthOccupyOrder.getWorkOrderId());
ResponseResult<?> approvalResult = approval(berthOccupyOrder.getWorkOrderId(),
BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null,
BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(), null, null);
if (approvalResult == null || !approvalResult.isSuccess()) {
log.error("初审发起失败,工单ID:{},返回结果:{}", berthOccupyOrder.getWorkOrderId(),
approvalResult != null ? approvalResult.getMsg() : "null");
throw new RuntimeException("初审发起失败:" + (approvalResult != null ? approvalResult.getMsg() : "未知错误"));
}
log.info("addEntryApply执行成功,工单ID:{}", berthOccupyOrder.getWorkOrderId());
return berthOccupyOrder.getWorkOrderId();
} catch (IllegalArgumentException e) {
log.warn("addEntryApply参数校验异常:{}", e.getMessage());
throw e;
} catch (Exception e) {
log.error("addEntryApply执行异常:{}", e.getMessage(), e);
throw new RuntimeException("创建占用申请失败:" + e.getMessage(), e);
}
}
```
### 3. 优化总结
- ✅ 增加参数校验(entryTime、phone、berthIds、parkId)
- ✅ 增加异常处理和详细日志
- ✅ 增加用户信息校验
- ✅ 增加approval返回值判断
- ✅ 增加数据库操作结果校验
## 使用体验
### Cursor 的优势(基于代码交接或者在其他开发人员开发的需求基础进行迭代维护)
- 代码健壮性大幅提升,异常和空指针风险大幅降低。
- 日志更详细,便于排查问题。
- 结构更清晰,便于后续维护和扩展。
### 注意事项
- 针对较大的文件,建议分批次进行优化,或者指定明确需要优化的方法
- 合理性接受Cursor做出的代码更改(例如:登录用户判空,其实已经在Controller层通过@NeedLogin注解增加了校验)
---
## 相关资源
- [完整对话记录](./original-conversations/cursor-service-code-optimize-conversation.md) - 查看与 Cursor AI 的完整问题分析过程
---
## 💡 学习建议
想要了解完整的问题分析过程?点击查看 [原始 Cursor 对话记录](./original-conversations/cursor-emqx-mqtt-reconnect-conversation.md),包含:
- AI 的完整分析思路
- 多轮问题诊断过程
- 代码生成和优化过程
\ No newline at end of file
# 优化业务类代码逻辑和可读性
---
**User**
梳理当前业务类中各个方法业务逻辑,优化代码,包括日志补全,异常捕获,潜在异常风险处理,提高代码可读性。分批次进行优化,并指出存在的问题,以及需要优化的建议
---
**Cursor**
好的,我会**分批次**梳理和优化`BerthOccupyOrderServiceImpl`类中的方法,逐步指出每个方法存在的问题,并给出优化建议和代码示例。
**本轮先梳理前5个主要方法**,后续可继续细化。
---
## 1. addEntryApply
### 业务逻辑
- 创建占用工单对象,设置属性
- 通过Feign保存工单
- 保存成功后自动发起初审
### 存在问题
- 参数未校验,可能NPE
- 异常未捕获
- 日志不够详细
- approval返回值未判断
### 优化建议
- 增加参数校验
- try-catch包裹主流程
- 日志补全:入参、出参、异常
- 判断approval返回值
---
## 2. applyExit
### 业务逻辑
- 查询工单
- 校验工单和时间
- 更新工单出场时间
- 发起出场申请
### 存在问题
- 参数未校验
- 异常未捕获
- 日志不够详细
- 可能NPE
### 优化建议
- 校验workOrderId、exitTime
- try-catch主流程
- 日志补全
- 对所有对象判空
---
## 3. getPageList
### 业务逻辑
- 根据泊位号查车场
- 查询分页数据
- richVo组装VO
### 存在问题
- 参数未校验
- 异常未捕获
- richVo可能NPE
- 日志不够详细
### 优化建议
- 校验分页参数
- try-catch主流程
- 日志补全
- richVo判空
---
## 4. richVo
### 业务逻辑
- 查询操作人、车场、泊位信息
- 组装VO
### 存在问题
- 外部接口调用未try-catch
- 集合操作未判空
- 日志不够详细
### 优化建议
- try-catch外部接口
- 判空处理
- 日志补全
---
## 5. getPayOrderList
### 业务逻辑
- 查询工单
- 查询泊位、车场、停车记录
- 组装VO
### 存在问题
- 外部接口未try-catch
- 集合操作未判空
- 日志不够详细
### 优化建议
- try-catch外部接口
- 判空处理
- 日志补全
---
# 优化代码示例(以addEntryApply为例)
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone, long parkId, String berthIds, String applyReason) {
log.info("addEntryApply入参: occupyType={}, entryTime={}, phone={}, parkId={}, berthIds={}, applyReason={}", occupyType, entryTime, phone, parkId, berthIds, applyReason);
if (StringUtils.isStrTrimNull(berthIds) || StringUtils.isStrTrimNull(phone) || entryTime == null) {
log.warn("addEntryApply参数校验失败");
throw new IllegalArgumentException("参数不能为空");
}
try {
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
// ...设置属性...
int i = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建条数,i={}", i);
if (i == 1) {
ResponseResult<?> approvalResult = approval(berthOccupyOrder.getWorkOrderId(), BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null, BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(),null,null);
if (!approvalResult.isSuccess()) {
log.error("初审失败: {}", approvalResult.getMsg());
throw new RuntimeException("初审失败");
}
}
return berthOccupyOrder.getWorkOrderId();
} catch (Exception e) {
log.error("addEntryApply异常: {}", e.getMessage(), e);
throw new RuntimeException("创建占用申请失败");
}
}
```
---
# 总结
- **每个方法都要加参数校验、try-catch、日志补全、判空处理。**
- 外部接口调用、集合操作、类型转换、IO等都要catch异常。
- 日志内容要包含入参、出参、异常、关键业务节点。
- 复杂逻辑建议拆分为私有方法,提升可读性。
---
请问需要先优化哪几个方法?
还是按顺序逐步优化?
如需详细优化某个方法,请直接告知方法名!
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone, long parkId, String berthIds, String applyReason) {
log.info("addEntryApply入参: occupyType={}, entryTime={}, phone={}, parkId={}, berthIds={}, applyReason={}", occupyType, entryTime, phone, parkId, berthIds, applyReason);
if (StringUtils.isStrTrimNull(berthIds) || StringUtils.isStrTrimNull(phone) || entryTime == null) {
log.warn("addEntryApply参数校验失败");
throw new IllegalArgumentException("参数不能为空");
}
try {
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
// ...设置属性...
int i = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建条数,i={}", i);
if (i == 1) {
ResponseResult<?> approvalResult = approval(berthOccupyOrder.getWorkOrderId(), BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null, BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(),null,null);
if (!approvalResult.isSuccess()) {
log.error("初审失败: {}", approvalResult.getMsg());
throw new RuntimeException("初审失败");
}
}
return berthOccupyOrder.getWorkOrderId();
} catch (Exception e) {
log.error("addEntryApply异常: {}", e.getMessage(), e);
throw new RuntimeException("创建占用申请失败");
}
}
```
---
**User**
按顺序逐步优化
---
**Cursor**
好的,我将按顺序逐步优化。首先从第一个方法开始:
## 第一批优化:addEntryApply 方法
现在开始第一批优化,先优化 `addEntryApply` 方法:
## 第一批优化:addEntryApply 方法
### 存在的问题:
1. **参数校验缺失**:没有对关键参数进行空值校验
2. **异常处理不完善**:整个方法没有try-catch,可能抛出未处理异常
3. **日志不够详细**:缺少入参日志和异常日志
4. **潜在NPE风险**`loginUser.getUserId()`可能为空
5. **approval调用结果未判断**:没有检查approval方法的返回值
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone,
long parkId, String berthIds, String applyReason) {
log.info("addEntryApply开始执行,入参:occupyType={}, entryTime={}, phone={}, parkId={}, berthIds={}, applyReason={}",
occupyType, entryTime, phone, parkId, berthIds, applyReason);
try {
// 参数校验
if (entryTime == null) {
log.warn("addEntryApply参数校验失败:entryTime为空");
throw new IllegalArgumentException("入场时间不能为空");
}
if (StringUtils.isStrTrimNull(phone)) {
log.warn("addEntryApply参数校验失败:phone为空");
throw new IllegalArgumentException("手机号不能为空");
}
if (StringUtils.isStrTrimNull(berthIds)) {
log.warn("addEntryApply参数校验失败:berthIds为空");
throw new IllegalArgumentException("泊位ID不能为空");
}
if (parkId <= 0) {
log.warn("addEntryApply参数校验失败:parkId无效,parkId={}", parkId);
throw new IllegalArgumentException("车场ID无效");
}
// 获取当前登录用户
LoginUser loginUser = ReqContextParams.getLoginUser();
if (loginUser == null || StringUtils.isStrTrimNull(loginUser.getUserId())) {
log.error("addEntryApply获取登录用户信息失败");
throw new RuntimeException("获取用户信息失败");
}
// 创建工单对象
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
berthOccupyOrder.setWorkOrderId(IdentifyUtils.getId());
berthOccupyOrder.setBerthIds(berthIds);
berthOccupyOrder.setOccupyType(occupyType);
berthOccupyOrder.setEntryTime(entryTime.getTime());
berthOccupyOrder.setPhone(phone);
berthOccupyOrder.setParkId(parkId);
// 在场状态:0-已离场;1-在场中;2-待入场
berthOccupyOrder.setRecordState(BerthOccupyRecordState.WAIT_ENTER.getCode());
berthOccupyOrder.setApplyReason(applyReason);
berthOccupyOrder.setD(0);
Long userId = Long.parseLong(loginUser.getUserId());
berthOccupyOrder.setUserId(userId);
berthOccupyOrder.setState(BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode());
log.info("占用申请创建,工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 保存工单
int saveResult = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建结果,影响行数:{}", saveResult);
if (saveResult != 1) {
log.error("占用申请创建失败,预期影响行数:1,实际影响行数:{}", saveResult);
throw new RuntimeException("占用申请创建失败");
}
// 发起初审
log.info("开始发起初审,工单ID:{}", berthOccupyOrder.getWorkOrderId());
ResponseResult<?> approvalResult = approval(berthOccupyOrder.getWorkOrderId(),
BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null,
BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(), null, null);
if (approvalResult == null || !approvalResult.isSuccess()) {
log.error("初审发起失败,工单ID:{},返回结果:{}", berthOccupyOrder.getWorkOrderId(),
approvalResult != null ? approvalResult.getMsg() : "null");
throw new RuntimeException("初审发起失败:" + (approvalResult != null ? approvalResult.getMsg() : "未知错误"));
}
log.info("addEntryApply执行成功,工单ID:{}", berthOccupyOrder.getWorkOrderId());
return berthOccupyOrder.getWorkOrderId();
} catch (IllegalArgumentException e) {
log.warn("addEntryApply参数校验异常:{}", e.getMessage());
throw e;
} catch (Exception e) {
log.error("addEntryApply执行异常:{}", e.getMessage(), e);
throw new RuntimeException("创建占用申请失败:" + e.getMessage(), e);
}
}
```
## 第二批优化:applyExit 方法
### 存在的问题:
1. **参数校验缺失**:没有对workOrderId和exitTime进行校验
2. **异常处理不完善**:外部接口调用没有try-catch
3. **日志不够详细**:缺少入参日志和关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **时间比较逻辑**:时间比较可能有问题
```java
@Override
public ResponseResult<?> applyExit(Long workOrderId, Date exitTime) {
log.info("applyExit开始执行,入参:workOrderId={}, exitTime={}", workOrderId, exitTime);
try {
// 参数校验
if (workOrderId == null || workOrderId <= 0) {
log.warn("applyExit参数校验失败:workOrderId无效,workOrderId={}", workOrderId);
return ResponseResult.replyFail("工单ID无效");
}
if (exitTime == null) {
log.warn("applyExit参数校验失败:exitTime为空");
return ResponseResult.replyFail("出场时间不能为空");
}
// 查询工单信息
log.info("开始查询工单信息,workOrderId={}", workOrderId);
BerthOccupyOrder berthOccupyOrder = berthOccupyOrderFeignClient.getWorkOrderById(workOrderId);
if (berthOccupyOrder == null) {
log.error("未找到该申请单,workOrderId={}", workOrderId);
return ResponseResult.replyFail("未找到该申请单!");
}
log.info("查询到工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 校验入场时间
if (berthOccupyOrder.getEntryTime() == null) {
log.error("工单入场时间为空,workOrderId={}", workOrderId);
return ResponseResult.replyFail("工单入场时间异常");
}
// 校验出场时间不能早于入场时间
if (berthOccupyOrder.getEntryTime() >= exitTime.getTime()) {
log.error("出场时间早于入场时间,工单ID:{},入场时间:{},出场时间:{}",
workOrderId, berthOccupyOrder.getEntryTime(), exitTime.getTime());
return ResponseResult.replyFail("出场时间不能早于入场时间!");
}
// 更新工单出场时间
log.info("开始更新工单出场时间,workOrderId={}, exitTime={}", workOrderId, exitTime.getTime());
BerthOccupyOrder berthOccupyOrderUpdate = new BerthOccupyOrder();
berthOccupyOrderUpdate.setWorkOrderId(workOrderId);
berthOccupyOrderUpdate.setExitTime(exitTime.getTime());
int updateResult = berthOccupyOrderFeignClient.updateOrder(berthOccupyOrderUpdate);
log.info("更新工单出场时间结果,影响行数:{}", updateResult);
if (updateResult != 1) {
log.error("更新工单出场时间失败,预期影响行数:1,实际影响行数:{}", updateResult);
return ResponseResult.replyFail("出场失败!");
}
// 发起出场申请
log.info("开始发起出场申请,workOrderId={}, currentState={}", workOrderId, berthOccupyOrder.getState());
ResponseResult<?> approvalResult = approval(workOrderId, berthOccupyOrder.getState(),
null, BerthOccupyOptions.OCCUPY_OUT_APPLY.getCode(), null, null);
if (approvalResult == null) {
log.error("出场申请发起失败,返回结果为null,workOrderId={}", workOrderId);
return ResponseResult.replyFail("出场申请发起失败");
}
log.info("applyExit执行成功,workOrderId={}, approvalResult={}", workOrderId, approvalResult.getMsg());
return approvalResult;
} catch (Exception e) {
log.error("applyExit执行异常,workOrderId={}:{}", workOrderId, e.getMessage(), e);
return ResponseResult.replyFail("出场申请失败:" + e.getMessage());
}
}
```
## 第三批优化:getPageList 方法
### 存在的问题:
1. **参数校验缺失**:分页参数和关键参数没有校验
2. **异常处理不完善**:外部接口调用没有try-catch
3. **日志不够详细**:缺少入参日志和关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **richVo调用未判断**:richVo方法可能返回null
```java
@Override
public ResponseResult<PageResult<BerthOccupyOrderVO>> getPageList(Date startTime, Date endTime, Long carId, Long parkId,String berthCode,
Long workOrderId, String phone, Integer recordState,
Integer state, Integer pageNum, Integer pageSize) {
log.info("getPageList开始执行,入参:startTime={}, endTime={}, carId={}, parkId={}, berthCode={}, workOrderId={}, phone={}, recordState={}, state={}, pageNum={}, pageSize={}",
startTime, endTime, carId, parkId, berthCode, workOrderId, phone, recordState, state, pageNum, pageSize);
try {
// 参数校验
if (pageNum == null || pageNum <= 0) {
log.warn("getPageList参数校验失败:pageNum无效,pageNum={}", pageNum);
return ResponseResult.replyFail("页码参数无效");
}
if (pageSize == null || pageSize <= 0 || pageSize > 1000) {
log.warn("getPageList参数校验失败:pageSize无效,pageSize={}", pageSize);
return ResponseResult.replyFail("每页大小参数无效");
}
// 初始化返回结果
PageResult<BerthOccupyOrderVO> result = new PageResult<>();
result.setList(new ArrayList<BerthOccupyOrderVO>());
result.setTotal(0);
result.setPageSize(pageSize);
result.setPageNum(pageNum);
Long berthId = 0L;
// 根据泊位编码查找车场信息
if (StringUtils.isNotNull(berthCode)) {
log.info("根据泊位编码查找车场信息,berthCode={}", berthCode);
try {
Berth berth = berthFeignClient.berthGetByCode(berthCode);
if (berth == null || berth.getParkId() == null) {
log.error("获取泊位占用工单列表,输入berthCode未找到泊位或车场,berthCode={}", berthCode);
return ResponseResult.replyFail("输入泊位编码未找到泊位或车场");
}
if (parkId != null && !Objects.equals(berth.getParkId(), parkId)) {
log.error("获取泊位占用工单列表,输入泊位号与车场不匹配,berthCode={}, berthParkId={}, inputParkId={}",
berthCode, berth.getParkId(), parkId);
return ResponseResult.replyFail("输入泊位号与车场不匹配");
}
parkId = berth.getParkId();
berthId = berth.getBerthId();
log.info("泊位编码查询结果:parkId={}, berthId={}", parkId, berthId);
} catch (Exception e) {
log.error("根据泊位编码查询车场信息异常,berthCode={}:{}", berthCode, e.getMessage(), e);
return ResponseResult.replyFail("查询泊位信息失败");
}
}
// 转换时间格式
String startStr = startTime == null ? null : DateUtil.dateToStr(startTime, DateUtil.PATTERN_STANDARD19H);
String endStr = endTime == null ? null : DateUtil.dateToStr(endTime, DateUtil.PATTERN_STANDARD19H);
log.info("开始查询工单列表,查询参数:startStr={}, endStr={}, carId={}, parkId={}, berthId={}, workOrderId={}, phone={}, recordState={}, state={}, pageNum={}, pageSize={}",
startStr, endStr, carId, parkId, berthId, workOrderId, phone, recordState, state, pageNum, pageSize);
// 查询工单列表
PageResult<BerthOccupyOrder> pageResult = berthOccupyOrderFeignClient.getList(startStr, endStr,
carId, parkId, berthId, workOrderId, phone, recordState, state, pageNum, pageSize);
if (pageResult == null) {
log.warn("查询工单列表返回null");
return ResponseResult.replySuccess(result);
}
log.info("查询工单列表结果:总数={}, 当前页数据量={}", pageResult.getTotal(),
pageResult.getList() != null ? pageResult.getList().size() : 0);
if (pageResult.getTotal() > 0 && pageResult.getList() != null && !pageResult.getList().isEmpty()) {
List<BerthOccupyOrder> orderList = pageResult.getList();
// 组装VO数据
log.info("开始组装VO数据,工单数量:{}", orderList.size());
List<BerthOccupyOrderVO> voList = richVo(orderList);
if (voList != null) {
result.getList().addAll(voList);
result.setTotal(pageResult.getTotal());
log.info("VO数据组装完成,返回数据量:{}", voList.size());
} else {
log.warn("richVo返回null,使用空列表");
}
}
log.info("getPageList执行成功,返回数据量:{}", result.getList().size());
return ResponseResult.replySuccess(result);
} catch (Exception e) {
log.error("getPageList执行异常:{}", e.getMessage(), e);
return ResponseResult.replyFail("查询工单列表失败:" + e.getMessage());
}
}
```
## 第四批优化:richVo 方法
### 存在的问题:
1. **异常处理不完善**:外部接口调用没有try-catch
2. **空值判断缺失**:多个地方可能NPE
3. **日志不够详细**:缺少关键步骤日志
4. **集合操作风险**:stream操作可能异常
5. **方法职责过重**:一个方法做了太多事情
```java
private List<BerthOccupyOrderVO> richVo(List<BerthOccupyOrder> orderList) {
log.info("richVo开始执行,工单数量:{}", orderList != null ? orderList.size() : 0);
try {
if (CollectionUtils.isEmpty(orderList)) {
log.warn("richVo输入工单列表为空");
return new ArrayList<>();
}
List<BerthOccupyOrderVO> berthOccupyOrderVOS = new ArrayList<>();
// 获取操作人信息
Map<Long, String> managerMap = getManagerMap(orderList);
// 获取车场信息
Map<Long, String> parkMap = getParkMap(orderList);
// 获取泊位信息
Map<Long, String> berthMap = getBerthMap(orderList);
// 组装VO数据
for (BerthOccupyOrder berthOccupyOrder : orderList) {
try {
BerthOccupyOrderVO berthOccupyOrderVO = buildBerthOccupyOrderVO(berthOccupyOrder, managerMap, parkMap, berthMap);
berthOccupyOrderVOS.add(berthOccupyOrderVO);
} catch (Exception e) {
log.error("组装单个工单VO异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
// 继续处理其他工单,不中断整个流程
}
}
log.info("richVo执行完成,成功组装VO数量:{}", berthOccupyOrderVOS.size());
return berthOccupyOrderVOS;
} catch (Exception e) {
log.error("richVo执行异常:{}", e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 获取操作人信息映射
*/
private Map<Long, String> getManagerMap(List<BerthOccupyOrder> orderList) {
try {
List<Long> userIds = orderList.stream()
.map(BerthOccupyOrder::getUserId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(userIds)) {
log.warn("没有有效的用户ID");
return new HashMap<>();
}
log.info("开始查询操作人信息,用户ID数量:{}", userIds.size());
List<BossManagerVO> bossManagers = bossManagerFeignClient.getBossManagerByIdList(userIds);
if (CollectionUtils.isEmpty(bossManagers)) {
log.warn("查询操作人信息返回空");
return new HashMap<>();
}
Map<Long, String> managerMap = bossManagers.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
BossManagerVO::getBossManagerId,
BossManagerVO::getBossManagerName,
(existing, replacement) -> existing
));
log.info("操作人信息查询完成,数量:{}", managerMap.size());
return managerMap;
} catch (Exception e) {
log.error("获取操作人信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 获取车场信息映射
*/
private Map<Long, String> getParkMap(List<BerthOccupyOrder> orderList) {
try {
List<Long> parkIds = orderList.stream()
.map(BerthOccupyOrder::getParkId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(parkIds)) {
log.warn("没有有效的车场ID");
return new HashMap<>();
}
log.info("开始查询车场信息,车场ID数量:{}", parkIds.size());
List<Park> parks = parkFeignClient.parkGetByParkIdList(parkIds);
if (CollectionUtils.isEmpty(parks)) {
log.warn("查询车场信息返回空");
return new HashMap<>();
}
Map<Long, String> parkMap = parks.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
Park::getParkId,
Park::getParkName,
(existing, replacement) -> existing
));
log.info("车场信息查询完成,数量:{}", parkMap.size());
return parkMap;
} catch (Exception e) {
log.error("获取车场信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 获取泊位信息映射
*/
private Map<Long, String> getBerthMap(List<BerthOccupyOrder> orderList) {
try {
List<Long> berthIdSet = orderList.stream()
.map(BerthOccupyOrder::getBerthIds)
.filter(StringUtils::isNotStrTrimNull)
.flatMap(berthIds -> Arrays.stream(berthIds.split(",")))
.filter(StringUtils::isNotStrTrimNull)
.map(berthId -> {
try {
return Long.parseLong(berthId.trim());
} catch (NumberFormatException e) {
log.warn("泊位ID格式错误:{}", berthId);
return null;
}
})
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(berthIdSet)) {
log.warn("没有有效的泊位ID");
return new HashMap<>();
}
log.info("开始查询泊位信息,泊位ID数量:{}", berthIdSet.size());
List<Berth> berths = berthFeignClient.byBerthIdList(berthIdSet);
if (CollectionUtils.isEmpty(berths)) {
log.warn("查询泊位信息返回空");
return new HashMap<>();
}
Map<Long, String> berthMap = berths.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
Berth::getBerthId,
Berth::getBerthCode,
(existing, replacement) -> existing
));
log.info("泊位信息查询完成,数量:{}", berthMap.size());
return berthMap;
} catch (Exception e) {
log.error("获取泊位信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 构建单个工单VO
*/
private BerthOccupyOrderVO buildBerthOccupyOrderVO(BerthOccupyOrder berthOccupyOrder,
Map<Long, String> managerMap,
Map<Long, String> parkMap,
Map<Long, String> berthMap) {
BerthOccupyOrderVO berthOccupyOrderVO = new BerthOccupyOrderVO();
BeanUtils.copyProperties(berthOccupyOrder, berthOccupyOrderVO);
// 停车时长
berthOccupyOrderVO.setOccupyTime(getParkTime(berthOccupyOrder));
// 入场时间
if (berthOccupyOrder.getEntryTime() != null) {
berthOccupyOrderVO.setEntryTimeStr(DateUtil.date2String(new Date(berthOccupyOrder.getEntryTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 出场时间
if (berthOccupyOrder.getExitTime() != null) {
berthOccupyOrderVO.setExitTimeStr(DateUtil.date2String(new Date(berthOccupyOrder.getExitTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 操作人
berthOccupyOrderVO.setUserName(managerMap.get(berthOccupyOrderVO.getUserId()));
// 车场名称
berthOccupyOrderVO.setParkName(parkMap.get(berthOccupyOrder.getParkId()));
// 泊位编号
String berthCodes = getBerthCodes(berthOccupyOrder.getBerthIds(), berthMap);
berthOccupyOrderVO.setBerthCodes(berthCodes);
// 占用类型枚举
berthOccupyOrderVO.setOccupyTypeStr(BerthOccupyType.getDescByCode(berthOccupyOrder.getOccupyType()));
// 操作时间
String operateTimeStr = DateUtil.date2String(berthOccupyOrder.getUpdatedTime() == null ?
berthOccupyOrder.getCreatedTime() : berthOccupyOrder.getUpdatedTime(), DateUtil.PATTERN_STANDARD19H);
berthOccupyOrderVO.setOperateTimeStr(operateTimeStr);
// 在场状态
berthOccupyOrderVO.setRecordStateStr(BerthOccupyRecordState.getByCode(berthOccupyOrder.getRecordState()).getDesc());
// 审核状态
berthOccupyOrderVO.setCheckStateStr(BerthOccupyOrderState.getEnum(berthOccupyOrder.getState()).getDesc());
return berthOccupyOrderVO;
}
/**
* 获取泊位编码字符串
*/
private String getBerthCodes(String berthIds, Map<Long, String> berthMap) {
if (StringUtils.isStrTrimNull(berthIds) || berthMap == null || berthMap.isEmpty()) {
return "";
}
try {
List<Long> berthIdList = Arrays.stream(berthIds.split(","))
.map(String::trim)
.filter(StringUtils::isNotStrTrimNull)
.map(berthId -> {
try {
return Long.parseLong(berthId);
} catch (NumberFormatException e) {
log.warn("泊位ID格式错误:{}", berthId);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
return berthIdList.stream()
.map(berthMap::get)
.filter(Objects::nonNull)
.collect(Collectors.joining(","));
} catch (Exception e) {
log.error("解析泊位编码异常,berthIds={}:{}", berthIds, e.getMessage(), e);
return "";
}
}
```
## 第五批优化:getPayOrderList 方法
### 存在的问题:
1. **参数校验缺失**:workOrderId没有校验
2. **异常处理不完善**:外部接口调用没有try-catch
3. **日志不够详细**:缺少入参日志和关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **集合操作风险**:stream操作可能异常
```java
@Override
public List<ParkRecordVO> getPayOrderList(Long workOrderId) {
log.info("getPayOrderList开始执行,入参:workOrderId={}", workOrderId);
try {
// 参数校验
if (workOrderId == null || workOrderId <= 0) {
log.warn("getPayOrderList参数校验失败:workOrderId无效,workOrderId={}", workOrderId);
return new ArrayList<>();
}
// 查询工单信息
log.info("开始查询工单信息,workOrderId={}", workOrderId);
BerthOccupyOrder berthOccupyOrder = berthOccupyOrderFeignClient.getWorkOrderById(workOrderId);
if (berthOccupyOrder == null) {
log.warn("未找到工单信息,workOrderId={}", workOrderId);
return new ArrayList<>();
}
log.info("查询到工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 校验工单状态和停车记录ID
if (berthOccupyOrder.getRecordState() == 2 || StringUtils.isStrTrimNull(berthOccupyOrder.getParkRecordIds())) {
log.info("工单状态为已离场或停车记录ID为空,返回空列表,workOrderId={}, recordState={}, parkRecordIds={}",
workOrderId, berthOccupyOrder.getRecordState(), berthOccupyOrder.getParkRecordIds());
return new ArrayList<>();
}
// 解析泊位ID列表
List<Long> berthIds = parseBerthIds(berthOccupyOrder.getBerthIds());
if (CollectionUtils.isEmpty(berthIds)) {
log.warn("解析泊位ID失败,berthIds={}", berthOccupyOrder.getBerthIds());
return new ArrayList<>();
}
// 解析停车记录ID列表
List<Long> parkRecordIds = parseParkRecordIds(berthOccupyOrder.getParkRecordIds());
if (CollectionUtils.isEmpty(parkRecordIds)) {
log.warn("解析停车记录ID失败,parkRecordIds={}", berthOccupyOrder.getParkRecordIds());
return new ArrayList<>();
}
// 校验泊位ID和停车记录ID数量是否一致
if (berthIds.size() != parkRecordIds.size()) {
log.error("泊位ID和停车记录ID数量不一致,berthIds.size={}, parkRecordIds.size={}",
berthIds.size(), parkRecordIds.size());
return new ArrayList<>();
}
// 获取泊位信息
Map<Long, String> berthMap = getBerthMapByIds(berthIds);
// 获取车场信息
String parkName = getParkName(berthOccupyOrder.getParkId());
// 组装停车记录VO列表
List<ParkRecordVO> recordVOList = buildParkRecordVOList(berthOccupyOrder, berthIds, parkRecordIds, berthMap, parkName);
log.info("getPayOrderList执行成功,返回记录数量:{}", recordVOList.size());
return recordVOList;
} catch (Exception e) {
log.error("getPayOrderList执行异常,workOrderId={}:{}", workOrderId, e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 解析泊位ID列表
*/
private List<Long> parseBerthIds(String berthIds) {
if (StringUtils.isStrTrimNull(berthIds)) {
return new ArrayList<>();
}
try {
return Arrays.stream(berthIds.split(","))
.map(String::trim)
.filter(StringUtils::isNotStrTrimNull)
.map(berthId -> {
try {
return Long.parseLong(berthId);
} catch (NumberFormatException e) {
log.warn("泊位ID格式错误:{}", berthId);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (Exception e) {
log.error("解析泊位ID异常,berthIds={}:{}", berthIds, e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 解析停车记录ID列表
*/
private List<Long> parseParkRecordIds(String parkRecordIds) {
if (StringUtils.isStrTrimNull(parkRecordIds)) {
return new ArrayList<>();
}
try {
return Arrays.stream(parkRecordIds.split(","))
.map(String::trim)
.filter(StringUtils::isNotStrTrimNull)
.map(recordId -> {
try {
return Long.parseLong(recordId);
} catch (NumberFormatException e) {
log.warn("停车记录ID格式错误:{}", recordId);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (Exception e) {
log.error("解析停车记录ID异常,parkRecordIds={}:{}", parkRecordIds, e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 根据泊位ID列表获取泊位信息映射
*/
private Map<Long, String> getBerthMapByIds(List<Long> berthIds) {
try {
if (CollectionUtils.isEmpty(berthIds)) {
return new HashMap<>();
}
log.info("开始查询泊位信息,泊位ID数量:{}", berthIds.size());
List<Berth> berths = berthFeignClient.byBerthIdList(berthIds);
if (CollectionUtils.isEmpty(berths)) {
log.warn("查询泊位信息返回空");
return new HashMap<>();
}
Map<Long, String> berthMap = berths.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
Berth::getBerthId,
Berth::getBerthCode,
(existing, replacement) -> existing
));
log.info("泊位信息查询完成,数量:{}", berthMap.size());
return berthMap;
} catch (Exception e) {
log.error("获取泊位信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 获取车场名称
*/
private String getParkName(Long parkId) {
try {
if (parkId == null) {
return "";
}
log.info("开始查询车场信息,parkId={}", parkId);
ParkVO parkVOById = parkFeignClient.getParkVOById(parkId);
if (parkVOById == null) {
log.warn("查询车场信息返回空,parkId={}", parkId);
return "";
}
String parkName = parkVOById.getParkName();
log.info("车场信息查询完成,parkName={}", parkName);
return parkName != null ? parkName : "";
} catch (Exception e) {
log.error("获取车场名称异常,parkId={}:{}", parkId, e.getMessage(), e);
return "";
}
}
/**
* 构建停车记录VO列表
*/
private List<ParkRecordVO> buildParkRecordVOList(BerthOccupyOrder berthOccupyOrder,
List<Long> berthIds,
List<Long> parkRecordIds,
Map<Long, String> berthMap,
String parkName) {
List<ParkRecordVO> recordVOList = new ArrayList<>();
for (int i = 0; i < berthIds.size(); i++) {
try {
Long berthId = berthIds.get(i);
Long parkRecordId = parkRecordIds.get(i);
ParkRecordVO parkRecordVO = new ParkRecordVO();
parkRecordVO.setParkRecordId(parkRecordId);
parkRecordVO.setBerthCode(berthMap.get(berthId));
parkRecordVO.setParkName(parkName);
parkRecordVO.setPlateNumber(berthOccupyOrder.getPlateNumber());
parkRecordVO.setMobile(berthOccupyOrder.getPhone());
// 设置入场时间
if (berthOccupyOrder.getEntryTime() != null) {
parkRecordVO.setStrEntryTime(DateUtil.date2String(new Date(berthOccupyOrder.getEntryTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 设置出场时间
if (berthOccupyOrder.getExitTime() != null) {
parkRecordVO.setStrExitTime(DateUtil.date2String(new Date(berthOccupyOrder.getExitTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 查询停车记录详情,获取应收、实收金额
ParkRecordVO parkRecordDetail = getParkRecordDetail(parkRecordId.toString());
if (parkRecordDetail != null) {
parkRecordVO.setShouldPay(parkRecordDetail.getShouldPay() != null ? parkRecordDetail.getShouldPay() : 0);
parkRecordVO.setActualPay(parkRecordDetail.getActualPay() != null ? parkRecordDetail.getActualPay() : 0);
} else {
parkRecordVO.setShouldPay(0);
parkRecordVO.setActualPay(0);
}
recordVOList.add(parkRecordVO);
} catch (Exception e) {
log.error("构建单个停车记录VO异常,berthId={}, parkRecordId={}:{}",
berthIds.get(i), parkRecordIds.get(i), e.getMessage(), e);
// 继续处理其他记录,不中断整个流程
}
}
return recordVOList;
}
```
## 第一批优化总结
我已经完成了前5个方法的优化,主要改进包括:
### 1. **addEntryApply 方法优化**
- ✅ 增加参数校验(entryTime、phone、berthIds、parkId)
- ✅ 增加异常处理和详细日志
- ✅ 增加用户信息校验
- ✅ 增加approval返回值判断
- ✅ 增加数据库操作结果校验
### 2. **applyExit 方法优化**
- ✅ 增加参数校验(workOrderId、exitTime)
- ✅ 增加异常处理和详细日志
- ✅ 增加入场时间校验
- ✅ 增加数据库操作结果校验
- ✅ 增加approval返回值判断
### 3. **getPageList 方法优化**
- ✅ 增加分页参数校验
- ✅ 增加异常处理和详细日志
- ✅ 增加外部接口调用异常处理
- ✅ 增加richVo返回值判断
- ✅ 增加查询结果空值判断
### 4. **richVo 方法优化**
- ✅ 拆分为多个职责单一的私有方法
- ✅ 增加异常处理和详细日志
- ✅ 增加集合操作异常处理
- ✅ 增加外部接口调用异常处理
- ✅ 增加空值判断和容错处理
### 5. **getPayOrderList 方法优化**
- ✅ 增加参数校验
- ✅ 增加异常处理和详细日志
- ✅ 拆分为多个职责单一的私有方法
- ✅ 增加数据一致性校验
- ✅ 增加外部接口调用异常处理
### 主要改进点:
1. **异常处理**:每个方法都增加了try-catch,避免未处理异常
2. **参数校验**:对所有关键参数进行空值和有效性校验
3. **日志补全**:增加了入参、出参、关键步骤、异常的详细日志
4. **空值判断**:对所有可能为空的对象和集合进行判断
5. **方法拆分**:将复杂方法拆分为多个职责单一的私有方法
6. **容错处理**:增加了数据格式错误、外部接口失败等情况的处理
---
**接下来继续优化剩余的方法吗?** 我可以继续优化:
- getDetailById
- getRecordDetailById
- entry
- exit
- 等其他方法
请告诉我是否继续,或者您希望先查看某个特定方法的优化。
---
**User**
继续
---
**Cursor**
好的,继续优化剩余的方法。接下来优化第6-10个方法:
## 第六批优化:getDetailById 方法
现在开始优化第6-10个方法:
## 第六批优化:getDetailById 方法
### 存在的问题:
1. **参数校验缺失**:workOrderId没有校验
2. **异常处理不完善**:外部接口调用没有try-catch
3. **日志不够详细**:缺少入参日志和关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **JSON解析风险**:JSONArray.parseArray可能异常
```java
@Override
public BerthOccupyOrderVO getDetailById(long workOrderId) {
log.info("getDetailById开始执行,入参:workOrderId={}", workOrderId);
try {
// 参数校验
if (workOrderId <= 0) {
log.warn("getDetailById参数校验失败:workOrderId无效,workOrderId={}", workOrderId);
return null;
}
// 查询工单信息
log.info("开始查询工单信息,workOrderId={}", workOrderId);
BerthOccupyOrder berthOccupyOrder = berthOccupyOrderFeignClient.getWorkOrderById(workOrderId);
if (berthOccupyOrder == null) {
log.warn("未找到工单信息,workOrderId={}", workOrderId);
return null;
}
log.info("查询到工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 构建VO对象
BerthOccupyOrderVO berthOccupyOrderVO = buildDetailVO(berthOccupyOrder);
log.info("getDetailById执行成功,workOrderId={}", workOrderId);
return berthOccupyOrderVO;
} catch (Exception e) {
log.error("getDetailById执行异常,workOrderId={}:{}", workOrderId, e.getMessage(), e);
return null;
}
}
/**
* 构建详情VO对象
*/
private BerthOccupyOrderVO buildDetailVO(BerthOccupyOrder berthOccupyOrder) {
BerthOccupyOrderVO berthOccupyOrderVO = new BerthOccupyOrderVO();
BeanUtils.copyProperties(berthOccupyOrder, berthOccupyOrderVO);
// 停车时长
berthOccupyOrderVO.setOccupyTime(getParkTime(berthOccupyOrder));
// 入场时间
if (berthOccupyOrder.getEntryTime() != null) {
berthOccupyOrderVO.setEntryTimeStr(DateUtil.date2String(new Date(berthOccupyOrder.getEntryTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 出场时间
if (berthOccupyOrder.getExitTime() != null) {
berthOccupyOrderVO.setExitTimeStr(DateUtil.date2String(new Date(berthOccupyOrder.getExitTime()),
DateUtil.PATTERN_STANDARD19H));
}
// 文件列表处理
processFileList(berthOccupyOrder, berthOccupyOrderVO);
// 计算应收、实收金额
calculatePaymentAmount(berthOccupyOrderVO);
return berthOccupyOrderVO;
}
/**
* 处理文件列表
*/
private void processFileList(BerthOccupyOrder berthOccupyOrder, BerthOccupyOrderVO berthOccupyOrderVO) {
try {
// 处理图片列表
if (StringUtils.isNotNull(berthOccupyOrder.getPicList())) {
String picList = berthOccupyOrder.getPicList();
List<BerthOccupyFile> picListEntity = JSONArray.parseArray(picList, BerthOccupyFile.class);
berthOccupyOrderVO.setPicListEntity(picListEntity);
log.debug("解析图片列表成功,数量:{}", picListEntity != null ? picListEntity.size() : 0);
}
// 处理文件列表
if (StringUtils.isNotNull(berthOccupyOrder.getFileList())) {
String fileList = berthOccupyOrder.getFileList();
List<BerthOccupyFile> fileListEntity = JSONArray.parseArray(fileList, BerthOccupyFile.class);
berthOccupyOrderVO.setFileListEntity(fileListEntity);
log.debug("解析文件列表成功,数量:{}", fileListEntity != null ? fileListEntity.size() : 0);
}
} catch (Exception e) {
log.error("解析文件列表异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
// 不中断流程,继续处理
}
}
/**
* 计算应收、实收金额
*/
private void calculatePaymentAmount(BerthOccupyOrderVO berthOccupyOrderVO) {
try {
// 应收、实收直接同步停车记录中的数据
List<ParkRecordVO> records = Optional.ofNullable(berthOccupyOrderVO.getParkRecordIds())
.filter(StringUtils::isNotStrTrimNull)
.map(ids -> Arrays.stream(ids.split(",")))
.map(stream -> stream
.map(this::getParkRecordDetail)
.filter(Objects::nonNull)
.collect(Collectors.toList()))
.orElse(Collections.emptyList());
int shouldPay = records.stream()
.mapToInt(r -> r.getShouldPay() != null ? r.getShouldPay() : 0)
.sum();
int actualPay = records.stream()
.mapToInt(r -> r.getActualPay() != null ? r.getActualPay() : 0)
.sum();
berthOccupyOrderVO.setShouldPay(shouldPay);
berthOccupyOrderVO.setActualPay(actualPay);
log.debug("计算应收实收金额完成,shouldPay={}, actualPay={}", shouldPay, actualPay);
} catch (Exception e) {
log.error("计算应收实收金额异常:{}", e.getMessage(), e);
// 设置默认值
berthOccupyOrderVO.setShouldPay(0);
berthOccupyOrderVO.setActualPay(0);
}
}
```
## 第七批优化:getRecordDetailById 方法
### 存在的问题:
1. **参数校验缺失**:recordId没有校验
2. **异常处理不完善**:外部接口调用没有try-catch
3. **日志不够详细**:缺少入参日志和关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **代码重复**:与getDetailById有重复逻辑
```java
@Override
public BerthOccupyOrderVO getRecordDetailById(long recordId) {
log.info("getRecordDetailById开始执行,入参:recordId={}", recordId);
try {
// 参数校验
if (recordId <= 0) {
log.warn("getRecordDetailById参数校验失败:recordId无效,recordId={}", recordId);
return null;
}
// 查询操作记录
log.info("开始查询操作记录,recordId={}", recordId);
BerthOccupyApprovalRecord approvalRecord = berthOccupyOrderFeignClient.getApprovalRecordById(recordId);
if (approvalRecord == null) {
log.warn("未找到操作记录,recordId={}", recordId);
return null;
}
log.info("查询到操作记录:{}", JSON.toJSONString(approvalRecord));
// 查询对应工单信息
Long workOrderId = approvalRecord.getWorkOrderId();
if (workOrderId == null || workOrderId <= 0) {
log.error("操作记录中的工单ID无效,recordId={}, workOrderId={}", recordId, workOrderId);
return null;
}
log.info("开始查询工单信息,workOrderId={}", workOrderId);
BerthOccupyOrder berthOccupyOrder = berthOccupyOrderFeignClient.getWorkOrderById(workOrderId);
if (berthOccupyOrder == null) {
log.warn("未找到工单信息,workOrderId={}", workOrderId);
return null;
}
log.info("查询到工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 构建基础VO对象(复用getDetailById的逻辑)
BerthOccupyOrderVO berthOccupyOrderVO = buildDetailVO(berthOccupyOrder);
// 补充操作记录相关信息
enrichApprovalRecordInfo(berthOccupyOrderVO, approvalRecord);
log.info("getRecordDetailById执行成功,recordId={}, workOrderId={}", recordId, workOrderId);
return berthOccupyOrderVO;
} catch (Exception e) {
log.error("getRecordDetailById执行异常,recordId={}:{}", recordId, e.getMessage(), e);
return null;
}
}
/**
* 补充操作记录相关信息
*/
private void enrichApprovalRecordInfo(BerthOccupyOrderVO berthOccupyOrderVO, BerthOccupyApprovalRecord approvalRecord) {
try {
// 获取操作人信息
List<Long> userIds = new ArrayList<>(1);
userIds.add(approvalRecord.getUserId());
Map<Long, String> userInfoMap = getUserInfoMap(userIds);
// 设置操作记录相关信息
berthOccupyOrderVO.setRecordId(approvalRecord.getRecordId());
berthOccupyOrderVO.setOperatorName(userInfoMap.get(approvalRecord.getUserId()));
berthOccupyOrderVO.setOption(approvalRecord.getOptionType());
// 设置下一操作类型
BerthOccupyOptions nextOption = BerthOccupyOptions.getNextEnum(approvalRecord.getOptionType());
berthOccupyOrderVO.setNextOption(nextOption == null ? 0 : nextOption.getCode());
// 设置审核状态
berthOccupyOrderVO.setTargetState(approvalRecord.getTargetState());
// 设置操作时间
if (approvalRecord.getCreatedTime() != null) {
berthOccupyOrderVO.setOptionTime(DateUtil.date2String(approvalRecord.getCreatedTime(), DateUtil.PATTERN_STANDARD19H));
}
// 设置驳回理由
berthOccupyOrderVO.setRejectReason(approvalRecord.getRejectReason());
log.debug("补充操作记录信息完成,recordId={}, operatorName={}",
approvalRecord.getRecordId(), userInfoMap.get(approvalRecord.getUserId()));
} catch (Exception e) {
log.error("补充操作记录信息异常,recordId={}:{}", approvalRecord.getRecordId(), e.getMessage(), e);
// 不中断流程,继续处理
}
}
```
## 第八批优化:entry 方法
### 存在的问题:
1. **参数校验缺失**:berthOccupyOrder没有校验
2. **异常处理不完善**:多个外部接口调用没有try-catch
3. **日志不够详细**:缺少关键步骤日志
4. **潜在NPE风险**:多个地方可能空指针
5. **方法职责过重**:一个方法做了太多事情
```java
private void entry(BerthOccupyOrder berthOccupyOrder) {
log.info("entry开始执行,工单信息:{}", JSON.toJSONString(berthOccupyOrder));
try {
// 参数校验
if (berthOccupyOrder == null) {
log.error("entry参数校验失败:berthOccupyOrder为空");
return;
}
if (StringUtils.isStrTrimNull(berthOccupyOrder.getBerthIds())) {
log.error("entry参数校验失败:berthIds为空,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
if (berthOccupyOrder.getParkId() == null) {
log.error("entry参数校验失败:parkId为空,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
// 解析泊位ID
List<Long> berthIds = parseBerthIdsForEntry(berthOccupyOrder.getBerthIds());
if (CollectionUtils.isEmpty(berthIds)) {
log.error("解析泊位ID失败,berthIds={}", berthOccupyOrder.getBerthIds());
return;
}
// 获取泊位信息
Map<Long, String> berthMap = getBerthMapForEntry(berthIds);
if (berthMap.isEmpty()) {
log.error("获取泊位信息失败,berthIds={}", berthIds);
return;
}
// 获取车场信息
ParkVO parkVO = getParkVOForEntry(berthOccupyOrder.getParkId());
if (parkVO == null) {
log.error("获取车场信息失败,parkId={}", berthOccupyOrder.getParkId());
return;
}
// 获取随机车牌
Car newPlate = getNewPlate();
if (newPlate == null) {
log.error("获取随机车牌失败");
return;
}
log.info("获取随机车牌成功:{}", objectMapper.writeValueAsString(newPlate));
// 创建停车记录
List<Long> parkRecordIds = createParkRecords(berthOccupyOrder, berthIds, berthMap, parkVO, newPlate);
if (CollectionUtils.isEmpty(parkRecordIds)) {
log.error("创建停车记录失败,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
// 更新工单状态
updateOrderAfterEntry(berthOccupyOrder, parkRecordIds, newPlate);
// 发送入场通知
sendEntryNotification(berthOccupyOrder, parkVO, newPlate);
log.info("entry执行成功,workOrderId={}", berthOccupyOrder.getWorkOrderId());
} catch (Exception e) {
log.error("entry执行异常,workOrderId={}:{}",
berthOccupyOrder != null ? berthOccupyOrder.getWorkOrderId() : "null", e.getMessage(), e);
}
}
/**
* 解析泊位ID(用于入场)
*/
private List<Long> parseBerthIdsForEntry(String berthIds) {
try {
String[] berthIdStr = berthIds.split(",");
return Arrays.stream(berthIdStr)
.map(String::trim)
.filter(StringUtils::isNotStrTrimNull)
.map(berthId -> {
try {
return Long.parseLong(berthId);
} catch (NumberFormatException e) {
log.warn("泊位ID格式错误:{}", berthId);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (Exception e) {
log.error("解析泊位ID异常,berthIds={}:{}", berthIds, e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 获取泊位信息(用于入场)
*/
private Map<Long, String> getBerthMapForEntry(List<Long> berthIds) {
try {
log.info("开始查询泊位信息,泊位ID数量:{}", berthIds.size());
List<Berth> berths = berthFeignClient.byBerthIdList(berthIds);
if (CollectionUtils.isEmpty(berths)) {
log.warn("查询泊位信息返回空");
return new HashMap<>();
}
Map<Long, String> berthMap = berths.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
Berth::getBerthId,
Berth::getBerthCode,
(existing, replacement) -> existing
));
log.info("泊位信息查询完成,数量:{}", berthMap.size());
return berthMap;
} catch (Exception e) {
log.error("获取泊位信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 获取车场信息(用于入场)
*/
private ParkVO getParkVOForEntry(Long parkId) {
try {
log.info("开始查询车场信息,parkId={}", parkId);
ParkVO parkVO = parkFeignClient.getParkVOById(parkId);
if (parkVO == null) {
log.warn("查询车场信息返回空,parkId={}", parkId);
return null;
}
log.info("车场信息查询完成,parkCode={}", parkVO.getParkCode());
return parkVO;
} catch (Exception e) {
log.error("获取车场信息异常,parkId={}:{}", parkId, e.getMessage(), e);
return null;
}
}
/**
* 创建停车记录
*/
private List<Long> createParkRecords(BerthOccupyOrder berthOccupyOrder, List<Long> berthIds,
Map<Long, String> berthMap, ParkVO parkVO, Car newPlate) {
List<Long> parkRecordIds = new ArrayList<>();
for (Long berthId : berthIds) {
try {
ParkRecord record = buildParkRecord(berthOccupyOrder, berthId, berthMap, parkVO, newPlate);
if (record != null) {
long parkRecordId = record.getParkRecordId();
parkRecordIds.add(parkRecordId);
log.info("创建停车记录成功,parkRecordId={}, berthId={}", parkRecordId, berthId);
}
} catch (Exception e) {
log.error("创建停车记录异常,berthId={}:{}", berthId, e.getMessage(), e);
// 继续处理其他泊位,不中断整个流程
}
}
return parkRecordIds;
}
/**
* 构建停车记录
*/
private ParkRecord buildParkRecord(BerthOccupyOrder berthOccupyOrder, Long berthId,
Map<Long, String> berthMap, ParkVO parkVO, Car newPlate) {
try {
ParkRecord record = new ParkRecord();
long parkRecordId = IdentifyUtils.getId();
record.setParkRecordId(parkRecordId);
record.setBerthId(berthId);
record.setBerthCode(berthMap.get(berthId));
record.setParkCode(parkVO.getParkCode());
record.setParkId(parkVO.getParkId());
record.setCarId(newPlate.getCarId());
record.setPlateNumber(newPlate.getPlateNumber());
record.setEntryTime(berthOccupyOrder.getEntryTime());
record.setRecordCode(UUID.randomUUID().toString().replaceAll("-", ""));
// 上传业务图片,获取流水号
String oprNum = uploadBusinessPic(parkVO.getParkCode(), berthMap.get(berthId), berthOccupyOrder.getEntryTime());
record.setEntryOprNum(oprNum);
// 创建流水
record.setEntryId(IdentifyUtils.getId());
record.setEntryDataSource(DataSource.MANUAL_ENTER.code());
// 创建入场OCR记录
createEntryOcrRecord(record);
// 保存停车记录
microRecordFeignClient.onlyEntry(record);
return record;
} catch (Exception e) {
log.error("构建停车记录异常,berthId={}:{}", berthId, e.getMessage(), e);
return null;
}
}
/**
* 更新工单状态(入场后)
*/
private void updateOrderAfterEntry(BerthOccupyOrder berthOccupyOrder, List<Long> parkRecordIds, Car newPlate) {
try {
log.info("开始更新工单状态,workOrderId={}", berthOccupyOrder.getWorkOrderId());
BerthOccupyOrder berthOccupyOrderUpdate = new BerthOccupyOrder();
berthOccupyOrderUpdate.setWorkOrderId(berthOccupyOrder.getWorkOrderId());
berthOccupyOrderUpdate.setRecordState(BerthOccupyRecordState.IN_PRESENCE.getCode());
berthOccupyOrderUpdate.setParkRecordIds(Joiner.on(",").join(parkRecordIds));
berthOccupyOrderUpdate.setPlateNumber(newPlate.getPlateNumber());
berthOccupyOrderUpdate.setCarId(newPlate.getCarId());
int updateResult = berthOccupyOrderFeignClient.updateOrder(berthOccupyOrderUpdate);
log.info("更新工单状态结果,影响行数:{}", updateResult);
if (updateResult != 1) {
log.error("更新工单状态失败,预期影响行数:1,实际影响行数:{}", updateResult);
}
} catch (Exception e) {
log.error("更新工单状态异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
}
}
/**
* 发送入场通知
*/
private void sendEntryNotification(BerthOccupyOrder berthOccupyOrder, ParkVO parkVO, Car newPlate) {
try {
log.info("开始发送入场通知,workOrderId={}", berthOccupyOrder.getWorkOrderId());
String uniKey = UUID.randomUUID().toString();
String caller = "mirco-acb";
// 短信动态字段参数
Map<String, String> params = new HashMap<>(3);
params.put("parkName", StringUtils.isNotStrTrimNull(parkVO.getParentParkName()) ?
parkVO.getParentParkName() : parkVO.getParkName());
params.put("entryTime", DateUtil.date2String(new Date(berthOccupyOrder.getEntryTime()),
DateUtil.PATTERN_STANDARD19H));
params.put("plateNumber", newPlate.getPlateNumber());
SmsModel smsModel = new SmsModel();
smsModel.setPhoneNumber(berthOccupyOrder.getPhone());
smsModel.setContent(TemplateParseUtils.parseTemplate(NoticeTmpl.BERTH_OCCUPY_ENTRY_SMS.getContent(), params));
smsModel.setTmplCode(NoticeTmpl.BERTH_OCCUPY_ENTRY_SMS.getCode());
smsModel.setUniKey(uniKey);
smsModel.setCaller(caller);
smsModel.setOperatorId(berthOccupyOrder.getUserId());
messageFeignClient.sms(smsModel);
log.info("入场通知发送成功,workOrderId={}", berthOccupyOrder.getWorkOrderId());
} catch (Exception e) {
log.error("发送入场通知异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
}
}
```
让我重新尝试优化entry方法:
现在优化entry方法:
```java
private void entry(BerthOccupyOrder berthOccupyOrder) {
log.info("entry开始执行,工单信息:{}", JSON.toJSONString(berthOccupyOrder));
try {
// 参数校验
if (berthOccupyOrder == null) {
log.error("entry参数校验失败:berthOccupyOrder为空");
return;
}
if (StringUtils.isStrTrimNull(berthOccupyOrder.getBerthIds())) {
log.error("entry参数校验失败:berthIds为空,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
if (berthOccupyOrder.getParkId() == null) {
log.error("entry参数校验失败:parkId为空,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
// 解析泊位ID
List<Long> berthIds = parseBerthIdsForEntry(berthOccupyOrder.getBerthIds());
if (CollectionUtils.isEmpty(berthIds)) {
log.error("解析泊位ID失败,berthIds={}", berthOccupyOrder.getBerthIds());
return;
}
// 获取泊位信息
Map<Long, String> berthMap = getBerthMapForEntry(berthIds);
if (berthMap.isEmpty()) {
log.error("获取泊位信息失败,berthIds={}", berthIds);
return;
}
// 获取车场信息
ParkVO parkVO = getParkVOForEntry(berthOccupyOrder.getParkId());
if (parkVO == null) {
log.error("获取车场信息失败,parkId={}", berthOccupyOrder.getParkId());
return;
}
// 获取随机车牌
Car newPlate = getNewPlate();
if (newPlate == null) {
log.error("获取随机车牌失败");
return;
}
log.info("获取随机车牌成功:{}", objectMapper.writeValueAsString(newPlate));
// 创建停车记录
List<Long> parkRecordIds = createParkRecords(berthOccupyOrder, berthIds, berthMap, parkVO, newPlate);
if (CollectionUtils.isEmpty(parkRecordIds)) {
log.error("创建停车记录失败,workOrderId={}", berthOccupyOrder.getWorkOrderId());
return;
}
// 更新工单状态
updateOrderAfterEntry(berthOccupyOrder, parkRecordIds, newPlate);
// 发送入场通知
sendEntryNotification(berthOccupyOrder, parkVO, newPlate);
log.info("entry执行成功,workOrderId={}", berthOccupyOrder.getWorkOrderId());
} catch (Exception e) {
log.error("entry执行异常,workOrderId={}:{}",
berthOccupyOrder != null ? berthOccupyOrder.getWorkOrderId() : "null", e.getMessage(), e);
}
}
/**
* 解析泊位ID(用于入场)
*/
private List<Long> parseBerthIdsForEntry(String berthIds) {
try {
String[] berthIdStr = berthIds.split(",");
return Arrays.stream(berthIdStr)
.map(String::trim)
.filter(StringUtils::isNotStrTrimNull)
.map(berthId -> {
try {
return Long.parseLong(berthId);
} catch (NumberFormatException e) {
log.warn("泊位ID格式错误:{}", berthId);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (Exception e) {
log.error("解析泊位ID异常,berthIds={}:{}", berthIds, e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 获取泊位信息(用于入场)
*/
private Map<Long, String> getBerthMapForEntry(List<Long> berthIds) {
try {
log.info("开始查询泊位信息,泊位ID数量:{}", berthIds.size());
List<Berth> berths = berthFeignClient.byBerthIdList(berthIds);
if (CollectionUtils.isEmpty(berths)) {
log.warn("查询泊位信息返回空");
return new HashMap<>();
}
Map<Long, String> berthMap = berths.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
Berth::getBerthId,
Berth::getBerthCode,
(existing, replacement) -> existing
));
log.info("泊位信息查询完成,数量:{}", berthMap.size());
return berthMap;
} catch (Exception e) {
log.error("获取泊位信息异常:{}", e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 获取车场信息(用于入场)
*/
private ParkVO getParkVOForEntry(Long parkId) {
try {
log.info("开始查询车场信息,parkId={}", parkId);
ParkVO parkVO = parkFeignClient.getParkVOById(parkId);
if (parkVO == null) {
log.warn("查询车场信息返回空,parkId={}", parkId);
return null;
}
log.info("车场信息查询完成,parkCode={}", parkVO.getParkCode());
return parkVO;
} catch (Exception e) {
log.error("获取车场信息异常,parkId={}:{}", parkId, e.getMessage(), e);
return null;
}
}
/**
* 创建停车记录
*/
private List<Long> createParkRecords(BerthOccupyOrder berthOccupyOrder, List<Long> berthIds,
Map<Long, String> berthMap, ParkVO parkVO, Car newPlate) {
List<Long> parkRecordIds = new ArrayList<>();
for (Long berthId : berthIds) {
try {
ParkRecord record = buildParkRecord(berthOccupyOrder, berthId, berthMap, parkVO, newPlate);
if (record != null) {
long parkRecordId = record.getParkRecordId();
parkRecordIds.add(parkRecordId);
log.info("创建停车记录成功,parkRecordId={}, berthId={}", parkRecordId, berthId);
}
} catch (Exception e) {
log.error("创建停车记录异常,berthId={}:{}", berthId, e.getMessage(), e);
// 继续处理其他泊位,不中断整个流程
}
}
return parkRecordIds;
}
/**
* 构建停车记录
*/
private ParkRecord buildParkRecord(BerthOccupyOrder berthOccupyOrder, Long berthId,
Map<Long, String> berthMap, ParkVO parkVO, Car newPlate) {
try {
ParkRecord record = new ParkRecord();
long parkRecordId = IdentifyUtils.getId();
record.setParkRecordId(parkRecordId);
record.setBerthId(berthId);
record.setBerthCode(berthMap.get(berthId));
record.setParkCode(parkVO.getParkCode());
record.setParkId(parkVO.getParkId());
record.setCarId(newPlate.getCarId());
record.setPlateNumber(newPlate.getPlateNumber());
record.setEntryTime(berthOccupyOrder.getEntryTime());
record.setRecordCode(UUID.randomUUID().toString().replaceAll("-", ""));
// 上传业务图片,获取流水号
String oprNum = uploadBusinessPic(parkVO.getParkCode(), berthMap.get(berthId), berthOccupyOrder.getEntryTime());
record.setEntryOprNum(oprNum);
// 创建流水
record.setEntryId(IdentifyUtils.getId());
record.setEntryDataSource(DataSource.MANUAL_ENTER.code());
// 创建入场OCR记录
createEntryOcrRecord(record);
// 保存停车记录
microRecordFeignClient.onlyEntry(record);
return record;
} catch (Exception e) {
log.error("构建停车记录异常,berthId={}:{}", berthId, e.getMessage(), e);
return null;
}
}
/**
* 更新工单状态(入场后)
*/
private void updateOrderAfterEntry(BerthOccupyOrder berthOccupyOrder, List<Long> parkRecordIds, Car newPlate) {
try {
log.info("开始更新工单状态,workOrderId={}", berthOccupyOrder.getWorkOrderId());
BerthOccupyOrder berthOccupyOrderUpdate = new BerthOccupyOrder();
berthOccupyOrderUpdate.setWorkOrderId(berthOccupyOrder.getWorkOrderId());
berthOccupyOrderUpdate.setRecordState(BerthOccupyRecordState.IN_PRESENCE.getCode());
berthOccupyOrderUpdate.setParkRecordIds(Joiner.on(",").join(parkRecordIds));
berthOccupyOrderUpdate.setPlateNumber(newPlate.getPlateNumber());
berthOccupyOrderUpdate.setCarId(newPlate.getCarId());
int updateResult = berthOccupyOrderFeignClient.updateOrder(berthOccupyOrderUpdate);
log.info("更新工单状态结果,影响行数:{}", updateResult);
if (updateResult != 1) {
log.error("更新工单状态失败,预期影响行数:1,实际影响行数:{}", updateResult);
}
} catch (Exception e) {
log.error("更新工单状态异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
}
}
/**
* 发送入场通知
*/
private void sendEntryNotification(BerthOccupyOrder berthOccupyOrder, ParkVO parkVO, Car newPlate) {
try {
log.info("开始发送入场通知,workOrderId={}", berthOccupyOrder.getWorkOrderId());
String uniKey = UUID.randomUUID().toString();
String caller = "mirco-acb";
// 短信动态字段参数
Map<String, String> params = new HashMap<>(3);
params.put("parkName", StringUtils.isNotStrTrimNull(parkVO.getParentParkName()) ?
parkVO.getParentParkName() : parkVO.getParkName());
params.put("entryTime", DateUtil.date2String(new Date(berthOccupyOrder.getEntryTime()),
DateUtil.PATTERN_STANDARD19H));
params.put("plateNumber", newPlate.getPlateNumber());
SmsModel smsModel = new SmsModel();
smsModel.setPhoneNumber(berthOccupyOrder.getPhone());
smsModel.setContent(TemplateParseUtils.parseTemplate(NoticeTmpl.BERTH_OCCUPY_ENTRY_SMS.getContent(), params));
smsModel.setTmplCode(NoticeTmpl.BERTH_OCCUPY_ENTRY_SMS.getCode());
smsModel.setUniKey(uniKey);
smsModel.setCaller(caller);
smsModel.setOperatorId(berthOccupyOrder.getUserId());
messageFeignClient.sms(smsModel);
log.info("入场通知发送成功,workOrderId={}", berthOccupyOrder.getWorkOrderId());
} catch (Exception e) {
log.error("发送入场通知异常,workOrderId={}:{}", berthOccupyOrder.getWorkOrderId(), e.getMessage(), e);
}
}
```
已完成第6-8批方法的优化,主要内容如下:
---
### 6. getDetailById 方法
- 增加参数校验、异常捕获、详细日志,所有外部接口和JSON解析都加try-catch,避免NPE和格式异常。
- 复杂逻辑(如文件列表处理、金额计算)拆分为私有方法,提升可读性和可维护性。
### 7. getRecordDetailById 方法
- 增加参数校验、异常捕获、详细日志,所有外部接口调用都加try-catch。
- 复用getDetailById的VO组装逻辑,避免重复代码。
- 操作记录相关信息单独封装为私有方法,便于维护。
### 8. entry 方法
- 增加参数校验、异常捕获、详细日志。
- 复杂流程(如泊位ID解析、泊位/车场信息获取、停车记录创建、工单状态更新、通知发送)全部拆分为私有方法,主流程清晰明了。
- 所有外部接口和数据转换都加try-catch,避免NPE和格式异常。
---
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment