Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cursor-usage-example
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
岳建彬
cursor-usage-example
Commits
f39c6de8
Commit
f39c6de8
authored
Jun 27, 2025
by
yanrui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cursor代码分析优化使用案例
parent
ff613c3c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
2131 additions
and
0 deletions
+2131
-0
20250627-代码检查以及优化案例.md
cases/backend/20250627-代码检查以及优化案例.md
+214
-0
cursor-service-code-optimize-conversation.md
...onversations/cursor-service-code-optimize-conversation.md
+1917
-0
No files found.
cases/backend/20250627-代码检查以及优化案例.md
0 → 100644
View file @
f39c6de8
# 项目页面代码检查优化以及潜在问题处理
# 项目页面代码检查优化以及潜在问题处理
> **场景**: 针对在旧版本需求基础上进行新需求的迭代,需要理解旧版本代码的逻辑,并在其基础进行开发新版本需求。
>
> **作者**: 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
cases/backend/original-conversations/cursor-service-code-optimize-conversation.md
0 → 100644
View file @
f39c6de8
# 优化业务类代码逻辑和可读性
---
**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和格式异常。
---
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment