docs: 新增完整的API接口文档

- 添加认证相关API文档(登录认证、验证码)
- 添加权限管理API文档(菜单管理、角色管理)
- 添加系统管理API文档(图片管理、文件管理、登录日志)
- 添加用户管理API文档
- 完善项目API文档结构,提升开发体验
This commit is contained in:
Leo 2025-07-06 00:54:47 +08:00
parent 83c7669c73
commit aea2b1fbd7
9 changed files with 6703 additions and 0 deletions

211
api/README.md Normal file
View File

@ -0,0 +1,211 @@
# Coder Common Thin Backend API 文档
## 项目概述
Coder Common Thin Backend 是一个基于Spring Boot 3.5.0的企业级开发框架,采用插件化架构设计,提供了完整的后台管理系统功能。
## 技术栈
- **后端框架**: Spring Boot 3.5.0 + Java 17
- **数据库**: MySQL 8 + MyBatis Plus 3.5.12
- **缓存**: Redis (Spring Data Redis)
- **安全认证**: Sa-Token 1.43.0
- **权限控制**: RBAC (Role-Based Access Control)
- **API文档**: OpenAPI 3.0 (Swagger)
- **工具库**: Hutool 5.8.38, Fastjson2 2.0.57, Guava 33.4.8
## 服务器信息
- **默认端口**: 18099
- **基础URL**: http://localhost:18099
- **API前缀**: /coder (除登录认证接口外)
## 认证方式
系统使用Sa-Token进行身份认证和权限管理
- **Token类型**: Bearer Token
- **Token位置**: 请求头 `Authorization` 字段
- **Token过期**: 支持自定义过期时间
- **权限验证**: 基于注解的权限验证
## 统一响应格式
所有接口均采用统一的JSON响应格式
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
// 具体数据
},
"traceId": "trace-id-value"
}
```
### 状态码说明
- **200**: 成功
- **400**: 请求参数错误
- **401**: 认证失败/未登录
- **403**: 权限不足
- **500**: 服务器内部错误
## 分页查询格式
分页查询请求参数:
```json
{
"pageNo": 1,
"pageSize": 10,
"params": {
// 查询参数
}
}
```
分页查询响应格式:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
// 数据记录
],
"total": 100,
"size": 10,
"current": 1,
"pages": 10,
"searchCount": true
},
"traceId": "trace-id-value"
}
```
## 权限系统
系统采用RBAC权限模型
- **用户 (User)**: 系统使用者
- **角色 (Role)**: 权限的集合
- **权限 (Permission)**: 具体的操作权限
- **菜单 (Menu)**: 系统菜单和按钮权限
### 权限验证流程
1. 用户登录获取Token
2. 请求接口时携带Token
3. 系统验证Token有效性
4. 根据用户角色验证权限
5. 允许或拒绝访问
## API模块分类
### 1. 认证模块 (Authentication)
- [登录认证API](./authentication/登录认证API)
- [验证码API](./authentication/验证码API)
### 2. 用户管理模块 (User Management)
- [用户管理API](./user/用户管理API)
### 3. 权限管理模块 (Permission Management)
- [菜单管理API](./permission/菜单管理API)
- [角色管理API](./permission/角色管理API)
### 4. 系统管理模块 (System Management)
- [文件管理API](./system/文件管理API)
- [图片管理API](./system/图片管理API)
- [登录日志API](./system/登录日志API)
## 错误处理
系统提供了完善的错误处理机制:
### 常见错误类型
1. **业务异常**: 自定义业务逻辑错误
2. **认证异常**: 登录认证相关错误
3. **权限异常**: 权限验证失败
4. **参数异常**: 请求参数验证失败
5. **系统异常**: 服务器内部错误
### 错误响应格式
```json
{
"status": 400,
"msg": "具体错误信息",
"data": null,
"traceId": "trace-id-value"
}
```
## 开发环境配置
### 数据库配置
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/coder_common_thin
username: root
password: your_password
```
### Redis配置
```yaml
spring:
redis:
host: localhost
port: 6379
password: your_password
```
### Sa-Token配置
```yaml
sa-token:
token-name: Authorization
timeout: 2592000
activity-timeout: -1
is-concurrent: true
is-share: false
is-read-head: true
is-read-cookie: false
```
## 接口调用示例
### 登录接口调用
```bash
curl -X POST \
http://localhost:18099/auth/login \
-H 'Content-Type: application/json' \
-d '{
"loginName": "admin",
"password": "123456",
"codeKey": "uuid-key",
"securityCode": "1234"
}'
```
### 携带Token调用接口
```bash
curl -X GET \
http://localhost:18099/coder/sysLoginUser/getLoginUserInformation \
-H 'Authorization: Bearer your-token-value'
```
## 注意事项
1. 所有接口都需要进行认证,除了登录接口和验证码接口
2. 权限验证基于角色和权限码进行
3. 系统支持多设备登录
4. 敏感操作会记录操作日志
5. 建议在生产环境中启用HTTPS
## 更新日志
- **v1.0.0** (2025-07-05): 初始版本发布
## 联系方式
如有问题,请联系开发团队。

View File

@ -0,0 +1,255 @@
# 登录认证API
## 概述
登录认证模块提供用户登录、退出、注册等功能使用Sa-Token进行身份认证和会话管理。
## 接口列表
### 1. 用户登录
**接口地址**: `POST /auth/login`
**接口描述**: 用户使用账号密码登录系统
**是否需要认证**: 否
**请求参数**:
```json
{
"loginName": "admin",
"password": "123456",
"codeKey": "uuid-key",
"securityCode": "1234",
"rememberMe": false
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| loginName | String | 是 | 登录账号 | 长度3-16位只能包含字母和数字 |
| password | String | 是 | 登录密码 | 不能为空 |
| codeKey | String | 是 | 验证码UUID | 不能为空 |
| securityCode | String | 是 | 验证码 | 不能为空 |
| rememberMe | Boolean | 否 | 记住登录 | 默认false |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"tokenName": "Authorization",
"tokenValue": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
},
"traceId": "trace-123456"
}
```
**响应参数说明**:
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tokenName | String | Token名称 |
| tokenValue | String | Token值 |
**错误码**:
| 状态码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 账号长度为 3-16 位 | 登录账号长度不符合要求 |
| 400 | 账号格式为数字以及字母 | 登录账号格式不正确 |
| 400 | 请输入登录名 | 登录名为空 |
| 400 | 请输入密码 | 密码为空 |
| 400 | 验证码已失效 | 验证码Key无效 |
| 400 | 请输入验证码 | 验证码为空 |
| 400 | 验证码错误 | 验证码不正确 |
| 400 | 用户不存在 | 用户账号不存在 |
| 400 | 密码错误 | 密码不正确 |
| 400 | 账号已被停用 | 用户账号被禁用 |
| 400 | 账号已被锁定 | 用户账号被锁定 |
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/auth/login \
-H 'Content-Type: application/json' \
-d '{
"loginName": "admin",
"password": "123456",
"codeKey": "550e8400-e29b-41d4-a716-446655440000",
"securityCode": "1234",
"rememberMe": false
}'
```
---
### 2. 用户退出
**接口地址**: `GET /auth/logout`
**接口描述**: 用户退出登录,清除会话信息
**是否需要认证**: 是
**请求头**:
```
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
```
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "退出成功",
"traceId": "trace-123456"
}
```
**错误码**:
| 状态码 | 错误信息 | 说明 |
|--------|----------|------|
| 401 | 当前会话未登录 | 用户未登录或Token无效 |
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/auth/logout \
-H 'Authorization: your-token-value'
```
---
### 3. 用户注册
**接口地址**: `POST /auth/register`
**接口描述**: 新用户注册账号
**是否需要认证**: 否
**请求参数**:
```json
{
"loginName": "newuser",
"password": "123456",
"userName": "新用户",
"codeKey": "uuid-key",
"securityCode": "1234"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| loginName | String | 是 | 登录账号 | 长度3-16位只能包含字母和数字 |
| password | String | 是 | 登录密码 | 不能为空 |
| userName | String | 是 | 用户姓名 | 不能为空 |
| codeKey | String | 是 | 验证码UUID | 不能为空 |
| securityCode | String | 是 | 验证码 | 不能为空 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "注册成功",
"traceId": "trace-123456"
}
```
**错误码**:
| 状态码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 账号长度为 3-16 位 | 登录账号长度不符合要求 |
| 400 | 账号格式为数字以及字母 | 登录账号格式不正确 |
| 400 | 请输入登录名 | 登录名为空 |
| 400 | 请输入密码 | 密码为空 |
| 400 | 请输入用户姓名 | 用户姓名为空 |
| 400 | 验证码已失效 | 验证码Key无效 |
| 400 | 请输入验证码 | 验证码为空 |
| 400 | 验证码错误 | 验证码不正确 |
| 400 | 账号已存在 | 登录账号已被注册 |
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/auth/register \
-H 'Content-Type: application/json' \
-d '{
"loginName": "newuser",
"password": "123456",
"userName": "新用户",
"codeKey": "550e8400-e29b-41d4-a716-446655440000",
"securityCode": "1234"
}'
```
---
## 认证流程说明
### 1. 登录流程
1. 用户获取验证码(调用验证码接口)
2. 用户输入账号、密码、验证码
3. 系统验证验证码有效性
4. 系统验证用户账号和密码
5. 系统检查用户状态(是否禁用/锁定)
6. 生成Token并返回给用户
7. 用户后续请求携带Token
### 2. Token使用
- Token需要在请求头中携带`Authorization: token-value`
- Token有过期时间过期后需要重新登录
- 系统支持多设备登录
- 管理员可以强制用户下线
### 3. 权限验证
- 登录后系统会根据用户角色加载权限
- 每个接口都会验证用户是否有相应权限
- 超级管理员拥有所有权限
### 4. 会话管理
- 用户登录信息存储在Redis中
- 支持会话延长
- 支持记住登录功能
- 系统会记录用户登录日志
## 安全特性
1. **密码加密**: 使用盐值加密存储密码
2. **验证码保护**: 防止暴力破解
3. **账号锁定**: 连续错误3次自动锁定
4. **IP限制**: 可配置IP白名单/黑名单
5. **会话安全**: Token有效期管理
6. **日志记录**: 记录所有登录操作
## 注意事项
1. 验证码有效期为5分钟
2. Token默认有效期为30天
3. 账号锁定时间为10分钟
4. 注册功能可通过配置开启/关闭
5. 建议在生产环境中启用HTTPS

View File

@ -0,0 +1,397 @@
# 验证码API
## 概述
验证码模块提供图形验证码生成功能支持PNG和GIF两种格式用于防止恶意攻击和机器人注册。
## 接口列表
### 1. 生成PNG验证码
**接口地址**: `GET /captcha/png`
**接口描述**: 生成PNG格式的图形验证码
**是否需要认证**: 否
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAkCAYAAAB...",
"captchaText": "1234"
},
"traceId": "trace-123456"
}
```
**响应参数说明**:
| 参数名 | 类型 | 说明 |
|--------|------|------|
| uuid | String | 验证码唯一标识,用于后续验证 |
| base64 | String | 验证码图片Base64编码 |
| captchaText | String | 验证码文本(开发环境返回,生产环境不返回) |
**特性说明**:
- 验证码长度4位数字
- 图片尺寸102x38像素
- 有效期5分钟
- 字体:随机字体
- 背景:随机背景色
- 干扰线:随机干扰线
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/captcha/png \
-H 'Content-Type: application/json'
```
**前端使用示例**:
```javascript
// 获取验证码
function getCaptcha() {
fetch('/captcha/png')
.then(response => response.json())
.then(data => {
if (data.status === 200) {
// 显示验证码图片
document.getElementById('captchaImg').src = data.data.base64;
// 保存验证码UUID用于登录时提交
document.getElementById('codeKey').value = data.data.uuid;
}
});
}
// 点击刷新验证码
document.getElementById('captchaImg').onclick = getCaptcha;
```
---
### 2. 生成GIF验证码
**接口地址**: `GET /captcha/gif`
**接口描述**: 生成GIF动画格式的图形验证码
**是否需要认证**: 否
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440001",
"base64": "data:image/gif;base64,R0lGODlhZgAyAPcAAAAAAP///wAAAP...",
"captchaText": "5678"
},
"traceId": "trace-123456"
}
```
**响应参数说明**:
| 参数名 | 类型 | 说明 |
|--------|------|------|
| uuid | String | 验证码唯一标识,用于后续验证 |
| base64 | String | 验证码图片Base64编码 |
| captchaText | String | 验证码文本(开发环境返回,生产环境不返回) |
**特性说明**:
- 验证码长度4位数字
- 图片尺寸102x38像素
- 有效期5分钟
- 动画效果:字符摆动动画
- 帧数10帧
- 动画速度100ms/帧
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/captcha/gif \
-H 'Content-Type: application/json'
```
**前端使用示例**:
```javascript
// 获取GIF验证码
function getGifCaptcha() {
fetch('/captcha/gif')
.then(response => response.json())
.then(data => {
if (data.status === 200) {
// 显示验证码图片
document.getElementById('captchaImg').src = data.data.base64;
// 保存验证码UUID用于登录时提交
document.getElementById('codeKey').value = data.data.uuid;
}
});
}
```
---
## 验证码配置
### 1. 验证码参数配置
```yaml
# application.yml
captcha:
# 验证码长度
length: 4
# 验证码宽度
width: 102
# 验证码高度
height: 38
# 验证码有效期(分钟)
timeout: 5
# 字体大小
font-size: 25
# 干扰线数量
line-count: 100
# 是否开启验证码
enabled: true
```
### 2. 验证码存储
- 验证码使用Redis存储
- Key格式`captcha:uuid`
- 过期时间5分钟自动删除
- 值存储:验证码文本(忽略大小写)
### 3. 验证码验证
```java
// 验证码验证逻辑
public boolean validateCaptcha(String uuid, String inputCode) {
// 从Redis获取验证码
String correctCode = redisTemplate.opsForValue().get("captcha:" + uuid);
if (correctCode == null) {
throw new BusinessException("验证码已过期");
}
// 不区分大小写验证
if (!correctCode.equalsIgnoreCase(inputCode)) {
throw new BusinessException("验证码错误");
}
// 验证成功后立即删除验证码(防止重复使用)
redisTemplate.delete("captcha:" + uuid);
return true;
}
```
---
## 安全特性
### 1. 防暴力破解
- 验证码一次性使用
- 验证后立即删除
- 5分钟自动过期
- 支持IP限制
### 2. 防机器识别
- 随机字体和颜色
- 随机背景和干扰线
- 字符位置随机偏移
- GIF动画增加识别难度
### 3. 防重放攻击
- 每次验证码都有唯一UUID
- 验证码使用后立即失效
- 不允许重复使用
## 错误处理
### 常见错误情况
| 错误场景 | 错误码 | 错误信息 |
|----------|--------|----------|
| 验证码过期 | 400 | 验证码已失效 |
| 验证码错误 | 400 | 验证码错误 |
| 验证码为空 | 400 | 请输入验证码 |
| UUID无效 | 400 | 验证码已失效 |
| 系统异常 | 500 | 验证码生成失败 |
### 错误响应示例
```json
{
"status": 400,
"msg": "验证码已失效",
"data": null,
"traceId": "trace-123456"
}
```
---
## 使用建议
### 1. 前端集成
```html
<!-- 验证码显示区域 -->
<div class="captcha-container">
<img id="captchaImg" src="" alt="验证码" onclick="refreshCaptcha()">
<input type="hidden" id="codeKey" value="">
<input type="text" id="securityCode" placeholder="请输入验证码">
<button type="button" onclick="refreshCaptcha()">刷新</button>
</div>
```
```javascript
// 初始化验证码
function initCaptcha() {
fetch('/captcha/png')
.then(response => response.json())
.then(data => {
if (data.status === 200) {
document.getElementById('captchaImg').src = data.data.base64;
document.getElementById('codeKey').value = data.data.uuid;
}
});
}
// 刷新验证码
function refreshCaptcha() {
initCaptcha();
}
// 页面加载时获取验证码
window.onload = initCaptcha;
```
### 2. 表单提交
```javascript
// 登录表单提交
function login() {
const formData = {
loginName: document.getElementById('loginName').value,
password: document.getElementById('password').value,
codeKey: document.getElementById('codeKey').value,
securityCode: document.getElementById('securityCode').value
};
fetch('/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.status === 200) {
// 登录成功
localStorage.setItem('token', data.data.tokenValue);
window.location.href = '/dashboard';
} else {
// 登录失败,刷新验证码
alert(data.msg);
refreshCaptcha();
}
});
}
```
### 3. 移动端适配
```css
/* 移动端验证码样式 */
@media (max-width: 768px) {
.captcha-container {
display: flex;
align-items: center;
gap: 10px;
}
#captchaImg {
width: 102px;
height: 38px;
cursor: pointer;
}
#securityCode {
width: 100px;
height: 38px;
}
}
```
## 性能优化
### 1. 缓存策略
- 验证码图片不缓存
- 验证码文本缓存5分钟
- 使用Redis集群提高性能
### 2. 并发控制
- 支持高并发验证码生成
- 每秒可生成1000+验证码
- 使用连接池管理Redis连接
### 3. 资源优化
- 图片大小优化小于2KB
- 内存使用优化
- 垃圾回收优化
## 监控和日志
### 1. 指标监控
- 验证码生成次数
- 验证码验证次数
- 验证码成功率
- 验证码过期率
### 2. 日志记录
- 验证码生成日志
- 验证码验证日志
- 异常错误日志
- 性能监控日志
### 3. 告警机制
- 验证码成功率过低告警
- 验证码生成异常告警
- Redis连接异常告警
## 注意事项
1. 生产环境不返回验证码文本
2. 验证码区分大小写(可配置)
3. 验证码只能使用一次
4. 建议定期清理过期验证码
5. 支持自定义验证码样式和难度

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,882 @@
# 角色管理API
## 概述
角色管理模块是权限系统的重要组成部分负责管理系统角色、角色权限分配和用户角色关联。基于RBAC权限模型实现了灵活的角色权限管理机制。
## 权限说明
角色管理接口需要相应的权限才能访问:
| 操作 | 权限码 | 说明 |
|------|--------|------|
| 查询角色列表 | `system:role:list` | 查看角色列表权限 |
| 新增角色 | `system:role:add` | 新增角色权限 |
| 修改角色 | `system:role:edit` | 修改角色信息权限 |
| 删除角色 | `system:role:remove` | 删除角色权限 |
| 分配权限 | `system:role:assign` | 分配角色权限 |
| 用户授权 | `system:user:role` | 分配用户角色权限 |
## 接口列表
### 1. 分页查询角色列表
**接口地址**: `GET /coder/sysRole/listPage`
**接口描述**: 分页查询系统角色列表
**是否需要认证**: 是
**权限要求**: `system:role:list`
**请求头**:
```
Authorization: your-token-value
```
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| pageNo | Integer | 否 | 页码 | 1 |
| pageSize | Integer | 否 | 每页大小 | 10 |
| roleName | String | 否 | 角色名称 | 管理员 |
| roleCode | String | 否 | 角色编码 | admin |
| roleStatus | String | 否 | 角色状态 | 0 |
| beginTime | String | 否 | 开始时间 | 2024-01-01 |
| endTime | String | 否 | 结束时间 | 2024-12-31 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
{
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin",
"roleStatus": "0",
"dataScope": "1",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 1,
"remark": "超级管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00",
"menuIds": [1, 2, 3, 4, 5],
"deptIds": [100, 101, 102]
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysRole/listPage?pageNo=1&pageSize=10&roleName=管理员" \
-H "Authorization: your-token-value"
```
---
### 2. 查询所有角色
**接口地址**: `GET /coder/sysRole/list`
**接口描述**: 查询所有系统角色(不分页)
**是否需要认证**: 是
**权限要求**: `system:role:list`
**请求参数**: 同分页查询除pageNo、pageSize外
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin",
"roleStatus": "0",
"dataScope": "1",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 1,
"remark": "超级管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00"
}
],
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysRole/list" \
-H "Authorization: your-token-value"
```
---
### 3. 根据ID查询角色
**接口地址**: `GET /coder/sysRole/getById/{id}`
**接口描述**: 根据角色ID查询角色详细信息
**是否需要认证**: 是
**权限要求**: `system:role:list`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 角色ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin",
"roleStatus": "0",
"dataScope": "1",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 1,
"remark": "超级管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00",
"menuIds": [1, 2, 3, 4, 5],
"deptIds": [100, 101, 102]
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysRole/getById/1 \
-H "Authorization: your-token-value"
```
---
### 4. 新增角色
**接口地址**: `POST /coder/sysRole/add`
**接口描述**: 新增系统角色
**是否需要认证**: 是
**权限要求**: `system:role:add`
**请求参数**:
```json
{
"roleName": "普通用户",
"roleCode": "user",
"roleStatus": "0",
"dataScope": "2",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 2,
"remark": "普通用户角色",
"menuIds": [1, 2, 3],
"deptIds": [100, 101]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| roleName | String | 是 | 角色名称 | 不能为空最长30字符 |
| roleCode | String | 是 | 角色编码 | 不能为空最长100字符唯一 |
| roleStatus | String | 是 | 角色状态 | 0-正常 1-停用 |
| dataScope | String | 否 | 数据范围 | 1-全部数据 2-自定义数据 3-本部门数据 4-本部门及以下数据 5-仅本人数据 |
| deptCheckStrictly | String | 否 | 部门树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 |
| menuCheckStrictly | String | 否 | 菜单树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 |
| sorted | Integer | 是 | 显示顺序 | 不能为空 |
| remark | String | 否 | 备注信息 | 最长200字符 |
| menuIds | Long[] | 否 | 菜单ID数组 | 有效的菜单ID |
| deptIds | Long[] | 否 | 部门ID数组 | 有效的部门ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysRole/add \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"roleName": "普通用户",
"roleCode": "user",
"roleStatus": "0",
"dataScope": "2",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 2,
"remark": "普通用户角色",
"menuIds": [1, 2, 3],
"deptIds": [100, 101]
}'
```
---
### 5. 获取最新排序号
**接口地址**: `GET /coder/sysRole/getSorted`
**接口描述**: 获取角色的最新排序号
**是否需要认证**: 是
**权限要求**: `system:role:add`
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": 10,
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysRole/getSorted \
-H "Authorization: your-token-value"
```
---
### 6. 修改角色信息
**接口地址**: `POST /coder/sysRole/update`
**接口描述**: 修改系统角色信息
**是否需要认证**: 是
**权限要求**: `system:role:edit`
**请求参数**:
```json
{
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin",
"roleStatus": "0",
"dataScope": "1",
"deptCheckStrictly": "1",
"menuCheckStrictly": "1",
"sorted": 1,
"remark": "超级管理员",
"menuIds": [1, 2, 3, 4, 5],
"deptIds": [100, 101, 102]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| roleId | Long | 是 | 角色ID | 必须是有效的角色ID |
| 其他参数 | - | - | 同新增角色 | - |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysRole/update \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin",
"roleStatus": "0",
"sorted": 1
}'
```
---
### 7. 删除角色
**接口地址**: `POST /coder/sysRole/deleteById/{id}`
**接口描述**: 根据ID删除角色
**是否需要认证**: 是
**权限要求**: `system:role:remove`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 角色ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysRole/deleteById/1 \
-H "Authorization: your-token-value"
```
---
### 8. 批量删除角色
**接口地址**: `POST /coder/sysRole/batchDelete`
**接口描述**: 批量删除角色
**是否需要认证**: 是
**权限要求**: `system:role:remove`
**请求参数**:
```json
{
"ids": [1, 2, 3]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | Long[] | 是 | 角色ID数组 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysRole/batchDelete \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"ids": [1, 2, 3]
}'
```
---
### 9. 修改角色状态
**接口地址**: `POST /coder/sysRole/updateStatus/{roleId}/{roleStatus}`
**接口描述**: 修改角色状态(正常/停用)
**是否需要认证**: 是
**权限要求**: `system:role:edit`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| roleId | Long | 是 | 角色ID |
| roleStatus | String | 是 | 角色状态0-正常 1-停用) |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysRole/updateStatus/1/0 \
-H "Authorization: your-token-value"
```
---
### 10. 查询正常角色穿梭框
**接口地址**: `GET /coder/sysRole/listNormalRole/{userId}`
**接口描述**: 查询正常状态的角色用于穿梭框显示
**是否需要认证**: 是
**权限要求**: `system:user:role`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| userId | Long | 是 | 用户ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"label": "超级管理员",
"value": 1,
"parentId": ""
},
{
"label": "普通用户",
"value": 2,
"parentId": ""
}
],
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysRole/listNormalRole/1 \
-H "Authorization: your-token-value"
```
---
### 11. 分配用户角色
**接口地址**: `GET /coder/sysRole/assignUserRole/{userId}/{roleIds}`
**接口描述**: 为用户分配角色
**是否需要认证**: 是
**权限要求**: `system:user:role`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| userId | Long | 是 | 用户ID |
| roleIds | String | 是 | 角色ID列表逗号分隔 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "分配成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysRole/assignUserRole/1/1,2,3 \
-H "Authorization: your-token-value"
```
---
### 12. 获取角色下拉框
**接口地址**: `GET /coder/sysRole/listRoleElSelect`
**接口描述**: 获取角色下拉框数据
**是否需要认证**: 是
**权限要求**: `system:role:list`
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"label": "超级管理员",
"value": 1
},
{
"label": "普通用户",
"value": 2
}
],
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysRole/listRoleElSelect \
-H "Authorization: your-token-value"
```
---
## 角色字段说明
### 基础字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| roleId | Long | 角色ID | 1 |
| roleName | String | 角色名称 | 超级管理员 |
| roleCode | String | 角色编码 | admin |
| roleStatus | String | 角色状态 | 0-正常 1-停用 |
| sorted | Integer | 显示顺序 | 1 |
| remark | String | 备注信息 | 超级管理员 |
### 权限字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| dataScope | String | 数据权限范围 | 1-全部数据 2-自定义数据 3-本部门数据 4-本部门及以下数据 5-仅本人数据 |
| deptCheckStrictly | String | 部门树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 |
| menuCheckStrictly | String | 菜单树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 |
### 关联字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| menuIds | Long[] | 菜单ID数组 | [1, 2, 3, 4, 5] |
| deptIds | Long[] | 部门ID数组 | [100, 101, 102] |
---
## 数据字典
### 角色状态 (roleStatus)
| 值 | 说明 |
|----|------|
| 0 | 正常 |
| 1 | 停用 |
### 数据权限范围 (dataScope)
| 值 | 说明 |
|----|------|
| 1 | 全部数据权限 |
| 2 | 自定数据权限 |
| 3 | 本部门数据权限 |
| 4 | 本部门及以下数据权限 |
| 5 | 仅本人数据权限 |
### 树选择项关联显示
| 值 | 说明 |
|----|------|
| 0 | 父子不互相关联显示 |
| 1 | 父子互相关联显示 |
---
## 权限验证机制
### 1. 角色权限验证
```java
// Sa-Token权限验证
@SaCheckPermission("system:role:list")
public List<SysRole> list() {
// 业务逻辑
}
```
### 2. 数据权限控制
```java
// 根据用户数据权限过滤数据
public List<SysRole> getRolesByDataScope(Long userId) {
SysUser user = getCurrentUser();
String dataScope = user.getDataScope();
switch (dataScope) {
case "1": // 全部数据权限
return getAllRoles();
case "2": // 自定义数据权限
return getRolesByDeptIds(user.getDeptIds());
case "3": // 本部门数据权限
return getRolesByDept(user.getDeptId());
case "4": // 本部门及以下数据权限
return getRolesByDeptAndChildren(user.getDeptId());
case "5": // 仅本人数据权限
return getRolesByUserId(userId);
default:
return new ArrayList<>();
}
}
```
### 3. 角色权限缓存
```java
// 缓存用户角色权限
@Cacheable(value = "userRoles", key = "#userId")
public List<String> getRolesByUserId(Long userId) {
return roleMapper.selectRolePermissionByUserId(userId);
}
// 清除角色权限缓存
@CacheEvict(value = "userRoles", key = "#userId")
public void clearUserRoleCache(Long userId) {
// 角色变更时清除缓存
}
```
---
## 错误码说明
| 错误码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 角色名称不能为空 | 角色名称为空 |
| 400 | 角色权限编码不能为空 | 角色编码为空 |
| 400 | 显示顺序不能为空 | 排序值为空 |
| 400 | 角色不存在 | 角色ID不存在 |
| 400 | 角色编码已存在 | 角色编码重复 |
| 400 | 角色已分配用户,不允许删除 | 角色已分配给用户时不能删除 |
| 400 | 不能删除超级管理员角色 | 超级管理员角色不能删除 |
| 400 | 不能停用超级管理员角色 | 超级管理员角色不能停用 |
| 400 | 用户不存在 | 用户ID不存在 |
| 400 | 角色ID列表不能为空 | 分配角色时角色ID为空 |
| 401 | 当前会话未登录 | 未登录或Token无效 |
| 403 | 权限不足 | 没有相应的操作权限 |
| 500 | 系统异常 | 服务器内部错误 |
---
## RBAC权限模型
### 1. 基本概念
- **用户 (User)**: 系统的使用者
- **角色 (Role)**: 权限的集合,连接用户和权限的桥梁
- **权限 (Permission)**: 对系统资源的操作权限
- **会话 (Session)**: 用户与系统的一次交互过程
### 2. 关系模型
```
用户 ←→ 用户角色关系 ←→ 角色 ←→ 角色权限关系 ←→ 权限
```
### 3. 数据库设计
```sql
-- 用户表
CREATE TABLE sys_login_user (
user_id BIGINT PRIMARY KEY,
login_name VARCHAR(32) UNIQUE NOT NULL,
user_name VARCHAR(32) NOT NULL,
-- 其他字段...
);
-- 角色表
CREATE TABLE sys_role (
role_id BIGINT PRIMARY KEY,
role_name VARCHAR(32) NOT NULL,
role_code VARCHAR(32) UNIQUE NOT NULL,
role_status CHAR(1) DEFAULT '0',
-- 其他字段...
);
-- 权限表(菜单表)
CREATE TABLE sys_menu (
menu_id BIGINT PRIMARY KEY,
menu_name VARCHAR(64) NOT NULL,
auth VARCHAR(128),
-- 其他字段...
);
-- 用户角色关联表
CREATE TABLE sys_user_role (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id)
);
-- 角色权限关联表
CREATE TABLE sys_role_menu (
role_id BIGINT NOT NULL,
menu_id BIGINT NOT NULL,
PRIMARY KEY (role_id, menu_id)
);
```
---
## 使用建议
### 1. 角色设计原则
- **最小权限原则**: 每个角色只分配必要的权限
- **职责分离**: 不同职责的操作分配给不同角色
- **角色层次**: 建立角色层次结构,高级角色继承低级角色权限
- **定期审查**: 定期审查角色权限,及时调整
### 2. 权限分配策略
- **默认无权限**: 新建角色默认无任何权限
- **逐步授权**: 根据业务需要逐步授权
- **权限组合**: 通过多个角色组合实现复杂权限需求
- **临时授权**: 支持临时权限授权机制
### 3. 数据权限控制
- **部门数据权限**: 基于用户所属部门控制数据访问范围
- **自定义数据权限**: 支持自定义数据访问范围
- **数据隔离**: 确保不同用户只能访问授权范围内的数据
- **审计日志**: 记录数据访问日志
### 4. 性能优化
- **权限缓存**: 将用户权限信息缓存到Redis
- **批量操作**: 支持批量分配和撤销权限
- **索引优化**: 对关联表建立合适的索引
- **分页查询**: 大数据量时使用分页查询
---
## 安全考虑
### 1. 权限验证
- **双重验证**: 前后端都要进行权限验证
- **接口鉴权**: 每个接口都要验证权限
- **数据鉴权**: 数据层面的权限验证
- **操作鉴权**: 敏感操作的二次验证
### 2. 权限变更
- **变更日志**: 记录所有权限变更操作
- **审批流程**: 重要权限变更需要审批
- **通知机制**: 权限变更及时通知相关人员
- **回滚机制**: 支持权限变更回滚
### 3. 会话安全
- **会话超时**: 设置会话超时时间
- **单点登录**: 防止重复登录
- **强制下线**: 支持强制用户下线
- **设备绑定**: 支持设备级别的访问控制
---
## 注意事项
1. **角色删除**: 删除角色前需要检查是否有用户关联
2. **权限继承**: 考虑角色之间的权限继承关系
3. **缓存一致性**: 角色权限变更后需要清理相关缓存
4. **数据完整性**: 保证角色权限数据的完整性
5. **超级管理员**: 超级管理员角色不能删除和停用
6. **权限验证**: 前后端都需要进行权限验证
7. **审计日志**: 记录所有角色操作日志
8. **性能考虑**: 大量用户时注意权限验证性能
9. **数据权限**: 正确配置数据权限范围
10. **定期清理**: 定期清理无效的角色和权限关联

