行间建议预测(NEXT):基于当前代码上下文和光标位置,动态预测代码变更意图,开发者只需按 Tab 即可接受建议,支持多行编辑、自动导入依赖及跨文件修改预测。
会话模式:
智能问答-Ask 模式:能够回答编码问题,并可对代码进行点评、优化、解释、生成建议、修复问题及排查编译错误。
智能体-Agent 模式:具备自主决策、环境感知与工具调度能力,可利用项目搜索、文件编辑、终端访问等工具,自主拆解任务、制定计划并修改多个代码文件,高效完成编码任务。
专家团-Experts 模式(多 Agent):面向复杂开发任务的多智能体协作功能,由 Team Lead 自动拆解任务、动态组建专家团队(前端、后端、QA、代码评审等),并行完成方案设计、编码实现、测试验证与质量检查,最终交付可落地的工程结果。
行间会话:行间会话(Inline Chat)允许开发者直接在代码编辑器中与 AI 对话,无需切换窗口即可在单个文件内完成代码修改或生成代码片段。
Diff 视图:以绿色(新增)和红色(删除)标记清晰展示 AI 的代码修改建议,让你在应用前逐行审查,并可按变更级或文件级接受或拒绝每项改动,确保对代码修改拥有完整的可见性与控制权。
上下文压缩:通过智能总结会话内容,保留关键信息并剔除冗余,从而释放上下文窗口空间,降低 Credits 消耗并提升 AI 响应速度。
Quest Mode:Qoder 的自主编程功能,你只需描述目标,Agent 即可端到端自主完成需求澄清、方案规划、代码执行与结果验证,支持 Spec 驱动开发、网站搭建和原型探索三种场景,并可在本地、并行及云端环境中长程运行,无需持续人工介入。【由于我们项目业务比较复杂,这个还没用过】
Repo Wiki:为项目自动生成结构化文档并持续跟踪代码变更,在开发过程中深入分析项目结构和代码实现,结合上下文信息给出更准确的解答和文档支持,让智能体具备更深入的代码库认知。
@ Mention:为 AI 对话添加上下文的功能,通过输入 @ 可快速引用代码文件、项目目录、本地附件和项目规则,让 AI 准确理解需求并生成符合项目规范的代码。
索引:打开项目时自动为代码库生成文件嵌入向量,以增量方式实时处理新建或修改的文件,从而支持基于 AI 的代码理解、智能推荐和语义搜索。
记忆:长期记忆功能,通过主动记忆和自动记忆逐步构建涵盖开发者偏好、项目细节及问题信息的记忆库,并随时间自动整理更新,使 AI 在长期使用中更深入地理解每位开发者的独特需求与上下文。
规则(rules):允许开发者在 .qoder/rules 目录中定义项目级指令,将编码规范、框架偏好等上下文自动注入 AI 提示中,确保 AI 响应始终符合团队的项目标准和开发习惯,并可通过 Git 与团队共享。
内置智能体:Qoder CLI 预置的专用 AI Agent,包含 code-reviewer(代码审查)、design-agent(软件设计与文档生成)、general-purpose(通用任务处理)和 task-executor(基于设计文档的开发执行)四个智能体,开箱即用,支持显式、隐式及串联唤起。
内置浏览器智能体(Browser Agent): Qoder 内置的浏览器操控工具,能够自动启动浏览器执行网页交互操作(如点击、输入、截图),帮助 AI 在开发过程中实时验证前端效果和调试 Web 应用。
内置规划智能体(Planning):让智能体在修改代码或执行命令之前,先生成一份结构化的实施方案与计划,适用于跨多文件的功能开发、重构或高风险变更等中大型任务,开发者可审阅、调整计划后再让智能体按步骤自动执行,兼顾安全与效率。
自定义智能体:Qoder 中用于处理特定任务的 AI Agent,开发者可通过定义独立的上下文窗口、工具权限和系统提示词来扩展 Qoder 能力,支持自动识别意图调用或手动触发,以 subagent 方式进行调度管理。
MCP(模型上下文协议):一种开放协议,通过标准化接口将外部系统(如 API、数据库、本地工具)无缝集成到 Qoder 中,使智能体能够获取实时信息、执行外部操作并处理结构化数据,从而扩展 AI 的上下文感知能力。
技能 Skills:Qoder 中将专业知识打包为可复用功能的机制,每个 Skill 通过 SKILL.md 文件定义描述与指令,支持智能调用和手动触发,可用于代码审查、日志分析、API 文档生成等专业任务,并支持用户级与项目级的灵活扩展与团队共享。
Deeplinks:允许通过简单的 URL 与他人分享 AI Chat 提示词、Quest 任务、规则和 MCP 服务器配置,点击链接后 IDE 会打开并显示确认对话框供用户审核,确认前不会自动执行任何操作。
指令(Commands): Qoder 中可通过 / 快速触发的预定义操作,用于在聊天中执行常用任务,如提交代码、生成测试、修复问题等,帮助开发者简化重复性工作流程。
智能问答-Ask 模式:能够回答编码问题,并可对代码进行点评、优化、解释、生成建议、修复问题及排查编译错误。
智能体-Agent 模式:具备自主决策、环境感知与工具调度能力,可利用项目搜索、文件编辑、终端访问等工具,自主拆解任务、制定计划并修改多个代码文件,高效完成编码任务。
专家团-Experts 模式(多 Agent):面向复杂开发任务的多智能体协作功能,由 Team Lead 自动拆解任务、动态组建专家团队(前端、后端、QA、代码评审等),并行完成方案设计、编码实现、测试验证与质量检查,最终交付可落地的工程结果。
目前项目中使用建议【智能体-Agent 模式】就可以了。
付费的话建议直接使用 Auto 就可以了。
分级选择:
手动选择模型:
还可以添加自定义模型,支持 Coding plan。
接手项目 or 开源项目调研时,先生成项目 Repo Wiki,可以帮我们快熟了解项目架构、技术栈、功能、配置等等,同时也让智能体具备更深入项目代码认知。

