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
ace6cbf5
Commit
ace6cbf5
authored
Jun 27, 2025
by
岳建彬
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 'master'
cursor代码分析优化使用案例 See merge request
!2
parents
1e2d0046
f39c6de8
Show 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 @
ace6cbf5
# 项目页面代码检查优化以及潜在问题处理
# 项目页面代码检查优化以及潜在问题处理
> **场景**: 针对在旧版本需求基础上进行新需求的迭代,需要理解旧版本代码的逻辑,并在其基础进行开发新版本需求。
>
> **作者**: 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 @
ace6cbf5
# 优化业务类代码逻辑和可读性
---
**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