提示词保存
This commit is contained in:
373
.cursor/rules/backend.mdc
Normal file
373
.cursor/rules/backend.mdc
Normal file
@@ -0,0 +1,373 @@
|
||||
---
|
||||
description: RuoYi Spring Boot 后端开发最佳实践与规范
|
||||
globs: **/*.java, **/*.xml, **/*.yaml, **/*.yml
|
||||
---
|
||||
|
||||
# RuoYi Spring Boot 后端开发规范
|
||||
|
||||
## 项目架构
|
||||
|
||||
### 模块结构
|
||||
- `yudao-dependencies`: Maven 依赖版本统一管理
|
||||
- `yudao-framework`: 框架拓展组件(技术组件)
|
||||
- `yudao-server`: 服务启动模块
|
||||
- `yudao-module-*`: 业务模块(如 system、member、ai 等)
|
||||
|
||||
### 分层架构
|
||||
- **Controller 层**: 接收请求,参数校验,调用 Service
|
||||
- **Service 层**: 业务逻辑处理,事务管理
|
||||
- **Mapper 层**: 数据访问,使用 MyBatis Plus
|
||||
- **VO 层**: 视图对象,用于前后端交互
|
||||
- **DO 层**: 数据对象,对应数据库表
|
||||
|
||||
## Controller 层规范
|
||||
|
||||
### 包结构
|
||||
- `controller.admin.*`: 管理后台接口
|
||||
- `controller.app.*`: 用户端接口(C 端)
|
||||
- App Controller 和 VO 必须添加 `App` 前缀
|
||||
|
||||
### 注解使用
|
||||
- 使用 `@RestController` 而非 `@Controller`
|
||||
- 使用 `@RequestMapping` 定义基础路径
|
||||
- 使用 `@Tag` 定义 Swagger 文档标签
|
||||
- 使用 `@Operation` 定义接口说明
|
||||
- 使用 `@Parameter` 定义参数说明
|
||||
- 使用 `@Valid` 或 `@Validated` 进行参数校验
|
||||
|
||||
### 权限控制
|
||||
- 管理后台接口使用 `@PreAuthorize("@ss.hasPermission('module:resource:action')")`
|
||||
- 用户端接口通过 `getLoginUserId()` 获取当前用户,确保数据隔离
|
||||
- 使用 `@PermitAll` 标记允许匿名访问的接口
|
||||
|
||||
### 返回值规范
|
||||
- 统一使用 `CommonResult<T>` 包装返回值
|
||||
- 使用 `success()` 静态方法返回成功结果
|
||||
- 异常由全局异常处理器统一处理
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
@Tag(name = "管理后台 - 用户提示词")
|
||||
@RestController
|
||||
@RequestMapping("/ai/user-prompt")
|
||||
@Validated
|
||||
public class UserPromptController {
|
||||
|
||||
@Resource
|
||||
private UserPromptService userPromptService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建用户提示词")
|
||||
@PreAuthorize("@ss.hasPermission('ai:user-prompt:create')")
|
||||
public CommonResult<Long> createUserPrompt(@Valid @RequestBody UserPromptSaveReqVO createReqVO) {
|
||||
return success(userPromptService.createUserPrompt(createReqVO));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Service 层规范
|
||||
|
||||
### 接口与实现
|
||||
- Service 接口定义在 `service` 包下
|
||||
- Service 实现类使用 `ServiceImpl` 后缀,实现对应接口
|
||||
- 使用 `@Service` 注解标记
|
||||
- 使用 `@Validated` 启用参数校验
|
||||
|
||||
### 事务管理
|
||||
- 涉及数据库写操作的方法使用 `@Transactional(rollbackFor = Exception.class)`
|
||||
- 查询方法不需要事务注解
|
||||
- 避免在 Service 方法中捕获异常后不抛出,导致事务无法回滚
|
||||
|
||||
### 业务逻辑
|
||||
- Service 层处理核心业务逻辑
|
||||
- 使用 `BeanUtils.toBean()` 进行对象转换
|
||||
- 使用 `validateXxxExists()` 方法校验数据存在性
|
||||
- 使用 `ServiceExceptionUtil.exception()` 抛出业务异常
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
@Service
|
||||
@Validated
|
||||
public class UserPromptServiceImpl implements UserPromptService {
|
||||
|
||||
@Resource
|
||||
private UserPromptMapper userPromptMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createUserPrompt(UserPromptSaveReqVO createReqVO) {
|
||||
// 1. 校验
|
||||
// 2. 转换
|
||||
UserPromptDO userPrompt = BeanUtils.toBean(createReqVO, UserPromptDO.class);
|
||||
// 3. 插入
|
||||
userPromptMapper.insert(userPrompt);
|
||||
// 4. 返回
|
||||
return userPrompt.getId();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Mapper 层规范
|
||||
|
||||
### 继承规范
|
||||
- Mapper 接口继承 `BaseMapperX<T>`,而非 `BaseMapper<T>`
|
||||
- `BaseMapperX` 提供了更强大的查询能力
|
||||
|
||||
### 方法命名
|
||||
- 查询方法使用 `select` 前缀
|
||||
- 插入方法使用 `insert` 前缀
|
||||
- 更新方法使用 `update` 前缀
|
||||
- 删除方法使用 `delete` 前缀
|
||||
|
||||
### 分页查询
|
||||
- 使用 `selectPage(PageReqVO pageReqVO)` 进行分页查询
|
||||
- 使用 `LambdaQueryWrapperX` 构建查询条件
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
@Mapper
|
||||
public interface UserPromptMapper extends BaseMapperX<UserPromptDO> {
|
||||
|
||||
default PageResult<UserPromptDO> selectPage(UserPromptPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<UserPromptDO>()
|
||||
.likeIfPresent(UserPromptDO::getName, reqVO.getName())
|
||||
.eqIfPresent(UserPromptDO::getCategory, reqVO.getCategory())
|
||||
.betweenIfPresent(UserPromptDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(UserPromptDO::getId));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## VO 对象规范
|
||||
|
||||
### 命名规范
|
||||
- Request VO: `XxxSaveReqVO`、`XxxPageReqVO`、`XxxUpdateReqVO`
|
||||
- Response VO: `XxxRespVO`
|
||||
- App VO: `AppXxxReqVO`、`AppXxxRespVO`
|
||||
|
||||
### 字段注解
|
||||
- 使用 `@Schema` 定义字段说明和示例
|
||||
- 使用 `@NotNull`、`@NotEmpty`、`@NotBlank` 等校验注解
|
||||
- 使用 `requiredMode = Schema.RequiredMode.REQUIRED` 标记必填字段
|
||||
|
||||
### 对象转换
|
||||
- Controller 层使用 `BeanUtils.toBean()` 进行 DO 到 VO 的转换
|
||||
- Service 层使用 `BeanUtils.toBean()` 进行 VO 到 DO 的转换
|
||||
- 复杂转换使用 MapStruct 或手动转换
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
@Schema(description = "管理后台 - 用户提示词创建 Request VO")
|
||||
@Data
|
||||
public class UserPromptSaveReqVO {
|
||||
|
||||
@Schema(description = "提示词名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "Java 开发助手")
|
||||
@NotBlank(message = "提示词名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "提示词内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "提示词内容不能为空")
|
||||
private String content;
|
||||
}
|
||||
```
|
||||
|
||||
## DO 对象规范
|
||||
|
||||
### 继承规范
|
||||
- 普通 DO 继承 `BaseDO`,包含 `id`、`createTime`、`updateTime`、`creator`、`updater`、`deleted`
|
||||
- 需要多租户的 DO 继承 `TenantBaseDO`,额外包含 `tenantId`
|
||||
- 使用 `@TableName` 指定表名
|
||||
|
||||
### 字段规范
|
||||
- 使用 `@TableId(type = IdType.AUTO)` 指定主键策略
|
||||
- 使用 `@TableLogic` 标记逻辑删除字段
|
||||
- 字段名使用驼峰命名,对应数据库下划线命名
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
@TableName("ai_user_prompt")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserPromptDO extends TenantBaseDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
private String content;
|
||||
private String category;
|
||||
}
|
||||
```
|
||||
|
||||
## 异常处理规范
|
||||
|
||||
### 异常定义
|
||||
- 业务异常使用 `ServiceException`,通过 `ServiceExceptionUtil.exception()` 创建
|
||||
- 异常码定义在 `ErrorCodeConstants` 中
|
||||
- 使用全局异常处理器统一处理
|
||||
|
||||
### 异常码规范
|
||||
- 格式:`MODULE_RESOURCE_ACTION_ERROR`
|
||||
- 例如:`USER_PROMPT_NOT_EXISTS`、`USER_PROMPT_NAME_DUPLICATE`
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
// 定义异常码
|
||||
public interface ErrorCodeConstants {
|
||||
ErrorCode USER_PROMPT_NOT_EXISTS = new ErrorCode(1_010_000_001, "用户提示词不存在");
|
||||
}
|
||||
|
||||
// 使用异常
|
||||
if (userPrompt == null) {
|
||||
throw exception(USER_PROMPT_NOT_EXISTS);
|
||||
}
|
||||
```
|
||||
|
||||
## 多租户规范
|
||||
|
||||
### DO 继承
|
||||
- 需要多租户的数据表,DO 继承 `TenantBaseDO`
|
||||
- 框架自动注入 `tenantId`,无需手动设置
|
||||
|
||||
### 数据隔离
|
||||
- Mapper 查询时,框架自动添加租户条件
|
||||
- 跨租户操作需要特殊处理
|
||||
|
||||
### 代码示例
|
||||
```java
|
||||
// DO 继承 TenantBaseDO
|
||||
public class UserPromptDO extends TenantBaseDO {
|
||||
// tenantId 自动注入,无需手动定义
|
||||
}
|
||||
|
||||
// Service 中无需关心租户,框架自动处理
|
||||
public UserPromptDO getUserPrompt(Long id) {
|
||||
return userPromptMapper.selectById(id); // 自动添加租户条件
|
||||
}
|
||||
```
|
||||
|
||||
## 权限控制规范
|
||||
|
||||
### 权限标识
|
||||
- 格式:`模块:资源:操作`
|
||||
- 例如:`ai:user-prompt:create`、`ai:user-prompt:query`、`ai:user-prompt:update`、`ai:user-prompt:delete`
|
||||
|
||||
### 权限注解
|
||||
- 使用 `@PreAuthorize("@ss.hasPermission('module:resource:action')")`
|
||||
- 查询操作使用 `query`,创建使用 `create`,更新使用 `update`,删除使用 `delete`
|
||||
|
||||
## API 路径规范
|
||||
|
||||
### 路径前缀
|
||||
- 管理后台:`/admin-api`
|
||||
- 用户端:`/app-api`
|
||||
- Controller 路径:`/模块/资源`,如 `/ai/user-prompt`
|
||||
|
||||
### HTTP 方法
|
||||
- GET: 查询操作
|
||||
- POST: 创建操作
|
||||
- PUT: 更新操作
|
||||
- DELETE: 删除操作
|
||||
|
||||
### 接口路径
|
||||
- 创建:`POST /模块/资源/create`
|
||||
- 更新:`PUT /模块/资源/update`
|
||||
- 删除:`DELETE /模块/资源/delete`
|
||||
- 查询单个:`GET /模块/资源/get?id=xxx`
|
||||
- 分页查询:`GET /模块/资源/page`
|
||||
- 导出:`GET /模块/资源/export-excel`
|
||||
|
||||
## 代码质量规范
|
||||
|
||||
### 命名规范
|
||||
- 类名使用大驼峰(PascalCase)
|
||||
- 方法名和变量名使用小驼峰(camelCase)
|
||||
- 常量使用大写下划线(UPPER_SNAKE_CASE)
|
||||
- 包名全小写,使用点分隔
|
||||
|
||||
### 注释规范
|
||||
- 类和方法必须有 JavaDoc 注释
|
||||
- 复杂业务逻辑添加行内注释
|
||||
- 使用 `@author` 标记作者
|
||||
|
||||
### 代码格式
|
||||
- 使用 4 个空格缩进
|
||||
- 每行代码不超过 120 个字符
|
||||
- 方法参数过多时换行对齐
|
||||
- 使用 IDE 格式化快捷键统一格式
|
||||
|
||||
### 导入规范
|
||||
- 使用静态导入简化代码:`import static ...`
|
||||
- 避免使用 `.*` 通配符导入
|
||||
- 导入顺序:Java 标准库 → 第三方库 → 项目内部
|
||||
|
||||
## 性能优化规范
|
||||
|
||||
### 数据库查询
|
||||
- 避免 N+1 查询问题,使用批量查询
|
||||
- 合理使用索引,避免全表扫描
|
||||
- 分页查询必须限制每页数量
|
||||
|
||||
### 缓存使用
|
||||
- 热点数据使用 Redis 缓存
|
||||
- 缓存 key 使用统一前缀:`模块:资源:id`
|
||||
- 注意缓存更新和失效策略
|
||||
|
||||
### 事务优化
|
||||
- 查询方法不使用事务
|
||||
- 事务范围尽可能小
|
||||
- 避免在事务中进行远程调用
|
||||
|
||||
## 安全规范
|
||||
|
||||
### 参数校验
|
||||
- 所有用户输入必须校验
|
||||
- 使用 `@Valid` 和 JSR-303 注解
|
||||
- 敏感操作进行二次校验
|
||||
|
||||
### SQL 注入防护
|
||||
- 使用 MyBatis Plus 的参数化查询
|
||||
- 禁止拼接 SQL 语句
|
||||
- 使用 `LambdaQueryWrapperX` 构建查询条件
|
||||
|
||||
### 权限校验
|
||||
- 所有接口必须进行权限校验
|
||||
- 数据操作前校验数据归属
|
||||
- 敏感操作记录操作日志
|
||||
|
||||
## 测试规范
|
||||
|
||||
### 单元测试
|
||||
- Service 层方法编写单元测试
|
||||
- 使用 Mockito 模拟依赖
|
||||
- 测试覆盖率不低于 70%
|
||||
|
||||
### 集成测试
|
||||
- 关键业务流程编写集成测试
|
||||
- 使用 `@SpringBootTest` 进行集成测试
|
||||
- 测试数据使用独立的测试数据库
|
||||
|
||||
## 日志规范
|
||||
|
||||
### 日志级别
|
||||
- ERROR: 系统错误,需要立即处理
|
||||
- WARN: 警告信息,需要关注
|
||||
- INFO: 关键业务流程日志
|
||||
- DEBUG: 调试信息,生产环境关闭
|
||||
|
||||
### 日志格式
|
||||
- 使用 SLF4J + Logback
|
||||
- 日志包含:时间、级别、线程、类名、消息
|
||||
- 关键操作记录操作日志(使用 `@ApiAccessLog`)
|
||||
|
||||
## 配置管理
|
||||
|
||||
### 配置文件
|
||||
- 使用 `application.yaml` 作为主配置
|
||||
- 使用 `application-{profile}.yaml` 作为环境配置
|
||||
- 敏感信息使用环境变量或配置中心
|
||||
|
||||
### 配置类
|
||||
- 使用 `@ConfigurationProperties` 绑定配置
|
||||
- 配置类使用 `@Validated` 进行校验
|
||||
- 提供默认值和说明文档
|
||||
87
.cursor/rules/vue.md
Normal file
87
.cursor/rules/vue.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
description: 现代 Web 应用中的 Vue.js 最佳实践与模式
|
||||
globs: **/*.vue, **/*.ts, components/**/*
|
||||
---
|
||||
|
||||
# Vue.js 最佳实践
|
||||
|
||||
## 组件结构
|
||||
- 优先使用组合式 API 而非选项式 API
|
||||
- 保持组件小巧且功能专注
|
||||
- 采用恰当的 TypeScript 集成方案
|
||||
- 实现规范的 props 验证
|
||||
- 使用标准的 emit 声明
|
||||
- 保持模板逻辑简洁
|
||||
- 优先使用template 语法,而不是函数组件
|
||||
|
||||
## 组合式 API
|
||||
- 正确使用 ref 与 reactive
|
||||
- 合理实现生命周期钩子
|
||||
- 通过组合式函数封装可复用逻辑
|
||||
- 保持 setup 函数整洁
|
||||
- 规范使用计算属性
|
||||
- 合理实现侦听器
|
||||
|
||||
## 状态管理
|
||||
- 使用 Pinia 进行状态管理
|
||||
- 保持仓库模块化
|
||||
- 采用合理的状态组织方式
|
||||
- 规范实现操作逻辑
|
||||
- 正确使用获取器
|
||||
- 妥善处理异步状态
|
||||
|
||||
## 性能优化
|
||||
- 实现组件懒加载
|
||||
- 配置恰当的缓存策略
|
||||
- 高效使用计算属性
|
||||
- 避免不必要的侦听器
|
||||
- 区分使用 v-show 与 v-if
|
||||
- 实现科学的 key 管理
|
||||
|
||||
## 路由管理
|
||||
- 规范使用 Vue Router
|
||||
- 实现完整的导航守卫
|
||||
- 合理配置路由元字段
|
||||
- 正确处理路由参数
|
||||
- 实现路由懒加载
|
||||
- 使用标准的导航方法
|
||||
|
||||
## 表单处理
|
||||
- 正确使用 v-model
|
||||
- 实现完善的验证机制
|
||||
- 规范处理表单提交
|
||||
- 展示合理的加载状态
|
||||
- 配置完整的错误处理
|
||||
- 实现表单重置功能
|
||||
|
||||
## TypeScript 集成
|
||||
- 使用规范的组件类型定义
|
||||
- 实现完整的 props 类型声明
|
||||
- 规范 emit 类型声明
|
||||
- 处理类型推断
|
||||
- 使用标准的组合函数类型
|
||||
- 实现完整的仓库类型定义
|
||||
|
||||
## 测试策略
|
||||
- 编写规范的单元测试
|
||||
- 实现完整的组件测试
|
||||
- 正确使用 Vue Test Utils
|
||||
- 全面测试组合式函数
|
||||
- 实现科学的模拟机制
|
||||
- 测试异步操作流程
|
||||
|
||||
## 开发规范
|
||||
- 遵循 Vue 样式指南
|
||||
- 使用统一的命名约定
|
||||
- 保持组件结构清晰
|
||||
- 实现完整的错误处理
|
||||
- 规范事件处理机制
|
||||
- 为复杂逻辑添加文档注释
|
||||
|
||||
## 构建与工具链
|
||||
- 使用 Vite 进行开发
|
||||
- 配置完整的构建方案
|
||||
- 规范使用环境变量
|
||||
- 实现代码分割方案
|
||||
- 正确处理静态资源
|
||||
- 配置完整的优化策略
|
||||
Reference in New Issue
Block a user