用 Cursor + Claude Code 重构遗留支付模块,5个技巧让效率翻倍

一个在老旧 PHP 项目里挣扎了两周的开发者,如何借助 AI 编程工具组合,把重构时间从预估的40小时压缩到11小时,并且代码质量反而更高。本文不是工具评测,而是一份真实战场上的操作手册。

起因:一块不敢碰的"屎山"

我手头有一个运行了5年的企业支付网关,核心模块是用 PHP 5.6 写的,大约1.2万行代码,没有单元测试,没有类型声明,函数之间通过全局变量传递状态。业务逻辑里还混杂着各种银行接口的硬编码参数。

上个月,我们需要对接一个新的支付通道,并且支持异步通知的幂等处理。在原代码上打补丁已经不可能------再打下去,我自己都看不懂了。

我决定重构支付请求与回调处理这一整块,但预估工期让我绝望:光是理解原有逻辑就需要两三天,再加上安全相关的敏感操作,手写+测试至少40个小时。

这一次,我决定让 AI 工具深度参与。我用的组合是:

  • Cursor (Pro版,配置了Claude Sonnet 4 模型):作为主力 IDE,负责代码生成、补全、多文件编辑。
  • Claude Code CLI:用于复杂的跨文件分析、重构方案设计,以及生成单元测试。
  • 自定义的 .cursorrulesCLAUDE.md:定义项目规范和约束,让两个工具在同一个频道里工作。

下文是重构全程中沉淀下来的5个关键技巧。

技巧一:让 AI 先"读懂"代码,而不是直接改

很多开发者用 AI 重构时,直接把旧代码丢进去说"帮我重构成 TypeScript",然后收到一堆无法运行的幻觉代码。

我的做法是:先让 AI 输出一份"代码理解文档",由我确认后再动手。

操作步骤

  1. 在项目根目录创建 CLAUDE.md,写上基本要求:
markdown 复制代码
# CLAUDE.md

## 项目背景
这是一个支付网关的旧版 PHP 代码,需要重构成 Node.js/TypeScript。
涉及敏感操作,任何涉及金额计算、签名验证、数据库事务的逻辑,必须保持原样。

## 输出要求
- 分析时给出原始代码依据,不要臆断
- 修改建议需要标明风险等级
- 不要删除任何原有注释,除非明确要求
  1. 在 Cursor 中打开整个项目文件夹,让 Cursor 自动索引(这一步利用它强大的项目级上下文)。

  2. 打开终端,运行 Claude Code,并指定要分析的目录:

bash 复制代码
claude "分析 payment/ 目录下所有 PHP 文件,输出以下内容:
1. 每个文件的职责和主要函数列表
2. 函数之间的调用关系图(用文本描述)
3. 全局变量和常量的定义及使用处
4. 标记哪些部分有安全隐患或逻辑疑点
输出为 Markdown 格式,保存为 /docs/legacy-analysis.md"
  1. Claude Code 运行了约3分钟,生成了一份2000多字的分析报告。它精确指出了:

    • processPayment() 函数依赖的全局 $config 数组,在多个地方被引用
    • 一个回调签名验证逻辑里,openssl_verify() 的返回值判断有误
    • 订单状态变更时缺少数据库事务保护
  2. 我花了20分钟审核这份报告,修正了一处误解,然后这份报告就成了后续所有重构操作的"圣经"。

为什么这步很重要?

如果让 AI 直接改代码,它在上下文窗口里看到的只是一个函数,无法理解整个模块的隐式约定。通过先输出分析报告,相当于让 AI 把它的理解"可视化",由人来把关,后续生成的代码才会准确。

技巧二:用 .cursorrules 把项目规范"注入"到每一次 AI 交互

Cursor 支持项目级别的 .cursorrules 文件,它会自动附加到每个 AI 请求的上下文中。这是保证 AI 输出符合团队规范的核心手段。

我的 .cursorrules 是这样的:

yaml 复制代码
# .cursorrules

## 语言与框架
- 所有新代码用 TypeScript + Express.js
- 严格模式,禁止使用 any
- 支付相关逻辑必须使用 Result 模式返回,禁止抛异常