多使用 @Mention 指定代码段、文件、文件夹、Terminal 或 rules,精准注入上下文,让 AI 准确理解。【如 Java 的类型安全、框架感知、依赖可见】
场景:用户登录时抛出 NullPointerException,日志显示在 AuthService 中。
❌ 不使用 @Mention
用户输入:“我的登录报错了,日志是
java.lang.NullPointerException at com.example.service.AuthService.login(AuthService.java:45),帮我修一下。”AI 反应:只能猜测可能是
user对象为空,或者passwordEncoder没初始化。给出的建议通常是通用的“加个判空检查”,但不知道你的UserRepository到底返回什么,也不知道User实体类的具体字段。
✅ 使用 @Mention
用户输入:“请分析
@AuthService.java第 45 行的空指针异常。结合@UserRepository.java的findByUsername方法和@User.java实体定义,找出根本原因并修复。”AI 反应:
读取
@AuthService.java:发现代码直接调用了user.getPassword()而没有判断user是否为 null。读取
@UserRepository.java:确认当用户名不存在时,确实返回Optional.empty()或null。读取
@User.java:确认字段名称无误。输出:直接给出修复后的代码,使用
Optional.orElseThrow()或显式的if (user == null)处理,并抛出自定义的UserNotFoundException,完全符合你项目的异常处理规范。
场景:需要在现有的电商系统中增加“计算订单含税总价”的功能。
❌ 不使用 @Mention
用户输入:“帮我写一个计算订单含税总价的方法。”
AI 反应:生成一段孤立的 Java 方法,可能使用了硬编码的税率(如 0.13),数据类型用了
double(在金额计算中是大忌),且不知道你的Order对象里有哪些字段(是否有discount?是否有vipLevel?)。
✅ 使用 @Mention
用户输入:“参考
@Order.java的字段结构和@TaxConfig.java中的税率配置逻辑,在@OrderService.java中新增一个calculateTotalWithTax方法。要求使用BigDecimal进行精确计算,并复用@DiscountStrategy.java中的折扣逻辑。”AI 反应:
读取
@Order.java:发现包含subtotal,itemId,userId等字段。读取
@TaxConfig.java:获取动态税率获取方法getTaxRate(String region)。读取
@DiscountStrategy.java:理解现有的折扣计算接口。输出
:生成严谨的 Java 代码:
使用
BigDecimal避免精度丢失。自动注入
TaxConfig和DiscountStrategy依赖。逻辑顺序:
原价 -> 应用折扣策略 -> 根据地区应用税率 -> 返回最终金额。代码风格与现有 Service 层完全一致(如使用了 Lombok, Spring 注解等)。
场景:需要修改 User 实体类,将 phoneNumber 字段从 String 改为自定义类型 PhoneNumber 对象,以支持格式验证。
❌ 不使用 @Mention
用户输入:“我把 User 类的手机号改成对象类型了,帮我看看哪里要改。”
AI 反应:无法知道项目中有多少个地方用到了
phoneNumber,只能泛泛地说“请检查所有 getter/setter 调用处”。
✅ 使用 @Mention
用户输入:“我将
@User.java中的phoneNumber字段重构为@PhoneNumber.java类型。请扫描@UserController.java、@UserDTO.java和@OrderMapper.xml(如果是 MyBatis),列出所有需要修改的地方,并给出修改后的代码片段。”AI 反应:
对比分析:对比新旧
User结构。定位调用
:
在
@UserController.java中:找到直接返回user.getPhoneNumber()给前端的接口,建议改为user.getPhoneNumber().getNumber()或适配 DTO。在
@UserDTO.java中:建议同步修改 DTO 字段类型,并提供 MapStruct 或 BeanUtils 的转换配置。在
@OrderMapper.xml中:提示 SQL 映射可能需要调整(如果直接映射了字段)。输出:提供一份详细的修改清单和具体的代码补丁,确保重构不会导致编译错误或运行时崩溃。
场景:为复杂的业务逻辑类编写 JUnit 5 + Mockito 测试用例。
❌ 不使用 @Mention
用户输入:“给 OrderService 写个测试。”
AI 反应:生成一个空的测试类,Mock 对象可能是瞎编的(比如 Mock 了一个不存在的
PaymentClient),断言逻辑也是通用的assertNotNull。
✅ 使用 @Mention
用户输入:“基于
@OrderService.java的业务逻辑,参考@PaymentGateway.java的接口定义,使用 JUnit 5 和 Mockito 编写单元测试。重点覆盖@OrderStatus.java中定义的 'PAID' 和 'FAILED' 状态流转,并模拟@InventoryException.java异常情况。”AI 反应:
理解依赖:准确 Mock
PaymentGateway和InventoryService(即使你没提,它通过读 Service 文件也能发现)。覆盖分支:针对
PAID成功流程、支付失败流程、库存不足抛出InventoryException的流程分别生成@Test方法。断言精准:使用
verify(mock, times(1)).deductStock(...)等精确验证交互,而不是简单的非空判断。
由于我们项目中使用的技术栈及框架是固定的,那么部分相同规则的代码可以快速生成。
比如:
基于 sql 语句生成 entity、mapper、service、impl、enums,指定所有数据类型与成员变量类型,如 bigint -> Long、integer -> Integer、datetime -> LocalDateTime、varchar -> String 等,加上 Lombok 注解、MyBatis-Plus ID 注解、字段注释及枚举路径等,涉及数据库内部字段需要提出修改建议。
我们可以创建一个可以复用的快捷指令:
---
description: 基于 SQL 建表语句,完整生成 Entity、Mapper、Service、ServiceImpl、Enums 代码,并对数据库字段设计给出审查建议
---
你是一个 Java 代码生成助手,根据用户提供的 SQL 建表语句,**严格按照本项目编码规范**,依次生成以下所有组件。
> **目录说明**:如果用户在请求中指定了目标目录(如 `生成到 /path/to/project` 或 `目录:xxx`),则所有文件的生成路径以用户指定目录为根目录,忽略第八步中的默认路径模板;否则使用默认路径规则。
---
## 第一步:解析 SQL,分析字段信息
仔细读取 SQL,提取以下信息:
1. **表名** → 推导 Java 类名(下划线转大驼峰)和模块名
2. **字段列表** → 逐一映射为 Java 字段(规则见下文)
3. **主键字段**(PRIMARY KEY 或注释含"主键/id")
4. **枚举字段**(注释中含有 `0-xx 1-xx` 或 `状态/类型/来源` 等枚举语义的字段)
### SQL 字段类型 → Java 类型映射规则
| SQL 类型 | Java 类型 |
|---|---|
| `bigint` | `Long` |
| `int` / `integer` / `tinyint` / `smallint` | `Integer` |
| `varchar` / `char` / `text` / `longtext` / `mediumtext` | `String` |
| `datetime` / `timestamp` | `LocalDateTime` |
| `date` | `LocalDate` |
| `decimal` / `numeric` | `BigDecimal` |
| `float` / `double` | `BigDecimal` |
| `bit` / `boolean` | `Boolean` |
---
## 第二步:数据库字段审查建议
在生成代码之前,先对 SQL 进行审查,输出以下格式的建议(如有问题才输出):
```
⚠️ 数据库字段审查建议:
1. [字段名] - 问题描述 → 建议:具体建议
2. [字段名] - 问题描述 → 建议:具体建议
```
审查维度:
- **字段命名**:不符合 `snake_case` 规范,或与 Java 关键字冲突
- **类型选择**:如用 `varchar` 存金额(应用 `decimal`),用 `int` 存手机号(应用 `varchar(20)`),时间字段用 `int`存时间戳(建议改为 `datetime`)
- **长度设计**:手机号建议 `varchar(20)`,身份证建议 `varchar(20)`,邮箱建议 `varchar(100)`,URL 建议 `varchar(500)`,状态类字段用 `tinyint` 更节省空间
- **索引建议**:高频查询字段(如 `company_id`、`create_time`、关联外键)建议添加索引
- **软删除字段**:若有 `is_deleted` / `del_flag`,建议结合 MyBatis-Plus 逻辑删除注解
---
## 第三步:生成 Entity 类
### 规范要求
- 继承 `com.baomidou.mybatisplus.extension.activerecord.Model<T>` 并实现 `pkVal()` 方法
- 注解顺序:`@Data`、`@EqualsAndHashCode(callSuper = false)`、`@Accessors(chain = true)`
- **仅当表名与类名不一致时**才添加 `@TableName("表名")`
- 主键字段如果是自增类型添加 `@TableId(value = "列名", type = IdType.AUTO)`,非自增类型添加 `@TableId(value = "列名")`
- 与 Java 关键字冲突或需要转义的字段使用 `@TableField("`字段名`")`
- 每个字段上方添加 `/** 字段注释说明 */` 格式的 Javadoc 注释(来自 SQL 注释)
- 包含 `private static final long serialVersionUID = 1L;`
- **不添加** `@Builder`、`@NoArgsConstructor`、`@AllArgsConstructor`(项目统一用 `@Accessors(chain = true)` 链式 setter)
### 导入语句顺序
```
com.baomidou.mybatisplus.annotation.IdType
com.baomidou.mybatisplus.annotation.TableId
com.baomidou.mybatisplus.annotation.TableName(按需)
com.baomidou.mybatisplus.annotation.TableField(按需)
com.baomidou.mybatisplus.extension.activerecord.Model
java.io.Serializable
java.time.LocalDateTime(按需)
java.time.LocalDate(按需)
java.math.BigDecimal(按需)
lombok.Data
lombok.EqualsAndHashCode
lombok.experimental.Accessors
```
### 代码模板
```java
package com.feixiang.pangu.{模块}.entity;
// imports...
/**
* <p>
* {表注释}
* </p>
*
* @author tools
* @since {今天日期}
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("{表名}") // 仅类名与表名不一致时添加
public class {ClassName} extends Model<{ClassName}> {
private static final long serialVersionUID = 1L;
/**
* {主键注释}
*/
@TableId(value = "{pk列名}", type = IdType.AUTO)
private {pkType} id;
/**
* {字段注释}
*/
private {JavaType} {fieldName};
// ... 其他字段
@Override
protected Serializable pkVal() {
return this.id;
}
}
```
---
## 第四步:生成 Mapper 接口
### 规范要求
- 继承 `com.baomidou.mybatisplus.core.mapper.BaseMapper<{Entity}>`
- 如有自定义查询需求(从 SQL 注释或业务语义推断),声明对应方法签名,使用 `@Param` 注解
- 注释格式与项目一致
### 代码模板
```java
package com.feixiang.pangu.{模块}.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.feixiang.pangu.{模块}.entity.{ClassName};
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* {表注释} Mapper 接口
* </p>
*
* @author tools
* @since {今天日期}
*/
public interface {ClassName}Mapper extends BaseMapper<{ClassName}> {
// 如有业务推断,声明自定义查询方法,例如:
// List<{ClassName}> selectByCompanyId(@Param("companyId") String companyId);
}
```
---
## 第五步:生成 Service 接口
### 规范要求
- 接口命名:`I{ClassName}Service`(有 `I` 前缀)
- 继承 `com.baomidou.mybatisplus.extension.service.IService<{Entity}>`
- 根据表的业务语义声明以下标准方法(按需,不是全部必须):
- `{ClassName}VO findById(Long id)` — 按 ID 查询
- `ApiResult<String> create({ClassName}AddRequest request)` — 新增
- `ApiResult<String> modify({ClassName}ModifyRequest request)` — 修改
- `ApiResult<String> delete(Long id)` — 删除(软删除)
- `ApiResult<List<{ClassName}VO>> list({ClassName}ListRequest request)` — 列表查询
- 每个方法添加 Javadoc 注释
### 代码模板
```java
package com.feixiang.pangu.{模块}.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.feixiang.pangu.{模块}.entity.{ClassName};
import com.feixiang.pangu.common.lib.result.ApiResult;
import java.util.List;
/**
* <p>
* {表注释} 服务类
* </p>
*
* @author tools
* @since {今天日期}
*/
public interface I{ClassName}Service extends IService<{ClassName}> {
/**
* 根据 ID 查询详情
*/
// {ClassName}VO findById(Long id);
/**
* 新增
*/
// ApiResult<String> create({ClassName}AddRequest request);
/**
* 修改
*/
// ApiResult<String> modify({ClassName}ModifyRequest request);
/**
* 删除
*/
// ApiResult<String> delete(Long id);
/**
* 列表查询
*/
// ApiResult<List<{ClassName}VO>> list({ClassName}ListRequest request);
}
```
---
## 第六步:生成 ServiceImpl 实现类
### 规范要求
- 命名:`{ClassName}ServiceImpl`
- 继承 `ServiceImpl<{ClassName}Mapper, {ClassName}>`
- 实现 `I{ClassName}Service` 接口
- 注解:`@Service`、`@Slf4j`(如涉及日志)
- 依赖注入使用 `@Resource`(不用 `@Autowired`)
- 实现 Service 接口中声明的方法(方法体中写基础实现骨架,加 TODO 注释提示补充逻辑)
### 代码模板
```java
package com.feixiang.pangu.{模块}.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feixiang.pangu.{模块}.dao.{ClassName}Mapper;
import com.feixiang.pangu.{模块}.entity.{ClassName};
import com.feixiang.pangu.{模块}.service.I{ClassName}Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* <p>
* {表注释} 服务实现类
* </p>
*
* @author tools
* @since {今天日期}
*/
@Slf4j
@Service
public class {ClassName}ServiceImpl extends ServiceImpl<{ClassName}Mapper, {ClassName}> implements I{ClassName}Service {
// TODO: 实现 I{ClassName}Service 中定义的业务方法
}
```
---
## 第七步:生成枚举类
仅对 SQL 中**注释含枚举语义的字段**生成对应枚举(如 `状态`、`类型`、`来源`、`标识` 等)。
### 规范要求
- 枚举放在 `api-{模块}` 模块下的 `enums` 包中(与业务实体解耦,供 API 层共享)
- 路径示例:`com.feixiang.pangu.api.{模块}.enums.{ClassName}{FieldName}Enum`
- 实现 `com.feixiang.pangu.common.base.BaseEnum` 接口
- 注解:`@AllArgsConstructor`、`@Getter`
- 字段:`private final Integer code;`(或 String)和 `private final String message;`
- 提供静态工厂方法 `of(Integer code)` 根据 code 获取枚举(找不到返回 null 或抛异常,根据语义决定)
### 代码模板
```java
package com.feixiang.pangu.api.{模块}.enums;
import com.feixiang.pangu.common.base.BaseEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* {表注释} - {字段注释} 枚举
*
* @author tools
* @since {今天日期}
*/
@Getter
@AllArgsConstructor
public enum {ClassName}{FieldName}Enum implements BaseEnum {
// 根据 SQL 注释中的枚举值生成,例如注释为 "0-待处理 1-处理中 2-已完成 -1-失败":
PENDING(0, "待处理"),
PROCESSING(1, "处理中"),
SUCCESS(2, "已完成"),
FAIL(-1, "失败"),
;
private final Integer code;
private final String message;
/**
* 根据 code 获取枚举
*/
public static {ClassName}{FieldName}Enum of(Integer code) {
if (code == null) {
return null;
}
for ({ClassName}{FieldName}Enum item : values()) {
if (item.getCode().equals(code)) {
return item;
}
}
return null;
}
}
```
---
## 第八步:生成汇总
输出以下格式的文件路径清单:
```
📁 生成文件清单:
├── Entity: server/{模块}/src/main/java/com/feixiang/pangu/{模块}/entity/{ClassName}.java
├── Mapper: server/{模块}/src/main/java/com/feixiang/pangu/{模块}/dao/{ClassName}Mapper.java
├── Service: server/{模块}/src/main/java/com/feixiang/pangu/{模块}/service/I{ClassName}Service.java
├── ServiceImpl: server/{模块}/src/main/java/com/feixiang/pangu/{模块}/service/impl/{ClassName}ServiceImpl.java
└── Enum(s): api/api-{模块}/src/main/java/com/feixiang/pangu/api/{模块}/enums/{ClassName}XXXEnum.java
```
qoder 支持视觉能力比较强,可以通过截图快速理解所需实现功能,再结合详细的需求描述可以快速定义接口。
比如: 图片:

