fix: 修复API接口规范和数据获取问题

1. 修复前端从res.rows改为res.data获取数据
2. 更新API接口基础规范文档:
   - 添加系统基础模块规范
   - 添加租户过滤规范
   - 统一返回值规范
   - 完善代码生成规范
This commit is contained in:
zlwu committed 2025-07-09 20:53:29 +08:00
1 parent 9b8e437c31
commit a4247ea901
2 files changed
+382 -33

No files matched your search

@@ -346,3 +346,196 @@
- 次要按钮: 使用轮廓式设计
- 危险按钮: 使用错误色
- 禁用状态: 降低透明度
# 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层
```java
@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层
```java
@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层
```java
@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 后端返回格式
```java
// 统一返回格式
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 前端获取数据规范
```typescript
// 标准数据获取
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模板
```java
@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模板
```java
@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
- 基于实际项目开发经验总结
- 持续补充和优化