## 代码风格
- 函数不超过50行
- 每个函数必须有 JSDoc
- 所有外部 API 调用必须封装在独立的 service 层
- 金额使用 big.js 处理,禁止直接浮点数运算

## 安全约束
- 签名验证逻辑必须逐行保留,只改语法,不改逻辑
- 数据库操作必须使用参数化查询
- 任何涉及事务的操作必须标明"需人工审查"

## 当前重构阶段:第一阶段------拆解 payment-process.php
请只关注文件拆分和类型定义,不要改变任何业务逻辑。

这个文件让我能分阶段控制 AI 的行为。比如第一阶段只做拆分和类型化,第二阶段再优化调用关系。否则 AI 容易"顺便"把代码风格也改了,导致 diff 巨大,难以审查。

实际效果

  • Cursor 的 Tab 补全会自动遵循 big.js 的用法,不会出现原生浮点数
  • 当我用 Cmd+K 生成一个函数时,自动带上了 Result 类型的返回值
  • 要求 AI 修改某个文件时,它不会顺手重构无关的代码

技巧三:用 Claude Code 的"多文件编辑"能力一次性完成拆分

当我把一个1800行的 payment-process.php 拆分成多个模块时,传统做法是:

  1. 手动切文件
  2. 一个一个复制函数
  3. 修改变量引用
  4. 解决循环依赖

这个过程极其枯燥且容易出错。我选择把这件事交给 Claude Code。

我的做法

  1. 先在 Cursor 中打开 payment-process.php,让 Cursor 索引该文件及其引用。
  2. 在终端进入项目目录,运行:
bash 复制代码
claude "请将 payment-process.php 拆分为以下文件结构,遵循单一职责原则:
- services/payment/PaymentValidator.ts (验证支付参数、签名)
- services/payment/PaymentProcessor.ts (执行支付,调用银行接口)
- services/payment/CallbackHandler.ts (处理异步回调,幂等逻辑)
- services/payment/PaymentRepository.ts (数据库操作)
- types/payment.ts (所有接口和类型定义)

要求:
1. 严格遵循项目根目录的 CLAUDE.md 规则
2. 保持原有业务逻辑100%不变,只做拆分和 TypeScript 改写
3. 所有 import 路径使用相对路径
4. 生成后自动检查是否有循环依赖
5. 为每个新文件生成基本的 Jest 测试用例"

Claude Code 执行了约8分钟,连续操作了以下步骤:
- 读取原文件
- 分析依赖
- 生成6个新文件(含 types)
- 自动替换原文件中的 `require` 为 `import`
- 检测到一个循环依赖并自行修复
- 为每个 service 生成了测试文件,mock 了外部依赖

3. 我在 Cursor 的 Git 面板里逐文件审查了 Diff,确认逻辑没有被改动,然后提交。

这8分钟完成了我手工需要至少4个小时的机械工作,而且没有引入因疲劳导致的错误。

---

## 技巧四:AI 写测试,人审查覆盖缺口

重构支付模块,测试是安全网。但手写单元测试是体力活,尤其是为原有的各种边界条件写 case。

我的策略是:**让 AI 生成所有能自动生成的测试,然后我专注审查它遗漏的场景。**

### 具体步骤

1. 在 Cursor 中打开刚拆分的 `PaymentValidator.ts`。
2. 使用 `Cmd+K`,输入:

