15 KiB
15 KiB
API 文档基础规范
📋 文档说明
本文档记录项目 API 接口的通用规范和标准,包括请求方式、参数说明、响应格式等。所有 API 接口必须遵循此基础规范。
🔧 基础信息
- 基础路径:
/api - 响应格式: JSON
- 字符编码: UTF-8
- 权限认证: Sa-Token + JWT
- 版本: v1.0
🌐 API 文档访问方式
🌟 Swagger UI 在线文档(推荐)
访问地址: http://localhost:8080/swagger-ui/index.html ⭐
功能特点:
- 🎨 可视化界面,易于浏览和理解
- 🧪 支持在线测试,无需其他工具
- 📊 按业务模块自动分组展示
- 🔍 支持接口搜索和筛选
- 📋 自动生成请求示例和响应格式
使用场景:
- ✅ 接口调试和测试
- ✅ 快速查看接口列表
- ✅ 了解请求参数和响应格式
- ✅ 验证接口功能
📁 项目内置文档(详细参考)
位置: docs/开发文档/API/
特点:
- 📝 中文详细说明和业务逻辑解释
- 💡 完整的使用示例和最佳实践
- 🔗 模块间交叉引用和关联说明
- 📊 业务流程图和数据字典
使用场景:
- ✅ 深入了解业务逻辑
- ✅ 开发时参考规范
- ✅ 新人学习和培训
🔐 请求头规范(强制性)
所有需要认证的接口必须在请求头中包含 Token,格式如下:
{
"Content-Type": "application/json;charset=utf-8",
"Authorization": "Bearer {access_token}",
"clientid": "e5cd7e4891bf95d1d19206ce24a7b32e",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"referer": "http://localhost/login?redirect=%252Findex"
}
📋 请求头字段说明
| 字段名 | 必填 | 说明 | 示例值 |
|---|---|---|---|
| Authorization | 是 | Bearer + Token 值(⚠️ 注意空格) | "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." |
| clientid | 是 | 客户端 ID,用于权限验证 | "e5cd7e4891bf95d1d19206ce24a7b32e" |
| Content-Type | 是 | 请求内容类型 | "application/json;charset=utf-8" |
| Accept-Language | 是 | 语言设置,用于国际化 | "zh-CN,zh;q=0.9,en;q=0.8" |
| referer | 是 | 来源页面,用于安全验证 | "http://localhost/login?redirect=%252Findex" |
⚠️ Token 格式强制要求
- ✅ 正确:
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." - ❌ 错误:
"Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."(缺少 Bearer 前缀) - ❌ 错误:
"Authorization": "Bearer eyJ0eXAi..."(Bearer 后面没有空格)
🔴 统一响应格式(强制性)
⚠️ 所有 API 接口必须严格遵循以下统一响应格式!
📊 分页列表响应格式
{
"total": 100,
"rows": [
{
"id": 1,
"name": "示例数据1",
"createTime": "2025-06-30 12:00:00"
},
{
"id": 2,
"name": "示例数据2",
"createTime": "2025-06-30 12:01:00"
}
],
"code": 200,
"msg": "查询成功"
}
🎯 非分页列表响应格式
{
"code": 200,
"msg": "查询成功",
"data": [
{
"id": 1,
"name": "示例数据1"
},
{
"id": 2,
"name": "示例数据2"
}
]
}
🎯 单条数据响应格式
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"name": "示例数据",
"createTime": "2025-06-30 12:00:00"
}
}
🎯 操作成功响应格式(无数据)
{
"code": 200,
"msg": "操作成功",
"data": null
}
❌ 错误响应格式
{
"code": 400,
"msg": "参数错误:用户名不能为空",
"data": null
}
📋 状态码规范
✅ 成功状态码
200- 操作成功201- 创建成功
🚫 客户端错误(4xx)
400- 请求参数错误401- 未认证/认证失败403- 无权限访问404- 资源不存在409- 数据冲突
💥 服务端错误(5xx)
500- 服务器内部错误502- 网关错误503- 服务不可用
🚨 开发强制要求
- 请求头必须包含 Bearer Token 格式的 Authorization
- 分页接口必须直接返回 TableDataInfo 格式(total、rows、code、msg)
- 非分页接口必须使用 R 类型包装返回结果
- 单条数据接口必须使用 R 类型包装返回结果
- 操作类接口必须使用 R 类型包装返回结果
- 必须包含 clientid、Content-Type 等必要请求头
- 查询类接口默认按创建时间倒序排列,若已有排序字段则在末尾追加
create_time DESC保证新增数据优先展示 - 所有列表查询接口默认按
create_time倒序排列;如接口自定义其他排序字段,必须在末尾追加create_time desc作为稳定排序项
📝 业务错误码
通用错误码
| 错误码 | 说明 | 解决方案 |
|---|---|---|
| 40001 | 参数校验失败 | 检查请求参数格式和必填字段 |
| 40002 | 数据不存在 | 检查资源 ID 是否正确 |
| 40003 | 权限不足 | 联系管理员分配权限 |
| 40004 | 操作失败 | 重试或联系技术支持 |
| 40005 | 数据冲突 | 检查数据是否重复 |
认证相关错误码
| 错误码 | 说明 | 解决方案 |
|---|---|---|
| 40101 | Token 无效 | 重新登录获取 Token |
| 40102 | Token 已过期 | 刷新 Token 或重新登录 |
| 40103 | 用户未登录 | 请先登录 |
| 40104 | 客户端 ID 异常 | 检查 clientId 配置 |
业务模块错误码
| 错误码 | 说明 | 解决方案 |
|---|---|---|
| 41001 | 物业报修相关错误 | 参考物业报修 API 文档 |
| 41002 | 满意度调查相关错误 | 参考满意度调查 API 文档 |
📚 数据字典
🎯 通用状态
| 值 | 说明 | 备注 |
|---|---|---|
| 0 | 停用 | 不可用状态 |
| 1 | 正常 | 可用状态 |
🎯 是否标识
| 值 | 说明 | 备注 |
|---|---|---|
| 0 | 否 | false |
| 1 | 是 | true |
🎯 删除标识
| 值 | 说明 | 备注 |
|---|---|---|
| 0 | 正常 | 未删除 |
| 1 | 删除 | 已删除 |
🎯 用户类型
| 值 | 说明 | 角色映射 |
|---|---|---|
| 1 | 学生 | student、学生、stu 等角色映射为此值 |
| 2 | 教师 | teacher、老师、教师、教职工、tea 等角色映射为此值 |
| 3 | 超级管理员 | admin、管理员、超级管理员、administrator 等角色映射为此值 |
⚙️ 开发配置说明
🔧 接口测试工具
推荐使用以下工具进行接口测试:
- Postman: 图形化接口测试工具
- Apifox: 国产 API 管理工具
- curl: 命令行工具
🔧 时间格式规范
所有时间字段统一使用以下格式:
- 数据库存储:
YYYY-MM-DD HH:mm:ss - API 传输:
ISO 8601格式YYYY-MM-DDTHH:mm:ss.sssZ
🔧 分页参数规范
所有分页接口统一使用以下参数:
pageNum: 页码,从 1 开始pageSize: 页大小,默认 10
🔧 安全传输规范
-
密码安全:
- BCrypt 哈希加密存储
- 登录失败次数限制
- 账户自动锁定机制
-
传输安全:
- AES+RSA 混合加密
- 防重放攻击保护
- HTTPS 协议传输
- 📌 前端请求头要求:
isEncrypt必须显式设置为字符串'true'才会触发前端 AES 加密逻辑(示例:headers: { isEncrypt: 'true' }),布尔true将被拦截器忽略,导致接口以明文发送。
-
会话安全:
- JWT Token 认证
- Token 自动过期机制
- 刷新 Token 机制
-
多租户安全:
- 租户隔离验证
- 客户端权限控制
- 不同设备类型支持
📞 联系方式
如有 API 相关问题,请联系开发团队或查看项目仓库的 Issues。
📝 维护: API 基础规范文档
🔄 更新: 2025-07-01
�� 文件: API 文档基础规范.md
UI 规范
主题色系统
- Web 端主题色: rgb(50, 20, 255)
- 变量定义: --art-primary
- 更新时间: 2025-07-05
Element Plus 主题定制
// Element Plus 主题色变量
--el-color-primary: rgb(var(--art-primary));
按钮样式规范
- 主要按钮: 使用主题色
- 次要按钮: 使用轮廓式设计
- 危险按钮: 使用错误色
- 禁用状态: 降低透明度
API接口基础规范(2025-07-01更新)
一、系统基础模块规范
1. 系统模块代码位置
所有涉及以下功能的API接口代码必须统一写在 ruoyi-system 工程中:
- 用户管理相关(SysUser)
- 组织机构相关(SysDept)
- 角色权限相关(SysRole)
- 菜单权限相关(SysMenu)
- 字典管理相关(SysDict)
- 系统配置相关(SysConfig)
- 租户管理相关(SysTenant)
代码组织结构
ruoyi-system/
├── src/main/java/org/dromara/system/
│ ├── controller/system/ # 控制器(注意是system子包)
│ ├── service/ # 服务接口
│ ├── service/impl/ # 服务实现
│ ├── mapper/ # 数据访问层
│ └── domain/ # 实体类和VO对象
2. 租户过滤规范
2.1 Controller层
@RestController
@RequestMapping("/system/xxx")
public class XxxController {
@GetMapping("/list")
public R<List<XxxVO>> list(@RequestParam(value = "tenantId", required = false) String tenantId) {
// 如果tenantId为空,会自动使用当前用户的租户ID
return R.ok(xxxService.selectXxxList(tenantId));
}
}
2.2 Service层
@Service
public class XxxServiceImpl implements IXxxService {
@Override
public List<XxxVO> selectXxxList(String tenantId) {
if (StringUtils.isEmpty(tenantId)) {
tenantId = SecurityUtils.getTenantId();
}
return baseMapper.selectXxxList(tenantId);
}
}
2.3 Mapper层
@Mapper
public interface XxxMapper {
@Select("""
SELECT
x.*
FROM xxx x
WHERE x.tenant_id = #{tenantId}
AND x.del_flag = '0'
ORDER BY x.create_time DESC
""")
List<Xxx> selectXxxList(@Param("tenantId") String tenantId);
}
3. 统一返回值规范
3.1 后端返回格式
// 统一返回格式
public class R<T> {
private int code; // 状态码
private String msg; // 消息
private T data; // 数据对象
}
// 分页返回格式
public class TableDataInfo<T> {
private int code; // 状态码
private String msg; // 消息
private List<T> data; // 数据对象
private long total; // 总记录数
}
3.2 前端获取数据规范
// 标准数据获取
const getList = async () => {
try {
const res = await listApi();
// 正确:从data字段获取数据
dataList.value = res.data || [];
} catch (error) {
console.error('获取数据失败:', error);
dataList.value = [];
}
};
// 分页数据获取
const getPageList = async (query: PageQuery) => {
try {
const res = await pageApi(query);
// 正确:从data字段获取列表数据
dataList.value = res.data || [];
// 获取总数
total.value = res.total || 0;
} catch (error) {
console.error('获取分页数据失败:', error);
dataList.value = [];
total.value = 0;
}
};
二、代码生成规范
1. 代码生成器配置
1.1 系统模块配置
- 当生成的代码涉及用户、组织、角色等基础功能时:
- 包名:
org.dromara.system - 模块名:
ruoyi-system - 表前缀:
sys_
- 包名:
1.2 租户字段配置
- 必须包含租户字段:
tenant_id - 字段类型:
varchar(20) - 默认值:
'000000' - 注释:
租户编号
2. 模板调整建议
2.1 Controller模板
@ApiOperation("查询${functionName}列表")
@SaCheckPermission("${permissionPrefix}:list")
@GetMapping("/list")
public R<List<${ClassName}VO>> list(${ClassName}BO bo) {
// 确保设置租户ID
if (StringUtils.isEmpty(bo.getTenantId())) {
bo.setTenantId(SecurityUtils.getTenantId());
}
return R.ok(${className}Service.queryList(bo));
}
2.2 Service模板
@Override
public List<${ClassName}VO> queryList(${ClassName}BO bo) {
// 租户过滤
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery();
lqw.eq(${ClassName}::getTenantId, bo.getTenantId());
// ... 其他查询条件
return baseMapper.selectVoList(lqw);
}
三、注意事项
1. 租户ID处理
- 前端可以选择性传入租户ID
- 如果未传入,后端使用当前用户的租户ID
- 禁止跨租户查询(除非特殊说明)
2. 返回值处理
- 前端统一从data字段获取数据
- 禁止使用rows或其他字段名
- 空值处理使用空数组或空对象
3. 系统模块开发
- 涉及基础功能必须在ruoyi-system中开发
- 保持代码结构统一
- 遵循权限命名规范
📝 维护说明:
- 更新时间:2025-07-01
- 更新人:wuzilong
- 基于实际项目开发经验总结
- 持续补充和优化
逻辑删除规范(2025-07-01更新)
- 所有删除操作必须为逻辑删除,禁止物理删除。
- 实体类需使用@TableLogic注解,deleted字段类型为Integer,0代表存在,1代表删除。
- 删除接口实际为将deleted字段置为1,数据不会被物理移除。
- 前端需在删除提示中明确“本操作为逻辑删除,数据不会被物理移除,可在后台恢复”。
- 参考示例:
@TableLogic
private Integer deleted; // 0-存在,1-删除
- 适用范围:所有业务表、VO、BO、API接口。