解决API文档和路由配置合并冲突
This commit is contained in:
commit
79a96a7dfd
662 files changed
+127608
-205195
No files matched your search
@@ -6,7 +6,18 @@
|
||||
|
||||
请参考 [API文档基础规范](./API文档基础规范.md) 了解通用的API调用规范、认证方式和响应格式。
|
||||
|
||||
<<<<<<< HEAD
|
||||
## API模块列表
|
||||
=======
|
||||
- [学生信息管理API](./学生信息管理API.md)
|
||||
- [学生信息收集批次管理API](./学生信息收集批次管理API.md)
|
||||
- [班级信息管理API](./班级信息管理API.md)
|
||||
- [班级干部信息管理API](./班级干部信息管理API.md)
|
||||
- [宿舍管理API](./宿舍管理API.md)
|
||||
- [宿舍管理员信息API](./宿舍管理员信息API.md)
|
||||
- [宿舍管理员授权API](./宿舍管理员授权API.md)
|
||||
- [学生管理员授权关系API](./学生管理员授权关系API.md)
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
### 1. 用户认证登录
|
||||
|
||||
@@ -30,7 +41,34 @@
|
||||
|
||||
[心理健康测评API](./心理健康测评API.md) - 包含测评问卷管理、测评结果分析等接口。
|
||||
|
||||
<<<<<<< HEAD
|
||||
### 4. 统计报表
|
||||
=======
|
||||
## 宿舍管理员信息API
|
||||
|
||||
- [宿舍管理员信息API](./宿舍管理员信息API.md):包含宿舍管理员信息的增删改查接口
|
||||
- 支持不同类型宿舍管理员(全校管理员、自定义管理员、班主任)的管理
|
||||
- 提供获取可用教职工信息的接口,支持选择教职工作为宿舍管理员
|
||||
- **新增功能**: 在添加管理员时,通过下拉选择可用教师,支持模糊搜索,并自动填充选中教师的手机号码和性别信息
|
||||
|
||||
**核心功能**:
|
||||
- 宿舍管理员信息分页查询(支持多条件搜索)
|
||||
- 宿舍管理员信息新增、修改、删除
|
||||
- 宿舍管理员信息导出
|
||||
- 获取可用教职工信息列表(排除已经成为指定类型管理员的人员)
|
||||
- 教师选择下拉搜索组件,支持模糊搜索和自动填充数据
|
||||
|
||||
**API基础路径**: `/xgStudentManager/studentManager`
|
||||
|
||||
**最新更新**:
|
||||
- 2025-07-25: 优化管理员添加界面,将姓名输入框改为可搜索的下拉选择框,选择后自动填充教师信息
|
||||
- 2025-07-24: 完成宿舍管理员信息管理模块的API接口设计
|
||||
- 2025-07-24: 添加获取可用的教职工信息列表接口,支持根据管理员类型筛选可用教职工
|
||||
|
||||
**详细文档**: [宿舍管理员信息API.md](./宿舍管理员信息API.md)
|
||||
|
||||
## 企业信息管理API
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
[统计报表API](./统计报表API.md) - 包含各类统计数据查询接口。
|
||||
|
||||
@@ -51,8 +89,59 @@
|
||||
|
||||
## 更新历史
|
||||
|
||||
<<<<<<< HEAD
|
||||
| 日期 | 版本 | 更新内容 | 更新人 |
|
||||
|------|------|---------|-------|
|
||||
| 2025-07-01 | 1.0 | 初始版本 | 系统管理员 |
|
||||
| 2025-07-15 | 1.1 | 添加心理健康测评API | 张工 |
|
||||
| 2025-07-30 | 1.2 | 添加预约限制功能API | Cursor |
|
||||
=======
|
||||
**详细文档**: [企业信息管理API.md](./企业信息管理API.md)
|
||||
|
||||
- [获取当前正在教学的班主任信息](/docs/开发文档/API/宿舍管理员信息API.md#获取当前正在教学的班主任信息)
|
||||
|
||||
---
|
||||
|
||||
## �� 最新更新日志
|
||||
|
||||
### 2025-01-27 - 新增班级学生查询接口
|
||||
- **新增功能**: 新增 `GET /studentMsg/studentMsg/listByClassId` 接口
|
||||
- **功能描述**: 查询指定班级中所有在籍学生信息
|
||||
- **过滤条件**:
|
||||
- `deleted = 0` (未删除)
|
||||
- `student_status = '1'` (在籍状态)
|
||||
- `class_id = 入参的classId` (班级ID)
|
||||
- `name LIKE '%入参的name%'` (姓名模糊查询,可选)
|
||||
- **排序方式**: 按创建时间倒序排列
|
||||
- **权限要求**: `studentMsg:studentMsg:query`
|
||||
|
||||
### 2025-07-24 - 学生信息管理界面重构
|
||||
- **界面重构**: 学生信息管理新增弹窗调整为多tab页形式
|
||||
- **功能增强**: 新增照片上传功能,支持完整的学生信息录入
|
||||
- **数据扩展**: 支持60+个学生信息字段,包括:
|
||||
- 基础信息: 学号、身份证号、姓名、性别、出生日期、民族、籍贯、政治面貌、照片等
|
||||
- 扩展信息: 文化程度、户口类型、宗教信仰、生源地区、紧急联系人、特殊情况标记等
|
||||
- 家庭信息: 父母信息、监护人信息、家庭经济状况等
|
||||
- 健康信息: 身高、体重、血型、健康状况、疾病史、过敏史等
|
||||
- 学籍信息: 录取类别、学籍状态、入学信息、专业班级、宿舍信息等
|
||||
- 银行卡信息: 银行卡号、开户银行等
|
||||
- **技术改进**: 使用el-tabs组件管理多个表单页面,提升用户体验
|
||||
|
||||
### 2025-07-01 - API文档架构重构
|
||||
- **重要重构**: 将原本集中的大型API文档按业务模块拆分,提升维护效率
|
||||
- **新增**: API文档模板,用于新API文档的生成
|
||||
- **优化**: 目录结构,按功能模块分类管理
|
||||
|
||||
## 🔗 API文档导航
|
||||
|
||||
### 👥 学工管理模块
|
||||
|
||||
| API文档 | 描述 | 状态 | 更新时间 |
|
||||
|---------|------|------|----------|
|
||||
| [学生信息收集批次管理API](./学生信息收集批次管理API.md) | 学生信息收集批次班级权限管理 | ✅ 完成 | 2025-01-27 |
|
||||
| [学生信息批次收集API](./学生信息批次收集API.md) | 学生信息批次收集管理(新增) | ✅ 完成 | 2025-01-27 |
|
||||
| [班级信息管理API](./班级信息管理API.md) | 班级基础信息增删改查 | ✅ 完成 | 2025-01-27 |
|
||||
| [班级干部信息管理API](./班级干部信息管理API.md) | 班级干部信息管理(含用户角色关联) | ✅ 完成 | 2025-01-27 |
|
||||
| [班干部管理API](./班干部管理API.md) | 班级干部职务管理 | ✅ 完成 | 2025-01-27 |
|
||||
| [班级教师关联管理API](./班级教师关联管理API.md) | 班主任辅导员关联关系 | ✅ 完成 | 2025-01-27 |
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
@@ -42,7 +42,7 @@
|
||||
| studentNo | string | 否 | 学号 |
|
||||
| name | string | 否 | 姓名(模糊查询) |
|
||||
| idCard | string | 否 | 身份证号 |
|
||||
| gender | string | 否 | 性别:M-男,F-女 |
|
||||
| gender | string | 否 | 性别:0-男,1-女 |
|
||||
| studentStatus | string | 否 | 学籍状态 |
|
||||
| enrollmentYear | integer | 否 | 入学年份 |
|
||||
| majorCode | string | 否 | 专业代码 |
|
||||
|
||||
@@ -0,0 +1,838 @@
|
||||
# 学生信息批次收集API文档
|
||||
|
||||
## 📋 文档信息
|
||||
|
||||
| 项目 | 信息 |
|
||||
|------|------|
|
||||
| **项目名称** | 校园管理系统 - 学生信息批次收集 |
|
||||
| **API模块** | 学生信息批次收集管理 |
|
||||
| **文档版本** | V1.0.0 |
|
||||
| **创建时间** | 2025-01-27 |
|
||||
| **基础路径** | `/studentMsgBatch/studentMsgBatch` |
|
||||
|
||||
## 🎯 API概述
|
||||
|
||||
### 模块说明
|
||||
学生信息批次收集系统提供学生信息收集、查询、历史记录管理等API接口,支持学生提交个人信息、管理员查询和审核学生信息等功能。
|
||||
|
||||
### 技术规范
|
||||
- **认证方式**: Bearer Token (Sa-Token)
|
||||
- **数据格式**: JSON
|
||||
- **响应格式**: 统一使用R类型或TableDataInfo分页格式
|
||||
- **权限控制**: 基于角色的权限管理(RBAC)
|
||||
|
||||
### 权限角色
|
||||
- **学生**: 查看和提交个人信息
|
||||
- **班主任**: 查看所带班级学生信息
|
||||
- **学工管理员**: 查看权限范围内的学生信息
|
||||
- **系统管理员**: 完整的学生信息管理权限
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 学生信息批次VO (XgStudentMsgBatchVo)
|
||||
|
||||
```java
|
||||
{
|
||||
"id": 1, // 主键ID(雪花ID)
|
||||
"deleted": 0, // 删除标志(0存在 1删除)
|
||||
"studentNo": "2025001", // 学号
|
||||
"idCard": "110101199901011234", // 身份证号
|
||||
"name": "张三", // 姓名
|
||||
"nameEnglish": "Zhang San", // 英文姓名
|
||||
"formerName": "", // 曾用名
|
||||
"gender": "0", // 性别(0-男,1-女)
|
||||
"birthDate": "1999-01-01", // 出生日期
|
||||
"nationality": "汉族", // 民族
|
||||
"nativePlace": "北京市", // 籍贯
|
||||
"politicalStatus": "团员", // 政治面貌
|
||||
"hukouLocation": "北京市海淀区", // 户籍所在地
|
||||
"homeAddress": "北京市海淀区中关村南大街1号", // 家庭地址
|
||||
"currentAddress": "北京市海淀区学院路8号", // 现住址
|
||||
"postalCode": "100081", // 邮政编码
|
||||
"photoUrl": "http://example.com/photo.jpg", // 照片URL
|
||||
"photoPath": "/upload/photo/2025/01/photo.jpg", // 照片存储路径
|
||||
"phone": "13800138000", // 手机号码
|
||||
"isBoarder": 1, // 是否住校(0-否,1-是)
|
||||
"educationLevel": "本科", // 文化程度
|
||||
"householdRegisterType": "城镇", // 户口类型
|
||||
"religion": "无", // 宗教信仰
|
||||
"sourceRegion": "北京市", // 生源地区
|
||||
"graduateSchool": "北京市第一中学", // 毕业院校
|
||||
"email": "zhangsan@example.com", // 电子邮箱
|
||||
"qq": "123456789", // QQ号码
|
||||
"wechat": "zhangsan_wx", // 微信号
|
||||
"maritalStatus": "1", // 婚姻状况(1未婚 2已婚 3离异 4丧偶)
|
||||
"emergencyContactName": "张父亲", // 紧急联系人姓名
|
||||
"emergencyContactPhone": "13900139000", // 紧急联系人电话
|
||||
"emergencyContactRelation": "父亲", // 紧急联系人关系
|
||||
"isPoorStudent": 0, // 是否贫困生(0-否,1-是)
|
||||
"isMinority": 0, // 是否少数民族(0-否,1-是)
|
||||
"isDisabled": 0, // 是否残疾(0-否,1-是)
|
||||
"isOrphan": 0, // 是否孤儿(0-否,1-是)
|
||||
"isLeftBehindChild": 0, // 是否留守儿童(0-否,1-是)
|
||||
"isSingleChild": 1, // 是否独生子女(0-否,1-是)
|
||||
"isLowIncome": 0, // 是否低保(0-否,1-是)
|
||||
"hasLoan": 0, // 是否有助学贷款(0-否,1-是)
|
||||
"loanAmount": 0.0, // 助学贷款金额
|
||||
"specialties": "篮球、编程", // 特长爱好
|
||||
"awards": "三好学生", // 获奖情况
|
||||
"violations": "", // 违纪记录
|
||||
"socialActivities": "志愿服务活动", // 社会活动
|
||||
"fatherName": "张父亲", // 父亲姓名
|
||||
"fatherPhone": "13900139001", // 父亲电话
|
||||
"fatherWorkUnit": "北京某公司", // 父亲工作单位
|
||||
"motherName": "张母亲", // 母亲姓名
|
||||
"motherPhone": "13900139002", // 母亲电话
|
||||
"motherWorkUnit": "北京某事业单位", // 母亲工作单位
|
||||
"guardianName": "张父亲", // 监护人姓名
|
||||
"guardianPhone": "13900139001", // 监护人电话
|
||||
"guardianRelation": "父亲", // 监护人关系
|
||||
"familyIncome": 100000.0, // 家庭年收入
|
||||
"perCapitaIncome": 33333.33, // 人均收入
|
||||
"incomeSource": "工资收入", // 收入来源
|
||||
"familyEconomicStatus": "一般", // 家庭经济状况
|
||||
"familyMembers": 3, // 家庭成员数量
|
||||
"height": 175.5, // 身高(cm)
|
||||
"weight": 65.0, // 体重(kg)
|
||||
"bloodType": "A", // 血型
|
||||
"healthStatus": "健康", // 健康状况
|
||||
"specialCondition": "", // 特殊体质或疾病
|
||||
"medicalHistory": "", // 病史
|
||||
"allergies": "", // 过敏史
|
||||
"disabilityType": "", // 残疾类型
|
||||
"disabilityLevel": "", // 残疾等级
|
||||
"admissionCategory": "统招", // 录取类别
|
||||
"studentStatus": "1", // 学籍状态(1在籍 2休学 3复学 4退学 5毕业)
|
||||
"enrollmentYear": 2025, // 入学年份
|
||||
"enrollmentDate": "2025-09-01", // 入学日期
|
||||
"bankCardNo": "6222081234567890123", // 银行卡号
|
||||
"bankName": "中国工商银行", // 开户银行
|
||||
"bankBranch": "北京中关村支行", // 开户支行
|
||||
"cardHolderName": "张三", // 持卡人姓名
|
||||
"infoStatus": "3", // 信息状态(1正常 2待审核 3审核中 4已驳回 5已锁定)
|
||||
"dataSource": "manual", // 数据来源(manual手工录入 import批量导入 sync系统同步)
|
||||
"lastBatchId": 1, // 最后修改批次ID
|
||||
"lastAuditTime": "2025-01-27 10:00:00", // 最后审核时间
|
||||
"isComplete": 1, // 信息是否完整(0不完整 1完整)
|
||||
"completionRate": 95.5, // 完整度百分比
|
||||
"schoolSystem": 4, // 学制(年)
|
||||
"academicLevel": "本科", // 学历层次
|
||||
"trainingType": "全日制", // 培养方式
|
||||
"majorId": "10001", // 专业ID
|
||||
"majorName": "计算机科学与技术", // 专业名称
|
||||
"classId": "20250101", // 班级ID
|
||||
"className": "计算机2025-1班", // 班级名称
|
||||
"grade": "2025", // 年级
|
||||
"collegeId": "1001", // 学院ID
|
||||
"collegeName": "计算机学院", // 学院名称
|
||||
"counselorId": 1001, // 辅导员ID
|
||||
"counselorName": "李辅导员", // 辅导员姓名
|
||||
"classTeacherId": 1002, // 班主任ID
|
||||
"classTeacherName": "王老师", // 班主任姓名
|
||||
"dormitoryBuilding": "1号楼", // 宿舍楼栋
|
||||
"dormitoryRoom": "101", // 宿舍房间号
|
||||
"extField1": "", // 扩展字段1
|
||||
"extField2": "", // 扩展字段2
|
||||
"extField3": "", // 扩展字段3
|
||||
"extField4": "", // 扩展字段4
|
||||
"extField5": "", // 扩展字段5
|
||||
"remark": "备注信息", // 备注信息
|
||||
"batchId": 1, // 正在进行中的批次ID
|
||||
"createBy": 1, // 创建者
|
||||
"createTime": "2025-01-27 10:00:00", // 创建时间
|
||||
"updateBy": 1, // 更新者
|
||||
"updateTime": "2025-01-27 10:00:00" // 更新时间
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 API接口列表
|
||||
|
||||
### 1. 分页查询学生信息批次收集列表
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/list`
|
||||
- **接口功能**: 分页查询学生信息批次收集列表
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:list`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| pageNum | Integer | 否 | 页码,默认1 |
|
||||
| pageSize | Integer | 否 | 每页条数,默认10 |
|
||||
| batchId | Long | 否 | 批次ID |
|
||||
| studentNo | String | 否 | 学号 |
|
||||
| name | String | 否 | 姓名(模糊查询) |
|
||||
| phone | String | 否 | 手机号码 |
|
||||
| infoStatus | String | 否 | 信息状态 |
|
||||
| classId | String | 否 | 班级ID |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
"phone": "13800138000",
|
||||
"infoStatus": "3",
|
||||
"className": "计算机2025-1班",
|
||||
"createTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 100
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 导出学生信息批次收集列表
|
||||
|
||||
- **接口路径**: POST `/studentMsgBatch/studentMsgBatch/export`
|
||||
- **接口功能**: 导出学生信息批次收集列表到Excel
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:export`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
同查询列表接口,用于筛选导出数据。
|
||||
|
||||
#### 响应数据
|
||||
|
||||
返回Excel文件流。
|
||||
|
||||
### 3. 获取学生信息批次收集详细信息
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/{id}`
|
||||
- **接口功能**: 根据主键ID获取学生信息详细信息
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:query`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | Long | 是 | 主键ID |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
// ... 完整的学生信息字段
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 新增学生信息批次收集
|
||||
|
||||
- **接口路径**: POST `/studentMsgBatch/studentMsgBatch`
|
||||
- **接口功能**: 新增学生信息批次收集记录
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:add`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
```json
|
||||
{
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"phone": "13800138000",
|
||||
"batchId": 1
|
||||
// ... 其他学生信息字段
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 修改学生信息批次收集
|
||||
|
||||
- **接口路径**: PUT `/studentMsgBatch/studentMsgBatch`
|
||||
- **接口功能**: 修改学生信息批次收集记录
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:edit`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"phone": "13800138000",
|
||||
"batchId": 1
|
||||
// ... 其他学生信息字段
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 删除学生信息批次收集
|
||||
|
||||
- **接口路径**: DELETE `/studentMsgBatch/studentMsgBatch/{ids}`
|
||||
- **接口功能**: 批量删除学生信息批次收集记录
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:remove`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| ids | Long[] | 是 | 主键ID数组 |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 查询学生信息完善历史记录
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/history/{batchId}`
|
||||
- **接口功能**: 查询学生信息完善的历史记录信息及最后一次提交的信息状态
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:query`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | Long | 是 | 批次ID |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"historyMsg": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "张三",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"createBy": 1,
|
||||
"createByName": "张三",
|
||||
"infoStatus": "3",
|
||||
"remark": "信息已提交"
|
||||
}
|
||||
],
|
||||
"currentMsg": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
// ... 完整的当前信息
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 获取用户该批次的历史已填写数据
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/userHistoryData/{batchId}`
|
||||
- **接口功能**: 获取当前用户在指定批次的历史已填写数据
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:query`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | Long | 是 | 批次ID |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
// ... 完整的学生信息字段
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. 学生提交信息完善数据
|
||||
|
||||
- **接口路径**: POST `/studentMsgBatch/studentMsgBatch/submitStudentMsg`
|
||||
- **接口功能**: 学生提交信息完善数据
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:add`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"phone": "13800138000",
|
||||
"batchId": 1
|
||||
// ... 其他学生信息字段
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 10. 驳回学生信息提交
|
||||
|
||||
- **接口路径**: POST `/studentMsgBatch/studentMsgBatch/rejectStudentMsg`
|
||||
- **接口功能**: 驳回学生信息提交,设置驳回状态并记录驳回原因
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:edit`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | Long | 是 | 批次ID |
|
||||
| userId | Long | 是 | 用户ID(学生ID) |
|
||||
| remark | String | 是 | 驳回原因 |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务逻辑说明
|
||||
|
||||
1. 更新 `xg_student_msg_batch` 表中符合条件的记录:
|
||||
- **更新条件**: `batch_id = #{batchId} AND id = #{userId} AND deleted = 0`
|
||||
- **更新字段**:
|
||||
- `remark = #{remark}` (驳回原因)
|
||||
- `info_status = '4'` (驳回状态)
|
||||
- `update_by = #{currentUserId}` (当前登录人ID)
|
||||
- `update_time = NOW()` (当前时间)
|
||||
|
||||
2. 记录操作日志,便于审计追踪
|
||||
|
||||
#### 使用示例
|
||||
|
||||
```javascript
|
||||
// 驳回学生信息提交
|
||||
fetch('/studentMsgBatch/studentMsgBatch/rejectStudentMsg', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: 'batchId=123&userId=456&remark=信息填写不完整,请重新提交'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 200) {
|
||||
console.log('驳回成功');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 状态说明
|
||||
|
||||
| 状态值 | 状态名称 | 说明 |
|
||||
|--------|----------|------|
|
||||
| 1 | 待填写 | 学生尚未开始填写信息 |
|
||||
| 2 | 填写中 | 学生正在填写信息 |
|
||||
| 3 | 已提交 | 学生已提交信息,等待审核 |
|
||||
| 4 | 审核不通过 | 管理员驳回,学生需要重新填写 |
|
||||
| 5 | 审核通过 | 管理员审核通过 |
|
||||
|
||||
### 11. 根据部门ID查询学生数据(新增)
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/listByDept`
|
||||
- **接口功能**: 根据部门ID查询该组织下所有已完善信息的学生数据
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:query`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | Long | 是 | 批次ID |
|
||||
| deptId | Long | 是 | 部门ID |
|
||||
| name | String | 否 | 学生姓名(模糊查询) |
|
||||
| studentNo | String | 否 | 学号(精确查询) |
|
||||
| phone | String | 否 | 手机号码(精确查询) |
|
||||
| infoStatus | String | 否 | 信息状态 |
|
||||
| pageNum | Integer | 否 | 页码,默认1 |
|
||||
| pageSize | Integer | 否 | 每页条数,默认10 |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2025001",
|
||||
"name": "张三",
|
||||
"phone": "13800138000",
|
||||
"infoStatus": "3",
|
||||
"className": "计算机2025-1班",
|
||||
"collegeName": "计算机学院",
|
||||
"createTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 50
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务逻辑说明
|
||||
|
||||
1. 根据 `deptId` 在 `sys_dept` 表中查询该部门及其所有子部门的ID列表
|
||||
2. 在 `xg_student_msg_batch` 表中查询:
|
||||
- `batch_id = 入参的batchId`
|
||||
- `deleted = 0`
|
||||
- `class_id IN 部门ID列表`(班级ID等于部门ID)
|
||||
- 支持按姓名、学号、手机号、信息状态等条件过滤
|
||||
- 分页查询
|
||||
|
||||
#### 使用示例
|
||||
|
||||
```javascript
|
||||
// 查询部门ID为101下的所有学生数据
|
||||
fetch('/studentMsgBatch/studentMsgBatch/listByDept?batchId=1&deptId=101&pageNum=1&pageSize=10')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('查询结果:', data);
|
||||
});
|
||||
```
|
||||
|
||||
### 12. 比较学生信息变更详情(新增)
|
||||
|
||||
- **接口路径**: GET `/studentMsgBatch/studentMsgBatch/compareStudentMsg`
|
||||
- **接口功能**: 比较学生提交信息与原始信息的字段变更详情
|
||||
- **权限要求**: `studentMsgBatch:studentMsgBatch:query`
|
||||
|
||||
#### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | Long | 是 | 批次ID |
|
||||
| userId | Long | 是 | 用户ID(学生ID) |
|
||||
|
||||
#### 响应数据
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"hasOriginalData": true,
|
||||
"hasBatchData": true,
|
||||
"changedFields": [
|
||||
{
|
||||
"fieldLabel": "姓名",
|
||||
"fieldName": "name",
|
||||
"originalValue": "张三",
|
||||
"newValue": "张三丰"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "手机号码",
|
||||
"fieldName": "phone",
|
||||
"originalValue": "13800138000",
|
||||
"newValue": "13900139000"
|
||||
},
|
||||
{
|
||||
"fieldLabel": "家庭地址",
|
||||
"fieldName": "homeAddress",
|
||||
"originalValue": "北京市海淀区中关村南大街1号",
|
||||
"newValue": "北京市朝阳区建国门外大街1号"
|
||||
}
|
||||
],
|
||||
"totalChanges": 3,
|
||||
"originalData": {...},
|
||||
"batchData": {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 返回字段说明
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| hasOriginalData | Boolean | 是否找到原始学生信息 |
|
||||
| hasBatchData | Boolean | 是否找到批次提交信息 |
|
||||
| changedFields | Array | 变更字段列表 |
|
||||
| totalChanges | Integer | 变更字段总数 |
|
||||
| originalData | Object | 完整的原始数据 |
|
||||
| batchData | Object | 完整的批次数据 |
|
||||
|
||||
#### changedFields字段结构
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| fieldLabel | String | 字段中文名称 |
|
||||
| fieldName | String | 字段英文名称 |
|
||||
| originalValue | Object | 原始值(可能为null) |
|
||||
| newValue | Object | 修改后的值(可能为null) |
|
||||
|
||||
#### 业务逻辑说明
|
||||
|
||||
1. **数据查询**:
|
||||
- 原始数据:从 `xg_student_msg` 表查询,条件:`id = userId AND deleted = 0`
|
||||
- 批次数据:从 `xg_student_msg_batch` 表查询,条件:`id = userId AND batch_id = batchId AND deleted = 0`
|
||||
|
||||
2. **字段比较**:
|
||||
- 比较两个对象的所有业务字段(70+个字段)
|
||||
- 支持空值安全比较,正确处理null值情况
|
||||
- 只返回有变更的字段,提高性能和可读性
|
||||
|
||||
3. **异常处理**:
|
||||
- 当原始数据不存在时,返回 `hasOriginalData: false`
|
||||
- 当批次数据不存在时,返回 `hasBatchData: false`
|
||||
- 查询异常时返回友好的错误信息
|
||||
|
||||
#### 涵盖字段范围
|
||||
|
||||
- **基本信息**: 姓名、性别、出生日期、民族、籍贯、政治面貌等
|
||||
- **联系信息**: 手机号码、邮箱、家庭地址、现住址等
|
||||
- **家庭信息**: 父母信息、监护人信息、家庭经济状况等
|
||||
- **健康信息**: 身高、体重、血型、健康状况、过敏史等
|
||||
- **学籍信息**: 录取类别、学籍状态、入学信息等
|
||||
- **银行信息**: 银行卡号、开户银行、开户支行等
|
||||
- **扩展字段**: 5个自定义扩展字段
|
||||
|
||||
#### 使用场景
|
||||
|
||||
1. **审核前查看**: 管理员审核前查看学生修改了哪些信息
|
||||
2. **变更记录**: 记录学生信息的变更历史
|
||||
3. **数据核实**: 对比确认学生提交的修改内容
|
||||
4. **审计追踪**: 提供完整的信息变更审计轨迹
|
||||
|
||||
#### 使用示例
|
||||
|
||||
```javascript
|
||||
// 比较学生ID为1001在批次ID为1中的信息变更
|
||||
fetch('/studentMsgBatch/studentMsgBatch/compareStudentMsg?batchId=1&userId=1001')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('变更详情:', data);
|
||||
if (data.data.totalChanges > 0) {
|
||||
console.log('共有', data.data.totalChanges, '个字段发生变更');
|
||||
data.data.changedFields.forEach(change => {
|
||||
console.log(`${change.fieldLabel}: ${change.originalValue} → ${change.newValue}`);
|
||||
});
|
||||
} else {
|
||||
console.log('没有字段变更');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 📝 使用示例
|
||||
|
||||
### 前端调用示例
|
||||
|
||||
```typescript
|
||||
import { request } from '@/utils/request';
|
||||
|
||||
// 查询学生信息列表
|
||||
export function getStudentMsgBatchList(params: any) {
|
||||
return request({
|
||||
url: '/studentMsgBatch/studentMsgBatch/list',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 根据部门查询学生信息
|
||||
export function getStudentMsgBatchByDept(params: any) {
|
||||
return request({
|
||||
url: '/studentMsgBatch/studentMsgBatch/listByDept',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取学生详细信息
|
||||
export function getStudentMsgBatchDetail(id: number) {
|
||||
return request({
|
||||
url: `/studentMsgBatch/studentMsgBatch/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 学生提交信息
|
||||
export function submitStudentMsg(data: any) {
|
||||
return request({
|
||||
url: '/studentMsgBatch/studentMsgBatch/submitStudentMsg',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 后端测试示例
|
||||
|
||||
```java
|
||||
@Test
|
||||
public void testQueryByDeptId() {
|
||||
// 测试根据部门ID查询学生数据
|
||||
PageQuery pageQuery = new PageQuery();
|
||||
pageQuery.setPageNum(1);
|
||||
pageQuery.setPageSize(10);
|
||||
|
||||
TableDataInfo<XgStudentMsgBatchVo> result =
|
||||
xgStudentMsgBatchService.queryPageListByDeptId(
|
||||
1L, // batchId
|
||||
101L, // deptId
|
||||
"张", // name
|
||||
null, // studentNo
|
||||
null, // phone
|
||||
"3", // infoStatus
|
||||
pageQuery // pageQuery
|
||||
);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertTrue(result.getTotal() >= 0);
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 数据安全
|
||||
1. **权限验证**: 所有接口都进行严格的权限验证
|
||||
2. **数据过滤**: 用户只能查看权限范围内的数据
|
||||
3. **SQL注入防护**: 使用参数绑定防止SQL注入
|
||||
|
||||
### 性能优化
|
||||
1. **查询优化**: 使用索引优化大数据量查询
|
||||
2. **部门树查询**: 使用FIND_IN_SET优化部门层级查询
|
||||
3. **分页查询**: 大列表数据支持分页
|
||||
|
||||
### 业务规则
|
||||
1. **数据关联**: 班级ID等于部门ID的设计规则
|
||||
2. **状态管理**: 信息状态流转(正常→待审核→审核中→已驳回/已锁定)
|
||||
3. **逻辑删除**: 支持数据的逻辑删除和恢复
|
||||
|
||||
### 错误处理
|
||||
1. **参数验证**: 对所有输入参数进行验证
|
||||
2. **异常捕获**: 完善的异常处理机制
|
||||
3. **友好提示**: 提供用户友好的错误信息
|
||||
|
||||
## 📈 版本更新记录
|
||||
|
||||
### V1.0.0 (2025-01-27)
|
||||
- 🆕 新增 `listByDept` 根据部门ID查询学生数据接口
|
||||
- 🔧 完善学生信息批次收集的完整API接口
|
||||
- 📝 完善API文档和使用示例
|
||||
- 🔐 完善权限控制策略
|
||||
- ✨ 支持部门层级查询和分页功能
|
||||
|
||||
### V1.1.0 (2025-01-27)
|
||||
- 🎯 **审核功能优化**: 审核按钮集成学生信息详情弹窗
|
||||
- 🔧 **前端集成**: 在学生信息审核界面(`auditDialog.vue`)中集成学生信息完善弹窗(`stuMsgDialog.vue`)
|
||||
- 📊 **参数传递优化**: 优化batchId和用户ID的传递机制
|
||||
- 🎨 **用户体验提升**: 从简单审核升级为完整信息查看和编辑
|
||||
|
||||
### V1.2.0 (2025-01-27)
|
||||
- 🆕 **新增比较接口**: `compareStudentMsg` 学生信息变更详情比较接口
|
||||
- 🔍 **字段对比功能**: 支持70+个字段的全面比较,包括基本信息、家庭信息、健康信息等
|
||||
- 📋 **变更记录**: 提供详细的字段变更记录,支持原值与新值对比
|
||||
- 🔒 **权限复用**: 复用现有查询权限,无需额外权限配置
|
||||
- 📝 **完善文档**: 更新API文档,添加接口使用示例和业务说明
|
||||
|
||||
## 🎯 前端审核功能集成
|
||||
|
||||
### 审核界面优化说明
|
||||
|
||||
**文件路径**: `web/src/views/stuMsgAudit/auditDialog.vue`
|
||||
|
||||
#### 功能升级
|
||||
- **原有功能**: 简单的通过/不通过审核弹窗
|
||||
- **升级后**: 完整的学生信息查看和编辑界面,包含历史记录、基础信息、扩展信息等
|
||||
|
||||
#### 技术实现
|
||||
```vue
|
||||
<!-- 审核按钮点击触发 -->
|
||||
<el-button link type="primary" icon="View" @click="handleAuditStudent(scope.row)">
|
||||
审核
|
||||
</el-button>
|
||||
|
||||
<!-- 学生信息详情弹窗 -->
|
||||
<component
|
||||
:is="StuMsgDialogComponent"
|
||||
:visible="stuMsgDialogVisible"
|
||||
:title="stuMsgDialogTitle"
|
||||
:batchInfo="stuMsgBatchInfo"
|
||||
@update:visible="stuMsgDialogVisible = $event"
|
||||
@confirm="handleStuMsgConfirm"
|
||||
v-if="StuMsgDialogComponent"
|
||||
/>
|
||||
```
|
||||
|
||||
#### 参数传递
|
||||
```typescript
|
||||
const handleAuditStudent = (row: StudentAuditInfo) => {
|
||||
// 构建传递给学生信息弹窗的批次信息
|
||||
stuMsgBatchInfo.value = {
|
||||
batchId: props.batchInfo?.id, // 批次ID
|
||||
userId: row.id, // 学生用户ID
|
||||
...props.batchInfo // 其他批次信息
|
||||
};
|
||||
stuMsgDialogTitle.value = `学生信息审核 - ${row.name}`;
|
||||
stuMsgDialogVisible.value = true;
|
||||
};
|
||||
```
|
||||
|
||||
#### 组件加载
|
||||
- 使用 `defineAsyncComponent` 动态加载组件
|
||||
- 避免静态导入可能的类型错误
|
||||
- 支持按需加载,优化性能
|
||||
|
||||
```typescript
|
||||
const StuMsgDialogComponent = defineAsyncComponent(() => import('./stuMsgDialog.vue'));
|
||||
```
|
||||
|
||||
### 集成效果
|
||||
|
||||
1. **操作流程**:
|
||||
- 点击学生列表中的"审核"按钮
|
||||
- 弹出完整的学生信息详情界面
|
||||
- 包含历史记录、基础信息、扩展信息、家庭信息等多个tab页
|
||||
- 支持信息查看和编辑
|
||||
- 确认后自动刷新学生列表
|
||||
|
||||
2. **数据传递**:
|
||||
- 自动传入当前批次的`batchId`
|
||||
- 传入当前学生的`userId`
|
||||
- 包含完整的批次配置信息
|
||||
|
||||
3. **用户体验**:
|
||||
- 无缝的界面切换
|
||||
- 丰富的学生信息展示
|
||||
- 完整的操作历史追踪
|
||||
|
||||
这次优化显著提升了审核功能的实用性和用户体验,从简单的审核操作升级为完整的学生信息管理功能。
|
||||
@@ -0,0 +1,608 @@
|
||||
# 学生信息收集批次管理API文档
|
||||
|
||||
## 📋 文档信息
|
||||
|
||||
| 项目 | 信息 |
|
||||
|------|------|
|
||||
| **项目名称** | 校园管理系统 - 学生信息收集批次管理 |
|
||||
| **API模块** | 学生信息收集批次班级权限管理 |
|
||||
| **文档版本** | V1.0.0 |
|
||||
| **创建时间** | 2025-01-27 |
|
||||
| **基础路径** | `/stuColBatchClass/stuColBatchClass` |
|
||||
|
||||
## 🎯 API概述
|
||||
|
||||
### 模块说明
|
||||
学生信息收集批次管理系统提供完整的批次权限配置、批次查询、权限范围管理等API接口,支持按班级权限控制学生信息收集范围。
|
||||
|
||||
### 技术规范
|
||||
- **认证方式**: Bearer Token (Sa-Token)
|
||||
- **数据格式**: JSON
|
||||
- **响应格式**: 统一使用R类型或TableDataInfo分页格式
|
||||
- **权限控制**: 基于角色的权限管理(RBAC)
|
||||
|
||||
### 权限角色
|
||||
- **学生管理员**: 查看权限范围内的批次信息
|
||||
- **班主任**: 查看所带班级的批次信息
|
||||
- **全校学生管理员**: 查看全校范围的批次信息
|
||||
- **系统管理员**: 完整的批次权限配置管理
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 批次信息VO (XgStuColBatchVo)
|
||||
|
||||
```java
|
||||
{
|
||||
"id": 1, // 批次ID
|
||||
"batchName": "2025年春季学期信息收集", // 批次名称
|
||||
"description": "收集学生基本信息", // 批次描述
|
||||
"startTime": "2025-02-01 00:00:00", // 开始时间
|
||||
"endTime": "2025-02-28 23:59:59", // 结束时间
|
||||
"status": "0", // 状态(0正常 1停用)
|
||||
"collectionType": "1", // 收集类型(1-新学期收集 2-其他)
|
||||
"remark": "备注信息", // 备注
|
||||
"createBy": 1, // 创建者
|
||||
"createTime": "2025-01-27 10:00:00", // 创建时间
|
||||
"updateBy": 1, // 更新者
|
||||
"updateTime": "2025-01-27 10:00:00" // 更新时间
|
||||
}
|
||||
```
|
||||
|
||||
### 批次班级权限VO (XgStuColBatchClassVo)
|
||||
|
||||
```java
|
||||
{
|
||||
"id": 1, // 主键ID
|
||||
"batchId": 1, // 批次ID
|
||||
"classId": 101, // 班级ID
|
||||
"className": "计算机2023-1", // 班级名称
|
||||
"majorId": 10, // 专业ID
|
||||
"majorName": "计算机科学与技术", // 专业名称
|
||||
"collegeId": 1, // 院系ID
|
||||
"collegeName": "计算机学院", // 院系名称
|
||||
"remark": "备注", // 备注
|
||||
"deleted": 0, // 删除标志
|
||||
"createBy": 1, // 创建者
|
||||
"createTime": "2025-01-27 10:00:00", // 创建时间
|
||||
"updateBy": 1, // 更新者
|
||||
"updateTime": "2025-01-27 10:00:00" // 更新时间
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 API接口列表
|
||||
|
||||
### 1. 基础管理接口
|
||||
|
||||
#### 1.1 查询批次班级权限列表
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/list`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:list`
|
||||
- **功能描述**: 分页查询学生信息收集批次班级权限列表
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| pageNum | integer | 否 | 页码,默认1 |
|
||||
| pageSize | integer | 否 | 每页大小,默认10 |
|
||||
| batchId | long | 否 | 批次ID |
|
||||
| classId | long | 否 | 班级ID |
|
||||
| className | string | 否 | 班级名称(模糊查询) |
|
||||
| majorName | string | 否 | 专业名称(模糊查询) |
|
||||
| collegeName | string | 否 | 院系名称(模糊查询) |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 获取批次班级权限详细信息
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/{id}`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:query`
|
||||
- **功能描述**: 根据主键获取批次班级权限详细信息
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | long | 是 | 主键ID |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院",
|
||||
"remark": "备注",
|
||||
"deleted": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 新增批次班级权限
|
||||
- **接口路径**: POST `/stuColBatchClass/stuColBatchClass`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:add`
|
||||
- **功能描述**: 新增学生信息收集批次班级权限
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院",
|
||||
"remark": "备注"
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "新增成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.4 修改批次班级权限
|
||||
- **接口路径**: PUT `/stuColBatchClass/stuColBatchClass`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:edit`
|
||||
- **功能描述**: 修改学生信息收集批次班级权限
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院",
|
||||
"remark": "修改后的备注"
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "修改成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.5 删除批次班级权限
|
||||
- **接口路径**: DELETE `/stuColBatchClass/stuColBatchClass/{ids}`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:remove`
|
||||
- **功能描述**: 删除学生信息收集批次班级权限(支持批量删除)
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| ids | string | 是 | 主键ID,多个用逗号分隔 |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.6 导出批次班级权限
|
||||
- **接口路径**: POST `/stuColBatchClass/stuColBatchClass/export`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:export`
|
||||
- **功能描述**: 导出学生信息收集批次班级权限列表
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机",
|
||||
"majorName": "计算机科学",
|
||||
"collegeName": "计算机学院"
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
- 直接返回Excel文件流
|
||||
|
||||
### 2. 权限范围管理接口
|
||||
|
||||
#### 2.1 获取批次收集范围
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/getScope/{batchId}`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:query`
|
||||
- **功能描述**: 获取指定批次配置的班级权限范围
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | long | 是 | 批次ID |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [101, 102, 103] // 班级ID列表
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 获取批次权限范围详情
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/getScopeDetail/{batchId}`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:query`
|
||||
- **功能描述**: 获取批次配置的权限范围详细信息
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | long | 是 | 批次ID |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"batchId": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 设置批次收集范围
|
||||
- **接口路径**: POST `/stuColBatchClass/stuColBatchClass/setScope`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:setScope`
|
||||
- **功能描述**: 设置学生信息收集批次班级权限范围
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | long | 是 | 批次ID |
|
||||
| deptIds | array | 是 | 授权的班级ID列表 |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "权限设置成功,共设置 3 个班级权限"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 用户相关接口
|
||||
|
||||
#### 3.1 查询学生可参与的批次
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/getStudentAvailableBatches`
|
||||
- **权限标识**: 无需权限(基于当前登录用户)
|
||||
- **功能描述**: 查询当前登录学生可参与的批次信息
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchName | string | 否 | 批次名称(模糊查询) |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"batchId": 1,
|
||||
"batchName": "2025年春季学期信息收集",
|
||||
"description": "收集学生基本信息",
|
||||
"startTime": "2025-02-01 00:00:00",
|
||||
"endTime": "2025-02-28 23:59:59",
|
||||
"status": "0",
|
||||
"collectionType": "1",
|
||||
"remark": "备注信息",
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1",
|
||||
"majorId": 10,
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": 1,
|
||||
"collegeName": "计算机学院"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 查询老师关联的批次信息 🆕
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/getTeacherRelatedBatches`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:query`
|
||||
- **功能描述**: 查询当前登录老师有权限管理的批次信息
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchName | string | 否 | 批次名称(模糊查询) |
|
||||
|
||||
**业务逻辑**:
|
||||
1. 调用 `XgStudentManagerSourceServiceImpl.getCurrentUserAuthDeptTree()` 获取当前用户有权限的部门树
|
||||
2. 递归提取所有部门ID
|
||||
3. 根据部门ID查询关联的批次信息
|
||||
4. 支持全校学生管理员、普通管理员、班主任三种权限模式
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"batchName": "2025年春季学期信息收集",
|
||||
"description": "收集学生基本信息",
|
||||
"startTime": "2025-02-01 00:00:00",
|
||||
"endTime": "2025-02-28 23:59:59",
|
||||
"status": "0",
|
||||
"collectionType": "1",
|
||||
"remark": "备注信息",
|
||||
"createBy": 1,
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateBy": 1,
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3 获取批次组织权限范围 🆕
|
||||
- **接口路径**: GET `/stuColBatchClass/stuColBatchClass/getBatchAuthScope/{batchId}`
|
||||
- **权限标识**: `stuColBatchClass:stuColBatchClass:query`
|
||||
- **功能描述**: 获取用户对应该批次的组织权限范围,返回过滤后的组织树形结构
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| batchId | long | 是 | 批次ID |
|
||||
|
||||
**业务逻辑**:
|
||||
1. **获取用户权限**: 调用 `XgStudentManagerSourceServiceImpl.getCurrentUserAuthDeptTree()` 获取当前用户所有的组织权限信息
|
||||
2. **查询批次班级**: 通过batchId在 `xg_stu_col_batch_class` 中获取class_id数据(过滤条件:`deleted=0`)
|
||||
3. **过滤组织树**: 将第一步获取的树形数据中,非第二步中存在的班级节点都剔除,只保留在第二步中存在的班级ID以及其上级节点,直到树形数据的顶点
|
||||
|
||||
**核心算法**:
|
||||
- 使用递归算法实现树形结构过滤
|
||||
- 保留目标班级节点及其所有上级节点
|
||||
- 确保组织层级关系的完整性
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"label": "计算机学院",
|
||||
"parentId": 101,
|
||||
"deptCategory": "college",
|
||||
"weight": 1,
|
||||
"disabled": false,
|
||||
"children": [
|
||||
{
|
||||
"id": 10,
|
||||
"label": "计算机科学与技术",
|
||||
"parentId": 1,
|
||||
"deptCategory": "major",
|
||||
"weight": 1,
|
||||
"disabled": false,
|
||||
"children": [
|
||||
{
|
||||
"id": 101,
|
||||
"label": "计算机2023-1班",
|
||||
"parentId": 10,
|
||||
"deptCategory": "class",
|
||||
"weight": 1,
|
||||
"disabled": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**异常情况**:
|
||||
- 当批次ID无效时返回空列表
|
||||
- 当用户无权限时返回空列表
|
||||
- 当批次未配置班级权限时返回空列表
|
||||
|
||||
**应用场景**:
|
||||
- 前端组织树选择器的数据源
|
||||
- 批次权限范围可视化显示
|
||||
- 权限验证和范围限制
|
||||
|
||||
## 🔐 权限设计
|
||||
|
||||
### 权限控制策略
|
||||
|
||||
#### 1. 全校学生管理员
|
||||
- **权限范围**: 可以查看和管理所有批次信息
|
||||
- **识别条件**: `xg_student_manager` 表中 `manager_type = '1'`
|
||||
- **部门权限**: 获取 `dept_id = 101` 下所有部门数据
|
||||
|
||||
#### 2. 普通管理员
|
||||
- **权限范围**: 基于 `xg_student_manager_source` 表中的授权范围
|
||||
- **识别条件**: `xg_student_manager` 表中 `manager_type != '1'`
|
||||
- **部门权限**: 根据授权的部门ID获取相关部门树
|
||||
|
||||
#### 3. 班主任
|
||||
- **权限范围**: 只能查看所带班级的批次信息
|
||||
- **识别条件**: `xg_class_msg` 表中 `class_teacher_id` 等于当前用户ID
|
||||
- **自动权限**: 系统自动将班主任权限合并到部门权限中
|
||||
|
||||
### 数据查询策略
|
||||
|
||||
#### 权限范围计算
|
||||
```sql
|
||||
-- 1. 查询用户授权的部门ID
|
||||
SELECT auth_source FROM xg_student_manager_source
|
||||
WHERE manager_id IN (
|
||||
SELECT id FROM xg_student_manager WHERE user_id = #{currentUserId}
|
||||
) AND status = '0' AND deleted = '0'
|
||||
|
||||
-- 2. 查询班主任权限
|
||||
SELECT id FROM xg_class_msg
|
||||
WHERE class_teacher_id = #{currentUserId} AND deleted = '0'
|
||||
|
||||
-- 3. 查询批次信息
|
||||
SELECT DISTINCT b.* FROM xg_stu_col_batch b
|
||||
INNER JOIN xg_stu_col_batch_class bc ON b.id = bc.batch_id
|
||||
WHERE bc.class_id IN (权限范围内的部门ID)
|
||||
AND b.deleted = 0 AND b.status = '0'
|
||||
```
|
||||
|
||||
## 📝 使用示例
|
||||
|
||||
### 前端调用示例
|
||||
|
||||
#### JavaScript/Vue示例
|
||||
```javascript
|
||||
// 查询老师关联的批次信息
|
||||
async function getTeacherBatches(batchName = '') {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/stuColBatchClass/stuColBatchClass/getTeacherRelatedBatches',
|
||||
method: 'get',
|
||||
params: {
|
||||
batchName: batchName
|
||||
}
|
||||
});
|
||||
|
||||
if (response.code === 200) {
|
||||
console.log('批次列表:', response.data);
|
||||
return response.data;
|
||||
} else {
|
||||
console.error('查询失败:', response.msg);
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求异常:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 设置批次权限范围
|
||||
async function setBatchScope(batchId, deptIds) {
|
||||
try {
|
||||
const response = await request({
|
||||
url: '/stuColBatchClass/stuColBatchClass/setScope',
|
||||
method: 'post',
|
||||
data: {
|
||||
batchId: batchId,
|
||||
deptIds: deptIds
|
||||
}
|
||||
});
|
||||
|
||||
if (response.code === 200) {
|
||||
console.log('权限设置成功:', response.msg);
|
||||
return true;
|
||||
} else {
|
||||
console.error('设置失败:', response.msg);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求异常:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 移动端调用示例
|
||||
|
||||
#### uni-app示例
|
||||
```javascript
|
||||
// 查询学生可参与的批次
|
||||
async function getStudentBatches() {
|
||||
try {
|
||||
const response = await uni.request({
|
||||
url: baseURL + '/stuColBatchClass/stuColBatchClass/getStudentAvailableBatches',
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Authorization': 'Bearer ' + getToken(),
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.code === 200) {
|
||||
return response.data.data;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.data.msg || '查询失败',
|
||||
icon: 'none'
|
||||
});
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求异常:', error);
|
||||
uni.showToast({
|
||||
title: '网络异常',
|
||||
icon: 'none'
|
||||
});
|
||||
return [];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 数据安全
|
||||
1. **权限验证**: 所有接口都进行严格的权限验证
|
||||
2. **数据过滤**: 用户只能查看权限范围内的数据
|
||||
3. **SQL注入防护**: 使用参数绑定防止SQL注入
|
||||
|
||||
### 性能优化
|
||||
1. **查询优化**: 使用索引优化大数据量查询
|
||||
2. **缓存策略**: 部门权限树适合进行缓存
|
||||
3. **分页查询**: 大列表数据支持分页
|
||||
|
||||
### 错误处理
|
||||
1. **参数验证**: 对所有输入参数进行验证
|
||||
2. **异常捕获**: 完善的异常处理机制
|
||||
3. **友好提示**: 提供用户友好的错误信息
|
||||
|
||||
## 📈 版本更新记录
|
||||
|
||||
### V1.0.0 (2025-01-27)
|
||||
- 🆕 新增 `getTeacherRelatedBatches` 接口
|
||||
- 🔧 修复 `XgStuColBatchVo` 缺少基础字段的问题
|
||||
- 📝 完善API文档和使用示例
|
||||
- 🔐 完善权限控制策略
|
||||
- ✨ 支持全校管理员、普通管理员、班主任三种权限模式
|
||||
@@ -0,0 +1,625 @@
|
||||
# 学生信息管理API文档
|
||||
|
||||
## 1. 文档说明
|
||||
|
||||
### 1.1 API基础信息
|
||||
- **模块名称**: 学工管理 - 学生信息管理
|
||||
- **模块代码**: ruoyi-xg
|
||||
- **基础路径**: `/studentMsg/studentMsg`
|
||||
- **权限前缀**: `studentMsg:studentMsg`
|
||||
- **版本**: 1.0.0
|
||||
- **更新时间**: 2025-01-27(新增班级学生查询接口)
|
||||
|
||||
### 1.2 通用规范
|
||||
- **请求方式**: 支持GET、POST、PUT、DELETE
|
||||
- **数据格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
- **认证方式**: Bearer Token
|
||||
- **权限控制**: Sa-Token + 数据权限
|
||||
|
||||
### 1.3 响应格式
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {},
|
||||
"timestamp": "2025-01-27T18:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 学生信息管理接口
|
||||
|
||||
### 2.1 查询学生信息列表
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/list`
|
||||
- **权限标识**: `studentMsg:studentMsg:list`
|
||||
- **功能描述**: 分页查询学生信息列表,支持多条件筛选
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| pageNum | integer | 否 | 页码,默认1 |
|
||||
| pageSize | integer | 否 | 每页大小,默认10 |
|
||||
| studentNo | string | 否 | 学号 |
|
||||
| name | string | 否 | 姓名(模糊查询) |
|
||||
| idCard | string | 否 | 身份证号 |
|
||||
| gender | string | 否 | 性别:0-男,1-女 |
|
||||
| studentStatus | string | 否 | 学籍状态 |
|
||||
| phone | string | 否 | 联系电话(模糊查询) |
|
||||
| email | string | 否 | 邮箱 |
|
||||
| classId | string | 否 | 班级ID |
|
||||
| className | string | 否 | 班级名称 |
|
||||
| majorId | string | 否 | 专业ID |
|
||||
| majorName | string | 否 | 专业名称 |
|
||||
| collegeId | string | 否 | 学院ID |
|
||||
| collegeName | string | 否 | 学院名称 |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 根据组织ID查询学生信息列表
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/listByDeptId`
|
||||
- **权限标识**: `studentMsg:studentMsg:list`
|
||||
- **功能描述**: 根据部门ID查询该组织下所有学生信息
|
||||
|
||||
#### 请求参数
|
||||
```json
|
||||
{
|
||||
"dept_id": 101,
|
||||
"name": "张",
|
||||
"studentNo": "2023001",
|
||||
"phone": "138",
|
||||
"studentStatus": "1",
|
||||
"beginTime": "2025-01-01",
|
||||
"endTime": "2025-01-27"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [...],
|
||||
"total": 10
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 查询班级中所有学生信息 ⭐ 新增
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/listByClassId`
|
||||
- **权限标识**: `studentMsg:studentMsg:query`
|
||||
- **功能描述**: 查询指定班级中所有在籍学生信息
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| classId | string | 是 | 班级ID |
|
||||
| name | string | 否 | 学生姓名(模糊查询) |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务逻辑
|
||||
1. 在 `xg_student_msg` 表中查询:
|
||||
- `deleted = 0` (未删除)
|
||||
- `student_status = '1'` (在籍状态)
|
||||
- `class_id = 入参的classId` (班级ID)
|
||||
- `name LIKE '%入参的name%'` (姓名模糊查询,可选)
|
||||
- 按创建时间倒序排列
|
||||
|
||||
### 2.4 获取学生信息详情
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/{id}`
|
||||
- **权限标识**: `studentMsg:studentMsg:query`
|
||||
- **功能描述**: 根据ID获取学生详细信息
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | long | 是 | 学生ID |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 新增学生信息
|
||||
- **接口路径**: POST `/studentMsg/studentMsg`
|
||||
- **权限标识**: `studentMsg:studentMsg:add`
|
||||
- **功能描述**: 新增学生信息
|
||||
|
||||
#### 请求参数
|
||||
```json
|
||||
{
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "新增成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.6 修改学生信息
|
||||
- **接口路径**: PUT `/studentMsg/studentMsg`
|
||||
- **权限标识**: `studentMsg:studentMsg:edit`
|
||||
- **功能描述**: 修改学生信息
|
||||
|
||||
#### 请求参数
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "修改成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.7 删除学生信息
|
||||
- **接口路径**: DELETE `/studentMsg/studentMsg/{ids}`
|
||||
- **权限标识**: `studentMsg:studentMsg:remove`
|
||||
- **功能描述**: 批量删除学生信息
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| ids | string | 是 | 学生ID列表,多个用逗号分隔 |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.8 导出学生信息
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/export`
|
||||
- **权限标识**: `studentMsg:studentMsg:export`
|
||||
- **功能描述**: 导出学生信息列表
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| studentNo | string | 否 | 学号 |
|
||||
| name | string | 否 | 姓名 |
|
||||
| studentStatus | string | 否 | 学籍状态 |
|
||||
|
||||
#### 响应数据
|
||||
返回Excel文件流
|
||||
|
||||
### 2.8.1 高级检索导出学生信息
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/advancedSearchExport`
|
||||
- **权限标识**: `studentMsg:studentMsg:export`
|
||||
- **功能描述**: 根据高级检索条件导出学生信息列表,支持多维度复合查询条件
|
||||
- **版本**: 1.2.1 (2025-01-07修复MapStruct转换错误)
|
||||
- **修复**: 解决 `XgStudentMsgVo` 到 `XgStudentMsgExportVo` 转换器缺失问题
|
||||
|
||||
#### 请求参数
|
||||
支持以下高级检索条件:
|
||||
|
||||
**基础信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| studentNo | string | 否 | 学号(模糊查询) |
|
||||
| name | string | 否 | 姓名(模糊查询) |
|
||||
| idCard | string | 否 | 身份证号(模糊查询) |
|
||||
| phone | string | 否 | 手机号码(模糊查询) |
|
||||
| email | string | 否 | 邮箱(模糊查询) |
|
||||
| gender | array | 否 | 性别数组:0-男,1-女 |
|
||||
| nationality | array | 否 | 民族数组 |
|
||||
| politicalStatus | array | 否 | 政治面貌数组 |
|
||||
| birthDateStart | string | 否 | 出生日期开始:yyyy-MM-dd |
|
||||
| birthDateEnd | string | 否 | 出生日期结束:yyyy-MM-dd |
|
||||
|
||||
**学籍信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| studentStatus | array | 否 | 学籍状态数组:1-在籍,2-休学,3-复学,4-退学,5-毕业 |
|
||||
| enrollmentYearStart | integer | 否 | 入学年份开始 |
|
||||
| enrollmentYearEnd | integer | 否 | 入学年份结束 |
|
||||
| admissionCategory | array | 否 | 录取类别数组 |
|
||||
|
||||
**学院专业班级检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| collegeName | string | 否 | 学院名称(模糊查询) |
|
||||
| majorName | string | 否 | 专业名称(模糊查询) |
|
||||
| className | string | 否 | 班级名称(模糊查询) |
|
||||
| grade | array | 否 | 年级数组 |
|
||||
| counselorName | string | 否 | 辅导员姓名(模糊查询) |
|
||||
| classTeacherName | string | 否 | 班主任姓名(模糊查询) |
|
||||
|
||||
**家庭信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| fatherName | string | 否 | 父亲姓名(模糊查询) |
|
||||
| motherName | string | 否 | 母亲姓名(模糊查询) |
|
||||
| familyEconomicStatus | array | 否 | 家庭经济状况数组 |
|
||||
| familyIncomeMin | number | 否 | 家庭收入最小值 |
|
||||
| familyIncomeMax | number | 否 | 家庭收入最大值 |
|
||||
|
||||
**特殊身份检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| isPoorStudent | array | 否 | 是否贫困生:0-否,1-是 |
|
||||
| isMinority | array | 否 | 是否少数民族:0-否,1-是 |
|
||||
| isDisabled | array | 否 | 是否残疾:0-否,1-是 |
|
||||
| isOrphan | array | 否 | 是否孤儿:0-否,1-是 |
|
||||
|
||||
**权限范围**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| deptIds | array | 否 | 部门ID数组,用于权限控制 |
|
||||
|
||||
#### 响应数据
|
||||
返回Excel文件流,包含完整的学生信息数据
|
||||
|
||||
#### 修复记录
|
||||
- **2025-01-07 v1.2.1**: 修复MapStruct转换错误,解决 `XgStudentMsgVo` 到 `XgStudentMsgExportVo` 转换器缺失问题
|
||||
- **问题**: `MapstructUtils.convert()` 无法找到两个VO类之间的转换器,导致导出功能报错
|
||||
- **解决**: 在Controller中添加手动转换方法 `convertToExportVo()` 和 `convertToExportVoList()`
|
||||
- **影响**: 导出功能正常工作,所有字段完整映射
|
||||
- **2025-01-07 v1.2.0**: 修复分页限制问题,导出时pageSize设置为50000,确保能导出所有符合条件的记录
|
||||
- **问题**: 之前由于BO类默认pageSize=10,导致只能导出10条记录
|
||||
- **解决**: 取消注释Controller中的分页参数设置代码
|
||||
|
||||
### 2.9 查询学生个人信息
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/personalInfo`
|
||||
- **权限标识**: `studentMsg:studentMsg:query`
|
||||
- **功能描述**: 查询当前登录学生的个人信息
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| userId | long | 否 | 用户ID,为空时使用当前登录用户ID |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.10 根据班级ID查询学生信息列表
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/listByClassId`
|
||||
- **权限标识**: `studentMsg:studentMsg:query`
|
||||
- **功能描述**: 查询指定班级中所有在籍学生信息
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| classId | string | 是 | 班级ID |
|
||||
| name | string | 否 | 学生姓名(模糊查询) |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentNo": "2023001001",
|
||||
"name": "张三",
|
||||
"gender": "0",
|
||||
"birthDate": "2000-01-01",
|
||||
"idCard": "110101199901010001",
|
||||
"phone": "13800138000",
|
||||
"email": "zhangsan@example.com",
|
||||
"classId": "101",
|
||||
"className": "计算机2023-1班",
|
||||
"majorId": "CS001",
|
||||
"majorName": "计算机科学与技术",
|
||||
"collegeId": "CS",
|
||||
"collegeName": "计算机学院",
|
||||
"studentStatus": "1",
|
||||
"createTime": "2025-01-27 10:00:00",
|
||||
"updateTime": "2025-01-27 10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.11 导入学生信息数据
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/importData`
|
||||
- **权限标识**: `studentMsg:studentMsg:import`
|
||||
- **功能描述**: 批量导入学生信息数据,支持Excel文件上传
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| file | MultipartFile | 是 | Excel文件(.xlsx格式) |
|
||||
| updateSupport | boolean | 否 | 是否支持更新已存在数据,默认false |
|
||||
|
||||
#### 请求示例
|
||||
```http
|
||||
POST /studentMsg/studentMsg/importData
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
file: [Excel文件]
|
||||
updateSupport: true
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "恭喜您,数据已全部导入成功!共 10 条,数据如下:",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应示例
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "很抱歉,导入失败!共 2 条数据格式不正确,错误如下:<br/>1、学号 2023001001 已存在<br/>2、学号 2023001002 导入失败:手机号码格式不正确",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 2.12 获取导入模板
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/importTemplate`
|
||||
- **权限标识**: `studentMsg:studentMsg:import`
|
||||
- **功能描述**: 下载学生信息导入模板文件
|
||||
|
||||
#### 请求参数
|
||||
无
|
||||
|
||||
#### 响应数据
|
||||
返回Excel模板文件(.xlsx格式)
|
||||
|
||||
#### 模板字段说明
|
||||
| 字段名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| 学号 | string | 是 | 学生学号,必须唯一 |
|
||||
| 姓名 | string | 是 | 学生姓名 |
|
||||
| 性别 | string | 是 | 0-男,1-女 |
|
||||
| 身份证号 | string | 否 | 身份证号码 |
|
||||
| 手机号码 | string | 否 | 手机号码,必须唯一 |
|
||||
| 电子邮箱 | string | 否 | 邮箱地址,必须唯一 |
|
||||
| 出生日期 | date | 否 | 出生日期 |
|
||||
| 民族 | string | 否 | 民族代码 |
|
||||
| 政治面貌 | string | 否 | 政治面貌代码 |
|
||||
| 家庭地址 | string | 否 | 家庭住址 |
|
||||
| 现住址 | string | 否 | 现居住地址 |
|
||||
| 班级ID | string | 否 | 班级编号 |
|
||||
| 班级名称 | string | 否 | 班级名称 |
|
||||
| 专业ID | string | 否 | 专业编号 |
|
||||
| 专业名称 | string | 否 | 专业名称 |
|
||||
| 学院ID | string | 否 | 学院编号 |
|
||||
| 学院名称 | string | 否 | 学院名称 |
|
||||
| 学籍状态 | string | 否 | 1-在籍,2-休学,3-复学,4-退学,5-毕业 |
|
||||
|
||||
## 3. 数据字典
|
||||
|
||||
### 3.1 性别字典
|
||||
| 字典值 | 字典标签 |
|
||||
|--------|----------|
|
||||
| 0 | 男 |
|
||||
| 1 | 女 |
|
||||
|
||||
### 3.2 学籍状态字典
|
||||
| 字典值 | 字典标签 |
|
||||
|--------|----------|
|
||||
| 1 | 在籍 |
|
||||
| 2 | 休学 |
|
||||
| 3 | 复学 |
|
||||
| 4 | 退学 |
|
||||
| 5 | 毕业 |
|
||||
|
||||
### 3.3 信息状态字典
|
||||
| 字典值 | 字典标签 |
|
||||
|--------|----------|
|
||||
| 1 | 正常 |
|
||||
| 2 | 待审核 |
|
||||
| 3 | 审核中 |
|
||||
| 4 | 已驳回 |
|
||||
| 5 | 已锁定 |
|
||||
|
||||
## 4. 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| 200 | 操作成功 |
|
||||
| 400 | 请求参数错误 |
|
||||
| 401 | 未授权 |
|
||||
| 403 | 无权限 |
|
||||
| 404 | 资源不存在 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 5. 权限说明
|
||||
|
||||
### 5.1 数据权限控制
|
||||
- **超级管理员**: 可查看所有学生信息
|
||||
- **学工管理员**: 可查看所有学生信息
|
||||
- **二级学院管理员**: 只能查看本学院学生信息
|
||||
- **辅导员**: 只能查看负责班级的学生信息
|
||||
- **班主任**: 只能查看负责班级的学生信息
|
||||
- **学生**: 只能查看自己的信息
|
||||
|
||||
### 5.2 操作权限控制
|
||||
- **新增**: 学工管理员、二级学院管理员
|
||||
- **修改**: 学工管理员、二级学院管理员、辅导员、班主任(限制范围)
|
||||
- **删除**: 学工管理员、二级学院管理员
|
||||
- **导入**: 学工管理员、二级学院管理员
|
||||
- **导出**: 学工管理员、二级学院管理员、辅导员、班主任
|
||||
- **查询**: 所有有权限的用户
|
||||
|
||||
## 6. 注意事项
|
||||
|
||||
1. 所有接口都需要Bearer Token认证
|
||||
2. 删除操作为逻辑删除,不会物理删除数据
|
||||
3. 学号和身份证号必须唯一
|
||||
4. 新增学生时会自动创建对应的系统用户账号
|
||||
5. 支持多租户数据隔离
|
||||
6. 所有时间字段使用yyyy-MM-dd HH:mm:ss格式
|
||||
7. 数据权限按照用户角色自动过滤
|
||||
8. 班级学生查询接口只返回在籍状态的学生
|
||||
|
||||
## 7. 更新日志
|
||||
|
||||
### 2025-01-27 - 新增学生信息导入功能
|
||||
- **新增功能**: 新增学生信息批量导入功能
|
||||
- **新增接口**:
|
||||
- `POST /studentMsg/studentMsg/importData` - 学生信息导入接口
|
||||
- `POST /studentMsg/studentMsg/importTemplate` - 导入模板下载接口
|
||||
- **功能特性**:
|
||||
- 支持Excel文件批量导入
|
||||
- 支持新增和更新两种模式
|
||||
- 自动验证学号、手机号、邮箱唯一性
|
||||
- 完整的错误处理和结果统计
|
||||
- 自动创建对应的系统用户账号
|
||||
- **技术实现**:
|
||||
- 使用自定义Listener处理Excel解析
|
||||
- 事务保证数据一致性
|
||||
- 详细的导入结果反馈
|
||||
|
||||
### 2025-01-27 - 新增班级学生查询接口
|
||||
- **新增功能**: 新增 `GET /studentMsg/studentMsg/listByClassId` 接口
|
||||
- **功能描述**: 查询指定班级中所有在籍学生信息
|
||||
- **过滤条件**:
|
||||
- `deleted = 0` (未删除)
|
||||
- `student_status = '1'` (在籍状态)
|
||||
- `class_id = 入参的classId` (班级ID)
|
||||
- `name LIKE '%入参的name%'` (姓名模糊查询,可选)
|
||||
- **排序方式**: 按创建时间倒序排列
|
||||
|
||||
---
|
||||
|
||||
**文档更新时间**: 2025-01-07
|
||||
**文档版本**: 1.2.0
|
||||
**维护人员**: Cursor AI
|
||||
**更新说明**:
|
||||
- 新增高级检索导出接口文档
|
||||
- 修复高级检索导出分页限制问题
|
||||
- 之前版本:新增学生信息导入功能,完善学生信息管理API文档
|
||||
@@ -0,0 +1,357 @@
|
||||
# 学生管理员授权关系API文档
|
||||
|
||||
## 1. 文档说明
|
||||
|
||||
### 1.1 API基础信息
|
||||
- **模块名称**: 学工管理 - 学生管理员授权关系
|
||||
- **模块代码**: ruoyi-xg
|
||||
- **基础路径**: `/xgStudentManagerSource/studentManagerSource`
|
||||
- **权限前缀**: `xgStudentManagerSource:studentManagerSource`
|
||||
- **版本**: 1.0.0
|
||||
- **更新时间**: 2025-07-24
|
||||
|
||||
### 1.2 通用规范
|
||||
- **请求方式**: 支持GET、POST、PUT、DELETE
|
||||
- **数据格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
- **认证方式**: Bearer Token
|
||||
- **权限控制**: Sa-Token + 数据权限
|
||||
|
||||
### 1.3 响应格式
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {},
|
||||
"timestamp": "2025-07-24T10:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 学生管理员授权关系接口
|
||||
|
||||
### 2.1 查询学生管理员授权关系列表
|
||||
- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/list`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:list`
|
||||
- **功能描述**: 分页查询学生管理员授权关系列表
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| pageNum | integer | 否 | 页码,默认1 |
|
||||
| pageSize | integer | 否 | 每页大小,默认10 |
|
||||
| managerId | long | 否 | 管理员ID |
|
||||
| permissionType | string | 否 | 权限类型(1查看 2编辑 3完全管理) |
|
||||
| authType | string | 否 | 授权类型(1全校级 2自定义 3班主任) |
|
||||
| authSource | long | 否 | 授权来源ID(对应班级id) |
|
||||
| status | string | 否 | 状态(0有效 1已撤销) |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"total": 10,
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"managerId": 123,
|
||||
"permissionType": "2",
|
||||
"authType": "2",
|
||||
"authSource": 456,
|
||||
"status": "0",
|
||||
"remark": "自定义管理员权限",
|
||||
"createTime": "2025-07-24 10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 获取学生管理员授权关系详细信息
|
||||
- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/{id}`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:query`
|
||||
- **功能描述**: 根据主键查询学生管理员授权关系详情
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | long | 是 | 主键ID |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"managerId": 123,
|
||||
"permissionType": "2",
|
||||
"authType": "2",
|
||||
"authSource": 456,
|
||||
"status": "0",
|
||||
"remark": "自定义管理员权限",
|
||||
"createTime": "2025-07-24 10:00:00",
|
||||
"updateTime": "2025-07-24 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 新增学生管理员授权关系
|
||||
- **接口路径**: POST `/xgStudentManagerSource/studentManagerSource`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:add`
|
||||
- **功能描述**: 新增学生管理员授权关系
|
||||
|
||||
#### 请求参数
|
||||
```json
|
||||
{
|
||||
"managerId": 123,
|
||||
"permissionType": "2",
|
||||
"authType": "2",
|
||||
"authSource": 456,
|
||||
"status": "0",
|
||||
"remark": "自定义管理员权限"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "新增成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 修改学生管理员授权关系
|
||||
- **接口路径**: PUT `/xgStudentManagerSource/studentManagerSource`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:edit`
|
||||
- **功能描述**: 修改学生管理员授权关系
|
||||
|
||||
#### 请求参数
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"managerId": 123,
|
||||
"permissionType": "3",
|
||||
"authType": "2",
|
||||
"authSource": 456,
|
||||
"status": "0",
|
||||
"remark": "修改后的权限说明"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "修改成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 删除学生管理员授权关系
|
||||
- **接口路径**: DELETE `/xgStudentManagerSource/studentManagerSource/{ids}`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:remove`
|
||||
- **功能描述**: 删除学生管理员授权关系(支持批量删除)
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| ids | long[] | 是 | 主键ID数组 |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.6 自定义学生管理员授予部门权限
|
||||
- **接口路径**: POST `/xgStudentManagerSource/studentManagerSource/grantDeptAuth`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:grantDeptAuth`
|
||||
- **功能描述**: 为指定管理员批量授予多个部门的权限
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| managerId | long | 是 | 管理员ID |
|
||||
| authSourceIds | long[] | 是 | 资源ID列表(部门ID数组) |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "授权成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.7 获取指定管理员的授权资源名称列表
|
||||
- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/authSourceNames`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:query`
|
||||
- **功能描述**: 获取指定管理员已授权的资源名称列表
|
||||
|
||||
#### 请求参数
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| managerId | long | 是 | 管理员ID |
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
"计算机学院",
|
||||
"计算机2023-1班",
|
||||
"计算机2023-2班"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.8 获取当前用户的学生管理权限部门树 🆕
|
||||
- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/currentUserAuthTree`
|
||||
- **权限标识**: `xgStudentManagerSource:studentManagerSource:query`
|
||||
- **功能描述**: 获取当前登录用户的学生管理权限部门树形结构,只有班级节点可以点击
|
||||
|
||||
#### 请求参数
|
||||
无需入参,自动获取当前登录用户信息
|
||||
|
||||
#### 接口逻辑
|
||||
1. **第一步**: 通过当前登录用户ID,关联 `xg_student_manager` 与 `xg_student_manager_source` 表,获取授权来源信息
|
||||
- 查询条件:`xg_student_manager.user_id = 当前用户ID AND xg_student_manager.deleted = '0' AND xg_student_manager.status = '0'`
|
||||
- 关联条件:`xg_student_manager_source.manager_id = xg_student_manager.id AND xg_student_manager_source.status = '0' AND xg_student_manager_source.deleted = '0'`
|
||||
|
||||
2. **第二步**: 根据授权来源关联 `sys_dept` 表获取部门数据和所有子节点
|
||||
- 查询条件:`sys_dept.dept_id IN (auth_source列表) AND sys_dept.status = '0' AND sys_dept.del_flag = '0'`
|
||||
- 同时获取所有子部门:通过 `ancestors` 字段查找子节点
|
||||
|
||||
3. **第三步**: 向上查找父节点直到根节点(id=101)
|
||||
- 通过 `ancestors` 字段解析父节点层级关系
|
||||
- 构建完整的部门树结构
|
||||
|
||||
#### 响应数据
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"deptId": 101,
|
||||
"parentId": null,
|
||||
"deptName": "杭州职业技术学院",
|
||||
"deptCategory": "university",
|
||||
"orderNum": 1,
|
||||
"clickable": false,
|
||||
"children": [
|
||||
{
|
||||
"deptId": 102,
|
||||
"parentId": 101,
|
||||
"deptName": "计算机学院",
|
||||
"deptCategory": "college",
|
||||
"orderNum": 1,
|
||||
"clickable": false,
|
||||
"children": [
|
||||
{
|
||||
"deptId": 103,
|
||||
"parentId": 102,
|
||||
"deptName": "计算机科学与技术专业",
|
||||
"deptCategory": "major",
|
||||
"orderNum": 1,
|
||||
"clickable": false,
|
||||
"children": [
|
||||
{
|
||||
"deptId": 104,
|
||||
"parentId": 103,
|
||||
"deptName": "计算机2023-1班",
|
||||
"deptCategory": "class",
|
||||
"orderNum": 1,
|
||||
"clickable": true,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"deptId": 105,
|
||||
"parentId": 103,
|
||||
"deptName": "计算机2023-2班",
|
||||
"deptCategory": "class",
|
||||
"orderNum": 2,
|
||||
"clickable": true,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应字段说明
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| deptId | long | 部门ID |
|
||||
| parentId | long | 父部门ID |
|
||||
| deptName | string | 部门名称 |
|
||||
| deptCategory | string | 部门类别编码 |
|
||||
| orderNum | integer | 显示顺序 |
|
||||
| clickable | boolean | 是否可点击(只有班级节点可点击) |
|
||||
| children | array | 子部门列表 |
|
||||
|
||||
#### 使用说明
|
||||
- 该接口无需传参,自动获取当前登录用户的权限范围
|
||||
- 返回的树形结构包含完整的层级关系,从根节点到叶子节点
|
||||
- `clickable` 字段标识节点是否可点击,只有班级节点(包含"班"字或dept_category包含"class")设置为true
|
||||
- 前端可根据 `clickable` 字段控制节点的交互行为
|
||||
- 树形结构按 `orderNum` 字段排序
|
||||
|
||||
## 3. 数据字典
|
||||
|
||||
### 3.1 权限类型 (permissionType)
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| 1 | 查看 |
|
||||
| 2 | 编辑 |
|
||||
| 3 | 完全管理 |
|
||||
|
||||
### 3.2 授权类型 (authType)
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| 1 | 全校级 |
|
||||
| 2 | 自定义 |
|
||||
| 3 | 班主任 |
|
||||
|
||||
### 3.3 状态 (status)
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| 0 | 有效 |
|
||||
| 1 | 已撤销 |
|
||||
|
||||
## 4. 权限说明
|
||||
|
||||
### 4.1 数据权限控制
|
||||
- **超级管理员**: 可管理所有学生管理员授权关系
|
||||
- **学工管理员**: 可管理所有学生管理员授权关系
|
||||
- **二级学院管理员**: 只能管理本学院相关的授权关系
|
||||
- **普通用户**: 只能查看自己的权限信息
|
||||
|
||||
### 4.2 操作权限控制
|
||||
- **查询**: 所有有相关权限的用户
|
||||
- **新增**: 学工管理员、二级学院管理员
|
||||
- **修改**: 学工管理员、二级学院管理员
|
||||
- **删除**: 学工管理员、二级学院管理员
|
||||
- **授权**: 学工管理员、二级学院管理员
|
||||
|
||||
## 5. 注意事项
|
||||
|
||||
1. 所有接口都需要Bearer Token认证
|
||||
2. 删除操作为逻辑删除,不会物理删除数据
|
||||
3. 授权关系具有层级性,上级权限包含下级权限
|
||||
4. 支持多租户数据隔离
|
||||
5. 获取当前用户权限树接口会自动过滤无权限的部门
|
||||
6. 部门树构建时会自动补全父节点层级关系
|
||||
|
||||
---
|
||||
|
||||
**文档更新时间**: 2025-07-24
|
||||
**文档版本**: 1.0.0
|
||||
**维护人员**: Cursor AI
|
||||
**更新说明**: 新增学生管理员授权关系管理接口,包含获取当前用户权限部门树功能
|
||||
@@ -0,0 +1,259 @@
|
||||
# 宿舍管理员信息API文档
|
||||
|
||||
## 1. API概述
|
||||
本文档提供宿舍管理员信息相关的API接口说明,包括管理员信息的查询、新增、修改、删除等功能,以及获取可用教师列表的接口。
|
||||
|
||||
## 2. 基本信息
|
||||
- **模块名称**:宿舍管理员信息管理
|
||||
- **接口前缀**:`/xgStudentManager/studentManager`
|
||||
- **数据权限**:需要相应的权限才能访问接口
|
||||
|
||||
## 3. API列表
|
||||
|
||||
### 3.1 查询宿舍管理员信息列表
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager/list`
|
||||
- **请求方式**:GET
|
||||
- **权限标识**:`xgStudentManager:studentManager:list`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|------------|--------|----------|-----------------------------------------------|
|
||||
| managerName| string | 否 | 管理员姓名,支持模糊查询 |
|
||||
| managerType| string | 否 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) |
|
||||
| managerLevel| number | 否 | 管理级别(1-3,1为最高) |
|
||||
| phone | string | 否 | 联系电话 |
|
||||
| gender | string | 否 | 性别(0男 1女 2未知) |
|
||||
| status | string | 否 | 状态(0正常 1停用) |
|
||||
| pageNum | number | 是 | 页码 |
|
||||
| pageSize | number | 是 | 每页记录数 |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"total": 2,
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"managerName": "张三",
|
||||
"managerType": "1",
|
||||
"managerLevel": 1,
|
||||
"userId": 103,
|
||||
"phone": "13800138001",
|
||||
"gender": "0",
|
||||
"status": "0",
|
||||
"remark": "全校管理员",
|
||||
"createTime": "2025-07-24 10:00:00",
|
||||
"updateTime": "2025-07-24 10:00:00"
|
||||
}
|
||||
],
|
||||
"code": 200,
|
||||
"msg": "查询成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 获取宿舍管理员信息详细信息
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager/{id}`
|
||||
- **请求方式**:GET
|
||||
- **权限标识**:`xgStudentManager:studentManager:query`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|-------|--------|----------|-------|
|
||||
| id | number | 是 | 主键ID |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": 1,
|
||||
"managerName": "张三",
|
||||
"managerType": "1",
|
||||
"managerLevel": 1,
|
||||
"userId": 103,
|
||||
"phone": "13800138001",
|
||||
"gender": "0",
|
||||
"status": "0",
|
||||
"remark": "全校管理员",
|
||||
"createTime": "2025-07-24 10:00:00",
|
||||
"updateTime": "2025-07-24 10:00:00"
|
||||
},
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 新增宿舍管理员信息
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager`
|
||||
- **请求方式**:POST
|
||||
- **权限标识**:`xgStudentManager:studentManager:add`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|------------|--------|----------|-----------------------------------------------|
|
||||
| managerName| string | 是 | 管理员姓名 |
|
||||
| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) |
|
||||
| managerLevel| number | 是 | 管理级别(1-3,1为最高) |
|
||||
| userId | number | 是 | 关联用户ID |
|
||||
| phone | string | 是 | 联系电话 |
|
||||
| gender | string | 是 | 性别(0男 1女 2未知) |
|
||||
| status | string | 否 | 状态(0正常 1停用),默认0 |
|
||||
| remark | string | 否 | 备注 |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 修改宿舍管理员信息
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager`
|
||||
- **请求方式**:PUT
|
||||
- **权限标识**:`xgStudentManager:studentManager:edit`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|------------|--------|----------|-----------------------------------------------|
|
||||
| id | number | 是 | 主键ID |
|
||||
| managerName| string | 是 | 管理员姓名 |
|
||||
| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) |
|
||||
| managerLevel| number | 是 | 管理级别(1-3,1为最高) |
|
||||
| userId | number | 是 | 关联用户ID |
|
||||
| phone | string | 是 | 联系电话 |
|
||||
| gender | string | 是 | 性别(0男 1女 2未知) |
|
||||
| status | string | 否 | 状态(0正常 1停用) |
|
||||
| remark | string | 否 | 备注 |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 删除宿舍管理员信息
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager/{ids}`
|
||||
- **请求方式**:DELETE
|
||||
- **权限标识**:`xgStudentManager:studentManager:remove`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|-------|--------|----------|-----------------------|
|
||||
| ids | array | 是 | 主键ID数组,格式:[1,2] |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.6 导出宿舍管理员信息
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager/export`
|
||||
- **请求方式**:POST
|
||||
- **权限标识**:`xgStudentManager:studentManager:export`
|
||||
- **请求参数**:与查询列表接口参数相同
|
||||
- **返回内容**:Excel文件
|
||||
|
||||
### 3.7 获取可用教师列表
|
||||
|
||||
- **接口地址**:`/xgStudentManager/studentManager/listAvailableTeachers`
|
||||
- **请求方式**:GET
|
||||
- **权限标识**:`xgStudentManager:studentManager:list`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 是否必须 | 描述 |
|
||||
|------------|--------|----------|-----------------------------------------------|
|
||||
| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) |
|
||||
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": 101,
|
||||
"managerName": "张三",
|
||||
"phone": "13800138001",
|
||||
"gender": "0"
|
||||
},
|
||||
{
|
||||
"id": 102,
|
||||
"managerName": "李四",
|
||||
"phone": "13800138002",
|
||||
"gender": "1"
|
||||
}
|
||||
],
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
## 获取当前正在教学的班主任信息
|
||||
|
||||
- **接口路径**:`/xgStudentManager/studentManager/listActiveClassTeachers`
|
||||
- **请求方式**:GET
|
||||
- **权限标识**:`xgStudentManager:studentManager:list`
|
||||
- **入参**:
|
||||
- `phone`(可选,string):手机号,模糊查询
|
||||
- `name`(可选,string):姓名,模糊查询
|
||||
- **出参**:
|
||||
- `name`:姓名
|
||||
- `phone`:手机号
|
||||
- `sex`:性别
|
||||
- `className`:班级名称
|
||||
- **返回示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"name": "张三",
|
||||
"phone": "13800001111",
|
||||
"sex": "0",
|
||||
"className": "2025级1班"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
- **说明**:
|
||||
- 仅返回当前“正在教学”的班主任(班级状态为1,未删除,班主任ID有效,用户状态正常)。
|
||||
- 支持姓名和手机号的模糊查询,均为可选参数。
|
||||
|
||||
## 4. 数据结构说明
|
||||
|
||||
### 4.1 宿舍管理员对象
|
||||
|
||||
| 字段名 | 类型 | 描述 |
|
||||
|------------|--------|-----------------------------------------------|
|
||||
| id | number | 主键ID |
|
||||
| managerName| string | 管理员姓名 |
|
||||
| managerType| string | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) |
|
||||
| managerLevel| number | 管理级别(1-3,1为最高) |
|
||||
| userId | number | 关联用户ID |
|
||||
| phone | string | 联系电话 |
|
||||
| gender | string | 性别(0男 1女 2未知) |
|
||||
| status | string | 状态(0正常 1停用) |
|
||||
| deleted | string | 删除标志(0代表存在 1代表删除) |
|
||||
| remark | string | 备注 |
|
||||
| createBy | number | 创建者 |
|
||||
| createTime | date | 创建时间 |
|
||||
| updateBy | number | 更新者 |
|
||||
| updateTime | date | 更新时间 |
|
||||
|
||||
## 5. 错误码说明
|
||||
|
||||
| 错误码 | 描述 | 解决方案 |
|
||||
|-------|----------------|-----------------------------|
|
||||
| 500 | 系统内部错误 | 联系系统管理员 |
|
||||
| 401 | 未授权 | 检查用户权限或重新登录 |
|
||||
| 400 | 请求参数错误 | 检查请求参数是否符合要求 |
|
||||
@@ -51,7 +51,7 @@
|
||||
| pageSize | Integer | 是 | 每页记录数 |
|
||||
| name | String | 否 | 姓名,支持模糊查询 |
|
||||
| idCard | String | 否 | 身份证号 |
|
||||
| gender | String | 否 | 性别(M-男 F-女) |
|
||||
| gender | String | 否 | 性别(0-男 1-女) |
|
||||
| examNumber | String | 否 | 准考证号 |
|
||||
| phone1 | String | 否 | 联系电话 |
|
||||
| examRegion | String | 否 | 中考地区 |
|
||||
@@ -67,7 +67,7 @@
|
||||
| id | Long | 主键ID |
|
||||
| name | String | 姓名 |
|
||||
| idCard | String | 身份证号 |
|
||||
| gender | String | 性别(M-男 F-女) |
|
||||
| gender | String | 性别(0-男 1-女) |
|
||||
| phone1 | String | 联系电话 |
|
||||
| examNumber | String | 准考证号 |
|
||||
| examRegion | String | 中考地区 |
|
||||
@@ -99,7 +99,7 @@
|
||||
| id | Long | 主键ID |
|
||||
| name | String | 姓名 |
|
||||
| idCard | String | 身份证号 |
|
||||
| gender | String | 性别(M-男 F-女) |
|
||||
| gender | String | 性别(0-男 1-女) |
|
||||
| isBoarding | Integer | 是否住校(0-否 1-是) |
|
||||
| birthDate | Date | 出生年月 |
|
||||
| phone1 | String | 联系电话1 |
|
||||
@@ -141,7 +141,7 @@
|
||||
|---------|--------|---------|-----|
|
||||
| name | String | 是 | 姓名 |
|
||||
| idCard | String | 是 | 身份证号 |
|
||||
| gender | String | 是 | 性别(M-男 F-女) |
|
||||
| gender | String | 是 | 性别(0-男 1-女) |
|
||||
| isBoarding | Integer | 否 | 是否住校(0-否 1-是) |
|
||||
| birthDate | Date | 否 | 出生年月 |
|
||||
| phone1 | String | 是 | 联系电话1 |
|
||||
@@ -190,7 +190,7 @@
|
||||
| id | Long | 是 | 主键ID |
|
||||
| name | String | 是 | 姓名 |
|
||||
| idCard | String | 是 | 身份证号 |
|
||||
| gender | String | 是 | 性别(M-男 F-女) |
|
||||
| gender | String | 是 | 性别(0-男 1-女) |
|
||||
| isBoarding | Integer | 否 | 是否住校(0-否 1-是) |
|
||||
| birthDate | Date | 否 | 出生年月 |
|
||||
| phone1 | String | 是 | 联系电话1 |
|
||||
|
||||
@@ -37,7 +37,7 @@ public class EnrollmentInfoVo {
|
||||
private Long id; // 主键ID
|
||||
private String name; // 姓名
|
||||
private String idCard; // 身份证号
|
||||
private String gender; // 性别(M-男 F-女)
|
||||
private String gender; // 性别(0-男 1-女)
|
||||
private Boolean isBoarding; // 是否住校
|
||||
private Date birthDate; // 出生日期
|
||||
private String phone1; // 联系手机号码1
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
# 班级干部信息管理API文档
|
||||
|
||||
## 📋 文档信息
|
||||
|
||||
| 项目 | 信息 |
|
||||
|------|------|
|
||||
| **模块名称** | 班级干部信息管理 |
|
||||
| **模块代码** | ruoyi-xg |
|
||||
| **基础路径** | `/xgClassPosMsg/xgClassPosMsg` |
|
||||
| **权限前缀** | `xgClassPosMsg:xgClassPosMsg` |
|
||||
| **版本** | V1.0.0 |
|
||||
| **创建时间** | 2025-01-27 |
|
||||
| **更新时间** | 2025-01-27 |
|
||||
|
||||
## 🎯 API概述
|
||||
|
||||
### 模块说明
|
||||
班级干部信息管理模块提供完整的班级干部信息管理功能,包括班级干部的任命、任期管理、状态跟踪等全生命周期管理,以及用户角色关联功能。
|
||||
|
||||
### 技术规范
|
||||
- **认证方式**: Bearer Token (Sa-Token)
|
||||
- **数据格式**: JSON
|
||||
- **响应格式**: 统一使用R类型或TableDataInfo分页格式
|
||||
- **权限控制**: 基于角色的权限管理(RBAC)
|
||||
|
||||
### 核心特性
|
||||
- **基础管理**: 班级干部信息的增删改查、导入导出
|
||||
- **任期管理**: 任职日期、任期时长、到期提醒
|
||||
- **状态跟踪**: 在任、到期、辞职、免职、调任、休学等状态
|
||||
- **用户角色关联**: 自动建立学生与角色的关联关系
|
||||
- **数据权限**: 支持按部门查询班级干部信息
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 班级干部信息VO (XgClassPosMsgVo)
|
||||
|
||||
```java
|
||||
{
|
||||
"id": 1, // 主键ID(雪花ID)
|
||||
"deleted": 0, // 删除标志(0代表存在 1代表删除)
|
||||
"classId": 101, // 班级ID,关联xg_class_msg.id
|
||||
"className": "计算机2023-1班", // 班级名称(联表查询获取)
|
||||
"studentId": 1001, // 学生ID,关联xg_student_msg.id
|
||||
"studentNo": "2023001", // 学号
|
||||
"studentName": "张三", // 学生姓名(冗余字段)
|
||||
"positionCode": "monitor", // 职务编码,关联xg_class_pos_dict.position_code
|
||||
"positionName": "班长", // 职务名称(联表查询获取)
|
||||
"appointmentDate": "2024-09-01", // 任职日期
|
||||
"termStartDate": "2024-09-01", // 任期开始日期
|
||||
"termEndDate": "2025-07-01", // 任期结束日期
|
||||
"termDuration": 10, // 任期时长(月)
|
||||
"isCurrent": 1, // 是否现任:0-否,1-是
|
||||
"cadreStatus": "1", // 学生职务任职状态:1-在任,2-到期,3-辞职,4-免职,5-调任,6-休学
|
||||
"appointmentReason": "综合表现优秀", // 任命原因
|
||||
"appointmentMethod": "appointment", // 学生职务任命方式:appointment-任命,election-选举,recommendation-推荐
|
||||
"dismissalDate": null, // 离任日期
|
||||
"dismissalReason": null, // 离任原因
|
||||
"remark": "备注信息", // 备注信息
|
||||
"createBy": 1, // 创建者
|
||||
"createTime": "2024-09-01 10:00:00", // 创建时间
|
||||
"updateBy": 1, // 更新者
|
||||
"updateTime": "2024-09-01 10:00:00" // 更新时间
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 API接口列表
|
||||
|
||||
### 1. 基础管理接口
|
||||
|
||||
#### 1.1 查询班级干部信息列表
|
||||
- **接口路径**: GET `/xgClassPosMsg/xgClassPosMsg/list`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:list`
|
||||
- **功能描述**: 分页查询班级干部信息列表,支持按部门查询
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| pageNum | integer | 否 | 页码,默认1 |
|
||||
| pageSize | integer | 否 | 每页大小,默认10 |
|
||||
| deptId | long | 否 | 部门ID,用于按部门查询班级干部信息 |
|
||||
| classId | long | 否 | 班级ID |
|
||||
| studentId | long | 否 | 学生ID |
|
||||
| studentNo | string | 否 | 学号(模糊查询) |
|
||||
| studentName | string | 否 | 学生姓名(模糊查询) |
|
||||
| positionCode | string | 否 | 职务编码 |
|
||||
| appointmentDate | string | 否 | 任职日期 |
|
||||
| termStartDate | string | 否 | 任期开始日期 |
|
||||
| termEndDate | string | 否 | 任期结束日期 |
|
||||
| termDuration | integer | 否 | 任期时长(月) |
|
||||
| isCurrent | integer | 否 | 是否现任:0-否,1-是 |
|
||||
| cadreStatus | string | 否 | 学生职务任职状态 |
|
||||
| appointmentReason | string | 否 | 任命原因 |
|
||||
| appointmentMethod | string | 否 | 学生职务任命方式 |
|
||||
| dismissalDate | string | 否 | 离任日期 |
|
||||
| dismissalReason | string | 否 | 离任原因 |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1班",
|
||||
"studentId": 1001,
|
||||
"studentNo": "2023001",
|
||||
"studentName": "张三",
|
||||
"positionCode": "monitor",
|
||||
"positionName": "班长",
|
||||
"appointmentDate": "2024-09-01",
|
||||
"termStartDate": "2024-09-01",
|
||||
"termEndDate": "2025-07-01",
|
||||
"termDuration": 10,
|
||||
"isCurrent": 1,
|
||||
"cadreStatus": "1",
|
||||
"appointmentReason": "综合表现优秀",
|
||||
"appointmentMethod": "appointment",
|
||||
"createTime": "2024-09-01 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 获取班级干部信息详情
|
||||
- **接口路径**: GET `/xgClassPosMsg/xgClassPosMsg/{id}`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:query`
|
||||
- **功能描述**: 根据主键获取班级干部信息详细信息
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | long | 是 | 主键ID |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"classId": 101,
|
||||
"className": "计算机2023-1班",
|
||||
"studentId": 1001,
|
||||
"studentNo": "2023001",
|
||||
"studentName": "张三",
|
||||
"positionCode": "monitor",
|
||||
"positionName": "班长",
|
||||
"appointmentDate": "2024-09-01",
|
||||
"termStartDate": "2024-09-01",
|
||||
"termEndDate": "2025-07-01",
|
||||
"termDuration": 10,
|
||||
"isCurrent": 1,
|
||||
"cadreStatus": "1",
|
||||
"appointmentReason": "综合表现优秀",
|
||||
"appointmentMethod": "appointment",
|
||||
"dismissalDate": null,
|
||||
"dismissalReason": null,
|
||||
"remark": "备注信息",
|
||||
"createTime": "2024-09-01 10:00:00",
|
||||
"updateTime": "2024-09-01 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 新增班级干部信息
|
||||
- **接口路径**: POST `/xgClassPosMsg/xgClassPosMsg`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:add`
|
||||
- **功能描述**: 新增班级干部信息,同时自动建立用户角色关联
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"classId": 101,
|
||||
"studentId": 1001,
|
||||
"studentNo": "2023001",
|
||||
"studentName": "张三",
|
||||
"positionCode": "monitor",
|
||||
"appointmentDate": "2024-09-01",
|
||||
"termStartDate": "2024-09-01",
|
||||
"termEndDate": "2025-07-01",
|
||||
"termDuration": 10,
|
||||
"isCurrent": 1,
|
||||
"cadreStatus": "1",
|
||||
"appointmentReason": "综合表现优秀",
|
||||
"appointmentMethod": "appointment",
|
||||
"remark": "备注信息"
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "新增成功"
|
||||
}
|
||||
```
|
||||
|
||||
**重要说明**:
|
||||
- 新增班级干部信息时,系统会自动向 `sys_user_role` 表插入一条数据
|
||||
- `user_id` = 当前记录的 `studentId`
|
||||
- `role_id` = 当前记录的 `id`(班级干部信息ID)
|
||||
- 此操作在事务中进行,确保数据一致性
|
||||
|
||||
#### 1.4 修改班级干部信息
|
||||
- **接口路径**: PUT `/xgClassPosMsg/xgClassPosMsg`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:edit`
|
||||
- **功能描述**: 修改班级干部信息
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"classId": 101,
|
||||
"studentId": 1001,
|
||||
"studentNo": "2023001",
|
||||
"studentName": "张三",
|
||||
"positionCode": "monitor",
|
||||
"appointmentDate": "2024-09-01",
|
||||
"termStartDate": "2024-09-01",
|
||||
"termEndDate": "2025-07-01",
|
||||
"termDuration": 10,
|
||||
"isCurrent": 1,
|
||||
"cadreStatus": "1",
|
||||
"appointmentReason": "综合表现优秀",
|
||||
"appointmentMethod": "appointment",
|
||||
"remark": "修改后的备注信息"
|
||||
}
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "修改成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.5 删除班级干部信息
|
||||
- **接口路径**: DELETE `/xgClassPosMsg/xgClassPosMsg/{ids}`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:remove`
|
||||
- **功能描述**: 删除班级干部信息(支持批量删除),同时删除对应的用户角色关联
|
||||
|
||||
**请求参数**:
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| ids | string | 是 | 主键ID,多个用逗号分隔 |
|
||||
|
||||
**响应数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "删除成功"
|
||||
}
|
||||
```
|
||||
|
||||
**重要说明**:
|
||||
- 删除班级干部信息时,系统会自动删除 `sys_user_role` 表中对应的角色关联
|
||||
- 删除操作会先清理关联数据,再删除主数据
|
||||
- 此操作在事务中进行,确保数据一致性
|
||||
|
||||
#### 1.6 导出班级干部信息
|
||||
- **接口路径**: POST `/xgClassPosMsg/xgClassPosMsg/export`
|
||||
- **权限标识**: `xgClassPosMsg:xgClassPosMsg:export`
|
||||
- **功能描述**: 导出班级干部信息列表
|
||||
|
||||
**请求参数**: 同列表查询参数
|
||||
|
||||
**响应数据**: Excel文件下载
|
||||
|
||||
## 🔐 用户角色关联功能
|
||||
|
||||
### 功能说明
|
||||
班级干部信息管理模块集成了用户角色关联功能,确保班级干部信息与系统权限管理的一致性。
|
||||
|
||||
### 关联规则
|
||||
1. **新增关联**: 新增班级干部信息时,自动建立用户角色关联
|
||||
- `sys_user_role.user_id` = `xg_class_pos_msg.student_id`
|
||||
- `sys_user_role.role_id` = `xg_class_pos_msg.id`
|
||||
|
||||
2. **删除关联**: 删除班级干部信息时,自动删除对应的用户角色关联
|
||||
- 根据 `role_id` 删除 `sys_user_role` 表中的记录
|
||||
|
||||
### 事务处理
|
||||
- 所有用户角色关联操作都在事务中进行
|
||||
- 关联操作失败不会影响主业务流程,但会记录警告日志
|
||||
- 使用 `@Transactional(rollbackFor = Exception.class)` 确保数据一致性
|
||||
|
||||
### 异常处理
|
||||
- 用户角色关联操作异常会被捕获并记录日志
|
||||
- 不会抛出异常影响主业务流程
|
||||
- 通过日志记录操作结果和异常信息
|
||||
|
||||
## 📝 数据字典
|
||||
|
||||
### 学生职务任职状态 (cadre_status)
|
||||
| 编码 | 名称 | 说明 |
|
||||
|------|------|------|
|
||||
| 1 | 在任 | 正常任职状态 |
|
||||
| 2 | 到期 | 任期已结束 |
|
||||
| 3 | 辞职 | 主动辞职 |
|
||||
| 4 | 免职 | 被免职 |
|
||||
| 5 | 调任 | 调任其他职务 |
|
||||
| 6 | 休学 | 因休学暂停职务 |
|
||||
|
||||
### 学生职务任命方式 (appointment_method)
|
||||
| 编码 | 名称 | 说明 |
|
||||
|------|------|------|
|
||||
| appointment | 任命 | 直接任命 |
|
||||
| election | 选举 | 通过选举产生 |
|
||||
| recommendation | 推荐 | 通过推荐产生 |
|
||||
|
||||
### 是否现任 (is_current)
|
||||
| 编码 | 名称 | 说明 |
|
||||
|------|------|------|
|
||||
| 0 | 否 | 非现任职务 |
|
||||
| 1 | 是 | 现任职务 |
|
||||
|
||||
## 🔒 权限说明
|
||||
|
||||
### 权限标识列表
|
||||
|
||||
| 权限标识 | 权限名称 | 说明 |
|
||||
|----------|----------|------|
|
||||
| xgClassPosMsg:xgClassPosMsg:list | 班级干部信息列表 | 查看班级干部信息列表 |
|
||||
| xgClassPosMsg:xgClassPosMsg:query | 班级干部信息查询 | 查询班级干部信息详情 |
|
||||
| xgClassPosMsg:xgClassPosMsg:add | 班级干部信息新增 | 新增班级干部信息 |
|
||||
| xgClassPosMsg:xgClassPosMsg:edit | 班级干部信息修改 | 修改班级干部信息 |
|
||||
| xgClassPosMsg:xgClassPosMsg:remove | 班级干部信息删除 | 删除班级干部信息 |
|
||||
| xgClassPosMsg:xgClassPosMsg:export | 班级干部信息导出 | 导出班级干部信息 |
|
||||
|
||||
### 数据权限
|
||||
- 支持按部门查询班级干部信息
|
||||
- 通过 `deptId` 参数控制数据权限范围
|
||||
- 自动包含子部门的数据
|
||||
|
||||
## 🚨 错误码说明
|
||||
|
||||
| 错误码 | 错误信息 | 说明 |
|
||||
|--------|----------|------|
|
||||
| 40001 | 学生不存在 | 指定的学生ID不存在 |
|
||||
| 40002 | 班级不存在 | 指定的班级ID不存在 |
|
||||
| 40003 | 职务不存在 | 指定的职务编码不存在 |
|
||||
| 40004 | 学生已担任该职务 | 学生已经担任该职务 |
|
||||
| 40005 | 班级干部记录不存在 | 指定的班级干部记录不存在 |
|
||||
| 40006 | 操作权限不足 | 当前用户没有操作权限 |
|
||||
| 40007 | 数据校验失败 | 提交的数据不符合规则 |
|
||||
| 40008 | 用户角色关联失败 | 用户角色关联操作失败 |
|
||||
|
||||
## 📋 使用示例
|
||||
|
||||
### 1. 查询班级干部信息
|
||||
```javascript
|
||||
// 查询指定部门的班级干部信息
|
||||
const response = await api.get('/xgClassPosMsg/xgClassPosMsg/list', {
|
||||
params: {
|
||||
deptId: 101,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
console.log(response.data);
|
||||
```
|
||||
|
||||
### 2. 新增班级干部
|
||||
```javascript
|
||||
// 新增班级干部信息
|
||||
const addData = {
|
||||
classId: 101,
|
||||
studentId: 1001,
|
||||
studentNo: "2023001",
|
||||
studentName: "张三",
|
||||
positionCode: "monitor",
|
||||
appointmentDate: "2024-09-01",
|
||||
termStartDate: "2024-09-01",
|
||||
termEndDate: "2025-07-01",
|
||||
termDuration: 10,
|
||||
isCurrent: 1,
|
||||
cadreStatus: "1",
|
||||
appointmentReason: "综合表现优秀",
|
||||
appointmentMethod: "appointment"
|
||||
};
|
||||
const response = await api.post('/xgClassPosMsg/xgClassPosMsg', addData);
|
||||
```
|
||||
|
||||
### 3. 删除班级干部
|
||||
```javascript
|
||||
// 删除班级干部信息
|
||||
const response = await api.delete('/xgClassPosMsg/xgClassPosMsg/1,2,3');
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **数据一致性**: 班级干部信息与用户角色关联保持一致
|
||||
2. **权限控制**: 严格按照角色权限进行操作控制
|
||||
3. **事务管理**: 所有关联操作都在事务中进行
|
||||
4. **任期管理**: 注意任期时间的合理性和连续性
|
||||
5. **状态管理**: 正确维护班级干部的任职状态
|
||||
6. **并发控制**: 防止同时操作导致的数据冲突
|
||||
7. **日志记录**: 重要操作都会记录详细日志
|
||||
|
||||
## 📈 更新日志
|
||||
|
||||
| 版本 | 日期 | 更新内容 |
|
||||
|------|------|----------|
|
||||
| V1.0.0 | 2025-01-27 | 初始版本,完整的班级干部信息管理API |
|
||||
| V1.0.1 | 2025-01-27 | 新增用户角色关联功能 |
|
||||
|
||||
---
|
||||
|
||||
**文档维护**: Cursor AI 辅助
|
||||
**最后更新**: 2025-01-27
|
||||
**文档状态**: 已完成
|
||||
+145
-2
@@ -398,6 +398,122 @@ def run_all_tests(self):
|
||||
3. **缓存策略**:对频繁查询的字典数据使用 Redis 缓存
|
||||
4. **接口响应优化**:减少不必要的字段传输
|
||||
|
||||
## 📁 文件下载最佳实践 (2025-08-02 新增)
|
||||
|
||||
### 核心问题解决
|
||||
|
||||
基于OSS文件下载功能的修复经验,总结文件下载相关的最佳实践。
|
||||
|
||||
#### 1. 响应头设置规范
|
||||
|
||||
**🔴 关键点:二进制文件下载不要设置charset**
|
||||
|
||||
```java
|
||||
// ❌ 错误方式 - 会导致下载失败
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
|
||||
|
||||
// ✅ 正确方式 - 纯二进制类型
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
|
||||
// ✅ 必需的缓存控制头
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
```
|
||||
|
||||
#### 2. Content-Length 正确设置
|
||||
|
||||
```java
|
||||
// ❌ 可能失效的方法引用
|
||||
storage.download(fileName, response.getOutputStream(), response::setContentLengthLong);
|
||||
|
||||
// ✅ 确保安全的设置方式
|
||||
storage.download(fileName, response.getOutputStream(), contentLength -> {
|
||||
if (contentLength != null && contentLength > 0) {
|
||||
response.setContentLengthLong(contentLength);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. 输出流处理
|
||||
|
||||
```java
|
||||
try {
|
||||
// 文件下载逻辑
|
||||
storage.download(fileName, response.getOutputStream(), contentLengthConsumer);
|
||||
|
||||
// 🔴 关键:必须手动刷新输出流
|
||||
response.getOutputStream().flush();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("文件下载失败: " + e.getMessage());
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 完整的文件下载模板
|
||||
|
||||
```java
|
||||
@GetMapping("/download/{fileId}")
|
||||
public void downloadFile(@PathVariable Long fileId, HttpServletResponse response) {
|
||||
try {
|
||||
// 1. 权限验证
|
||||
if (!hasDownloadPermission(fileId)) {
|
||||
throw new ServiceException("无权限下载该文件");
|
||||
}
|
||||
|
||||
// 2. 获取文件信息
|
||||
FileVo fileInfo = fileService.getById(fileId);
|
||||
if (fileInfo == null) {
|
||||
throw new ServiceException("文件不存在");
|
||||
}
|
||||
|
||||
// 3. 设置响应头
|
||||
FileUtils.setAttachmentResponseHeader(response, fileInfo.getOriginalName());
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
// 4. 执行下载
|
||||
OssClient storage = OssFactory.instance(fileInfo.getService());
|
||||
storage.download(fileInfo.getFileName(), response.getOutputStream(), contentLength -> {
|
||||
if (contentLength != null && contentLength > 0) {
|
||||
response.setContentLengthLong(contentLength);
|
||||
}
|
||||
});
|
||||
|
||||
// 5. 刷新输出流
|
||||
response.getOutputStream().flush();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("文件下载失败: {}", e.getMessage(), e);
|
||||
throw new ServiceException("文件下载失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 常见问题排查
|
||||
|
||||
#### 问题1:文件传输完成但客户端未收到
|
||||
- **原因**:Content-Type包含charset或缺少flush()
|
||||
- **解决**:移除charset,添加手动flush
|
||||
|
||||
#### 问题2:下载的文件损坏
|
||||
- **原因**:Content-Length设置错误
|
||||
- **解决**:使用lambda表达式确保Content-Length正确设置
|
||||
|
||||
#### 问题3:浏览器缓存导致下载异常
|
||||
- **原因**:缺少缓存控制头
|
||||
- **解决**:设置no-cache相关响应头
|
||||
|
||||
### 测试验证标准
|
||||
|
||||
1. **Postman测试**:能正确下载文件
|
||||
2. **浏览器测试**:点击下载链接正常
|
||||
3. **文件完整性**:下载文件与原文件MD5一致
|
||||
4. **不同文件类型**:图片、文档、压缩包都能正常下载
|
||||
5. **权限控制**:无权限用户被正确拒绝
|
||||
|
||||
## 🔄 持续改进
|
||||
|
||||
### 规范迭代
|
||||
@@ -438,5 +554,32 @@ def run_all_tests(self):
|
||||
**总结**:本最佳实践基于场地预约管理系统的成功开发经验,形成了一套完整的 API 开发标准流程,为后续 API 模块开发提供了可复制的标准模板和质量保证体系。
|
||||
|
||||
**维护人员**:开发团队
|
||||
**最后更新**:2025-07-01
|
||||
**文档版本**:v1.0
|
||||
**最后更新**:2025-08-02
|
||||
**文档版本**:v1.1 (新增文件下载最佳实践)
|
||||
|
||||
## 前端开发最佳实践
|
||||
|
||||
### 🎯 组件开发规范
|
||||
|
||||
#### ImagePreview图片预览组件
|
||||
- **认证图片加载**: 通过axios获取blob数据,确保认证信息传递
|
||||
- **内存管理**: 使用`onBeforeUnmount`清理blob URLs,防止内存泄漏
|
||||
- **缓存优化**: 实现blob URL缓存机制,提升性能
|
||||
|
||||
**核心实现**:
|
||||
```javascript
|
||||
// 认证图片加载
|
||||
const getImageBlobUrl = async (imageUrl: string): Promise<string> => {
|
||||
const response = await request({
|
||||
url: imageUrl,
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
});
|
||||
return URL.createObjectURL(response.data);
|
||||
};
|
||||
|
||||
// 生命周期管理
|
||||
onBeforeUnmount(() => {
|
||||
blobUrls.value.forEach(url => URL.revokeObjectURL(url));
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,131 @@
|
||||
# ImagePreview 组件使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
ImagePreview 是一个图片预览组件,支持两种模式:
|
||||
1. **普通模式**:直接使用URL字符串
|
||||
2. **OSS模式**:通过ossid调用接口获取真实URL
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ 支持单张和多张图片预览
|
||||
- ✅ 支持OSS ID模式,自动获取真实URL
|
||||
- ✅ 内置缓存机制,避免重复请求
|
||||
- ✅ 加载状态显示
|
||||
- ✅ 错误状态处理
|
||||
- ✅ 响应式尺寸设置
|
||||
- ✅ 图片预览功能
|
||||
|
||||
## 组件属性
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| src | String | '' | 图片源,可以是URL或OSS ID |
|
||||
| width | Number/String | '' | 图片宽度 |
|
||||
| height | Number/String | '' | 图片高度 |
|
||||
| isOssId | Boolean | false | 是否为OSS ID模式 |
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 普通模式(直接使用URL)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImagePreview
|
||||
src="https://example.com/image1.jpg,https://example.com/image2.jpg"
|
||||
:width="200"
|
||||
:height="150"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 2. OSS模式(通过ossid获取URL)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImagePreview
|
||||
src="123,456,789"
|
||||
:width="200"
|
||||
:height="150"
|
||||
:is-oss-id="true"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3. 单张图片
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImagePreview
|
||||
src="123"
|
||||
:width="100"
|
||||
:height="100"
|
||||
:is-oss-id="true"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 核心功能
|
||||
|
||||
1. **OSS ID解析**:支持逗号分隔的多个OSS ID
|
||||
2. **URL缓存**:使用Map缓存已获取的URL,避免重复请求
|
||||
3. **异步加载**:通过watch监听src变化,异步获取真实URL
|
||||
4. **错误处理**:完善的错误处理和日志记录
|
||||
|
||||
### API调用
|
||||
|
||||
组件内部使用 `listByIds` API获取OSS文件信息:
|
||||
|
||||
```typescript
|
||||
// 通过ossid获取真实URL
|
||||
const getUrlByOssId = async (ossId: string): Promise<string> => {
|
||||
// 检查缓存
|
||||
if (urlCache.value.has(ossId)) {
|
||||
return urlCache.value.get(ossId)!;
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
const response = await listByIds(ossId);
|
||||
const ossList: OssVO[] = response.data;
|
||||
|
||||
if (ossList && ossList.length > 0) {
|
||||
const url = ossList[0].url;
|
||||
// 缓存结果
|
||||
urlCache.value.set(ossId, url);
|
||||
return url;
|
||||
}
|
||||
return '';
|
||||
} catch (error) {
|
||||
console.error('获取OSS URL失败:', error);
|
||||
return '';
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 缓存机制
|
||||
|
||||
```typescript
|
||||
const urlCache = ref<Map<string, string>>(new Map());
|
||||
```
|
||||
|
||||
- 使用Map结构缓存ossid到url的映射
|
||||
- 避免重复的API调用
|
||||
- 提升用户体验和性能
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **网络请求**:OSS模式下会发起网络请求,确保网络连接正常
|
||||
2. **权限控制**:确保用户有访问OSS文件的权限
|
||||
3. **错误处理**:组件内置错误处理,但建议在业务层面也做相应处理
|
||||
4. **性能优化**:缓存机制已内置,无需额外优化
|
||||
|
||||
## 更新记录
|
||||
|
||||
- **2025-08-02**:修复组件,支持OSS ID模式,添加缓存机制和加载状态
|
||||
- 修复了导入错误和computed未定义的问题
|
||||
- 添加了完整的错误处理和日志记录
|
||||
@@ -0,0 +1,261 @@
|
||||
# ImageUpload组件新文件显示修复说明
|
||||
|
||||
**更新时间**: 2025-01-27
|
||||
**版本**: v1.1.0
|
||||
**修复类型**: Bug修复
|
||||
|
||||
## 修复概述
|
||||
|
||||
本次修复解决了ImageUpload组件中新上传文件图片不显示的问题,**特别是修复了通过OSS ID获取图片的关键机制**,确保新上传的文件能够与历史文件一样正常显示。
|
||||
|
||||
## 问题现象
|
||||
|
||||
### 修复前
|
||||
- 新上传的文件显示为空白或占位符
|
||||
- 新上传的文件没有经过认证处理
|
||||
- 新上传的文件缺少必要的属性
|
||||
- **🔴 关键问题**: 新上传文件直接使用URL,而不是通过OSS ID获取
|
||||
|
||||
### 修复后
|
||||
- ✅ 新上传的文件能正常显示
|
||||
- ✅ 新上传的文件经过认证的blob URL转换
|
||||
- ✅ 新上传的文件具有完整的属性
|
||||
- ✅ 支持占位符显示和加载状态
|
||||
- ✅ **🔴 新上传文件通过OSS ID获取图片**
|
||||
|
||||
## 技术改进
|
||||
|
||||
### 1. 🔴 OSS ID获取机制(关键修复)
|
||||
```javascript
|
||||
// 新上传文件异步加载处理 - 优先使用OSS ID
|
||||
const loadPromises = newUploadedFiles.map((item, index) => {
|
||||
return (async () => {
|
||||
try {
|
||||
let blobUrl = '';
|
||||
|
||||
if (item.ossId) {
|
||||
// 🔴 关键修复:通过OSS ID获取预览URL
|
||||
blobUrl = await getPreviewUrlByOssId(item.ossId);
|
||||
} else if (item.url) {
|
||||
// 降级处理:直接URL
|
||||
blobUrl = await getPreviewImageBlobUrl(item.url);
|
||||
}
|
||||
|
||||
// 更新文件列表
|
||||
updateFileList(item, blobUrl);
|
||||
} catch (error) {
|
||||
// 降级处理:重新通过OSS ID获取
|
||||
fallbackToOssId(item);
|
||||
}
|
||||
})();
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 占位符显示机制
|
||||
```javascript
|
||||
// 占位符项目创建
|
||||
const placeholderItems = newUploadedFiles.map((item, index) => ({
|
||||
name: item.name,
|
||||
url: 'data:image/svg+xml;base64,...', // 加载中占位图片
|
||||
originalUrl: item.url,
|
||||
ossId: item.ossId,
|
||||
isLoaded: false,
|
||||
isPlaceholder: true
|
||||
}));
|
||||
```
|
||||
|
||||
### 3. 错误处理和降级机制
|
||||
- 网络异常时自动降级到原始URL
|
||||
- 完整的错误日志记录
|
||||
- 用户友好的错误提示
|
||||
- **🔴 多级降级策略**: OSS ID → URL → 重新OSS ID → 原始URL
|
||||
|
||||
## 🔴 OSS ID获取流程
|
||||
|
||||
### 1. 上传成功响应
|
||||
```javascript
|
||||
// 服务器返回的数据结构
|
||||
{
|
||||
code: 200,
|
||||
data: {
|
||||
url: "http://example.com/file.jpg", // 文件URL
|
||||
fileName: "test.jpg", // 文件名
|
||||
ossId: "1951584287279034370" // 🔴 关键:OSS ID
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 前端处理流程
|
||||
```javascript
|
||||
// 1. 接收上传响应
|
||||
const uploadItem = {
|
||||
name: res.data.fileName,
|
||||
url: res.data.url,
|
||||
ossId: res.data.ossId // 🔴 保存OSS ID
|
||||
};
|
||||
|
||||
// 2. 通过OSS ID获取文件信息
|
||||
const ossList = await listByIds(ossId);
|
||||
|
||||
// 3. 获取认证的blob URL
|
||||
const blobUrl = await getPreviewImageBlobUrl(ossList[0].url);
|
||||
|
||||
// 4. 更新文件列表显示
|
||||
fileList[index].url = blobUrl;
|
||||
```
|
||||
|
||||
### 3. 降级处理策略
|
||||
1. **第一优先级**: 通过OSS ID获取图片
|
||||
2. **第二优先级**: 直接使用URL获取图片
|
||||
3. **第三优先级**: 重新尝试OSS ID获取
|
||||
4. **最终降级**: 使用原始URL
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 基本用法
|
||||
```vue
|
||||
<template>
|
||||
<ImageUpload v-model="form.images" :limit="5" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import ImageUpload from '@/components/ImageUpload/index.vue';
|
||||
|
||||
const form = ref({
|
||||
images: ''
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### 高级配置
|
||||
```vue
|
||||
<template>
|
||||
<ImageUpload
|
||||
v-model="form.images"
|
||||
:limit="10"
|
||||
:file-size="5"
|
||||
:file-type="['png', 'jpg', 'jpeg']"
|
||||
:compress-support="true"
|
||||
:compress-target-size="300"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 测试页面
|
||||
使用测试页面验证功能:`web/src/views/demo/ImageUploadTest.vue`
|
||||
|
||||
### 测试步骤
|
||||
1. 打开测试页面
|
||||
2. 上传新图片文件
|
||||
3. 验证图片是否正常显示
|
||||
4. 测试图片预览功能
|
||||
5. 测试删除功能
|
||||
6. **🔴 验证OSS ID获取机制**
|
||||
|
||||
### 验证要点
|
||||
- ✅ 新上传图片正常显示
|
||||
- ✅ 历史图片正常显示
|
||||
- ✅ 混合文件场景正常
|
||||
- ✅ 图片预览功能正常
|
||||
- ✅ 删除功能正常
|
||||
- ✅ 错误处理有效
|
||||
- ✅ **🔴 新上传文件通过OSS ID获取图片**
|
||||
|
||||
## 调试信息
|
||||
|
||||
### 控制台日志
|
||||
组件会在控制台输出详细的调试信息:
|
||||
```
|
||||
handleUploadSuccess:res {code: 200, data: {...}}
|
||||
handleUploadSuccess:file File {...}
|
||||
添加上传项到uploadList: {name: "test.jpg", url: "...", ossId: "123"}
|
||||
uploadedSuccessfully called, number: 1, uploadList length: 1
|
||||
开始处理新上传的文件: [...]
|
||||
通过OSS ID获取预览URL for 123
|
||||
获取到的blob URL for 123: blob:http://...
|
||||
成功更新文件 123
|
||||
```
|
||||
|
||||
### 🔴 OSS ID相关日志
|
||||
```
|
||||
通过OSS ID获取预览URL for 1951584287279034370
|
||||
loadFileImageAsync: 通过OSS ID获取预览URL for 1951584287279034370
|
||||
降级处理:重新通过OSS ID获取 1951584287279034370
|
||||
```
|
||||
|
||||
### 调试方法
|
||||
1. 打开浏览器开发者工具
|
||||
2. 查看Console面板的日志输出
|
||||
3. 根据日志信息排查问题
|
||||
4. **🔴 特别关注OSS ID相关的日志**
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 新上传的图片仍然不显示?
|
||||
**A**: 检查控制台是否有错误信息,确认网络连接正常,OSS服务可用。**特别检查OSS ID获取相关的日志**。
|
||||
|
||||
### Q2: 图片加载很慢?
|
||||
**A**: 这是正常的,因为需要经过OSS ID获取和认证的blob URL转换。可以通过网络优化或CDN加速改善。
|
||||
|
||||
### Q3: 某些图片无法预览?
|
||||
**A**: 可能是权限问题或文件损坏,检查OSS文件是否正常,权限是否正确。**确认是否通过OSS ID正确获取**。
|
||||
|
||||
### Q4: 如何禁用异步加载?
|
||||
**A**: 目前不支持禁用,异步加载和OSS ID获取是必需的认证机制。如需优化,可以考虑缓存策略。
|
||||
|
||||
### Q5: 🔴 为什么必须通过OSS ID获取?
|
||||
**A**: OSS ID获取机制确保:
|
||||
- 文件访问权限验证
|
||||
- 统一的认证处理
|
||||
- 与历史文件处理一致性
|
||||
- 更好的安全性和稳定性
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 1. 缓存机制
|
||||
- blob URL缓存避免重复请求
|
||||
- 预览URL缓存提升响应速度
|
||||
- **🔴 OSS ID信息缓存**
|
||||
|
||||
### 2. 并行处理
|
||||
- 多文件并行加载
|
||||
- 异步处理不阻塞UI
|
||||
- **🔴 OSS ID批量获取**
|
||||
|
||||
### 3. 内存管理
|
||||
- 自动清理blob URL
|
||||
- 组件卸载时释放资源
|
||||
- **🔴 OSS ID缓存清理**
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.1.0 (2025-01-27)
|
||||
- 🐛 修复新上传文件图片不显示问题
|
||||
- ✨ 添加异步加载机制
|
||||
- ✨ 添加占位符显示
|
||||
- ✨ 完善错误处理
|
||||
- 📝 添加详细调试日志
|
||||
- 🎨 优化样式和动画
|
||||
- **🔴 关键修复**: 新上传文件通过OSS ID获取图片
|
||||
|
||||
### v1.0.0 (之前版本)
|
||||
- 基础图片上传功能
|
||||
- 历史文件显示
|
||||
- 图片预览功能
|
||||
|
||||
## 技术支持
|
||||
|
||||
如遇到问题,请:
|
||||
1. 查看控制台错误信息
|
||||
2. 检查网络连接状态
|
||||
3. 验证OSS服务配置
|
||||
4. 参考测试页面示例
|
||||
5. **🔴 特别检查OSS ID获取相关日志**
|
||||
6. 联系技术支持团队
|
||||
|
||||
---
|
||||
|
||||
**注意**: 本次修复向后兼容,不会影响现有功能的使用。**关键改进是确保新上传文件通过OSS ID获取图片,与历史文件处理机制保持一致**。
|
||||
@@ -0,0 +1,260 @@
|
||||
# SQL缓存导出配置使用指南
|
||||
|
||||
## 🎯 功能概述
|
||||
|
||||
SQL缓存导出配置功能允许您在导出Excel时,通过配置SQL语句来加载数据到缓存进行匹配,实现高性能的数据转换。
|
||||
|
||||
## 🚀 核心特性
|
||||
|
||||
### 1. 高性能缓存机制
|
||||
- **静态缓存**:使用`ConcurrentHashMap`存储SQL查询结果
|
||||
- **预加载机制**:导出前批量预加载所有SQL数据
|
||||
- **缓存命中优化**:从内存缓存获取数据,避免重复数据库查询
|
||||
- **线程安全**:支持多用户并发导出
|
||||
|
||||
### 2. 灵活的SQL配置
|
||||
- **自定义SQL**:支持任意SQL查询语句
|
||||
- **字段映射**:可配置值字段和标签字段
|
||||
- **动态参数**:支持SQL参数占位符
|
||||
- **配置管理**:统一的配置注册和管理
|
||||
|
||||
### 3. 简单易用的注解
|
||||
- **@ExcelSqlCacheFormat**:配置SQL缓存转换
|
||||
- **自动转换**:值到标签的自动转换
|
||||
- **反向查找**:支持标签到值的反向转换
|
||||
|
||||
## 📋 使用步骤
|
||||
|
||||
### 1. 注册SQL配置
|
||||
|
||||
#### 方式一:通过配置初始化器(推荐)
|
||||
```java
|
||||
@Component
|
||||
public class SqlCacheConfigInitializer implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private SqlCacheConfigService sqlCacheConfigService;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
// 注册SQL配置
|
||||
sqlCacheConfigService.registerSqlConfig(
|
||||
"student_class_info", // SQL键
|
||||
"SELECT class_id as id, class_name as name FROM xg_class WHERE deleted = 0", // SQL语句
|
||||
"id", // 值字段
|
||||
"name" // 标签字段
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 方式二:通过服务直接注册
|
||||
```java
|
||||
@Autowired
|
||||
private SqlCacheConfigService sqlCacheConfigService;
|
||||
|
||||
public void registerConfig() {
|
||||
sqlCacheConfigService.registerSqlConfig(
|
||||
"college_info",
|
||||
"SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0",
|
||||
"id",
|
||||
"name"
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 在VO类中使用注解
|
||||
|
||||
```java
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class XgStudentMsgExportVo implements Serializable {
|
||||
|
||||
/**
|
||||
* 班级名称 - 使用SQL缓存转换
|
||||
*/
|
||||
@ExcelProperty(value = "班级名称", converter = ExcelSqlCacheConvert.class)
|
||||
@ExcelSqlCacheFormat(
|
||||
sqlKey = "student_class_info", // 对应注册的SQL键
|
||||
valueColumn = "id", // 值字段名
|
||||
labelColumn = "name" // 标签字段名
|
||||
)
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 学院名称 - 使用SQL缓存转换
|
||||
*/
|
||||
@ExcelProperty(value = "学院名称", converter = ExcelSqlCacheConvert.class)
|
||||
@ExcelSqlCacheFormat(
|
||||
sqlKey = "college_info",
|
||||
valueColumn = "id",
|
||||
labelColumn = "name"
|
||||
)
|
||||
private String collegeName;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 在Controller中预加载缓存
|
||||
|
||||
```java
|
||||
@RestController
|
||||
public class XgStudentMsgController extends BaseController {
|
||||
|
||||
/**
|
||||
* 预加载导出所需的SQL缓存数据
|
||||
*/
|
||||
private void preloadExportSqlData() {
|
||||
try {
|
||||
SqlCacheConfigService sqlCacheConfigService = SpringUtils.getBean(SqlCacheConfigService.class);
|
||||
|
||||
// 预加载SQL配置
|
||||
sqlCacheConfigService.preloadSqlData("student_class_info");
|
||||
sqlCacheConfigService.preloadSqlData("college_info");
|
||||
sqlCacheConfigService.preloadSqlData("major_info");
|
||||
|
||||
log.info("SQL缓存预加载完成");
|
||||
} catch (Exception e) {
|
||||
log.warn("SQL缓存预加载失败,将使用默认处理方式", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出方法
|
||||
*/
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response) {
|
||||
// 预加载缓存
|
||||
preloadExportSqlData();
|
||||
|
||||
// 执行导出
|
||||
List<XgStudentMsgExportVo> list = service.queryExportList();
|
||||
ExcelUtil.exportExcel(list, "学生信息", XgStudentMsgExportVo.class, response);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 配置示例
|
||||
|
||||
### 1. 基础查询配置
|
||||
```java
|
||||
// 班级信息查询
|
||||
"student_class_info" -> "SELECT class_id as id, class_name as name FROM xg_class WHERE deleted = 0"
|
||||
|
||||
// 学院信息查询
|
||||
"college_info" -> "SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0"
|
||||
|
||||
// 专业信息查询
|
||||
"major_info" -> "SELECT major_id as id, major_name as name FROM xg_major WHERE deleted = 0"
|
||||
```
|
||||
|
||||
### 2. 复杂查询配置
|
||||
```java
|
||||
// 带条件的查询
|
||||
"active_teachers" -> "SELECT user_id as id, nick_name as name FROM sys_user WHERE deleted = 0 AND user_type = '00' AND status = '0'"
|
||||
|
||||
// 关联查询
|
||||
"class_with_teacher" -> """
|
||||
SELECT c.class_id as id,
|
||||
CONCAT(c.class_name, ' (', u.nick_name, ')') as name
|
||||
FROM xg_class c
|
||||
LEFT JOIN sys_user u ON c.class_teacher_id = u.user_id
|
||||
WHERE c.deleted = 0
|
||||
"""
|
||||
|
||||
// 聚合查询
|
||||
"dept_student_count" -> """
|
||||
SELECT dept_id as id,
|
||||
CONCAT(dept_name, ' (', COUNT(*), '人)') as name
|
||||
FROM xg_student_msg
|
||||
WHERE deleted = 0
|
||||
GROUP BY dept_id, dept_name
|
||||
"""
|
||||
```
|
||||
|
||||
### 3. 动态参数查询
|
||||
```java
|
||||
// 支持参数的查询(需要特殊处理)
|
||||
"tenant_college_info" -> "SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0 AND tenant_id = ?"
|
||||
```
|
||||
|
||||
## 📊 性能优化
|
||||
|
||||
### 1. 缓存策略
|
||||
- **预加载**:导出前批量加载所有SQL数据
|
||||
- **静态缓存**:使用`ConcurrentHashMap`避免重复查询
|
||||
- **内存优化**:合理控制缓存数据量
|
||||
|
||||
### 2. SQL优化
|
||||
- **索引优化**:确保查询字段有合适的索引
|
||||
- **查询优化**:避免复杂的关联查询
|
||||
- **数据量控制**:限制单次查询的数据量
|
||||
|
||||
### 3. 监控和统计
|
||||
```java
|
||||
// 获取缓存统计信息
|
||||
Map<String, Integer> stats = sqlCacheConfigService.getCacheStats();
|
||||
log.info("SQL缓存统计: {}", stats);
|
||||
|
||||
// 清理缓存
|
||||
sqlCacheConfigService.clearAllCache();
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. SQL安全
|
||||
- **参数化查询**:避免SQL注入风险
|
||||
- **权限控制**:确保SQL查询权限合理
|
||||
- **数据验证**:验证SQL查询结果的正确性
|
||||
|
||||
### 2. 缓存管理
|
||||
- **内存使用**:监控缓存占用的内存
|
||||
- **缓存更新**:数据变更时及时清理缓存
|
||||
- **缓存失效**:设置合理的缓存过期策略
|
||||
|
||||
### 3. 错误处理
|
||||
- **异常捕获**:妥善处理SQL执行异常
|
||||
- **降级策略**:SQL失败时的降级处理
|
||||
- **日志记录**:详细记录错误信息
|
||||
|
||||
## 🔄 与现有功能的对比
|
||||
|
||||
### 1. 与字典转换的对比
|
||||
| 特性 | 字典转换 | SQL缓存转换 |
|
||||
|------|----------|-------------|
|
||||
| 数据源 | 字典表 | 任意表 |
|
||||
| 配置方式 | 字典类型 | SQL语句 |
|
||||
| 灵活性 | 固定格式 | 高度灵活 |
|
||||
| 性能 | 预加载缓存 | 预加载缓存 |
|
||||
| 适用场景 | 标准字典 | 复杂业务数据 |
|
||||
|
||||
### 2. 使用场景
|
||||
- **字典转换**:适用于标准的字典数据(性别、状态等)
|
||||
- **SQL缓存转换**:适用于复杂的业务数据(班级、学院、专业等)
|
||||
|
||||
## 📝 最佳实践
|
||||
|
||||
### 1. 配置管理
|
||||
- 将SQL配置集中管理
|
||||
- 使用有意义的SQL键名
|
||||
- 定期检查和优化SQL语句
|
||||
|
||||
### 2. 性能优化
|
||||
- 合理使用索引
|
||||
- 控制查询数据量
|
||||
- 监控缓存使用情况
|
||||
|
||||
### 3. 错误处理
|
||||
- 实现降级策略
|
||||
- 记录详细日志
|
||||
- 定期检查缓存状态
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
SQL缓存导出配置功能为Excel导出提供了强大的数据转换能力:
|
||||
|
||||
1. **高性能**:通过预加载缓存显著提升导出性能
|
||||
2. **灵活性**:支持任意SQL查询和字段映射
|
||||
3. **易用性**:简单的注解配置即可使用
|
||||
4. **可扩展性**:支持复杂的业务场景
|
||||
|
||||
该功能特别适用于需要从多个业务表获取数据进行导出的场景,能够有效解决传统导出方式中的性能瓶颈问题。
|
||||
@@ -27,8 +27,8 @@
|
||||
### 1. 导入API和类型
|
||||
|
||||
```typescript
|
||||
import { listColleges, collegeTree, listMajorsByCollegeId } from '@/api/classMsg/college';
|
||||
import { SysDeptVo } from '@/api/classMsg/types';
|
||||
import { listColleges, collegeTree, listMajorsByCollegeId } from '@/api/xg/xsjcxx/classmsg/college';
|
||||
import { SysDeptVo } from '@/api/xg/xsjcxx/classmsg/types';
|
||||
```
|
||||
|
||||
### 2. 定义数据变量
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
# 图片上传组件安全改造说明
|
||||
|
||||
## 📋 概述
|
||||
|
||||
为了配合MinIO安全改造,图片上传组件 `ImageUpload/index.vue` 已经进行了安全升级,支持bucket密码验证和预签名URL机制。
|
||||
|
||||
## 🔧 主要改动
|
||||
|
||||
### 1. 新增安全功能
|
||||
- ✅ **Bucket密码验证**: 支持在文件上传时验证bucket访问密码
|
||||
- ✅ **自定义上传**: 使用 `:http-request="customUpload"` 替代默认上传
|
||||
- ✅ **密码输入对话框**: 当需要密码验证时,弹出密码输入界面
|
||||
- ✅ **安全预览**: 文件预览时使用安全机制
|
||||
|
||||
### 2. 新增Props参数
|
||||
|
||||
```typescript
|
||||
interface Props {
|
||||
// ... 原有参数 ...
|
||||
|
||||
// bucket访问密码
|
||||
bucketPassword?: string;
|
||||
|
||||
// 是否启用bucket密码验证
|
||||
enablePasswordValidation?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 基础用法(不启用密码验证)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImageUpload
|
||||
v-model="imageList"
|
||||
:limit="5"
|
||||
:file-size="10"
|
||||
:file-type="['png', 'jpg', 'jpeg']"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 启用密码验证
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImageUpload
|
||||
v-model="imageList"
|
||||
:limit="5"
|
||||
:file-size="10"
|
||||
:file-type="['png', 'jpg', 'jpeg']"
|
||||
:enable-password-validation="true"
|
||||
:bucket-password="bucketPassword"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const imageList = ref([])
|
||||
const bucketPassword = ref('your_bucket_password')
|
||||
</script>
|
||||
```
|
||||
|
||||
### 动态密码验证
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ImageUpload
|
||||
v-model="imageList"
|
||||
:limit="5"
|
||||
:file-size="10"
|
||||
:file-type="['png', 'jpg', 'jpeg']"
|
||||
:enable-password-validation="true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const imageList = ref([])
|
||||
// 不传入bucketPassword,组件会自动弹出密码输入对话框
|
||||
</script>
|
||||
```
|
||||
|
||||
## 🔐 密码验证流程
|
||||
|
||||
### 1. 自动密码验证
|
||||
- 当 `enablePasswordValidation=true` 且 `bucketPassword` 有值时
|
||||
- 组件会自动在请求头中添加 `bucket-password` 参数
|
||||
- 后端验证密码后允许上传
|
||||
|
||||
### 2. 手动密码验证
|
||||
- 当 `enablePasswordValidation=true` 且 `bucketPassword` 为空时
|
||||
- 用户选择文件后,弹出密码输入对话框
|
||||
- 用户输入密码后,组件验证密码并执行上传
|
||||
|
||||
## 📝 上传接口变更
|
||||
|
||||
### 原有接口
|
||||
```javascript
|
||||
// 直接上传到 /resource/oss/upload
|
||||
const uploadImgUrl = baseUrl + '/resource/oss/upload'
|
||||
```
|
||||
|
||||
### 新安全接口
|
||||
```javascript
|
||||
// 使用自定义上传方法
|
||||
const customUpload = async (options) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', options.file)
|
||||
|
||||
const response = await fetch(uploadImgUrl.value, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers.value,
|
||||
'bucket-password': bucketPassword || passwordForm.bucketPassword || ''
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
|
||||
// 处理响应...
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 预览功能升级
|
||||
|
||||
### 安全预览
|
||||
```javascript
|
||||
const handlePictureCardPreview = async (file) => {
|
||||
try {
|
||||
if (file.ossId) {
|
||||
// 使用安全预览机制
|
||||
dialogImageUrl.value = file.url // 简化处理,实际应调用安全预览API
|
||||
} else {
|
||||
// 直接使用URL预览
|
||||
dialogImageUrl.value = file.url
|
||||
}
|
||||
dialogVisible.value = true
|
||||
} catch (error) {
|
||||
console.error('预览失败:', error)
|
||||
proxy?.$modal.msgError('预览失败')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. 后端接口要求
|
||||
- 上传接口需要支持 `bucket-password` 请求头
|
||||
- 需要验证bucket密码的有效性
|
||||
- 返回标准的响应格式:`{ code: 200, data: { fileName, url, ossId } }`
|
||||
|
||||
### 2. 密码安全
|
||||
- 密码不会在组件中明文存储
|
||||
- 密码验证失败时会提示用户重新输入
|
||||
- 建议使用强密码并定期更换
|
||||
|
||||
### 3. 兼容性
|
||||
- 组件保持向后兼容,不启用密码验证时行为不变
|
||||
- 原有的文件上传、预览、删除功能正常工作
|
||||
|
||||
## 🔄 迁移指南
|
||||
|
||||
### 从旧版本迁移
|
||||
1. **不启用密码验证**: 无需修改,组件自动兼容
|
||||
2. **启用密码验证**: 添加 `enable-password-validation="true"` 属性
|
||||
3. **提供密码**: 通过 `bucket-password` 属性或对话框输入
|
||||
|
||||
### 示例迁移
|
||||
```vue
|
||||
<!-- 旧版本 -->
|
||||
<ImageUpload v-model="images" />
|
||||
|
||||
<!-- 新版本(启用密码验证) -->
|
||||
<ImageUpload
|
||||
v-model="images"
|
||||
:enable-password-validation="true"
|
||||
:bucket-password="bucketPassword"
|
||||
/>
|
||||
```
|
||||
|
||||
## 🧪 测试建议
|
||||
|
||||
### 1. 功能测试
|
||||
- [ ] 基础文件上传功能正常
|
||||
- [ ] 密码验证功能正常
|
||||
- [ ] 密码错误时提示正确
|
||||
- [ ] 预览功能正常
|
||||
- [ ] 删除功能正常
|
||||
|
||||
### 2. 安全测试
|
||||
- [ ] 无密码时无法上传
|
||||
- [ ] 错误密码时无法上传
|
||||
- [ ] 密码验证失败时提示正确
|
||||
- [ ] 密码不会在控制台泄露
|
||||
|
||||
### 3. 兼容性测试
|
||||
- [ ] 不启用密码验证时功能正常
|
||||
- [ ] 原有页面无需修改即可使用
|
||||
- [ ] 文件格式限制正常
|
||||
- [ ] 文件大小限制正常
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [MinIO安全改造方案](../中间件配置/minio-security-solution.md)
|
||||
- [Bucket密码管理API](../API/用户认证登录API.md)
|
||||
- [文件访问安全API](../API/API文档基础规范.md)
|
||||
|
||||
---
|
||||
|
||||
**更新时间**: 2025-01-27
|
||||
**版本**: v2.0.0
|
||||
**维护者**: 开发团队
|
||||
@@ -0,0 +1,221 @@
|
||||
# 图片上传认证问题解决方案
|
||||
|
||||
## 🚨 问题描述
|
||||
|
||||
调用 `http://localhost/dev-api/resource/oss/upload` 接口时,返回401认证失败错误:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 401,
|
||||
"msg": "认证失败,无法访问系统资源",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
### 1. 认证头缺失
|
||||
根据项目规范,上传接口需要以下认证头:
|
||||
|
||||
| 字段名 | 必填 | 说明 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| Authorization | 是 | Bearer + Token | "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." |
|
||||
| clientid | 是 | 客户端ID | "e5cd7e4891bf95d1d19206ce24a7b32e" |
|
||||
| Content-Language | 是 | 语言设置 | "zh-CN,zh;q=0.9,en;q=0.8" |
|
||||
| referer | 是 | 来源页面 | "http://localhost/login?redirect=%252Findex" |
|
||||
|
||||
### 2. 当前问题
|
||||
- ❌ 缺少 `clientid` 字段
|
||||
- ❌ 缺少 `Content-Language` 字段
|
||||
- ❌ 缺少 `referer` 字段
|
||||
- ❌ Token格式可能不正确
|
||||
|
||||
## 🔧 解决方案
|
||||
|
||||
### 1. 修复Headers设置
|
||||
|
||||
在 `ImageUpload/index.vue` 中,已修复headers设置:
|
||||
|
||||
```typescript
|
||||
// 获取token函数
|
||||
const getToken = () => {
|
||||
return localStorage.getItem('token') || '';
|
||||
};
|
||||
|
||||
// 获取语言设置
|
||||
const getLanguage = () => {
|
||||
return localStorage.getItem('language') || 'zh-CN';
|
||||
};
|
||||
|
||||
// 构建完整的请求头
|
||||
const requestHeaders = {
|
||||
'Authorization': 'Bearer ' + getToken(),
|
||||
'clientid': import.meta.env.VITE_APP_CLIENT_ID || 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
||||
'Content-Language': getLanguage(),
|
||||
'referer': window.location.origin + '/login?redirect=' + encodeURIComponent(window.location.pathname),
|
||||
'bucket-password': props.bucketPassword || passwordForm.value.bucketPassword || ''
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 验证Token有效性
|
||||
|
||||
确保用户已登录且Token有效:
|
||||
|
||||
```javascript
|
||||
// 检查Token是否存在
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
console.error('Token不存在,请先登录');
|
||||
// 跳转到登录页面
|
||||
window.location.href = '/login';
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 测试认证信息
|
||||
|
||||
在浏览器控制台中运行以下代码测试认证信息:
|
||||
|
||||
```javascript
|
||||
// 检查认证信息
|
||||
function checkAuth() {
|
||||
const token = localStorage.getItem('token');
|
||||
const headers = {
|
||||
'Authorization': 'Bearer ' + token,
|
||||
'clientid': 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
||||
'Content-Language': 'zh-CN',
|
||||
'referer': window.location.origin + '/login?redirect=' + encodeURIComponent(window.location.pathname)
|
||||
};
|
||||
|
||||
console.log('Token:', token);
|
||||
console.log('Headers:', headers);
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
// 测试上传接口
|
||||
async function testUpload() {
|
||||
const headers = checkAuth();
|
||||
|
||||
try {
|
||||
const response = await fetch('/dev-api/resource/oss/upload', {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: new FormData()
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
console.log('测试结果:', result);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testUpload();
|
||||
```
|
||||
|
||||
## 🧪 调试步骤
|
||||
|
||||
### 步骤1:检查Token
|
||||
```javascript
|
||||
// 在浏览器控制台运行
|
||||
console.log('Token:', localStorage.getItem('token'));
|
||||
```
|
||||
|
||||
### 步骤2:检查Headers
|
||||
```javascript
|
||||
// 在浏览器控制台运行
|
||||
const headers = {
|
||||
'Authorization': 'Bearer ' + localStorage.getItem('token'),
|
||||
'clientid': 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
||||
'Content-Language': 'zh-CN',
|
||||
'referer': window.location.origin + '/login?redirect=' + encodeURIComponent(window.location.pathname)
|
||||
};
|
||||
console.log('Headers:', headers);
|
||||
```
|
||||
|
||||
### 步骤3:测试接口
|
||||
```javascript
|
||||
// 在浏览器控制台运行
|
||||
fetch('/dev-api/resource/oss/upload', {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: new FormData()
|
||||
}).then(response => response.json()).then(console.log);
|
||||
```
|
||||
|
||||
## ⚠️ 常见问题
|
||||
|
||||
### 1. Token过期
|
||||
**症状**: 401认证失败
|
||||
**解决**: 重新登录获取新Token
|
||||
|
||||
### 2. clientid错误
|
||||
**症状**: 401认证失败
|
||||
**解决**: 检查环境变量 `VITE_APP_CLIENT_ID` 或使用默认值
|
||||
|
||||
### 3. 缺少必需字段
|
||||
**症状**: 401认证失败
|
||||
**解决**: 确保包含所有必需的认证头字段
|
||||
|
||||
### 4. 跨域问题
|
||||
**症状**: CORS错误
|
||||
**解决**: 检查后端CORS配置
|
||||
|
||||
## 🔄 验证修复
|
||||
|
||||
### 1. 功能测试
|
||||
- [ ] 用户已登录且Token有效
|
||||
- [ ] Headers包含所有必需字段
|
||||
- [ ] 上传接口返回200状态码
|
||||
- [ ] 文件上传成功
|
||||
|
||||
### 2. 安全测试
|
||||
- [ ] 未登录用户无法上传
|
||||
- [ ] 过期Token无法上传
|
||||
- [ ] 错误clientid无法上传
|
||||
|
||||
## 📝 使用示例
|
||||
|
||||
### 正确的Headers示例
|
||||
```javascript
|
||||
{
|
||||
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
|
||||
"clientid": "e5cd7e4891bf95d1d19206ce24a7b32e",
|
||||
"Content-Language": "zh-CN",
|
||||
"referer": "http://localhost/login?redirect=%2Findex",
|
||||
"bucket-password": "your_bucket_password"
|
||||
}
|
||||
```
|
||||
|
||||
### 错误示例
|
||||
```javascript
|
||||
// ❌ 缺少Bearer前缀
|
||||
"Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
|
||||
|
||||
// ❌ 缺少clientid
|
||||
{
|
||||
"Authorization": "Bearer ...",
|
||||
"Content-Language": "zh-CN"
|
||||
}
|
||||
|
||||
// ❌ 缺少必需字段
|
||||
{
|
||||
"Authorization": "Bearer ..."
|
||||
}
|
||||
```
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
- [API文档基础规范](../API/API文档基础规范.md)
|
||||
- [图片上传组件安全改造说明](./图片上传组件安全改造说明.md)
|
||||
- [MinIO安全改造方案](../中间件配置/minio-security-solution.md)
|
||||
|
||||
---
|
||||
|
||||
**更新时间**: 2025-01-27
|
||||
**版本**: v1.0.0
|
||||
**维护者**: 开发团队
|
||||
@@ -0,0 +1,257 @@
|
||||
# 🚀 文件下载缓存机制说明
|
||||
|
||||
## 📋 功能概述
|
||||
|
||||
为了提高文件下载性能,减少对MinIO存储的重复请求,系统实现了基于内存的文件缓存机制。该机制具有以下特性:
|
||||
|
||||
### ✨ 核心特性
|
||||
- **LRU淘汰策略**: 当缓存空间不足时,自动淘汰最久未访问的文件
|
||||
- **智能大小控制**: 只缓存小于50MB的文件,避免内存溢出
|
||||
- **过期时间管理**: 缓存条目具有30分钟的有效期
|
||||
- **并发安全**: 使用读写锁保证多线程环境下的数据一致性
|
||||
- **统计监控**: 提供缓存命中率、大小等统计信息
|
||||
- **配置化管理**: 所有缓存参数可通过配置文件调整
|
||||
|
||||
## 🔧 配置参数
|
||||
|
||||
### 基础配置
|
||||
在 `application.yml` 或 `application-dev.yml` 中添加以下配置:
|
||||
|
||||
```yaml
|
||||
system:
|
||||
file-cache:
|
||||
# 是否启用文件缓存
|
||||
enabled: true
|
||||
|
||||
# 最大缓存文件数量
|
||||
max-cache-size: 100
|
||||
|
||||
# 最大缓存大小(字节)- 500MB
|
||||
max-cache-size-bytes: 524288000
|
||||
|
||||
# 缓存过期时间(毫秒)- 30分钟
|
||||
expire-time-ms: 1800000
|
||||
|
||||
# 最大缓存单个文件大小(字节)- 50MB
|
||||
max-single-file-size: 52428800
|
||||
|
||||
# LRU淘汰比例(百分比)
|
||||
evict-ratio: 20
|
||||
|
||||
# 是否启用缓存统计
|
||||
enable-stats: true
|
||||
|
||||
# 缓存清理间隔(毫秒)- 5分钟
|
||||
cleanup-interval-ms: 300000
|
||||
```
|
||||
|
||||
### 参数说明
|
||||
|
||||
| 参数名 | 默认值 | 说明 |
|
||||
|--------|--------|------|
|
||||
| `enabled` | `true` | 是否启用文件缓存功能 |
|
||||
| `max-cache-size` | `100` | 缓存的最大文件数量 |
|
||||
| `max-cache-size-bytes` | `524288000` | 缓存的最大总大小(500MB) |
|
||||
| `expire-time-ms` | `1800000` | 缓存条目的过期时间(30分钟) |
|
||||
| `max-single-file-size` | `52428800` | 单个文件的最大缓存大小(50MB) |
|
||||
| `evict-ratio` | `20` | LRU淘汰时移除的条目比例(20%) |
|
||||
| `enable-stats` | `true` | 是否启用缓存统计功能 |
|
||||
| `cleanup-interval-ms` | `300000` | 自动清理过期条目的间隔(5分钟) |
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 1. 文件下载
|
||||
缓存机制对用户透明,正常使用文件下载接口即可:
|
||||
|
||||
```http
|
||||
GET /resource/oss/download/{ossId}
|
||||
```
|
||||
|
||||
系统会自动:
|
||||
1. 检查缓存中是否存在该文件
|
||||
2. 如果存在且未过期,直接从缓存返回
|
||||
3. 如果不存在或已过期,从MinIO下载并缓存
|
||||
|
||||
### 2. 缓存管理API
|
||||
|
||||
#### 获取缓存统计信息
|
||||
```http
|
||||
GET /resource/oss/cache/stats
|
||||
```
|
||||
|
||||
返回示例:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"cacheSize": 25,
|
||||
"currentCacheSizeBytes": 104857600,
|
||||
"maxCacheSizeBytes": 524288000,
|
||||
"cacheHits": 150,
|
||||
"cacheMisses": 50,
|
||||
"hitRate": "75.00%"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 清空缓存
|
||||
```http
|
||||
DELETE /resource/oss/cache/clear
|
||||
```
|
||||
|
||||
#### 移除指定文件缓存
|
||||
```http
|
||||
DELETE /resource/oss/cache/{ossId}
|
||||
```
|
||||
|
||||
## 📊 性能优化
|
||||
|
||||
### 缓存命中率优化
|
||||
- **增加缓存大小**: 对于内存充足的环境,适当增加 `max-cache-size-bytes`
|
||||
- **调整文件数量**: 对于小文件较多的场景,增加 `max-cache-size`
|
||||
- **优化过期时间**: 根据文件访问频率调整 `expire-time-ms`
|
||||
|
||||
### 内存使用优化
|
||||
- **控制单个文件大小**: 根据实际情况调整 `max-single-file-size`
|
||||
- **调整淘汰策略**: 通过 `evict-ratio` 控制淘汰比例
|
||||
- **定期清理**: 设置合适的 `cleanup-interval-ms`
|
||||
|
||||
### 监控指标
|
||||
- **缓存命中率**: 目标 > 70%
|
||||
- **内存使用率**: 监控缓存占用的内存大小
|
||||
- **响应时间**: 缓存命中时的下载速度应显著提升
|
||||
|
||||
## 🔍 技术实现
|
||||
|
||||
### 核心组件
|
||||
|
||||
#### 1. 缓存条目类 (CacheEntry)
|
||||
```java
|
||||
private class CacheEntry {
|
||||
private final byte[] data; // 文件数据
|
||||
private final long size; // 文件大小
|
||||
private final long createTime; // 创建时间
|
||||
private final long lastAccessTime; // 最后访问时间
|
||||
private final String contentType; // 内容类型
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. LRU淘汰策略
|
||||
```java
|
||||
private void evictLRUEntries() {
|
||||
// 按最后访问时间排序
|
||||
List<Map.Entry<Long, CacheEntry>> entries = new ArrayList<>(fileCache.entrySet());
|
||||
entries.sort((e1, e2) -> Long.compare(e1.getValue().getLastAccessTime(), e2.getValue().getLastAccessTime()));
|
||||
|
||||
// 淘汰最旧的20%条目
|
||||
int evictCount = Math.max(1, entries.size() / 5);
|
||||
for (int i = 0; i < evictCount && i < entries.size(); i++) {
|
||||
Map.Entry<Long, CacheEntry> entry = entries.get(i);
|
||||
fileCache.remove(entry.getKey());
|
||||
currentCacheSize.addAndGet(-entry.getValue().getSize());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 并发安全
|
||||
- 使用 `ConcurrentHashMap` 存储缓存数据
|
||||
- 使用 `ReentrantReadWriteLock` 保证读写安全
|
||||
- 使用 `AtomicLong` 统计缓存大小和命中率
|
||||
|
||||
### 工作流程
|
||||
|
||||
1. **文件下载请求**
|
||||
```
|
||||
用户请求 → 权限验证 → 检查缓存 → 返回文件
|
||||
```
|
||||
|
||||
2. **缓存命中流程**
|
||||
```
|
||||
检查缓存 → 验证过期 → 直接返回 → 更新统计
|
||||
```
|
||||
|
||||
3. **缓存未命中流程**
|
||||
```
|
||||
检查缓存 → 从MinIO下载 → 添加到缓存 → 返回文件
|
||||
```
|
||||
|
||||
4. **缓存管理流程**
|
||||
```
|
||||
检查大小限制 → LRU淘汰 → 清理过期 → 添加新条目
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. 内存管理
|
||||
- 缓存会占用JVM堆内存,需要合理配置缓存大小
|
||||
- 建议监控应用的内存使用情况
|
||||
- 大文件不会被缓存,避免内存溢出
|
||||
|
||||
### 2. 数据一致性
|
||||
- 缓存的文件数据可能与MinIO中的文件不同步
|
||||
- 如果需要最新数据,可以手动清除缓存
|
||||
- 建议在文件更新后清除相关缓存
|
||||
|
||||
### 3. 性能考虑
|
||||
- 缓存命中时响应速度显著提升
|
||||
- 缓存未命中时会有轻微的性能开销(用于缓存数据)
|
||||
- 建议根据实际访问模式优化缓存参数
|
||||
|
||||
### 4. 安全考虑
|
||||
- 缓存数据存储在内存中,应用重启后会丢失
|
||||
- 敏感文件建议设置较短的过期时间
|
||||
- 可以通过API手动管理缓存
|
||||
|
||||
## 🔧 故障排查
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **缓存命中率低**
|
||||
- 检查缓存大小配置是否合理
|
||||
- 分析文件访问模式
|
||||
- 调整过期时间
|
||||
|
||||
2. **内存使用过高**
|
||||
- 减少缓存大小限制
|
||||
- 降低单个文件大小限制
|
||||
- 增加淘汰比例
|
||||
|
||||
3. **缓存不生效**
|
||||
- 检查 `enabled` 配置是否为 `true`
|
||||
- 确认文件大小是否超过限制
|
||||
- 查看日志中的缓存相关信息
|
||||
|
||||
### 监控建议
|
||||
|
||||
1. **定期检查缓存统计**
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/resource/oss/cache/stats"
|
||||
```
|
||||
|
||||
2. **监控应用内存使用**
|
||||
```bash
|
||||
jstat -gc <pid> 1000
|
||||
```
|
||||
|
||||
3. **查看缓存相关日志**
|
||||
```bash
|
||||
tail -f logs/application.log | grep "cache"
|
||||
```
|
||||
|
||||
## 📈 性能测试
|
||||
|
||||
### 测试场景
|
||||
1. **首次下载**: 从MinIO下载并缓存
|
||||
2. **缓存命中**: 从内存直接返回
|
||||
3. **并发下载**: 多用户同时下载同一文件
|
||||
4. **大文件下载**: 超过缓存大小限制的文件
|
||||
|
||||
### 预期性能提升
|
||||
- **缓存命中时**: 响应时间减少 80-90%
|
||||
- **并发访问**: 显著减少MinIO压力
|
||||
- **整体性能**: 平均下载速度提升 60-80%
|
||||
|
||||
---
|
||||
|
||||
**📝 维护说明**: 本文档基于文件缓存机制的实现,如需修改缓存策略或参数,请同步更新相关代码和配置。
|
||||
Reference in new issue
Block a user