需求:基于@ rules 和 @实体对象根据图片生成以下接口定义,包括请求参数、响应参数、Controller
查询部门分页列表
创建部门
编辑部门
查询部门详情
删除部门
TODO 注释作为代码的一部分,让 Agent :
明确需要执行的目标
TODO 是永久保存在文件中,在长上下文中可以达到断点续传、意图锁定效果。
针对性生成代码,直接结果更精准,不会盲目扩张。
案例:
场景 A:没有 TODO
人类:“写个天气插件。” Agent:生成了代码,但可能忽略了错误处理,或者硬编码了 API Key,因为它认为“代码能跑”就是完成了。
场景 B:利用 TODO 驱动开发
人类:创建一个骨架文件,写下:
1def get_weather(city): 2 # TODO: 验证 city 参数是否为空 3 # TODO: 调用 OpenWeatherMap API (Key 从环境变量读取) 4 # TODO: 处理 API 限流错误 (Retry 机制) 5 # TODO: 将结果转换为 JSON 格式 6 passAgent 的执行过程:
解析:发现 4 个明确的
TODO。规划:生成计划列表 [1. 加校验, 2. 写 API 调用, 3. 加重试, 4. 格式化]。
执行:逐个击破,每完成一个就删除或修改对应的注释。
验证:最后检查是否还有
TODO。如果有,继续修;如果没有,报告任务完成。
使用提示词增强功能,让开发关注要做什么,而 AI 关注怎么做最好。
Rules 是 Qoder 的项目级规则配置功能,存储在 .qoder/rules 目录中,仅作用于当前项目。其核心作用是将预定义的上下文注入到 AI 提示中,使 AI 的响应更符合你的项目标准和编码偏好(如框架、代码风格等)。
四种规则类型:
---
trigger: always_on
alwaysApply: true
---
# Java 后端开发规范
## 框架与技术栈
- Spring Boot 2.1.9.RELEASE
- MyBatis-Plus
- Lombok
- Apollo 配置中心
- Redis 缓存
- Feign 客户端
- Sentinel 流控
- Sleuth 链路追踪
- XXL-JOB 分布式任务调度
- DDD 领域驱动设计架构
## 代码风格
- 使用驼峰命名法
- 类名使用大写字母开头的驼峰命名(UpperCamelCase)
- 方法名和变量名使用小写字母开头的驼峰命名(lowerCamelCase)
- 常量全部大写,单词间用下划线分隔
- 接口使用名词或形容词+名词命名,如 UserService, OrderService
- 实现类使用接口名+Impl 命名,如 UserServiceImpl
- DTO/VO/Entity 类使用 Req/Resp 后缀区分请求响应对象
- 方法命名应体现业务意图,如 getUserById, calculateOrderAmount
- 使用有意义的变量名,避免单字母变量(循环变量除外)
## 分层架构
- Controller 层:接收请求,参数校验,调用 Application Service
- Application 层:协调领域服务,处理用例流程,跨领域编排
- Domain 层:包含实体、聚合根、领域服务、领域事件,实现核心业务逻辑
- Infrastructure 层:数据访问、外部服务调用、消息队列等基础设施实现
- Repository 接口定义在 Domain 层,实现在 Infrastructure 层
- 使用 Assembler 模式进行 Entity 与 DTO 之间的转换
## 异常处理
- 定义业务异常枚举,实现 ApiCode 接口,如 CartExceptionEnum
- 使用 BusinessException 包装业务异常信息
- 在 Application 层抛出业务异常,由全局异常处理器统一处理
- Controller 层不直接处理异常,交由 GlobalExceptionHandler 统一处理
- 在关键操作点添加事务注解 @Transactional(rollbackFor = Exception.class)
- 对于无效参数,使用 @Validated 注解配合参数校验框架处理
- 对于外部接口调用失败,应捕获异常并适当处理
## 日志规范
- 使用 Lombok 的 @Slf4j 注解
- 关键业务操作必须记录 INFO 日志
- 异常捕获记录 ERROR 日志,包含堆栈信息
- 请求外部接口时,请求参数和响应参数必须记录 INFO 日志
- 敏感信息(如用户ID)需做脱敏处理后再记录
- 在 Controller 层使用 @MyLog 注解记录接口调用日志
- 在关键业务节点记录操作结果,如"移除失效商品成功, storeId={}, clientUserId={}, 移除数量={}"
## 示例 - 良好的 Controller 写法
```java
@Api(tags = "购物车接口")
@RestController
@RequestMapping("/cart")
public class CartController extends MyBaseController {
@Resource
private CartAppService cartAppService;
@ApiOperation("添加购物车")
@PostMapping("/add")
@MyLog(level = MyLog.Level.info, msg = "添加购物车")
public ApiResult<Void> addCart(@RequestBody @Validated CartAddReq req) {
return cartAppService.addCart(getClientUser(), req);
}
}
```
## 数据库操作规范
- 使用 MyBatis-Plus 提供的通用 CRUD 方法
- 复杂查询使用自定义 Mapper,遵循 QueryObject 模式
- 避免 N+1 查询问题,批量查询时使用 IN 查询
- 在 Repository 实现中处理数据库操作,Domain 层只调用 Repository 接口
- 合理使用缓存减少数据库压力
## Redis 使用规范
- 使用 RedisTemplate 进行缓存操作
- 注意序列化安全问题,避免反序列化漏洞
- 设置合理的缓存过期时间
- 缓存键命名遵循统一规范,如 "module:entity:id"
## 安全规范
- 验证用户身份和权限
- 防止 SQL 注入,使用预编译语句
- 对外部传入的数据进行严格校验
- 避免在日志中记录敏感信息
- 配置文件中的敏感信息通过配置中心管理
## 性能优化
- 避免在循环中进行数据库查询
- 合理使用索引,优化慢查询
- 对频繁查询的数据进行缓存
- 使用批量操作提高效率
- 合理设置连接池参数
## 测试规范
- 编写单元测试覆盖核心业务逻辑
- 使用 Mock 框架模拟外部依赖
- 编写集成测试验证系统整体功能
- 对异常场景进行测试---
trigger: always_on
alwaysApply: true
---
# 前端开发规范
# 前端开发规范
## 技术栈
- 框架:React 18 + TypeScript 5
- 状态管理:Zustand
- 样式方案:Tailwind CSS + CSS Modules
- 路由:React Router v6
- 构建工具:Vite 5
- 包管理器:pnpm
## 项目结构
- `src/components/` — 通用 UI 组件
- `src/pages/` — 页面级组件
- `src/hooks/` — 自定义 Hooks
- `src/stores/` — Zustand 状态管理
- `src/services/` — API 请求封装
- `src/utils/` — 工具函数
- `src/types/` — TypeScript 类型定义
## 命名规范
- 组件文件使用 PascalCase:`UserProfile.tsx`
- Hook 文件以 use 开头:`useAuth.ts`
- 工具函数使用 camelCase:`formatDate.ts`
- 类型/接口使用 PascalCase 并以 I 或 T 前缀区分:`IUserProps`、`TStatus`
- CSS Modules 文件与组件同名:`UserProfile.module.scss`
## 组件规范
- 优先使用函数式组件 + Hooks
- Props 必须定义 TypeScript 接口
- 单个组件不超过 200 行,超出请拆分
- 使用解构获取 Props
## 示例 - 良好的组件写法
```tsx
interface IUserCardProps {
name: string;
avatar: string;
role: 'admin' | 'user';
onClick?: () => void;
}
const UserCard: React.FC<IUserCardProps> = ({ name, avatar, role, onClick }) => {
const { t } = useTranslation();
return (
<div className="flex items-center gap-3 p-4 rounded-lg shadow-sm" onClick={onClick}>
<img src={avatar} alt={name} className="w-10 h-10 rounded-full" />
<div>
<h3 className="text-sm font-medium">{name}</h3>
<span className="text-xs text-gray-500">{t(`roles.${role}`)}</span>
</div>
</div>
);
};
export default UserCard;
```
## Hooks 规范
- 自定义 Hook 必须以 use 开头
- 将复杂逻辑从组件中抽离到自定义 Hook
- 副作用逻辑统一在 Hook 中管理
## 示例 - 良好的 Hook 写法
``` tsx
const useUserList = () => {
const [users, setUsers] = useState<IUser[]>([]);
const [loading, setLoading] = useState(false);
const fetchUsers = useCallback(async () => {
setLoading(true);
try {
const data = await userService.getList();
setUsers(data);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchUsers();
}, [fetchUsers]);
return { users, loading, refetch: fetchUsers };
};
```
## API 请求规范
- 使用 Axios 统一封装,配置拦截器处理 Token 和错误
- 请求和响应类型必须定义 TypeScript 接口
- 错误处理统一在拦截器中完成,组件层不重复 try-catch
## 样式规范
- 优先使用 Tailwind CSS 工具类
- 复杂样式或动画使用 CSS Modules
- 禁止使用内联样式(style 属性)
- 响应式设计使用 Tailwind 断点:sm、md、lg、xl
## 性能优化
- 列表渲染必须提供稳定的 key
- 大列表使用虚拟滚动(react-virtuoso)
- 使用 React.memo 包裹纯展示组件
- 使用 useMemo / useCallback 避免不必要的重渲染
- 图片使用懒加载
## 可访问性 (a11y)
- 交互元素必须包含 aria-label
- 图片必须包含 alt 属性
- 表单元素必须关联 label不要一上来就说:“根据接口文档 url:xxx 帮我把接口对接好”,为了保障生成的代码质量,我们可以逐步进行:
基于网站接口文档内容生成 Markdown 接口文件,可以使用 fetch 或者内置浏览器获取内容。
review Markdown 文件,完善并确认文档内容是否有识别偏差。
生成 API 对接封装计划任务明细,包含接口封装、枚举提取、表设计等等任务,输出 Markdown。
分步或直接执行计划任务。
前期小步可以快速验证是否是你想要的结果,比如先完成一个接口封装,调整后没问题按同样的方式执行即可。
进阶:自定义【三方 API 接口对接】Skill,以 supplier-sdk 为例:
---
name: api-wrapper-from-doc
description: 基于接口文档内容(网页URL或文档文件),分析接口规范并在Java项目中生成完整的接口封装实现,包括请求/响应模型类、API方法类、常量类等。遵循项目现有代码风格和设计模式。当用户提供接口文档并要求"封装接口"、"实现接口"、"生成接口SDK"或"基于文档创建接口"时使用此技能。
---
# 基于接口文档生成Java接口封装
## 工作流程
参考本项目已有的开放平台封装实现(`src/main/java/com/feixiang/pangu/supply/chain/api/test/`),按以下步骤执行:
### Task 1: 分析现有代码风格
执行前必读以下文件,理解项目规范:
- `OpenPlatformApi.java` - 主入口门面类
- `constant/OpenPlatformConstant.java` - 常量定义风格
- `model/OpenPlatformConfig.java` - 配置类结构
- `model/OpenPlatformResponse.java` - 通用响应封装
- `util/SignUtil.java` / `util/HttpUtil.java` / `util/RandomUtil.java` - 工具类
- 任意一个已有的 `XxxApi.java` 及其 model 子目录
### Task 2: 解析接口文档
从用户提供的文档(URL或文件)中提取:
**全局信息:**
- Base URL(QA/生产环境)
- 认证方式(Header参数名、签名规则)
- 全局请求参数(如 `rand_str`)
- 通用响应结构(code/message/data/request_id)
- 错误码列表
**每个接口:**
- 接口名称和功能描述
- HTTP路径和方式
- 请求参数(名称、类型、是否必传、描述)
- 响应字段(名称、类型、是否必传、描述)
- 嵌套对象结构
### Task 3: 确定包结构
根据文档中的接口分组,在适当位置创建包,结构为:
```
{base_package}/{vendor_name}/
├── {VendorName}Api.java # 主门面类(可选,多模块时使用)
├── config/
│ └── {VendorName}Config.java # 配置类
├── constant/
│ └── {VendorName}Constant.java # 常量(URL路径、错误码等)
├── {module}/
│ ├── {Module}Api.java # 模块API类
│ └── model/
│ ├── request/ # 请求参数类
│ └── response/ # 响应数据类
└── util/
├── SignUtil.java # 签名工具(如已有则复用)
├── HttpUtil.java # HTTP工具(如已有则复用)
└── RandomUtil.java # 随机数工具(如已有则复用)
```
### Task 4: 生成代码
**生成顺序(严格按此顺序):**
1. **常量类** (`XxxConstant.java`) - 包含所有API路径、Header名、状态码
2. **配置类** (`XxxConfig.java`) - 包含 appId/appSecret/secretKey/requestUrl 等
3. **响应封装类** (`XxxResponse.java`) - 通用响应包装,含 isSuccess() 方法
4. **工具类** - SignUtil、HttpUtil、RandomUtil(如项目已有可直接复用)
5. **请求模型类** (`model/request/XxxRequest.java`) - 每个需要复杂参数的接口一个
6. **响应模型类** (`model/response/XxxResponse.java`) - 每个接口响应的数据对象
7. **API实现类** (`XxxApi.java`) - 每个模块一个,包含所有接口方法
#### 代码规范
**配置类模板:**
```java
@Data
public class XxxConfig {
/** 对接账号 */
private String appId;
/** 对接密钥 */
private String appSecret;
/** 签名密钥 */
private String secretKey;
/** 请求URL: QA: https://xxx.com/ 生产: https://xxx.com/ */
private String requestUrl;
/** API描述 */
private String apiDesc = "XXX API";
}
```
**通用响应类模板:**
```java
@Data
public class XxxResponse<T> {
private Integer code;
private String message;
private T data;
private String requestId;
public boolean isSuccess() {
return XxxConstant.SUCCESS_CODE.equals(this.code);
}
}
```
**API方法模板:**
```java
/**
* 方法功能描述
*
* @param accessToken 访问令牌
* @param request 请求参数
* @return 返回类型描述
*/
public XxxResponse<ResponseType> methodName(String accessToken, RequestType request) {
Map<String, Object> params = new HashMap<>();
params.put("field_name", request.getFieldName());
// 可选参数用 if != null 判断后放入
if (request.getOptionalField() != null) {
params.put("optional_field", request.getOptionalField());
}
params.put(XxxConstant.PARAM_RAND_STR, RandomUtil.generateNumeric(6));
String url = config.getRequestUrl() + XxxConstant.API_XXX_METHOD;
String response = HttpUtil.post(url, params, config.getSecretKey(), accessToken);
if (Strings.isNullOrEmpty(response)) {
log.error("[{}]功能描述失败, response is null", config.getApiDesc());
return null;
}
return JSON.parseObject(response, new TypeReference<XxxResponse<ResponseType>>() {});
}
```
**模型类规范:**
- 使用 `@Data` (Lombok)
- 字段命名用 `camelCase`,JSON映射用 `@JSONField(name = "snake_case")`(如字段名与JSON不一致)
- 每个字段必须有中文注释
- 枚举值在注释中说明,如 `/** 状态 1上架 2下架 */`
**常量类规范:**
```java
public class XxxConstant {
/** 成功状态码 */
public static final Integer SUCCESS_CODE = 2000;
/** Header - Access Token */
public static final String HEADER_ACCESS_TOKEN = "access-token";
/** Body参数 - 随机字符串 */
public static final String PARAM_RAND_STR = "rand_str";
// 按模块分组定义API路径
/** 鉴权接口 */
public static final String API_AUTH_TOKEN = "/api/auth/token";
}
```
### Task 5: 验证完整性
生成完成后检查:
- [ ] 所有接口文档中的接口都有对应实现
- [ ] 请求参数(必传/可选)处理正确
- [ ] 响应字段完整映射
- [ ] 废弃接口(标注"已移除")跳过或注释说明
- [ ] 工具类(SignUtil、HttpUtil)是否与文档中签名规则一致
- [ ] 编译通过,无红线错误
## 关键规则
1. **复用优先**:项目已有工具类(SignUtil/HttpUtil/RandomUtil)直接复用,不重复创建
2. **废弃接口跳过**:文档中标注"已移除"或废弃的接口不生成代码
3. **数组参数特殊处理**:数组类型参数在签名时不参与(参考 SignUtil 实现)
4. **Token接口不传 access-token**:获取token和刷新token接口使用 `postWithoutToken` 方法
5. **字段注释务必包含枚举说明**:如状态码 `1-待付款 2-待发货` 等
## 参考文件位置
本项目的完整参考实现位于:
`src/main/java/com/feixiang/pangu/supply/chain/api/test/`
在创建新封装前,务必先读取该目录下的文件作为代码风格参考。mastergo、figma:可以读取原型设计,快速生成前端页面、对象、接口等代码。
fetch:可以抓取网页内容。
mysql:提供执行数据库 sql 能力。
drawio:提供绘图能力,配合 vscode 插件,可以制动完成绘图。
Apifox:基于已知接口文档快速对接接口,比如一些三方接口。
github:开源项目调研。
更多:https://www.modelscope.cn/mcp?page=1
在同样使用 Auto(智能路由) 模式下,有两种主要方式降低积分消耗:
压缩当前会话(Compact Chat):当会话变长、上下文窗口快满时,点击「压缩当前会话」,系统会智能总结保留关键信息、剔除冗余内容,有效降低 Credits 消耗并提升响应速度。
及时新建会话(New Chat):切换新话题时,开启全新会话,避免无关历史上下文导致的 Credits 浪费。
核心原理是:Credits 消耗与 Token 数量直接相关,上下文越长消耗越多,控制上下文长度是关键。
