1. 项目概述:当AI成为你的编程搭档
如果你还在把AI编程助手当作一个偶尔帮你补全几行代码的“高级自动补全工具”,那可能就有点落伍了。最近半年,我深度体验了Cursor,用它从零开始构建了一个功能完整的电商促销系统。整个过程,与其说是我在编程,不如说是我在扮演一个“产品经理”和“架构师”,而Cursor则是我手下那个不知疲倦、能力超群的“首席开发工程师”。
这个电商促销系统麻雀虽小,五脏俱全。它包含了限时秒杀、优惠券、满减、拼团等主流促销玩法,前端用React,后端用Node.js,数据库是PostgreSQL,还集成了Redis做缓存和消息队列。听起来工作量不小,对吧?但实际开发周期比我预想的缩短了至少60%。这其中的关键,就在于我彻底转变了与AI协作的模式:从“我问它答”的问答模式,升级为“我定方向,它来执行”的智能体驱动模式。
Cursor的核心魅力,在于它不仅仅是一个集成在IDE里的聊天机器人。它的“智能体”(Agent)模式,尤其是像Composer这样的自主智能体,能够理解整个项目的上下文,然后像一名真正的开发者一样,去规划任务、搜索代码、编写实现、甚至运行测试和调试。你只需要用自然语言描述你想要的功能,比如“在用户服务里添加一个根据用户等级计算优惠券可用张数的接口”,它就能分析现有代码结构,找到userService.js文件,理解已有的用户等级字段,然后生成符合项目风格的、带参数校验和错误处理的完整函数代码。
这次,我就把用Cursor构建这个电商促销系统的完整过程、踩过的坑、以及总结出的高效协作心法,毫无保留地分享给你。无论你是想体验AI编程的威力,还是正打算启动一个类似的项目,这篇文章都能给你提供一份可复现的“实战地图”。
2. 环境准备与Cursor深度配置
工欲善其事,必先利其器。在开始敲代码之前,花点时间把Cursor和环境配置好,能让你后续的开发体验流畅十倍。
2.1 Cursor安装与核心设置
首先,去Cursor官网下载对应你操作系统的安装包。安装过程很简单,和安装VS Code差不多。安装完成后,第一次启动会让你登录。这里有个小技巧:如果你在注册时遇到手机号验证问题,可以尝试使用邮箱注册,或者查看官方社区是否有临时的解决方案,因为其验证策略可能随时间调整。
登录后,第一件事就是设置成中文界面。虽然对开发者来说英文界面也不是障碍,但母语界面能让你在快速浏览菜单和提示时更省心。点击左下角的设置图标(或按Cmd+,/Ctrl+,),在设置搜索框输入“locale”,找到Application > Language选项,将其改为“zh-CN”即可。如果重启后仍未生效,检查是否有扩展冲突,或者尝试在命令行通过cursor --locale=zh-CN启动。
接下来是关键一步:模型选择与配置。Cursor的强大之处在于它聚合了多家顶尖模型。在设置中,找到Features > AI Models。对于日常开发,我推荐如下配置:
- 自动补全(Inline Suggestions):选择“Cursor Composer”。这是Cursor自研的模型,针对代码补全做了深度优化,响应速度快,对项目上下文的理解非常精准。
- 聊天与编辑(Chat & Edit):选择“GPT-4o”或“Claude 3.5 Sonnet”。前者综合能力强,后者在复杂逻辑和长上下文理解上表现优异。你可以根据任务切换,比如写业务逻辑用GPT-4o,重构一段复杂算法用Claude。
- 智能体(Agent):这是重头戏。对于构建新项目,强烈推荐使用“Cursor Composer 2.5”。它被设计为可以自主规划并执行任务的智能体,非常适合从零开始搭建系统。你只需要给它一个目标,它就能拆解任务、编写代码、甚至运行命令。
注意:Cursor的免费版本有使用次数限制。如果提示“免费次数用完”,你需要订阅Pro版。对于严肃的项目开发,Pro版是必须的,它提供无限制的Composer使用和更快的模型。个人开发者月度订阅性价比很高。
2.2 项目初始化与环境搭建
我们的电商促销系统采用前后端分离的架构。打开Cursor,新建一个文件夹作为项目根目录,例如ecommerce-promotion。
首先,初始化后端项目。在Cursor内置的终端(`Ctrl+``)中,进入项目目录,执行:
mkdir backend && cd backend npm init -y然后,我们告诉Cursor我们的技术栈。在项目根目录创建一个.cursorrules文件。这个文件是Cursor的“项目说明书”,能极大地提升AI理解项目的准确度。
{ "projectContext": { "name": "Ecommerce Promotion System", "description": "A full-stack system for managing e-commerce promotions like flash sales, coupons, and group buys.", "techStack": { "backend": "Node.js (Express), PostgreSQL, Redis, Prisma ORM", "frontend": "React (Vite), TypeScript, Tailwind CSS, Shadcn/ui", "testing": "Jest, Supertest" }, "codeStyle": { "backend": "ES modules, async/await, centralized error handling", "frontend": "Functional components with React Hooks, modular CSS" } } }接着,我们可以直接让Cursor Composer智能体来搭建基础框架。在Cursor中按下Cmd+K(Mac)或Ctrl+K(Windows/Linux),打开命令面板,输入“/composer”并回车,启动Composer智能体。然后输入你的第一个指令:
请为我初始化一个Node.js + Express的后端项目。需要包含以下内容: 1. 安装express, cors, dotenv, helmet等基础依赖。 2. 安装prisma作为ORM,并初始化PostgreSQL配置。 3. 安装redis客户端ioredis。 4. 创建基本的项目结构:src/目录下包含app.js, server.js,以及routes/, controllers/, services/, utils/等子目录。 5. 创建.env.example文件,列出必要的环境变量(如数据库连接字符串、Redis连接、JWT密钥等)。 6. 在package.json中配置好启动脚本(start, dev)。Composer会开始工作,它首先会生成一个计划(Plan),列出将要执行的步骤,然后逐一执行:创建文件、安装依赖、编写基础代码。你只需要在它询问时确认(比如安装依赖),或者在某些关键决策点提供输入。整个过程是可视化的,你能看到它在“思考”和“操作”。
用同样的方式,我们可以在另一个终端(或新窗口)初始化前端项目。在项目根目录下:
mkdir frontend && cd frontend然后在Cursor中对该frontend目录启动一个新的Composer会话,输入:
请使用Vite和React (TypeScript模板)初始化一个前端项目。 然后,集成Tailwind CSS和Shadcn/ui组件库。 配置好基本的路由结构(使用React Router),并创建一个简单的布局组件。 最后,安装axios用于API调用,并创建一个统一的API请求工具模块。Composer会帮你完成所有这些繁琐的初始化工作,并且生成的代码质量很高,符合当前的最佳实践。
3. 核心模块设计与AI协作拆解
有了基础框架,接下来就是定义核心业务模块。电商促销系统,核心在于“规则”和“计算”。我们需要设计清晰的数据模型和业务边界。
3.1 数据模型设计:让AI理解业务实体
在backend/prisma/schema.prisma文件中,我们需要定义数据模型。与其自己苦思冥想,不如让Cursor基于我们的描述来生成初稿。打开schema.prisma文件,然后使用Cmd+K打开Chat,输入:
请根据以下电商促销需求,设计Prisma数据模型: 1. 用户(User):id, 邮箱, 密码哈希, 用户等级, 创建时间。 2. 产品(Product):id, 名称, 描述, 价格, 库存, 状态。 3. 促销活动(Promotion):这是一个抽象基类。包含id, 名称, 描述, 开始时间, 结束时间, 状态(未开始/进行中/已结束/已失效)。它应该能被具体促销类型继承。 4. 具体促销类型: a. 限时秒杀(FlashSale):继承自Promotion。关联产品,并包含秒杀价、秒杀总库存、每人限购数。 b. 优惠券(Coupon):继承自Promotion。包含优惠码、折扣类型(百分比/固定金额)、折扣值、最低消费额、总发行量、每人限领。 c. 满减活动(DiscountRule):继承自Promotion。包含满减条件(如满100减20),可以多阶梯。 d. 拼团活动(GroupBuy):继承自Promotion。关联产品,包含拼团价、成团人数、成团有效期。 5. 关联关系: - 用户领取优惠券(UserCoupon):记录用户领取和使用情况。 - 秒杀订单(FlashSaleOrder):记录秒杀成功记录。 - 拼团实例(GroupInstance):记录每个发起的拼团,包含状态、剩余人数、截止时间。 - 用户参与拼团(GroupParticipant):记录用户参与了哪个拼团。 请使用Prisma的继承和多态关联最佳实践来实现这个模型。Cursor(特别是GPT-4o或Claude)会生成一个非常详细且专业的schema.prisma文件。它可能会使用@@inherit或抽象模型(abstract model)等方式来实现继承。生成后,你需要审查一下,特别是关联关系的外键设置是否正确。然后运行npx prisma db push将模型同步到数据库。
3.2 业务逻辑实现:从接口定义到具体实现
数据模型有了,接下来实现API。传统的做法是手动创建routes/promotion.js、controllers/promotionController.js等文件。现在,我们可以让AI批量生成。
在backend/src/routes/目录下,新建一个promotion.routes.js文件。然后,在同一个Chat会话中(这样它记得之前的上下文),输入:
基于我们刚才定义的Prisma模型,请为“限时秒杀(FlashSale)”模块实现完整的RESTful API路由和控制器。 需要以下端点: 1. GET /api/flash-sales:获取所有进行中的秒杀活动列表(带分页)。 2. GET /api/flash-sales/:id:获取秒杀活动详情,包括关联产品信息。 3. POST /api/flash-sales:管理员创建秒杀活动(需要请求体验证)。 4. POST /api/flash-sales/:id/seckill:用户执行秒杀。这是核心逻辑,需要: a. 校验活动是否进行中。 b. 校验库存。 c. 校验用户是否已达到限购数量。 d. 使用Redis分布式锁,防止超卖。 e. 扣减库存,创建秒杀订单。 f. 返回成功结果。 请将路由逻辑写在当前文件(promotion.routes.js)中,并生成对应的控制器文件(flashSale.controller.js)和服务层文件(flashSale.service.js)。在服务层实现具体的秒杀逻辑,包括Redis锁的使用。 请使用async/await,并包含必要的错误处理。Cursor会开始分析现有的项目结构,然后生成代码。它会先创建控制器和服务文件,然后在路由文件中引入它们。这里有一个关键技巧:当AI生成代码后,不要直接全盘接受。要扮演“代码审查者”的角色。
例如,它生成的秒杀逻辑可能先查询数据库检查库存。你应该指出问题:“在高并发下,查询后更新会有超卖风险。请使用Redis的WATCH、MULTI、EXEC命令实现一个简单的分布式锁,或者直接使用SETNX(现在叫SETwithNXflag)来实现乐观锁。” 把这个问题抛回给AI,让它修正。通过这种迭代对话,你能得到更健壮的代码。
3.3 前端页面联调:让AI编写组件和状态管理
后端API完成后,转到前端项目。假设我们要做一个秒杀活动列表页和详情页。
在frontend/src/pages/目录下,新建FlashSalePage.tsx。在文件中,我们可以直接让Cursor编写组件骨架:
请创建一个秒杀活动列表页面组件。 要求: 1. 使用React函数组件和TypeScript。 2. 使用TanStack Query (React Query) 从 `/api/flash-sales` 端点获取数据。 3. 使用Shadcn/ui的Card、Button、Badge组件来展示每个秒杀活动。 4. 每个卡片展示:产品图片(占位图)、产品名、原价、秒杀价、倒计时、立即抢购按钮。 5. 倒计时需要实时更新(使用useEffect和setInterval)。 6. “立即抢购”按钮在活动未开始、已结束或库存为0时为禁用状态。 7. 点击按钮后,调用秒杀接口(`/api/flash-sales/:id/seckill`),处理加载状态和成功/错误提示(使用Shadcn/ui的Toast组件)。 请生成完整的代码,包括必要的类型定义和导入语句。Cursor会生成一个非常现代化的、功能完整的组件。它甚至会帮你安装好@tanstack/react-query和date-fns(用于时间处理)等依赖,如果你还没安装的话。
实操心得:与AI协作前端时,要特别关注状态管理和副作用清理。比如上面提到的倒计时,AI生成的useEffect可能忘记清理定时器,你需要提醒它:“请确保在组件卸载时清理倒计时的interval,避免内存泄漏。” AI会立刻修正。这种细节,正是人机协作中“人”的价值所在——把握那些容易出错的关键点。
4. 高级功能实现与AI调试技巧
基础CRUD和页面都搞定后,我们来挑战一些更复杂的功能,比如拼团活动的状态机和优惠券的复杂计算逻辑。这也是检验AI编程能力的好机会。
4.1 复杂状态流转:拼团活动状态机
拼团活动的状态(如“待成团”、“已成团”、“失败”)流转比简单的启用/禁用要复杂。我们可以在GroupBuy模型上增加一个status字段,但状态变化的逻辑需要严格封装。
在backend/src/services/groupBuy.service.js中,我们可以让AI实现一个状态机。输入提示:
请实现一个拼团活动实例(GroupInstance)的状态机服务。 状态包括:PENDING(待成团)、SUCCESS(已成团)、FAILED(失败)。 状态转换规则: 1. 新建拼团实例时,状态为PENDING,并设置expiresAt(截止时间)。 2. 当有新人加入拼团(GroupParticipant创建)时,检查是否达到成团人数。若达到,状态转为SUCCESS,并触发后续逻辑(如订单创建)。 3. 后台有一个定时任务,检查所有PENDING状态的实例,如果expiresAt已过但未成团,状态转为FAILED,并可能触发退款。 4. 状态一旦变为SUCCESS或FAILED,则不可再改变。 请实现以下方法: - createGroupInstance(productId, creatorId, expiresInHours): 创建新拼团。 - joinGroupInstance(instanceId, userId): 用户加入拼团,内部处理状态检查与转换。 - checkAndUpdateExpiredInstances(): 供定时任务调用,处理过期拼团。 请使用一个Map或数据库事务来确保状态转换的原子性,避免并发问题。同时,当状态变化时,使用一个事件发射器(EventEmitter)发布事件,以便其他服务(如订单服务、通知服务)订阅。这个提示非常具体,包含了业务规则、技术要求和设计模式(状态机、事件驱动)。Cursor的Composer智能体会尝试生成一个完整的服务类。它可能会引入一个简单的内存Map来管理状态锁,或者建议使用数据库的SELECT ... FOR UPDATE行锁。你需要根据你的并发量级来决定采用哪种方案。对于一般应用,使用Prisma事务配合状态检查通常就够了。
4.2 优惠券计算引擎:策略模式的应用
优惠券的计算规则可能很复杂:满减、折扣、是否可叠加、是否排除特价商品等。实现一个可扩展的计算引擎很有必要。
我们可以提示AI使用策略模式(Strategy Pattern)。在backend/src/services/discount/目录下,新建一个Calculator.js文件,然后输入:
请设计一个优惠券计算引擎,使用策略模式。 1. 定义一个接口(或抽象类)`DiscountStrategy`,包含一个`calculate(cart)`方法。 2. 实现具体策略: - `PercentageDiscountStrategy`: 百分比折扣。 - `FixedAmountDiscountStrategy`: 固定金额减免。 - `ThresholdDiscountStrategy`: 满减(支持多阶梯,如满100减10,满200减25)。 3. 实现一个`DiscountCalculator`上下文类,它接收一个`DiscountStrategy`,并调用其`calculate`方法。 4. 购物车(`cart`)对象假设包含:商品列表(每个商品有单价、数量、是否参与优惠),总金额。 5. 在计算时,需要考虑优惠券的适用范围(全场、指定品类、指定商品)和排除规则。 请生成完整的JavaScript ES6类代码,并附带一个使用示例,展示如何为一张“满200减30”的优惠券创建策略并进行计算。AI会生成结构清晰的面向对象代码。这展示了如何用自然语言描述设计模式,AI就能输出符合该模式的实现。这极大地降低了应用高级软件设计原则的门槛。
4.3 与AI协作调试:定位并修复诡异Bug
开发中难免遇到Bug。以前,我们靠console.log和断点。现在,我们可以让AI成为第一线的调试助手。
假设我们收到报告:用户秒杀时,偶尔会扣减了库存但没生成订单。
首先,把相关的服务代码片段(比如seckill函数)和日志错误信息复制到Cursor的Chat中。然后提问:
请看这段秒杀逻辑代码和错误日志。日志显示在‘createOrder’步骤有时会抛出‘数据库连接超时’错误,但库存已经扣减了。这导致了数据不一致。请分析可能的原因,并提供修复方案。要求修复后保证操作的原子性:要么库存和订单都成功,要么都失败。AI可能会分析出几个原因:1. 数据库连接池不足;2. 扣库存和创建订单不在同一个数据库事务中;3. 网络波动。
它会给出建议:使用数据库事务包裹扣库存和创建订单的操作。并可能直接为你重写那段代码,使用Prisma的$transaction方法。它还会提醒你,Redis锁应该在事务开始前获取,在事务提交后再释放,以避免死锁。
更高级的用法是,你可以让Cursor Composer智能体直接运行测试来定位问题。在项目根目录下,你可以对它说:“请运行针对flashSale.service的Jest测试套件,并告诉我哪个测试失败了,以及失败的原因。” 智能体会自动运行npm test或jest命令,分析测试输出,并定位到出错的代码行,有时甚至能直接给出修复建议。
5. 项目优化、部署与避坑指南
功能开发完毕,进入优化和部署阶段。AI同样能在这里发挥巨大作用。
5.1 性能优化:缓存与数据库查询
在backend/src/services/flashSale.service.js中,获取秒杀列表的接口可能直接查询数据库,压力大。我们可以让AI优化:
请优化`getActiveFlashSales`函数,它目前直接从数据库查询所有进行中的秒杀活动。 优化要求: 1. 引入Redis缓存,缓存键为`flash-sales:active`,过期时间设为60秒。 2. 实现“缓存穿透”保护:如果缓存中没有,查询数据库,并将结果写入缓存。查询数据库时,使用互斥锁(Redis setnx)防止大量并发请求同时击穿数据库。 3. 数据库查询本身也需要优化:只选择必要的字段(id, productId, seckillPrice, stock, limitPerUser),并使用Prisma的`include`关联获取产品名称和图片(但产品信息也可以考虑单独缓存)。 请生成优化后的代码,并解释你所做的每一步为什么能提升性能。AI会生成一个带有双重检查锁(Double-Checked Locking)模式的缓存逻辑代码,并详细解释缓存穿透、缓存击穿的概念以及对应的解决方案。
5.2 安全加固:输入验证与防刷
安全无小事。我们可以让AI审查我们的代码,并提出加固建议。将用户下单的控制器代码发给AI,并提问:
请从Web安全角度审查这段用户提交订单的控制器代码。重点关注: 1. 输入验证是否充分(防止XSS、SQL注入)。 2. 业务逻辑安全(如用户是否能修改订单金额、是否能重复提交同一秒杀请求)。 3. 是否存在并发漏洞导致超额购买。 4. 身份验证和授权(当前用户是否能替他人下单)。 请指出潜在风险,并给出具体的代码修复建议。AI可能会指出:使用了Prisma ORM已能防止SQL注入,但自定义的查询仍需注意;金额应从服务端重新计算,而不是信任前端传值;对于重复提交,应在Redis中为每个用户+活动设置一个短时间的提交标记(token);并发漏洞需要如前所述用分布式锁解决。
5.3 部署上线:容器化与CI/CD
最后,我们需要将应用部署出去。我们可以让AI编写Dockerfile和docker-compose.yml文件。
在项目根目录创建Dockerfile.backend文件,然后让Cursor编辑它:
请为这个Node.js后端项目编写一个生产环境优化的Dockerfile。 要求: 1. 使用多阶段构建,减少镜像体积。 2. 使用node:20-alpine作为基础镜像。 3. 在构建阶段安装Prisma客户端。 4. 设置非root用户运行。 5. 正确处理健康检查。 6. 优化npm install,利用层缓存。同样地,再创建一个docker-compose.yml文件,让AI生成包含PostgreSQL、Redis、后端服务、前端服务(Nginx)的完整编排配置。
对于CI/CD,你可以让AI根据你的Git托管平台(如GitHub Actions)生成流水线配置文件。提示它:“请为这个项目创建一个GitHub Actions工作流,实现以下步骤:在main分支推送时,运行lint和测试,构建Docker镜像,并推送到Docker Hub。”
5.4 避坑实录:我踩过的那些“坑”
- Cursor的“过度理解”:有时AI会“自作聪明”。比如你让它“添加一个用户验证的中间件”,它可能会引入一个你项目里没有的第三方认证库。对策:指令要尽可能精确。比如改成“使用jsonwebtoken库,编写一个验证JWT token的Express中间件函数,命名为
authMiddleware,并把它放在src/middlewares/目录下”。 - 上下文丢失:在复杂的多轮对话后,AI可能会忘记很早之前设定的项目结构或约定。对策:重要的项目信息(如技术栈、目录结构)写在
.cursorrules文件中。对于复杂的任务,拆分成多个独立的、上下文清晰的对话会话。 - 生成的代码需要“接地气”:AI生成的代码有时过于理想化或通用,可能忽略了你的业务特殊性。对策:永远把AI当作一个强大的“初级开发者”,你作为“高级架构师”必须进行严格的代码审查和逻辑校验。特别是核心的业务规则和金钱相关的计算,必须人工复核。
- 依赖版本冲突:AI在
package.json中生成的依赖版本可能是最新的,可能导致不兼容。对策:在.cursorrules里指定大版本号,或者生成后手动调整版本号,然后运行安装。 - 免费额度焦虑:频繁使用Composer智能体模式会快速消耗免费额度。对策:对于简单的、明确的代码片段生成,多用
Cmd+K编辑指令和Chat模式。将复杂的、探索性的任务(如“设计一个XX系统”)留给Composer。对于正式项目,订阅Pro版是性价比最高的投资。
通过这个完整的电商促销系统项目,我深刻体会到,Cursor这类AI辅助编程工具,已经将开发者从大量的重复性、模式化的编码劳动中解放出来。我们的角色正在从“码农”向“解决方案设计师”和“AI训练师”转变。你需要做的,是清晰地定义问题、设计架构、制定规则,然后让AI去高效地执行。这不仅是生产力的飞跃,更是编程思维的一次升级。现在,就打开Cursor,开始你的第一个AI协同开发项目吧。