View File

@ -0,0 +1,871 @@
# 图片管理API
## 概述
图片管理模块专门用于管理系统中的图片资源,提供图片的上传、存储、展示和管理功能。支持多种图片格式,具备图片压缩、水印、缩略图生成等高级功能。
## 权限说明
图片管理接口需要相应的权限才能访问:
| 操作 | 权限码 | 说明 |
|------|--------|------|
| 查询图片列表 | `system:picture:list` | 查看图片列表权限 |
| 上传图片 | `system:picture:upload` | 上传图片权限 |
| 删除图片 | `system:picture:remove` | 删除图片权限 |
| 编辑图片 | `system:picture:edit` | 编辑图片信息权限 |
## 接口列表
### 1. 分页查询图片列表
**接口地址**: `GET /coder/sysPicture/listPage`
**接口描述**: 分页查询系统图片列表
**是否需要认证**: 是
**权限要求**: `system:picture:list`
**请求头**:
```
Authorization: Bearer your-token-value
```
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| pageNo | Integer | 否 | 页码 | 1 |
| pageSize | Integer | 否 | 每页大小 | 10 |
| pictureName | String | 否 | 图片名称 | banner.jpg |
| pictureType | String | 否 | 图片类型 | jpg |
| albumName | String | 否 | 相册名称 | banner |
| pictureStatus | String | 否 | 图片状态 | 0 |
| beginTime | String | 否 | 开始时间 | 2024-01-01 |
| endTime | String | 否 | 结束时间 | 2024-12-31 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
{
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysPicture/listPage?pageNo=1&pageSize=10&albumName=banner" \
-H "Authorization: Bearer your-token-value"
```
---
### 2. 查询所有图片
**接口地址**: `GET /coder/sysPicture/list`
**接口描述**: 查询所有系统图片(不分页)
**是否需要认证**: 是
**权限要求**: `system:picture:list`
**请求参数**: 同分页查询除pageNo、pageSize外
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysPicture/list?albumName=banner" \
-H "Authorization: Bearer your-token-value"
```
---
### 3. 根据ID查询图片
**接口地址**: `GET /coder/sysPicture/getById/{id}`
**接口描述**: 根据图片ID查询图片详细信息
**是否需要认证**: 是
**权限要求**: `system:picture:list`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 图片ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"pictureId": 1,
"pictureName": "banner_20240705_001.jpg",
"originalName": "主页横幅.jpg",
"picturePath": "/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg",
"albumName": "banner",
"pictureSize": 2048000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1920,
"height": 1080,
"pictureStatus": "0",
"isWatermark": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "主页横幅图片",
"tags": "横幅,主页,展示",
"viewCount": 100,
"downloadCount": 10,
"remark": "网站主页横幅",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysPicture/getById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 4. 新增图片记录
**接口地址**: `POST /coder/sysPicture/add`
**接口描述**: 新增系统图片记录
**是否需要认证**: 是
**权限要求**: `system:picture:upload`
**请求参数**:
```json
{
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/thumb_product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"isWatermark": "1",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "产品展示图片",
"tags": "产品,展示,商品",
"remark": "商品详情页图片"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| pictureName | String | 是 | 存储图片名 | 不能为空 |
| originalName | String | 是 | 原始图片名 | 不能为空 |
| picturePath | String | 是 | 图片相对路径 | 不能为空 |
| pictureUrl | String | 是 | 图片访问URL | 不能为空 |
| thumbnailUrl | String | 否 | 缩略图URL | 可为空 |
| albumName | String | 是 | 相册名称 | 不能为空 |
| pictureSize | Long | 是 | 图片大小 | 必须大于0 |
| pictureType | String | 是 | 图片类型 | 不能为空 |
| pictureFormat | String | 是 | 图片格式 | 不能为空 |
| width | Integer | 否 | 图片宽度 | 大于0 |
| height | Integer | 否 | 图片高度 | 大于0 |
| pictureStatus | String | 是 | 图片状态 | 0-正常 1-删除 |
| isWatermark | String | 否 | 是否水印 | 0-否 1-是 |
| uploadUserId | Long | 否 | 上传用户ID | 有效的用户ID |
| uploadUserName | String | 否 | 上传用户名 | 可为空 |
| description | String | 否 | 图片描述 | 最长500字符 |
| tags | String | 否 | 图片标签 | 逗号分隔 |
| remark | String | 否 | 备注信息 | 最长200字符 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysPicture/add \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"description": "产品展示图片",
"tags": "产品,展示,商品"
}'
```
---
### 5. 修改图片信息
**接口地址**: `POST /coder/sysPicture/update`
**接口描述**: 修改系统图片记录信息
**是否需要认证**: 是
**权限要求**: `system:picture:edit`
**请求参数**:
```json
{
"pictureId": 1,
"pictureName": "product_20240705_001.jpg",
"originalName": "产品展示图.jpg",
"picturePath": "/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"pictureUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/product_20240705_001.jpg",
"thumbnailUrl": "http://localhost:18099/upload/pictures/product/2024/07/05/thumb_product_20240705_001.jpg",
"albumName": "product",
"pictureSize": 1536000,
"pictureType": "jpg",
"pictureFormat": "JPEG",
"width": 1200,
"height": 800,
"pictureStatus": "0",
"isWatermark": "1",
"uploadUserId": 1,
"uploadUserName": "admin",
"description": "产品展示图片(已更新)",
"tags": "产品,展示,商品,新品",
"remark": "商品详情页图片(已更新)"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| pictureId | Long | 是 | 图片ID | 必须是有效的图片ID |
| 其他参数 | - | - | 同新增图片记录 | - |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysPicture/update \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"pictureId": 1,
"description": "产品展示图片(已更新)",
"tags": "产品,展示,商品,新品"
}'
```
---
### 6. 删除图片
**接口地址**: `POST /coder/sysPicture/deleteById/{id}`
**接口描述**: 根据ID删除图片记录和物理文件
**是否需要认证**: 是
**权限要求**: `system:picture:remove`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 图片ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysPicture/deleteById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 7. 批量删除图片
**接口地址**: `POST /coder/sysPicture/batchDelete`
**接口描述**: 批量删除图片记录和物理文件
**是否需要认证**: 是
**权限要求**: `system:picture:remove`
**请求参数**:
```json
{
"ids": [1, 2, 3]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | Long[] | 是 | 图片ID数组 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysPicture/batchDelete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"ids": [1, 2, 3]
}'
```
---
## 图片字段说明
### 基础字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| pictureId | Long | 图片ID | 1 |
| pictureName | String | 存储图片名 | banner_20240705_001.jpg |
| originalName | String | 原始图片名 | 主页横幅.jpg |
| picturePath | String | 图片相对路径 | /upload/pictures/banner/2024/07/05/banner_20240705_001.jpg |
| pictureUrl | String | 图片访问URL | http://localhost:18099/upload/pictures/banner/2024/07/05/banner_20240705_001.jpg |
| thumbnailUrl | String | 缩略图URL | http://localhost:18099/upload/pictures/banner/2024/07/05/thumb_banner_20240705_001.jpg |
### 分类字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| albumName | String | 相册名称 | banner |
| pictureType | String | 图片扩展名 | jpg |
| pictureFormat | String | 图片格式 | JPEG |
| pictureSize | Long | 图片大小(字节) | 2048000 |
### 尺寸字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| width | Integer | 图片宽度(像素) | 1920 |
| height | Integer | 图片高度(像素) | 1080 |
### 状态字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| pictureStatus | String | 图片状态 | 0-正常 1-删除 |
| isWatermark | String | 是否有水印 | 0-否 1-是 |
| uploadUserId | Long | 上传用户ID | 1 |
| uploadUserName | String | 上传用户名 | admin |
### 描述字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| description | String | 图片描述 | 主页横幅图片 |
| tags | String | 图片标签 | 横幅,主页,展示 |
| remark | String | 备注信息 | 网站主页横幅 |
### 统计字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| viewCount | Integer | 查看次数 | 100 |
| downloadCount | Integer | 下载次数 | 10 |
---
## 数据字典
### 图片状态 (pictureStatus)
| 值 | 说明 |
|----|------|
| 0 | 正常 |
| 1 | 已删除 |
### 是否水印 (isWatermark)
| 值 | 说明 |
|----|------|
| 0 | 无水印 |
| 1 | 有水印 |
### 支持的图片格式
| 格式 | 扩展名 | MIME类型 | 说明 |
|------|--------|----------|------|
| JPEG | jpg, jpeg | image/jpeg | 有损压缩,适合照片 |
| PNG | png | image/png | 无损压缩,支持透明 |
| GIF | gif | image/gif | 支持动画 |
| WebP | webp | image/webp | 现代格式,压缩率高 |
| BMP | bmp | image/bmp | 位图格式 |
| TIFF | tiff, tif | image/tiff | 高质量图像 |
### 相册分类
| 相册名称 | 说明 | 用途 |
|----------|------|------|
| banner | 横幅图片 | 网站横幅展示 |
| product | 产品图片 | 商品展示 |
| avatar | 头像图片 | 用户头像 |
| gallery | 图库图片 | 相册展示 |
| article | 文章图片 | 文章配图 |
| icon | 图标图片 | 小图标 |
| background | 背景图片 | 页面背景 |
---
## 图片处理功能
### 1. 图片上传处理
```java
@Service
public class PictureUploadService {
/**
* 上传图片
*/
public PictureUploadResult uploadPicture(MultipartFile file, String album) {
// 1. 图片校验
validatePicture(file);
// 2. 生成文件名
String fileName = generatePictureName(file.getOriginalFilename());
// 3. 保存原图
String originalPath = savePicture(file, album, fileName);
// 4. 生成缩略图
String thumbnailPath = generateThumbnail(originalPath, album, fileName);
// 5. 添加水印
if (needWatermark(album)) {
addWatermark(originalPath);
}
// 6. 获取图片信息
BufferedImage image = ImageIO.read(new File(originalPath));
int width = image.getWidth();
int height = image.getHeight();
// 7. 生成访问URL
String pictureUrl = generatePictureUrl(album, fileName);
String thumbnailUrl = generateThumbnailUrl(album, fileName);
// 8. 返回结果
return PictureUploadResult.builder()
.pictureName(fileName)
.originalName(file.getOriginalFilename())
.picturePath(originalPath)
.pictureUrl(pictureUrl)
.thumbnailUrl(thumbnailUrl)
.pictureSize(file.getSize())
.pictureType(getFileExtension(fileName))
.pictureFormat(getImageFormat(file))
.width(width)
.height(height)
.build();
}
/**
* 生成缩略图
*/
private String generateThumbnail(String originalPath, String album, String fileName) {
try {
BufferedImage originalImage = ImageIO.read(new File(originalPath));
// 计算缩略图尺寸
int thumbnailWidth = 200;
int thumbnailHeight = 150;
// 保持宽高比
double ratio = Math.min((double) thumbnailWidth / originalImage.getWidth(),
(double) thumbnailHeight / originalImage.getHeight());
int width = (int) (originalImage.getWidth() * ratio);
int height = (int) (originalImage.getHeight() * ratio);
// 生成缩略图
BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = thumbnailImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(originalImage, 0, 0, width, height, null);
g2d.dispose();
// 保存缩略图
String thumbnailPath = getThumbnailPath(album, fileName);
ImageIO.write(thumbnailImage, "jpg", new File(thumbnailPath));
return thumbnailPath;
} catch (IOException e) {
throw new BusinessException("生成缩略图失败", e);
}
}
/**
* 添加水印
*/
private void addWatermark(String imagePath) {
try {
BufferedImage originalImage = ImageIO.read(new File(imagePath));
Graphics2D g2d = originalImage.createGraphics();
// 设置水印属性
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.setColor(Color.LIGHT_GRAY);
g2d.setFont(new Font("Arial", Font.BOLD, 20));
// 计算水印位置
FontMetrics fm = g2d.getFontMetrics();
String watermarkText = "© Your Company";
int x = originalImage.getWidth() - fm.stringWidth(watermarkText) - 10;
int y = originalImage.getHeight() - fm.getHeight() + fm.getAscent() - 10;
// 绘制水印
g2d.drawString(watermarkText, x, y);
g2d.dispose();
// 保存带水印的图片
ImageIO.write(originalImage, "jpg", new File(imagePath));
} catch (IOException e) {
throw new BusinessException("添加水印失败", e);
}
}
}
```
### 2. 图片压缩
```java
/**
* 图片压缩
*/
public void compressPicture(String inputPath, String outputPath, float quality) {
try {
BufferedImage image = ImageIO.read(new File(inputPath));
// 创建输出流
FileOutputStream fos = new FileOutputStream(outputPath);
// 获取JPEG写入器
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = writers.next();
// 设置输出
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
writer.setOutput(ios);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality); // 压缩质量 0.0-1.0
// 写入图片
writer.write(null, new IIOImage(image, null, null), param);
// 清理资源
ios.close();
fos.close();
writer.dispose();
} catch (IOException e) {
throw new BusinessException("图片压缩失败", e);
}
}
```
### 3. 图片格式转换
```java
/**
* 图片格式转换
*/
public void convertPictureFormat(String inputPath, String outputPath, String format) {
try {
BufferedImage image = ImageIO.read(new File(inputPath));
// 如果转换为JPEG需要处理透明背景
if ("jpg".equalsIgnoreCase(format) || "jpeg".equalsIgnoreCase(format)) {
BufferedImage jpegImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = jpegImage.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
image = jpegImage;
}
// 保存转换后的图片
ImageIO.write(image, format, new File(outputPath));
} catch (IOException e) {
throw new BusinessException("图片格式转换失败", e);
}
}
```
---
## 错误码说明
| 错误码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 图片不能为空 | 上传图片为空 |
| 400 | 图片大小不能超过{size}MB | 图片大小超过限制 |
| 400 | 不支持的图片格式 | 图片格式不支持 |
| 400 | 图片尺寸超过限制 | 图片宽高超过限制 |
| 400 | 图片名称不能为空 | 图片名称为空 |
| 400 | 相册名称不能为空 | 相册名称为空 |
| 400 | 图片不存在 | 图片ID不存在 |
| 400 | 图片已被删除 | 图片状态为已删除 |
| 401 | 当前会话未登录 | 未登录或Token无效 |
| 403 | 权限不足 | 没有相应的操作权限 |
| 500 | 图片上传失败 | 图片保存到磁盘失败 |
| 500 | 缩略图生成失败 | 缩略图生成过程失败 |
| 500 | 水印添加失败 | 水印添加过程失败 |
| 500 | 图片压缩失败 | 图片压缩过程失败 |
| 500 | 图片删除失败 | 物理文件删除失败 |
---
## 安全特性
### 1. 图片验证
- **格式验证**: 验证图片格式和MIME类型
- **尺寸验证**: 验证图片宽高限制
- **内容验证**: 验证图片内容安全性
- **病毒扫描**: 对上传图片进行病毒扫描
### 2. 访问控制
- **权限验证**: 验证用户访问权限
- **防盗链**: 防止图片被盗链
- **水印保护**: 添加水印保护版权
- **下载限制**: 限制图片下载次数
### 3. 存储安全
- **路径安全**: 防止路径遍历攻击
- **文件重命名**: 重命名避免冲突
- **备份策略**: 重要图片定期备份
- **权限设置**: 设置合适的文件权限
---
## 性能优化
### 1. 图片处理优化
- **异步处理**: 图片压缩和水印添加异步处理
- **批量处理**: 支持批量图片处理
- **缓存策略**: 缓存处理后的图片
- **CDN加速**: 使用CDN加速图片访问
### 2. 存储优化
- **分目录存储**: 按相册和日期分目录存储
- **格式优化**: 自动选择最优图片格式
- **压缩存储**: 自动压缩降低存储空间
- **重复检测**: 检测重复图片避免冗余
### 3. 访问优化
- **懒加载**: 图片懒加载技术
- **响应式图片**: 根据设备提供不同尺寸
- **WebP支持**: 支持WebP格式提高性能
- **预加载**: 关键图片预加载
---
## 使用建议
### 1. 图片命名规范
- **唯一性**: 确保图片名唯一
- **时间戳**: 包含时间戳信息
- **分类标识**: 包含相册分类信息
- **版本控制**: 支持图片版本管理
### 2. 相册管理
- **分类管理**: 按用途分类管理图片
- **权限控制**: 不同相册设置不同权限
- **容量限制**: 设置相册容量限制
- **定期清理**: 定期清理无用图片
### 3. 图片优化
- **尺寸适配**: 根据用途选择合适尺寸
- **格式选择**: 根据内容选择最优格式
- **质量平衡**: 平衡图片质量和文件大小
- **缓存策略**: 设置合适的缓存时间
---
## 注意事项
1. **图片安全**: 严格验证上传图片格式和内容
2. **版权保护**: 添加水印保护图片版权
3. **存储管理**: 定期清理无效和重复图片
4. **性能考虑**: 大图片上传时注意性能影响
5. **备份策略**: 重要图片需要备份
6. **访问控制**: 合理设置图片访问权限
7. **格式支持**: 根据需要支持不同图片格式
8. **缩略图**: 为提高加载速度生成缩略图
9. **压缩处理**: 适当压缩减少存储空间
10. **监控告警**: 监控存储空间和访问异常

View File

@ -0,0 +1,867 @@
# 文件管理API
## 概述
文件管理模块提供文件上传、下载、存储管理等功能。支持多种文件类型,提供文件记录管理和批量操作功能。分为通用文件上传接口和系统文件记录管理两部分。
## 权限说明
文件管理接口需要相应的权限才能访问:
| 操作 | 权限码 | 说明 |
|------|--------|------|
| 查询文件列表 | `system:file:list` | 查看文件列表权限 |
| 上传文件 | `system:file:upload` | 上传文件权限 |
| 下载文件 | `system:file:download` | 下载文件权限 |
| 删除文件 | `system:file:remove` | 删除文件权限 |
## 文件上传接口
### 1. 上传文件(需认证)
**接口地址**: `POST /coder/file/uploadFile/{fileSize}/{folderName}/{fileParam}`
**接口描述**: 上传文件到服务器(需要登录认证)
**是否需要认证**: 是
**权限要求**: `system:file:upload`
**请求头**:
```
Authorization: Bearer your-token-value
Content-Type: multipart/form-data
```
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| fileSize | Integer | 是 | 文件大小限制MB | 10 |
| folderName | String | 是 | 存储文件夹名称 | avatar |
| fileParam | String | 是 | 文件参数名 | file |
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| file | File | 是 | 上传的文件 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"fileName": "avatar.jpg",
"originalName": "my-avatar.jpg",
"filePath": "/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"fileUrl": "http://localhost:18099/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"fileSize": 1024000,
"fileType": "jpg",
"uploadTime": "2024-07-05 10:00:00"
},
"traceId": "trace-123456"
}
```
**响应参数说明**:
| 参数名 | 类型 | 说明 |
|--------|------|------|
| fileName | String | 存储文件名 |
| originalName | String | 原始文件名 |
| filePath | String | 文件相对路径 |
| fileUrl | String | 文件访问URL |
| fileSize | Long | 文件大小(字节) |
| fileType | String | 文件类型 |
| uploadTime | String | 上传时间 |
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/file/uploadFile/10/avatar/file \
-H "Authorization: Bearer your-token-value" \
-F "file=@avatar.jpg"
```
**前端使用示例**:
```javascript
// 使用FormData上传文件
function uploadFile(file, folder, maxSize) {
const formData = new FormData();
formData.append('file', file);
fetch(`/coder/file/uploadFile/${maxSize}/${folder}/file`, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
body: formData
})
.then(response => response.json())
.then(data => {
if (data.status === 200) {
console.log('上传成功:', data.data.fileUrl);
} else {
console.error('上传失败:', data.msg);
}
});
}
```
---
### 2. 匿名上传文件
**接口地址**: `POST /coder/file/uploadAnyFile/{fileSize}/{folderName}/{fileParam}`
**接口描述**: 匿名上传文件到服务器(无需登录认证)
**是否需要认证**: 否
**权限要求**: 无
**路径参数**: 同上传文件接口
**请求参数**: 同上传文件接口
**响应示例**: 同上传文件接口
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/file/uploadAnyFile/5/temp/file \
-F "file=@document.pdf"
```
**使用场景**:
- 用户注册时上传头像
- 访客上传临时文件
- 公开资源上传
---
## 系统文件记录管理接口
### 1. 分页查询文件列表
**接口地址**: `GET /coder/sysFile/listPage`
**接口描述**: 分页查询系统文件记录列表
**是否需要认证**: 是
**权限要求**: `system:file:list`
**请求头**:
```
Authorization: Bearer your-token-value
```
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| pageNo | Integer | 否 | 页码 | 1 |
| pageSize | Integer | 否 | 每页大小 | 10 |
| fileName | String | 否 | 文件名称 | avatar.jpg |
| fileType | String | 否 | 文件类型 | jpg |
| folderName | String | 否 | 文件夹名称 | avatar |
| beginTime | String | 否 | 开始时间 | 2024-01-01 |
| endTime | String | 否 | 结束时间 | 2024-12-31 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
{
"fileId": 1,
"fileName": "avatar_20240705_001.jpg",
"originalName": "my-avatar.jpg",
"filePath": "/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"fileUrl": "http://localhost:18099/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"folderName": "avatar",
"fileSize": 1024000,
"fileType": "jpg",
"contentType": "image/jpeg",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "用户头像",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysFile/listPage?pageNo=1&pageSize=10&fileName=avatar" \
-H "Authorization: Bearer your-token-value"
```
---
### 2. 查询所有文件
**接口地址**: `GET /coder/sysFile/list`
**接口描述**: 查询所有系统文件记录(不分页)
**是否需要认证**: 是
**权限要求**: `system:file:list`
**请求参数**: 同分页查询除pageNo、pageSize外
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"fileId": 1,
"fileName": "avatar_20240705_001.jpg",
"originalName": "my-avatar.jpg",
"filePath": "/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"fileUrl": "http://localhost:18099/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"folderName": "avatar",
"fileSize": 1024000,
"fileType": "jpg",
"contentType": "image/jpeg",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "用户头像",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
}
],
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysFile/list?fileType=jpg" \
-H "Authorization: Bearer your-token-value"
```
---
### 3. 根据ID查询文件
**接口地址**: `GET /coder/sysFile/getById/{id}`
**接口描述**: 根据文件ID查询文件详细信息
**是否需要认证**: 是
**权限要求**: `system:file:list`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 文件ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"fileId": 1,
"fileName": "avatar_20240705_001.jpg",
"originalName": "my-avatar.jpg",
"filePath": "/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"fileUrl": "http://localhost:18099/upload/avatar/2024/07/05/avatar_20240705_001.jpg",
"folderName": "avatar",
"fileSize": 1024000,
"fileType": "jpg",
"contentType": "image/jpeg",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "用户头像",
"createBy": "admin",
"createTime": "2024-07-05 10:00:00",
"updateBy": "admin",
"updateTime": "2024-07-05 10:00:00"
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysFile/getById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 4. 新增文件记录
**接口地址**: `POST /coder/sysFile/add`
**接口描述**: 新增系统文件记录
**是否需要认证**: 是
**权限要求**: `system:file:upload`
**请求参数**:
```json
{
"fileName": "document_20240705_001.pdf",
"originalName": "重要文档.pdf",
"filePath": "/upload/documents/2024/07/05/document_20240705_001.pdf",
"fileUrl": "http://localhost:18099/upload/documents/2024/07/05/document_20240705_001.pdf",
"folderName": "documents",
"fileSize": 2048000,
"fileType": "pdf",
"contentType": "application/pdf",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "重要文档"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| fileName | String | 是 | 存储文件名 | 不能为空 |
| originalName | String | 是 | 原始文件名 | 不能为空 |
| filePath | String | 是 | 文件相对路径 | 不能为空 |
| fileUrl | String | 是 | 文件访问URL | 不能为空 |
| folderName | String | 是 | 文件夹名称 | 不能为空 |
| fileSize | Long | 是 | 文件大小 | 必须大于0 |
| fileType | String | 是 | 文件类型 | 不能为空 |
| contentType | String | 是 | MIME类型 | 不能为空 |
| fileStatus | String | 是 | 文件状态 | 0-正常 1-删除 |
| uploadUserId | Long | 否 | 上传用户ID | 有效的用户ID |
| uploadUserName | String | 否 | 上传用户名 | 可为空 |
| remark | String | 否 | 备注信息 | 最长200字符 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysFile/add \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"fileName": "document_20240705_001.pdf",
"originalName": "重要文档.pdf",
"filePath": "/upload/documents/2024/07/05/document_20240705_001.pdf",
"fileUrl": "http://localhost:18099/upload/documents/2024/07/05/document_20240705_001.pdf",
"folderName": "documents",
"fileSize": 2048000,
"fileType": "pdf",
"contentType": "application/pdf",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "重要文档"
}'
```
---
### 5. 修改文件信息
**接口地址**: `POST /coder/sysFile/update`
**接口描述**: 修改系统文件记录信息
**是否需要认证**: 是
**权限要求**: `system:file:edit`
**请求参数**:
```json
{
"fileId": 1,
"fileName": "document_20240705_001.pdf",
"originalName": "重要文档.pdf",
"filePath": "/upload/documents/2024/07/05/document_20240705_001.pdf",
"fileUrl": "http://localhost:18099/upload/documents/2024/07/05/document_20240705_001.pdf",
"folderName": "documents",
"fileSize": 2048000,
"fileType": "pdf",
"contentType": "application/pdf",
"fileStatus": "0",
"uploadUserId": 1,
"uploadUserName": "admin",
"remark": "重要文档(已更新)"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| fileId | Long | 是 | 文件ID | 必须是有效的文件ID |
| 其他参数 | - | - | 同新增文件记录 | - |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysFile/update \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"fileId": 1,
"fileName": "document_20240705_001.pdf",
"originalName": "重要文档.pdf",
"remark": "重要文档(已更新)"
}'
```
---
### 6. 删除文件
**接口地址**: `POST /coder/sysFile/deleteById/{id}`
**接口描述**: 根据ID删除文件记录和物理文件
**是否需要认证**: 是
**权限要求**: `system:file:remove`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 文件ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysFile/deleteById/1 \
-H "Authorization: Bearer your-token-value"
```
---
### 7. 批量删除文件
**接口地址**: `POST /coder/sysFile/batchDelete`
**接口描述**: 批量删除文件记录和物理文件
**是否需要认证**: 是
**权限要求**: `system:file:remove`
**请求参数**:
```json
{
"ids": [1, 2, 3]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | Long[] | 是 | 文件ID数组 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysFile/batchDelete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-value" \
-d '{
"ids": [1, 2, 3]
}'
```
---
## 文件字段说明
### 基础字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| fileId | Long | 文件ID | 1 |
| fileName | String | 存储文件名 | avatar_20240705_001.jpg |
| originalName | String | 原始文件名 | my-avatar.jpg |
| filePath | String | 文件相对路径 | /upload/avatar/2024/07/05/avatar_20240705_001.jpg |
| fileUrl | String | 文件访问URL | http://localhost:18099/upload/avatar/2024/07/05/avatar_20240705_001.jpg |
### 分类字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| folderName | String | 文件夹名称 | avatar |
| fileType | String | 文件扩展名 | jpg |
| contentType | String | MIME类型 | image/jpeg |
| fileSize | Long | 文件大小(字节) | 1024000 |
### 状态字段
| 字段名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| fileStatus | String | 文件状态 | 0-正常 1-删除 |
| uploadUserId | Long | 上传用户ID | 1 |
| uploadUserName | String | 上传用户名 | admin |
| remark | String | 备注信息 | 用户头像 |
---
## 数据字典
### 文件状态 (fileStatus)
| 值 | 说明 |
|----|------|
| 0 | 正常 |
| 1 | 已删除 |
### 常见文件类型
| 文件类型 | 扩展名 | MIME类型 | 说明 |
|----------|--------|----------|------|
| 图片 | jpg, jpeg, png, gif, bmp | image/* | 图片文件 |
| 文档 | pdf, doc, docx, xls, xlsx, ppt, pptx | application/* | 办公文档 |
| 音频 | mp3, wav, flac, aac | audio/* | 音频文件 |
| 视频 | mp4, avi, mov, wmv | video/* | 视频文件 |
| 压缩包 | zip, rar, 7z, tar, gz | application/* | 压缩文件 |
| 文本 | txt, md, csv | text/* | 文本文件 |
---
## 文件配置
### 1. 文件存储配置
```yaml
# application-dev.yml
coder:
# 文件存储路径
filePath: /data/upload/
# 文件访问域名
domain: http://localhost:18099
# 文件大小限制MB
maxFileSize: 100
# 允许的文件类型
allowedTypes:
- jpg
- jpeg
- png
- gif
- pdf
- doc
- docx
- xls
- xlsx
# 禁止的文件类型
forbiddenTypes:
- exe
- bat
- sh
- jsp
- php
```
### 2. 文件夹分类
```java
// 文件夹类型枚举
public enum FolderType {
AVATAR("avatar", "用户头像"),
DOCUMENT("document", "文档文件"),
IMAGE("image", "图片文件"),
TEMP("temp", "临时文件"),
EXPORT("export", "导出文件");
private final String code;
private final String name;
}
```
### 3. 文件上传工具类
```java
@Component
public class FileUploadUtil {
/**
* 上传文件
*/
public FileUploadResult uploadFile(MultipartFile file, String folder, int maxSize) {
// 1. 文件校验
validateFile(file, maxSize);
// 2. 生成文件名
String fileName = generateFileName(file.getOriginalFilename());
// 3. 创建目录
String datePath = DateUtil.format(new Date(), "yyyy/MM/dd");
String dirPath = filePath + folder + "/" + datePath + "/";
FileUtil.createDirs(dirPath);
// 4. 保存文件
String filePath = dirPath + fileName;
file.transferTo(new File(filePath));
// 5. 生成访问URL
String fileUrl = domain + "/upload/" + folder + "/" + datePath + "/" + fileName;
// 6. 返回结果
return FileUploadResult.builder()
.fileName(fileName)
.originalName(file.getOriginalFilename())
.filePath(filePath)
.fileUrl(fileUrl)
.fileSize(file.getSize())
.fileType(FileUtil.getExtension(fileName))
.uploadTime(new Date())
.build();
}
/**
* 文件校验
*/
private void validateFile(MultipartFile file, int maxSize) {
if (file.isEmpty()) {
throw new BusinessException("文件不能为空");
}
if (file.getSize() > maxSize * 1024 * 1024) {
throw new BusinessException("文件大小不能超过" + maxSize + "MB");
}
String extension = FileUtil.getExtension(file.getOriginalFilename());
if (!allowedTypes.contains(extension.toLowerCase())) {
throw new BusinessException("不支持的文件类型:" + extension);
}
if (forbiddenTypes.contains(extension.toLowerCase())) {
throw new BusinessException("禁止上传的文件类型:" + extension);
}
}
/**
* 生成文件名
*/
private String generateFileName(String originalName) {
String extension = FileUtil.getExtension(originalName);
String baseName = FileUtil.getBaseName(originalName);
String timestamp = DateUtil.format(new Date(), "yyyyMMdd_HHmmss");
String random = RandomUtil.randomString(3);
return baseName + "_" + timestamp + "_" + random + "." + extension;
}
}
```
---
## 错误码说明
| 错误码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 文件不能为空 | 上传文件为空 |
| 400 | 文件大小不能超过{size}MB | 文件大小超过限制 |
| 400 | 不支持的文件类型 | 文件类型不在允许列表中 |
| 400 | 禁止上传的文件类型 | 文件类型在禁止列表中 |
| 400 | 文件名不能为空 | 文件名为空 |
| 400 | 文件路径不能为空 | 文件路径为空 |
| 400 | 文件不存在 | 文件ID不存在 |
| 400 | 文件已被删除 | 文件状态为已删除 |
| 401 | 当前会话未登录 | 未登录或Token无效 |
| 403 | 权限不足 | 没有相应的操作权限 |
| 500 | 文件上传失败 | 文件保存到磁盘失败 |
| 500 | 文件删除失败 | 物理文件删除失败 |
| 500 | 磁盘空间不足 | 服务器磁盘空间不足 |
---
## 安全特性
### 1. 文件类型验证
- **扩展名校验**: 验证文件扩展名
- **MIME类型校验**: 验证文件MIME类型
- **文件内容校验**: 验证文件真实类型
- **黑名单过滤**: 禁止上传危险文件类型
### 2. 文件大小限制
- **单文件大小限制**: 限制单个文件大小
- **总文件大小限制**: 限制用户总文件大小
- **磁盘空间检查**: 检查服务器磁盘空间
### 3. 访问控制
- **权限验证**: 验证用户上传和访问权限
- **路径防护**: 防止路径遍历攻击
- **防盗链**: 防止文件被盗链
### 4. 病毒扫描
- **文件扫描**: 上传文件病毒扫描
- **隔离机制**: 可疑文件隔离处理
- **定期扫描**: 定期扫描存储文件
---
## 性能优化
### 1. 文件存储
- **分目录存储**: 按日期和类型分目录存储
- **CDN加速**: 使用CDN加速文件访问
- **压缩存储**: 自动压缩图片文件
- **缓存策略**: 设置合适的缓存策略
### 2. 上传优化
- **分片上传**: 大文件分片上传
- **断点续传**: 支持断点续传功能
- **并发上传**: 支持多文件并发上传
- **进度显示**: 实时显示上传进度
### 3. 存储优化
- **重复文件检测**: 检测并避免重复文件
- **文件压缩**: 自动压缩文件
- **定期清理**: 清理临时文件和无效文件
- **存储监控**: 监控存储空间使用情况
---
## 使用建议
### 1. 文件命名规范
- **唯一性**: 确保文件名唯一
- **时间戳**: 包含时间戳信息
- **随机性**: 添加随机字符
- **可读性**: 保持一定的可读性
### 2. 文件分类管理
- **按类型分类**: 不同类型文件存储在不同目录
- **按用户分类**: 不同用户文件分开存储
- **按时间分类**: 按年月日创建目录结构
- **按业务分类**: 按业务模块分类存储
### 3. 安全防护
- **输入验证**: 严格验证上传文件
- **权限控制**: 细粒度的权限控制
- **日志记录**: 记录所有文件操作
- **备份策略**: 重要文件定期备份
### 4. 监控告警
- **存储监控**: 监控存储空间使用
- **性能监控**: 监控上传下载性能
- **安全监控**: 监控异常文件操作
- **容量告警**: 存储空间不足告警
---
## 注意事项
1. **文件安全**: 严格验证上传文件类型和内容
2. **存储路径**: 确保文件存储路径安全
3. **权限控制**: 合理设置文件访问权限
4. **磁盘空间**: 定期清理无效文件,避免磁盘满
5. **备份策略**: 重要文件需要备份
6. **访问控制**: 防止文件被恶意访问
7. **性能考虑**: 大文件上传时注意性能影响
8. **并发控制**: 处理并发上传时的文件冲突
9. **错误处理**: 完善的错误处理和回滚机制
10. **日志审计**: 记录所有文件操作日志

File diff suppressed because it is too large Load Diff

888
api/user/用户管理API.md Normal file
View File

@ -0,0 +1,888 @@
# 用户管理API
## 概述
用户管理模块提供系统用户的增删改查功能,包括用户信息管理、状态控制、密码管理、角色分配等核心功能。
## 权限说明
用户管理接口需要相应的权限才能访问:
| 操作 | 权限码 | 说明 |
|------|--------|------|
| 查询用户列表 | `system:user:list` | 查看用户列表权限 |
| 新增用户 | `system:user:add` | 新增用户权限 |
| 修改用户 | `system:user:edit` | 修改用户信息权限 |
| 删除用户 | `system:user:remove` | 删除用户权限 |
| 重置密码 | `system:user:resetPwd` | 重置用户密码权限 |
| 修改状态 | `system:user:status` | 修改用户状态权限 |
| 分配角色 | `system:user:role` | 分配用户角色权限 |
| 导入用户 | `system:user:import` | 导入用户数据权限 |
| 导出用户 | `system:user:export` | 导出用户数据权限 |
## 接口列表
### 1. 分页查询用户列表
**接口地址**: `GET /coder/sysLoginUser/listPage`
**接口描述**: 分页查询系统用户列表
**是否需要认证**: 是
**权限要求**: `system:user:list`
**请求头**:
```
Authorization: your-token-value
```
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| pageNo | Integer | 否 | 页码 | 1 |
| pageSize | Integer | 否 | 每页大小 | 10 |
| loginName | String | 否 | 登录账号 | admin |
| userName | String | 否 | 用户姓名 | 管理员 |
| userType | String | 否 | 用户类型 | 1 |
| phone | String | 否 | 手机号码 | 13800138000 |
| sex | String | 否 | 用户性别 | 1 |
| userStatus | String | 否 | 用户状态 | 0 |
| beginTime | String | 否 | 开始时间 | 2024-01-01 |
| endTime | String | 否 | 结束时间 | 2024-12-31 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"records": [
{
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"userType": "1",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"userStatus": "0",
"loginIp": "127.0.0.1",
"loginTime": "2024-01-01 10:00:00",
"pwdUpdateTime": "2024-01-01 10:00:00",
"remark": "系统管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00",
"roleIds": [1, 2]
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysLoginUser/listPage?pageNo=1&pageSize=10&loginName=admin" \
-H "Authorization: your-token-value"
```
---
### 2. 查询所有用户
**接口地址**: `GET /coder/sysLoginUser/list`
**接口描述**: 查询所有系统用户(不分页)
**是否需要认证**: 是
**权限要求**: `system:user:list`
**请求参数**: 同分页查询除pageNo、pageSize外
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": [
{
"userId": 1,
"loginName": "admin",
"userName": "管理员",
// 其他字段...
}
],
"traceId": "trace-123456"
}
```
---
### 3. 根据ID查询用户
**接口地址**: `GET /coder/sysLoginUser/getById/{id}`
**接口描述**: 根据用户ID查询用户详细信息
**是否需要认证**: 是
**权限要求**: `system:user:list`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 用户ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"userType": "1",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"userStatus": "0",
"loginIp": "127.0.0.1",
"loginTime": "2024-01-01 10:00:00",
"pwdUpdateTime": "2024-01-01 10:00:00",
"remark": "系统管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00",
"roleIds": [1, 2]
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysLoginUser/getById/1 \
-H "Authorization: your-token-value"
```
---
### 4. 新增用户
**接口地址**: `POST /coder/sysLoginUser/add`
**接口描述**: 新增系统用户
**是否需要认证**: 是
**权限要求**: `system:user:add`
**请求参数**:
```json
{
"loginName": "newuser",
"userName": "新用户",
"password": "123456",
"userType": "1",
"email": "newuser@example.com",
"phone": "13800138001",
"sex": "1",
"userStatus": "0",
"remark": "新用户备注",
"roleIds": [2]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| loginName | String | 是 | 登录账号 | 3-16位字母数字 |
| userName | String | 是 | 用户姓名 | 不能为空 |
| password | String | 是 | 登录密码 | 不能为空 |
| userType | String | 是 | 用户类型 | 1-系统用户 2-注册用户 |
| email | String | 否 | 邮箱地址 | 邮箱格式验证 |
| phone | String | 否 | 手机号码 | 手机号格式验证 |
| sex | String | 否 | 用户性别 | 1-男 2-女 3-未知 |
| userStatus | String | 是 | 用户状态 | 0-启用 1-停用 |
| remark | String | 否 | 备注信息 | 最长200字符 |
| roleIds | Long[] | 否 | 角色ID数组 | 有效的角色ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "新增成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/add \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"loginName": "newuser",
"userName": "新用户",
"password": "123456",
"userType": "1",
"email": "newuser@example.com",
"phone": "13800138001",
"sex": "1",
"userStatus": "0",
"remark": "新用户备注",
"roleIds": [2]
}'
```
---
### 5. 修改用户信息
**接口地址**: `POST /coder/sysLoginUser/update`
**接口描述**: 修改系统用户信息
**是否需要认证**: 是
**权限要求**: `system:user:edit`
**请求参数**:
```json
{
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"userType": "1",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"userStatus": "0",
"remark": "系统管理员",
"roleIds": [1, 2]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| userId | Long | 是 | 用户ID | 必须是有效的用户ID |
| loginName | String | 是 | 登录账号 | 3-16位字母数字 |
| userName | String | 是 | 用户姓名 | 不能为空 |
| userType | String | 是 | 用户类型 | 1-系统用户 2-注册用户 |
| email | String | 否 | 邮箱地址 | 邮箱格式验证 |
| phone | String | 否 | 手机号码 | 手机号格式验证 |
| sex | String | 否 | 用户性别 | 1-男 2-女 3-未知 |
| userStatus | String | 是 | 用户状态 | 0-启用 1-停用 |
| remark | String | 否 | 备注信息 | 最长200字符 |
| roleIds | Long[] | 否 | 角色ID数组 | 有效的角色ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/update \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"userType": "1",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"userStatus": "0",
"remark": "系统管理员",
"roleIds": [1, 2]
}'
```
---
### 6. 删除用户
**接口地址**: `POST /coder/sysLoginUser/deleteById/{id}`
**接口描述**: 根据ID删除用户
**是否需要认证**: 是
**权限要求**: `system:user:remove`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 用户ID |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/deleteById/1 \
-H "Authorization: your-token-value"
```
---
### 7. 批量删除用户
**接口地址**: `POST /coder/sysLoginUser/batchDelete`
**接口描述**: 批量删除用户
**是否需要认证**: 是
**权限要求**: `system:user:remove`
**请求参数**:
```json
{
"ids": [1, 2, 3]
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | Long[] | 是 | 用户ID数组 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "删除成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/batchDelete \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"ids": [1, 2, 3]
}'
```
---
### 8. 修改用户状态
**接口地址**: `POST /coder/sysLoginUser/updateStatus/{userId}/{userStatus}`
**接口描述**: 修改用户状态(启用/停用)
**是否需要认证**: 是
**权限要求**: `system:user:status`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| userId | Long | 是 | 用户ID |
| userStatus | String | 是 | 用户状态0-启用 1-停用) |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/updateStatus/1/0 \
-H "Authorization: your-token-value"
```
---
### 9. 获取登录用户信息
**接口地址**: `GET /coder/sysLoginUser/getLoginUserInformation`
**接口描述**: 获取当前登录用户的详细信息
**是否需要认证**: 是
**权限要求**: 无(已登录用户可访问)
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"userType": "1",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"userStatus": "0",
"loginIp": "127.0.0.1",
"loginTime": "2024-01-01 10:00:00",
"pwdUpdateTime": "2024-01-01 10:00:00",
"remark": "系统管理员",
"createBy": "admin",
"createTime": "2024-01-01 10:00:00",
"updateBy": "admin",
"updateTime": "2024-01-01 10:00:00",
"roleIds": [1, 2],
"roles": [
{
"roleId": 1,
"roleName": "超级管理员",
"roleCode": "admin"
}
],
"permissions": [
"*:*:*"
]
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysLoginUser/getLoginUserInformation \
-H "Authorization: your-token-value"
```
---
### 10. 获取个人资料
**接口地址**: `GET /coder/sysLoginUser/getPersonalData`
**接口描述**: 获取当前用户的个人资料
**是否需要认证**: 是
**权限要求**: 无(已登录用户可访问)
**请求参数**: 无
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"userId": 1,
"loginName": "admin",
"userName": "管理员",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"remark": "系统管理员"
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysLoginUser/getPersonalData \
-H "Authorization: your-token-value"
```
---
### 11. 修改个人资料
**接口地址**: `POST /coder/sysLoginUser/updateBasicData`
**接口描述**: 修改当前用户的个人资料
**是否需要认证**: 是
**权限要求**: 无(已登录用户可访问)
**请求参数**:
```json
{
"userName": "管理员",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"remark": "系统管理员"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| userName | String | 是 | 用户姓名 | 不能为空 |
| email | String | 否 | 邮箱地址 | 邮箱格式验证 |
| phone | String | 否 | 手机号码 | 手机号格式验证 |
| sex | String | 否 | 用户性别 | 1-男 2-女 3-未知 |
| avatar | String | 否 | 头像地址 | 有效的文件路径 |
| remark | String | 否 | 备注信息 | 最长200字符 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/updateBasicData \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"userName": "管理员",
"email": "admin@example.com",
"phone": "13800138000",
"sex": "1",
"avatar": "/upload/avatar/admin.jpg",
"remark": "系统管理员"
}'
```
---
### 12. 修改登录密码
**接口地址**: `POST /coder/sysLoginUser/updateUserPwd`
**接口描述**: 修改当前用户的登录密码
**是否需要认证**: 是
**权限要求**: 无(已登录用户可访问)
**请求参数**:
```json
{
"oldPassword": "123456",
"newPassword": "654321",
"confirmPassword": "654321"
}
```
**请求参数说明**:
| 参数名 | 类型 | 必填 | 说明 | 校验规则 |
|--------|------|------|------|----------|
| oldPassword | String | 是 | 原密码 | 不能为空 |
| newPassword | String | 是 | 新密码 | 不能为空 |
| confirmPassword | String | 是 | 确认密码 | 必须与新密码一致 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "修改成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/updateUserPwd \
-H "Content-Type: application/json" \
-H "Authorization: your-token-value" \
-d '{
"oldPassword": "123456",
"newPassword": "654321",
"confirmPassword": "654321"
}'
```
---
### 13. 重置用户密码
**接口地址**: `POST /coder/sysLoginUser/resetPwd/{id}/{password}`
**接口描述**: 重置指定用户的密码
**是否需要认证**: 是
**权限要求**: `system:user:resetPwd`
**路径参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 用户ID |
| password | String | 是 | 新密码 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": "重置成功",
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/resetPwd/1/123456 \
-H "Authorization: your-token-value"
```
---
### 14. 下载用户导入模板
**接口地址**: `GET /coder/sysLoginUser/downloadExcelTemplate`
**接口描述**: 下载用户批量导入的Excel模板
**是否需要认证**: 是
**权限要求**: `system:user:import`
**请求参数**: 无
**响应**: Excel文件下载
**调用示例**:
```bash
curl -X GET \
http://localhost:18099/coder/sysLoginUser/downloadExcelTemplate \
-H "Authorization: your-token-value" \
-o user_template.xlsx
```
---
### 15. 导出用户数据
**接口地址**: `GET /coder/sysLoginUser/exportExcelData`
**接口描述**: 导出用户数据到Excel
**是否需要认证**: 是
**权限要求**: `system:user:export`
**请求参数**: 同查询参数
**响应**: Excel文件下载
**调用示例**:
```bash
curl -X GET \
"http://localhost:18099/coder/sysLoginUser/exportExcelData?userStatus=0" \
-H "Authorization: your-token-value" \
-o users.xlsx
```
---
### 16. 导入用户数据
**接口地址**: `POST /coder/sysLoginUser/importExcelData`
**接口描述**: 从Excel文件导入用户数据
**是否需要认证**: 是
**权限要求**: `system:user:import`
**请求参数**: 文件上传
**Content-Type**: `multipart/form-data`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| file | File | 是 | Excel文件 |
| updateSupport | Boolean | 否 | 是否更新已存在的用户 |
**响应示例**:
```json
{
"status": 200,
"msg": "SUCCESS",
"data": {
"total": 100,
"success": 95,
"failed": 5,
"message": "导入成功95条失败5条"
},
"traceId": "trace-123456"
}
```
**调用示例**:
```bash
curl -X POST \
http://localhost:18099/coder/sysLoginUser/importExcelData \
-H "Authorization: your-token-value" \
-F "file=@users.xlsx" \
-F "updateSupport=true"
```
---
## 数据字典
### 用户类型 (userType)
| 值 | 说明 |
|----|------|
| 1 | 系统用户 |
| 2 | 注册用户 |
| 3 | 微信用户 |
### 用户性别 (sex)
| 值 | 说明 |
|----|------|
| 1 | 男 |
| 2 | 女 |
| 3 | 未知 |
### 用户状态 (userStatus)
| 值 | 说明 |
|----|------|
| 0 | 启用 |
| 1 | 停用 |
---
## 错误码说明
| 错误码 | 错误信息 | 说明 |
|--------|----------|------|
| 400 | 账号长度为 3-16 位 | 登录账号长度不符合要求 |
| 400 | 账号格式为数字以及字母 | 登录账号格式不正确 |
| 400 | 登录账号不能为空 | 登录账号为空 |
| 400 | 用户真实姓名不能为空 | 用户姓名为空 |
| 400 | 用户不存在 | 用户ID不存在 |
| 400 | 账号已存在 | 登录账号已被使用 |
| 400 | 手机号已存在 | 手机号已被使用 |
| 400 | 邮箱已存在 | 邮箱已被使用 |
| 400 | 不能删除当前用户 | 不能删除自己的账号 |
| 400 | 不能停用当前用户 | 不能停用自己的账号 |
| 400 | 原密码错误 | 修改密码时原密码不正确 |
| 400 | 新密码不能与原密码相同 | 新密码与原密码一致 |
| 400 | 两次输入的密码不一致 | 确认密码与新密码不一致 |
| 401 | 当前会话未登录 | 未登录或Token无效 |
| 403 | 权限不足 | 没有相应的操作权限 |
| 500 | 系统异常 | 服务器内部错误 |
---
## 注意事项
1. **权限验证**: 所有用户管理操作都需要相应的权限
2. **数据校验**: 新增和修改用户时会进行数据格式校验
3. **唯一性约束**: 登录账号、手机号、邮箱必须唯一
4. **密码安全**: 密码使用盐值加密存储
5. **操作日志**: 所有用户操作都会记录日志
6. **批量操作**: 批量删除时会跳过超级管理员账号
7. **Excel导入**: 支持Excel模板导入用户数据
8. **角色关联**: 用户删除时会自动删除角色关联关系
9. **会话管理**: 用户状态变更时会影响其登录会话
10. **数据完整性**: 删除用户前会检查关联数据