```text
为这个文件生成完整的单元测试,覆盖:
- 正常场景
- 参数缺失
- 签名错误
- 金额格式异常
- 订单号为空
使用 Jest,mock 掉外部依赖 crypto

Cursor 生成了一个约120行的测试文件,包含11个 test case。

  1. 我逐一审查,发现 AI 遗漏了:

    • 签名验证时,参数排序不同但值相同的情况
    • 金额包含千位分隔符
    • 回调通知中 sign_type 字段不存在
  2. 我手动补充了这3个 case,然后问 Cursor 另一个问题:

text 复制代码
请检查我补充的3个测试用例的逻辑是否正确,并优化描述文字。

它修正了我手写的一个断言错误------openssl_verify 的返回值是 1 而非 true,这是我凭记忆写错的。

这一步的核心理念 :AI 和我形成了 "AI 生成骨架 + 人补边界 + AI 复查" 的协作闭环。最终这个文件有14个测试用例,覆盖了所有已知的支付验证场景。

技巧五:用 Git 分支策略控制 AI 的风险

AI 重构的风险在于,它可能在一个看似无害的改动里引入微妙的问题,而你在审查大量代码时容易忽略。

我建立了一套简单的分支策略来隔离风险:

bash 复制代码
# 主干分支,保持稳定
main

# 每个 AI 任务一个独立分支,命名体现任务内容
refactor/payment-split        # 拆分文件
refactor/payment-tests        # 补充测试
refactor/payment-optimize     # 优化性能

# 每晚合入一个经过人工审查的分支

工作流

  1. main 拉出任务分支
  2. 在分支上让 Claude Code 或 Cursor 完成一项明确的任务
  3. git diff 查看所有改动,重点关注:
    • 金额计算逻辑是否被修改
    • 数据库查询是否正确参数化
    • 签名验证的算法是否完整
  4. 跑测试套件,并手动执行几个关键路径的端到端测试
  5. 合入 main

在整个重构过程中,我从未让 AI 直接操作 main 分支。每次合入前,我会问自己一句:"如果这个改动出了问题,最坏会发生什么?" 如果答案涉及资金损失,就再检查一遍。


重构结果与复盘

最终,支付模块的重构用时11个小时(包含中间的休息和等待),远低于预估的40小时。

指标 重构前 重构后
代码行数 12,400 (PHP) 8,200 (TypeScript)
文件数 18个混杂文件 6个职责清晰的文件
单元测试覆盖 0% 87%
静态类型覆盖 0% 100%
新增支付通道所需时间 ~3天 ~4小时

更重要的是,新代码的可维护性完全不是一个量级。下一周另一个同事需要对接另一个通道,他花了半天时间就完成了。

五个技巧总结

  1. 让 AI 先分析再动手:输出代码理解文档,由人确认后作为后续所有操作的基础。
  2. 用规则文件注入上下文.cursorrulesCLAUDE.md 是让 AI 始终遵守团队规范的廉价手段。
  3. 多文件操作交给 Claude Code:拆分文件、修复引用、检测循环依赖,这种机械工作 AI 做得比人好。
  4. AI 写测试,人查遗漏:形成协作闭环,把人的精力用在发现边界条件上。
  5. 用分支隔离风险:每个 AI 任务一个分支,人工审查后再合入,永远不让 AI 直接触碰主干。

这些技巧不仅适用于 PHP 到 TypeScript 的重构,任何遗留系统的现代化改造都能用上。关键是:把 AI 当作一个超级勤奋但缺乏业务常识的初级程序员,你来负责方向,它来负责执行。


你在用 AI 辅助重构的时候,踩过什么坑?或者有什么独门技巧?欢迎评论区交流。

相关推荐
戈伊1 小时前
独立开发纪实:我如何用 Gemini CLI 和 Claude Code 打造一个“100% 含 AI 量”的小程序
微信小程序·ai编程
仅此而已6101 小时前
GPT-5.5 Codex 国内使用教程:Windows / macOS / Linux 配置
ai编程
AI砖家1 小时前
DeepSeek TUI 保姆级安装配置全指南 -Windows||macOS双平台全覆盖
服务器·前端·人工智能·windows·macos·ai编程·策略模式
Finger#0000FF2 小时前
从零上手VibeCoding(ClaudeCode+DeepSeek V4.Pro)
java·人工智能·ai编程·vibe coding·claudecode
Pkmer2 小时前
Javthon古法: Python中哪些让人搞不清的参数
python·ai编程
有梦想的小何3 小时前
Cursor AI 编程实战(篇三):Domain、Infrastructure 与策略模式
java·ai编程·策略模式
键盘飞行员3 小时前
Windsurf + Claude 4.7 前端开发:用 ui-ux-pro-max 根治 “AI 味”、实现全站 UI 统一
前端·ui·ai编程
陆业聪3 小时前
两次Flutter全屏白踩坑复盘:Layout的静默失败,以及AI结对编程的认知盲区
flutter·ai编程·大前端·跨端开发
wanderist.4 小时前
完美解决VS Code/Cursor远程连接报错:远程主机不满足运行 VS Code 服务器的先决条件(附AI编程最佳实践)
运维·服务器·ssh·ai编程