Commit f39c6de8 by yanrui

cursor代码分析优化使用案例

parent ff613c3c
# 项目页面代码检查优化以及潜在问题处理
# 项目页面代码检查优化以及潜在问题处理
> **场景**: 针对在旧版本需求基础上进行新需求的迭代,需要理解旧版本代码的逻辑,并在其基础进行开发新版本需求。
>
> **作者**: yanrui
> **日期**: 2025-06-27
---
## 案例背景描述
在旧版本需求上进行功能迭代时,可以通过Cursor对现有代码进行以下操作:
- 分析各个方法的业务逻辑
- 增加异常捕获以及日志补全
- 发现方法中隐藏的潜在问题(NullPointException...)
- 减少代码冗余、硬编码等,提高可读性、健壮性
## 使用 Cursor 的解决过程
### 1. 问题诊断 Prompt
```
@/BerthOccupyOrderServiceImpl 梳理当前业务类中各个方法业务逻辑,优化代码,包括日志补全,异常捕获,潜在异常风险处理,提高代码可读性。分批次进行优化,并指出存在的问题,以及需要优化的建议
```
### 2. 代码分析与优化方案
#### 举例其中一个方法优化分析过程
1. addEntryApply方法
### 业务逻辑
- 创建占用工单对象,设置属性
- 通过Feign保存工单
- 保存成功后自动发起初审
### 存在问题
- 参数未校验,可能NPE
- 异常未捕获
- 日志不够详细
- approval返回值未判断
### 优化建议
- 增加参数校验
- try-catch包裹主流程
- 日志补全:入参、出参、异常
- 判断approval返回值
#### 解决方案代码
**优化前的 addEntryApply方法**
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone,
long parkId, String berthIds, String applyReason) {
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
berthOccupyOrder.setWorkOrderId(IdentifyUtils.getId());
berthOccupyOrder.setBerthIds(berthIds);
berthOccupyOrder.setOccupyType(occupyType);
berthOccupyOrder.setEntryTime(entryTime.getTime());
berthOccupyOrder.setPhone(phone);
berthOccupyOrder.setParkId(parkId);
// 在场状态:0-已离场;1-在场中;2-待入场
berthOccupyOrder.setRecordState(BerthOccupyRecordState.WAIT_ENTER.getCode());
berthOccupyOrder.setApplyReason(applyReason);
berthOccupyOrder.setD(0);
LoginUser loginUser = ReqContextParams.getLoginUser();
Long userId = Long.parseLong(loginUser.getUserId());
berthOccupyOrder.setUserId(userId);
berthOccupyOrder.setState(BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode());
log.info("占用申请创建:{}", JSON.toJSONString(berthOccupyOrder));
int i = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建条数,i={}", i);
if (i == 1) {
//处理记录
approval(berthOccupyOrder.getWorkOrderId(), BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null, BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(),null,null);
}
return berthOccupyOrder.getWorkOrderId();
}
```
**优化后的 addEntryApply方法**
```java
@Override
public Long addEntryApply(int occupyType, Date entryTime, String phone,
long parkId, String berthIds, String applyReason) {
log.info("addEntryApply开始执行,入参:occupyType={}, entryTime={}, phone={}, parkId={}, berthIds={}, applyReason={}",
occupyType, entryTime, phone, parkId, berthIds, applyReason);
try {
// 参数校验
if (entryTime == null) {
log.warn("addEntryApply参数校验失败:entryTime为空");
throw new IllegalArgumentException("入场时间不能为空");
}
if (StringUtils.isStrTrimNull(phone)) {
log.warn("addEntryApply参数校验失败:phone为空");
throw new IllegalArgumentException("手机号不能为空");
}
if (StringUtils.isStrTrimNull(berthIds)) {
log.warn("addEntryApply参数校验失败:berthIds为空");
throw new IllegalArgumentException("泊位ID不能为空");
}
if (parkId <= 0) {
log.warn("addEntryApply参数校验失败:parkId无效,parkId={}", parkId);
throw new IllegalArgumentException("车场ID无效");
}
// 获取当前登录用户
LoginUser loginUser = ReqContextParams.getLoginUser();
if (loginUser == null || StringUtils.isStrTrimNull(loginUser.getUserId())) {
log.error("addEntryApply获取登录用户信息失败");
throw new RuntimeException("获取用户信息失败");
}
// 创建工单对象
BerthOccupyOrder berthOccupyOrder = new BerthOccupyOrder();
berthOccupyOrder.setWorkOrderId(IdentifyUtils.getId());
berthOccupyOrder.setBerthIds(berthIds);
berthOccupyOrder.setOccupyType(occupyType);
berthOccupyOrder.setEntryTime(entryTime.getTime());
berthOccupyOrder.setPhone(phone);
berthOccupyOrder.setParkId(parkId);
// 在场状态:0-已离场;1-在场中;2-待入场
berthOccupyOrder.setRecordState(BerthOccupyRecordState.WAIT_ENTER.getCode());
berthOccupyOrder.setApplyReason(applyReason);
berthOccupyOrder.setD(0);
Long userId = Long.parseLong(loginUser.getUserId());
berthOccupyOrder.setUserId(userId);
berthOccupyOrder.setState(BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode());
log.info("占用申请创建,工单信息:{}", JSON.toJSONString(berthOccupyOrder));
// 保存工单
int saveResult = berthOccupyOrderFeignClient.addEntryApply(berthOccupyOrder);
log.info("占用申请创建结果,影响行数:{}", saveResult);
if (saveResult != 1) {
log.error("占用申请创建失败,预期影响行数:1,实际影响行数:{}", saveResult);
throw new RuntimeException("占用申请创建失败");
}
// 发起初审
log.info("开始发起初审,工单ID:{}", berthOccupyOrder.getWorkOrderId());
ResponseResult<?> approvalResult = approval(berthOccupyOrder.getWorkOrderId(),
BerthOccupyOrderState.WAIT_FIRST_APPROVAL.getCode(), null,
BerthOccupyOptions.OCCUPY_IN_APPLY.getCode(), null, null);
if (approvalResult == null || !approvalResult.isSuccess()) {
log.error("初审发起失败,工单ID:{},返回结果:{}", berthOccupyOrder.getWorkOrderId(),
approvalResult != null ? approvalResult.getMsg() : "null");
throw new RuntimeException("初审发起失败:" + (approvalResult != null ? approvalResult.getMsg() : "未知错误"));
}
log.info("addEntryApply执行成功,工单ID:{}", berthOccupyOrder.getWorkOrderId());
return berthOccupyOrder.getWorkOrderId();
} catch (IllegalArgumentException e) {
log.warn("addEntryApply参数校验异常:{}", e.getMessage());
throw e;
} catch (Exception e) {
log.error("addEntryApply执行异常:{}", e.getMessage(), e);
throw new RuntimeException("创建占用申请失败:" + e.getMessage(), e);
}
}
```
### 3. 优化总结
- ✅ 增加参数校验(entryTime、phone、berthIds、parkId)
- ✅ 增加异常处理和详细日志
- ✅ 增加用户信息校验
- ✅ 增加approval返回值判断
- ✅ 增加数据库操作结果校验
## 使用体验
### Cursor 的优势(基于代码交接或者在其他开发人员开发的需求基础进行迭代维护)
- 代码健壮性大幅提升,异常和空指针风险大幅降低。
- 日志更详细,便于排查问题。
- 结构更清晰,便于后续维护和扩展。
### 注意事项
- 针对较大的文件,建议分批次进行优化,或者指定明确需要优化的方法
- 合理性接受Cursor做出的代码更改(例如:登录用户判空,其实已经在Controller层通过@NeedLogin注解增加了校验)
---
## 相关资源
- [完整对话记录](./original-conversations/cursor-service-code-optimize-conversation.md) - 查看与 Cursor AI 的完整问题分析过程
---
## 💡 学习建议
想要了解完整的问题分析过程?点击查看 [原始 Cursor 对话记录](./original-conversations/cursor-emqx-mqtt-reconnect-conversation.md),包含:
- AI 的完整分析思路
- 多轮问题诊断过程
- 代码生成和优化过程
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment