提交请假销假代码

This commit is contained in:
zlwu committed 2025-08-06 01:32:11 +08:00
1 parent 4e8b6d77b6
commit 86f65df783
22 files changed
+4583 -191

No files matched your search

@@ -0,0 +1,153 @@
# 销假表单附件上传区域优化变更记录
**变更时间**: 2025-01-27 14:30:00
**变更人员**: Cursor AI
**变更文件**: `web/src/views/xg/xsjcxx/xsqj/xjdialog.vue`
**变更类型**: 功能优化
## 🎯 变更目标
解决销假表单中附件上传区域当上传很多附件时,附件区域信息显示不完整的问题。
## 🔧 具体变更内容
### 1. 附件容器高度优化
- **原高度**: `max-height: 600px`
- **新高度**: `max-height: 800px`
- **优化效果**: 增加200px高度,支持更多附件显示
### 2. 滚动条样式优化
```css
/* 新增滚动条样式 */
.attachment-upload-container::-webkit-scrollbar {
width: 8px;
}
.attachment-upload-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.attachment-upload-container::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
.attachment-upload-container::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
```
**优化效果**: 滚动条更明显,用户体验更好
### 3. 响应式布局优化
```css
/* 支持响应式布局 */
.attachment-upload-container :deep(.el-upload-list--picture-card) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 12px;
margin-top: 12px;
padding-bottom: 20px;
min-height: 200px;
}
/* 大屏幕:5列布局 */
@media (min-width: 1200px) {
grid-template-columns: repeat(5, 1fr);
}
/* 中等屏幕:4列布局 */
@media (min-width: 768px) and (max-width: 1199px) {
grid-template-columns: repeat(4, 1fr);
}
/* 小屏幕:3列布局 */
@media (max-width: 767px) {
grid-template-columns: repeat(3, 1fr);
}
```
**优化效果**: 不同屏幕尺寸下都有最佳显示效果
### 4. 附件数量提示功能
```vue
<!-- 新增附件数量提示 -->
<div v-if="cancelAttachmentList.length > 0" class="attachment-count-tip">
<el-icon><Document /></el-icon>
<span>已上传 {{ cancelAttachmentList.length }} 个附件</span>
<span v-if="cancelAttachmentList.length >= 8" class="scroll-tip">(可滚动查看更多)</span>
</div>
```
**优化效果**: 用户清楚知道已上传的附件数量,当附件较多时提示可滚动
### 5. 附件卡片布局优化
- **卡片高度**: 从 `180px` 增加到 `200px`
- **文件名区域**: 从 `32px` 增加到 `40px`
- **字体大小**: 从 `11px` 增加到 `12px`
- **字体粗细**: 增加 `font-weight: 500`
**优化效果**: 附件信息显示更清晰,可读性更好
### 6. 附件数量提示样式
```css
.attachment-count-tip {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
background: #e6f7ff;
border: 1px solid #91d5ff;
border-radius: 4px;
margin-bottom: 8px;
font-size: 13px;
color: #1890ff;
}
.scroll-tip {
color: #52c41a;
font-weight: 500;
}
```
**优化效果**: 美观的提示样式,用户友好
## 📊 优化效果对比
### 优化前
- ❌ 附件容器高度限制600px,附件多时显示不全
- ❌ 滚动条不明显,用户可能不知道可以滚动
- ❌ 固定5列布局,小屏幕显示效果差
- ❌ 没有附件数量提示
- ❌ 附件卡片信息显示空间有限
### 优化后
- ✅ 附件容器高度增加到800px,支持更多附件
- ✅ 滚动条样式优化,更明显易用
- ✅ 响应式布局,适配不同屏幕尺寸
- ✅ 附件数量提示,用户清楚了解状态
- ✅ 附件卡片布局优化,信息显示更清晰
## 🎯 用户体验提升
1. **信息完整性**: 附件多时也能完整显示所有信息
2. **操作便利性**: 明显的滚动条和提示信息
3. **视觉友好性**: 响应式布局和优化的卡片设计
4. **状态清晰性**: 附件数量提示让用户了解当前状态
## 📝 技术要点
1. **CSS Grid布局**: 使用 `grid-template-columns: repeat(auto-fit, minmax(160px, 1fr))` 实现响应式
2. **媒体查询**: 针对不同屏幕尺寸优化列数
3. **滚动条定制**: 使用 `::-webkit-scrollbar` 伪元素定制滚动条样式
4. **Vue响应式**: 利用 `cancelAttachmentList.length` 动态显示提示信息
## 🔄 后续建议
1. **性能优化**: 当附件数量特别多时,可考虑虚拟滚动
2. **交互优化**: 可添加附件预览功能
3. **批量操作**: 可添加批量删除、批量下载功能
4. **拖拽排序**: 可添加附件拖拽排序功能
---
**变更状态**: ✅ 已完成
**测试状态**: 🔄 待测试
**文档状态**: ✅ 已更新
@@ -1,5 +1,204 @@
# 代码调整记录 - 2025-01-27 - cursor
## 🔧 前端销假API调用优化 (2025-01-27 14:30:00)
### 功能概述
修改前端销假对话框(`xjdialog.vue`)中的`submitForm`方法,将`addStudentCancelLeave` API调用改为调用后端`XgStudentCancelLeaveController.java`中的`add`方法,主要针对出参处理进行了优化。
### 详细变更
#### 1. 前端API类型定义优化
**文件**: `web/src/api/workflow/studentCancelLeave/studentCancelLeave/index.ts`
**修改内容**:
- 为`addStudentCancelLeave`方法添加了返回类型定义:`AxiosPromise<StudentCancelLeaveVO>`
- 为`getCancelLeaveIdByLeaveId`方法添加了返回类型定义:`AxiosPromise<number>`
**修改前**:
```typescript
export const addStudentCancelLeave = (data: StudentCancelLeaveForm) => {
return request({
url: '/studentCancelLeave/studentCancelLeave',
method: 'post',
data: data
});
};
```
**修改后**:
```typescript
export const addStudentCancelLeave = (data: StudentCancelLeaveForm): AxiosPromise<StudentCancelLeaveVO> => {
return request({
url: '/studentCancelLeave/studentCancelLeave',
method: 'post',
data: data
});
};
```
#### 2. 前端业务逻辑优化
**文件**: `web/src/views/xg/xsjcxx/xsqj/xjdialog.vue`
**修改内容**:
1. **新增销假记录处理优化**:
```javascript
// 调用后端 XgStudentCancelLeaveController 的 add 方法
res = await addStudentCancelLeave(updateData).finally(() => (buttonLoading.value = false));
// 从返回结果中获取新创建的销假记录ID
if (res && res.data && res.data.id) {
cancelLeaveId = res.data.id;
}
```
2. **销假信息获取优化**:
```javascript
// 根据id 获取销假的信息 传给流程启动的函数
const cancelInfoResponse = await getStudentCancelLeave(cancelLeaveId);
const cancelInfo = cancelInfoResponse?.data;
```
### 修改原因
1. **API返回类型统一**: 确保前端API调用与后端控制器返回类型一致
2. **数据处理优化**: 正确处理后端`R<XgStudentCancelLeaveVo>`类型的返回数据
3. **业务逻辑完善**: 确保新增销假记录后能正确获取新创建的记录ID
### 影响范围
- 前端销假功能的新增操作
- 工作流启动时的数据传递
- API类型定义的完整性
### 测试建议
1. 测试新增销假记录功能
2. 验证工作流启动时数据传递的正确性
3. 检查API返回数据的处理是否正确
### 相关文件
- `web/src/views/xg/xsjcxx/xsqj/xjdialog.vue`
- `web/src/api/workflow/studentCancelLeave/studentCancelLeave/index.ts`
- `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentCancelLeaveController.java`
---
## 🔧 学生销假控制器新增根据请假ID获取销假ID功能 (2025-01-27 17:00:00)
### 功能概述
在 `XgStudentCancelLeaveController.java` 中新增了根据请假ID获取销假ID的功能,支持通过请假记录快速查找对应的销假记录。
### 详细变更
#### 1. Service接口扩展
**文件**: `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentCancelLeaveService.java`
**新增方法**:
```java
/**
* 根据请假ID获取销假ID
*
* @param leaveId 请假ID
* @return 销假ID,如果不存在则返回null
*/
Long getCancelLeaveIdByLeaveId(Long leaveId);
```
#### 2. Service实现类
**文件**: `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentCancelLeaveServiceImpl.java`
**新增实现方法**:
```java
/**
* 根据请假ID获取销假ID
*
* @param leaveId 请假ID
* @return 销假ID,如果不存在则返回null
*/
@Override
public Long getCancelLeaveIdByLeaveId(Long leaveId) {
LambdaQueryWrapper<XgStudentCancelLeave> lqw = Wrappers.lambdaQuery();
lqw.eq(XgStudentCancelLeave::getLeaveId, leaveId);
lqw.eq(XgStudentCancelLeave::getDeleted, 0L); // 只查询未删除的记录
lqw.select(XgStudentCancelLeave::getId);
XgStudentCancelLeave cancelLeave = baseMapper.selectOne(lqw);
return cancelLeave != null ? cancelLeave.getId() : null;
}
```
#### 3. Controller接口
**文件**: `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentCancelLeaveController.java`
**新增接口方法**:
```java
/**
* 根据请假ID获取销假ID
*
* @param leaveId 请假ID
*/
@SaCheckPermission("studentCancelLeave:studentCancelLeave:query")
@GetMapping("/getCancelLeaveId/{leaveId}")
public R<Long> getCancelLeaveIdByLeaveId(@NotNull(message = "请假ID不能为空")
@PathVariable Long leaveId) {
Long cancelLeaveId = xgStudentCancelLeaveService.getCancelLeaveIdByLeaveId(leaveId);
return R.ok(cancelLeaveId);
}
```
### 技术实现要点
#### 1. 数据库查询优化
- 使用 `LambdaQueryWrapper` 构建查询条件
- 通过 `leaveId` 字段进行精确匹配
- 使用 `select()` 方法只查询需要的 `id` 字段,提高查询效率
#### 2. 权限控制
- 使用 `@SaCheckPermission("studentCancelLeave:studentCancelLeave:query")` 注解
- 复用现有的查询权限,无需额外配置
#### 3. 参数验证
- 使用 `@NotNull` 注解确保请假ID不为空
- 提供清晰的错误提示信息
#### 4. 返回值处理
- 返回 `R<Long>` 类型,符合项目统一响应格式
- 如果不存在对应的销假记录,返回 `null`
### API接口信息
**接口路径**: `GET /studentCancelLeave/studentCancelLeave/getCancelLeaveId/{leaveId}`
**请求参数**:
- `leaveId` (Long, 必填): 请假ID
**响应格式**:
```json
{
"code": 200,
"msg": "操作成功",
"data": 123456
}
```
**权限要求**: `studentCancelLeave:studentCancelLeave:query`
### 变更时间
2025-01-27 17:00:00
### 变更人员
Cursor AI
### 备注
此功能为请假管理模块的重要补充,支持根据请假记录快速查找对应的销假记录,提升系统查询效率。
### 🔧 重要修复 (2025-01-27 17:15:00)
**问题**: 查询条件缺少 `deleted = 0` 过滤条件,可能导致查询到已删除的记录
**修复**: 在 `getCancelLeaveIdByLeaveId` 方法中添加 `lqw.eq(XgStudentCancelLeave::getDeleted, 0L)` 条件
**影响**: 确保只查询未删除的有效销假记录,避免数据污染
---
## 🔧 前端金额格式化函数修复 (2025-01-27 16:30:00)
### 问题描述
@@ -9301,5 +9500,102 @@ public XgStudentLeaveVo insertByBo(XgStudentLeaveBo bo) {
**记录人**: cursor
**记录时间**: 2025-01-27 14:30:00
=======
---
# 代码调整记录 - 2025-01-27 (续)
## 修改时间
2025-01-27 15:30:00
## 修改内容
### 销假界面getStudentLeaveInfo方法优化
**修改原因**: 用户需求 - 在销假界面中根据销假ID获取请假ID,以便正确显示请假信息
#### 涉及文件
1. `web/src/api/workflow/studentCancelLeave/studentCancelLeave/index.ts`
2. `web/src/views/xg/xsjcxx/xsqj/xjdialog.vue`
#### 具体修改
**1. 前端API接口新增**
- 文件: `web/src/api/workflow/studentCancelLeave/studentCancelLeave/index.ts`
- 新增方法: `getLeaveIdByCancelLeaveId`
- 功能: 根据销假ID获取请假ID
- 调用后端接口: `XgStudentCancelLeaveController.getLeaveIdByCancelLeaveId`
```typescript
/**
* 根据销假ID获取请假ID
* @param cancelLeaveId
*/
export const getLeaveIdByCancelLeaveId = (cancelLeaveId: string | number): AxiosPromise<number> => {
return request({
url: `/studentCancelLeave/studentCancelLeave/getLeaveId/${cancelLeaveId}`,
method: 'get'
});
};
```
**2. 销假界面方法修改**
- 文件: `web/src/views/xg/xsjcxx/xsqj/xjdialog.vue`
- 修改方法: `getStudentLeaveInfo`
- 修改内容:
- 导入新增的API方法
- 修改逻辑,使用 `getLeaveIdByCancelLeaveId` 替代 `getCancelLeaveIdByLeaveId`
```typescript
// 导入语句修改
import {
getStudentCancelLeave,
updateStudentCancelLeave,
getCancelLeaveIdByLeaveId,
getLeaveIdByCancelLeaveId, // 新增
addStudentCancelLeave
} from '@/api/workflow/studentCancelLeave/studentCancelLeave';
// getStudentLeaveInfo方法修改
const getStudentLeaveInfo = async (id: string | number) => {
try {
//通过销假id获取请假id
const leaveIdResp = await getLeaveIdByCancelLeaveId(id); // 修改:使用新的API方法
let leaveId = leaveIdResp?.data;
console.log('通过销假ID获取到的请假ID:', leaveId);
id = leaveId || id;
// ... 后续逻辑保持不变
} catch (error) {
// ... 错误处理
}
};
```
#### 修改效果
**修改前**:
- 销假界面使用 `getCancelLeaveIdByLeaveId` 方法(根据请假ID获取销假ID)
- 逻辑错误,无法正确获取请假信息
**修改后**:
- 销假界面使用 `getLeaveIdByCancelLeaveId` 方法(根据销假ID获取请假ID)
- 逻辑正确,能够根据销假ID正确获取对应的请假信息
#### 涉及的后端接口
- `XgStudentCancelLeaveController.getLeaveIdByCancelLeaveId` - 根据销假ID获取请假ID
#### 测试建议
1. 在销假界面中打开一个销假记录
2. 验证是否正确获取到对应的请假信息
3. 检查控制台日志,确认API调用正常
#### 影响范围
- 销假界面 (`xjdialog.vue`) 的数据获取逻辑
- 前端API接口层新增方法
- 不影响请假界面 (`dialog.vue`) 的功能
---
**记录人**: cursor
**记录时间**: 2025-01-27 15:30:00
@@ -1,171 +1,82 @@
# 文件下载缓存机制实现 - 变更记录
# 代码调整记录 - 2025-01-27
**变更时间**: 2025-01-27 15:30:00
**变更人员**: wuzilong
**变更类型**: 功能增强
**影响范围**: 文件下载服务
## 学生销假编辑功能同步更新学生请假信息
## 📋 变更概述
### 修改时间
2025-01-27 10:30:00
为提升文件下载性能,减少对MinIO存储的重复请求,在 `SysOssServiceImpl` 中实现了基于内存的文件缓存机制。
### 修改内容
## 🔧 技术实现
#### 1. 修改学生销假服务实现类
**文件**: `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentCancelLeaveServiceImpl.java`
### 1. 核心组件
**修改内容**:
- 在 `updateByBo` 方法中添加了 `@Transactional(rollbackFor = Exception.class)` 事务注解
- 添加了同步更新学生请假表中销假相关字段的逻辑
- 当销假信息更新成功后,根据 `leaveId` 关联更新学生请假表中的以下字段:
- `cancelStatus` - 销假状态
- `cancelTime` - 销假时间
- `cancelLocation` - 销假地理位置
- `cancelPhotoOssIds` - 销假照片OSS文件ID
- `cancelRemark` - 销假备注
#### 缓存条目类 (CacheEntry)
- 位置: `SysOssServiceImpl.java` (第67-120行)
- 功能: 存储文件数据、大小、创建时间、访问时间、内容类型
- 特性: 支持过期时间检查
**修改原因**:
- 确保学生销假信息的修改能够同步更新到学生请假表中
- 保持两个表之间销假信息的一致性
- 避免数据不一致的问题
#### LRU缓存实现
- 存储: `ConcurrentHashMap<Long, CacheEntry>`
- 并发安全: `ReentrantReadWriteLock`
- 统计: `AtomicLong` 计数器
### 技术实现
### 2. 配置管理
#### 事务管理
- 使用 `@Transactional(rollbackFor = Exception.class)` 确保数据一致性
- 如果销假表更新失败或请假表更新失败,都会回滚整个事务
#### 配置类
- 文件: `FileCacheConfig.java`
- 功能: 管理所有缓存参数
- 配置前缀: `system.file-cache`
#### 同步逻辑
```java
if (flag) {
// 同步更新学生请假表中的销假相关字段
if (bo.getLeaveId() != null) {
XgStudentLeaveBo leaveBo = new XgStudentLeaveBo();
leaveBo.setId(bo.getLeaveId());
leaveBo.setCancelStatus(bo.getCancelStatus());
leaveBo.setCancelTime(bo.getCancelTime());
leaveBo.setCancelLocation(bo.getCancelLocation());
leaveBo.setCancelPhotoOssIds(bo.getCancelPhotoOssIds());
leaveBo.setCancelRemark(bo.getCancelRemark());
#### 配置参数
```yaml
system:
file-cache:
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分钟)
xgStudentLeaveService.updateByBo(leaveBo);
}
}
```
### 3. API接口
### 影响范围
- **学生销假管理**: 编辑销假信息时会同步更新请假表
- **数据一致性**: 确保销假信息在两个表中保持一致
- **业务流程**: 不影响现有的销假业务流程
#### 新增接口
1. **获取缓存统计**: `GET /resource/oss/cache/stats`
2. **清空缓存**: `DELETE /resource/oss/cache/clear`
3. **移除指定缓存**: `DELETE /resource/oss/cache/{ossId}`
### 测试建议
1. 测试编辑学生销假信息功能
2. 验证学生请假表中的销假字段是否正确更新
3. 测试事务回滚功能(模拟更新失败场景)
#### 权限配置
- `system:oss:cache:stats` - 查看缓存统计
- `system:oss:cache:clear` - 清空缓存
- `system:oss:cache:remove` - 移除指定缓存
### 相关文件
- `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentCancelLeaveController.java`
- `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentCancelLeaveService.java`
- `backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/XgStudentCancelLeaveBo.java`
## 📁 修改文件清单
#### 2. 创建学生销假管理API文档
**文件**: `docs/开发文档/API/学生销假管理API.md`
### 1. 核心实现文件
- `backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java`
- 新增缓存相关字段和方法
- 修改 `secureDownload` 方法支持缓存
- 新增缓存管理方法
**创建内容**:
- 完整的学生销假管理API接口文档
- 包含7个主要接口的详细说明
- 重点说明修改销假接口的同步更新功能
- 提供技术实现说明和使用示例
- 包含数据字典和注意事项
### 2. 接口定义文件
- `backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java`
- 新增缓存管理接口方法
#### 3. 更新API文档总览
**文件**: `docs/开发文档/API/API文档总览.md`
### 3. 控制器文件
- `backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssController.java`
- 新增缓存管理API接口
### 4. 配置类文件
- `backend/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/config/FileCacheConfig.java`
- 新增文件缓存配置类
### 5. 配置文件
- `backend/ruoyi-modules/ruoyi-system/src/main/resources/application-file-cache.yml`
- 新增配置示例文件
### 6. 文档文件
- `docs/开发文档/文件下载缓存机制说明.md`
- 新增详细的功能说明文档
## 🚀 功能特性
### 1. 智能缓存策略
- **大小控制**: 只缓存小于50MB的文件
- **LRU淘汰**: 空间不足时淘汰最久未访问的文件
- **过期管理**: 30分钟自动过期
- **并发安全**: 读写锁保证数据一致性
### 2. 性能优化
- **缓存命中**: 直接从内存返回,响应时间减少80-90%
- **流式传输**: 支持大文件分块下载
- **统计监控**: 实时监控缓存命中率和大小
### 3. 管理功能
- **统计信息**: 缓存大小、命中率、访问次数
- **手动管理**: 支持清空和移除指定缓存
- **配置化**: 所有参数可通过配置文件调整
## 📊 性能提升
### 预期效果
- **响应时间**: 缓存命中时减少80-90%
- **MinIO压力**: 显著减少重复请求
- **并发性能**: 支持多用户同时访问
- **整体性能**: 平均下载速度提升60-80%
### 监控指标
- 缓存命中率 > 70%
- 内存使用率合理控制
- 响应时间显著提升
## ⚠️ 注意事项
### 1. 内存管理
- 缓存占用JVM堆内存,需要合理配置大小
- 建议监控应用内存使用情况
- 大文件不会被缓存,避免内存溢出
### 2. 数据一致性
- 缓存数据可能与MinIO不同步
- 文件更新后建议清除相关缓存
- 可通过API手动管理缓存
### 3. 配置建议
- 根据服务器内存调整缓存大小
- 根据访问模式优化过期时间
- 定期监控缓存统计信息
## 🔧 测试建议
### 1. 功能测试
- 测试文件下载缓存机制
- 验证LRU淘汰策略
- 检查过期时间管理
### 2. 性能测试
- 对比缓存命中前后的响应时间
- 测试并发下载性能
- 监控内存使用情况
### 3. 压力测试
- 模拟大量文件下载请求
- 测试缓存满时的淘汰机制
- 验证系统稳定性
## 📝 后续优化
### 1. 功能增强
- 支持缓存预热
- 添加缓存压缩
- 实现分布式缓存
### 2. 监控完善
- 集成Prometheus监控
- 添加缓存告警
- 完善日志记录
### 3. 性能优化
- 优化LRU算法
- 支持缓存分片
- 添加缓存预热
---
**📋 变更确认**: 本次变更已完成代码实现、文档编写和配置管理,建议在测试环境验证后部署到生产环境。
**更新内容**:
- 在API模块列表中添加学生销假管理API的链接
- 保持文档结构的一致性
+1
View File
@@ -15,6 +15,7 @@
- [宿舍管理员信息API](./宿舍管理员信息API.md)
- [宿舍管理员授权API](./宿舍管理员授权API.md)
- [学生管理员授权关系API](./学生管理员授权关系API.md)
- [学生销假管理API](./学生销假管理API.md)
### 1. 用户认证登录
@@ -0,0 +1,579 @@
# 学生销假管理 API 接口文档
## 模块概述
**模块名称**:Student Cancel Leave / 学生销假管理
**基础路径**:`/studentCancelLeave/studentCancelLeave`
**版本**:v1.0
**负责人**:zlwu
**更新时间**:2025-01-27
### 模块功能
学生销假管理模块负责处理学生的销假申请和审批流程,包括销假信息的录入、修改、查询和删除。该模块与学生请假管理模块紧密关联,确保销假信息在两个表之间保持同步。
**核心特性**:
- 销假信息的完整生命周期管理
- 与学生请假表的自动同步更新
- 支持销假状态跟踪和地理位置记录
- 提供照片上传和备注功能
### 权限说明
- **权限前缀**:`studentCancelLeave:studentCancelLeave:`
- **权限列表**:
- `studentCancelLeave:studentCancelLeave:list` - 查询销假列表
- `studentCancelLeave:studentCancelLeave:query` - 查询销假详情
- `studentCancelLeave:studentCancelLeave:add` - 新增销假
- `studentCancelLeave:studentCancelLeave:edit` - 编辑销假
- `studentCancelLeave:studentCancelLeave:remove` - 删除销假
- `studentCancelLeave:studentCancelLeave:export` - 导出销假数据
---
## 📊 接口概览
### 接口分类
#### 基础 CRUD 接口
| 接口名称 | HTTP 方法 | 路径 | 权限要求 | 功能描述 |
| -------------- | --------- | --------------------------------------- | ------------------------------------------- | ---------------------- |
| 查询销假列表 | GET | `/studentCancelLeave/studentCancelLeave/list` | `studentCancelLeave:studentCancelLeave:list` | 分页查询销假列表 |
| 查询销假详情 | GET | `/studentCancelLeave/studentCancelLeave/{id}` | `studentCancelLeave:studentCancelLeave:query` | 根据 ID 查询销假详情 |
| 新增销假 | POST | `/studentCancelLeave/studentCancelLeave` | `studentCancelLeave:studentCancelLeave:add` | 创建新的销假记录 |
| 修改销假 | PUT | `/studentCancelLeave/studentCancelLeave` | `studentCancelLeave:studentCancelLeave:edit` | 更新销假信息 |
| 删除销假 | DELETE | `/studentCancelLeave/studentCancelLeave/{ids}` | `studentCancelLeave:studentCancelLeave:remove` | 批量删除销假记录 |
#### 业务逻辑接口
| 接口名称 | HTTP 方法 | 路径 | 权限要求 | 功能描述 |
| ------------------ | --------- | ------------------------------------------------------- | ------------------------------------------- | ---------------------- |
| 导出销假数据 | POST | `/studentCancelLeave/studentCancelLeave/export` | `studentCancelLeave:studentCancelLeave:export` | 导出销假数据到Excel |
| 根据请假ID获取销假ID | GET | `/studentCancelLeave/studentCancelLeave/getCancelLeaveId/{leaveId}` | `studentCancelLeave:studentCancelLeave:query` | 根据请假ID查询对应的销假ID |
### 通用响应格式
#### 成功响应
```json
{
"code": 200,
"msg": "操作成功",
"data": {
// 响应数据
}
}
```
#### 分页响应
```json
{
"code": 200,
"msg": "查询成功",
"rows": [
// 数据列表
],
"total": 100
}
```
#### 错误响应
```json
{
"code": 400001,
"msg": "参数错误",
"data": null
}
```
---
## 🔌 详细接口说明
### 1. 查询销假列表
- **接口路径**:`GET /studentCancelLeave/studentCancelLeave/list`
- **权限标识**:`studentCancelLeave:studentCancelLeave:list`
- **功能描述**:分页查询学生销假列表,支持多条件筛选
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
| ---------------- | ------ | ---- | ------------------------ |
| pageNum | int | 否 | 页码,默认1 |
| pageSize | int | 否 | 每页大小,默认10 |
| studentName | string | 否 | 学生姓名(模糊查询) |
| studentNo | string | 否 | 学号 |
| className | string | 否 | 班级名称(模糊查询) |
| collegeName | string | 否 | 学院名称(模糊查询) |
| leaveTypeCode | string | 否 | 请假类型编码 |
| approvalStatus | string | 否 | 审批状态 |
| cancelStatus | string | 否 | 销假状态 |
| startTime | date | 否 | 开始时间 |
| endTime | date | 否 | 结束时间 |
#### 响应数据
```json
{
"code": 200,
"msg": "查询成功",
"rows": [
{
"id": 1,
"studentId": 1001,
"studentName": "张三",
"studentNo": "2023001001",
"className": "计算机2023-1班",
"collegeName": "计算机学院",
"leaveTypeName": "事假",
"startTime": "2025-01-20 08:00:00",
"endTime": "2025-01-22 18:00:00",
"leaveDuration": 3.0,
"approvalStatus": "finish",
"cancelStatus": "1",
"cancelTime": "2025-01-22 16:30:00",
"cancelLocation": "北京市朝阳区",
"cancelRemark": "已按时返校",
"leaveId": 2001
}
],
"total": 1
}
```
### 2. 查询销假详情
- **接口路径**:`GET /studentCancelLeave/studentCancelLeave/{id}`
- **权限标识**:`studentCancelLeave:studentCancelLeave:query`
- **功能描述**:根据ID查询销假详细信息
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ---- | ---- | ------ |
| id | long | 是 | 销假ID |
#### 响应数据
```json
{
"code": 200,
"msg": "查询成功",
"data": {
"id": 1,
"studentId": 1001,
"studentName": "张三",
"studentNo": "2023001001",
"classId": 101,
"className": "计算机2023-1班",
"majorId": 1,
"majorName": "计算机科学与技术",
"collegeId": 1,
"collegeName": "计算机学院",
"leaveTypeCode": "SJ",
"leaveTypeName": "事假",
"startTime": "2025-01-20 08:00:00",
"endTime": "2025-01-22 18:00:00",
"leaveDuration": 3.0,
"isLeaveSchool": "1",
"needCancel": "1",
"emergencyContact": "张父",
"emergencyPhone": "13900139000",
"leaveReason": "家中有事需要处理",
"leaveLocation": "北京市朝阳区",
"attachmentOssIds": "123,456",
"approvalStatus": "finish",
"approvalOpinion": "同意请假",
"approvalTime": "2025-01-19 14:30:00",
"approvalBy": 1001,
"approvalByName": "李老师",
"cancelStatus": "1",
"cancelTime": "2025-01-22 16:30:00",
"cancelLocation": "北京市朝阳区",
"cancelPhotoOssIds": "789,101",
"cancelRemark": "已按时返校",
"leaveId": 2001
}
}
```
### 3. 新增销假
- **接口路径**:`POST /studentCancelLeave/studentCancelLeave`
- **权限标识**:`studentCancelLeave:studentCancelLeave:add`
- **功能描述**:新增学生销假记录,并同步更新学生请假表的销假信息
#### 请求参数
```json
{
"studentId": 1001,
"studentName": "张三",
"studentNo": "2023001001",
"classId": 101,
"className": "计算机2023-1班",
"majorId": 1,
"majorName": "计算机科学与技术",
"collegeId": 1,
"collegeName": "计算机学院",
"leaveTypeCode": "SJ",
"leaveTypeName": "事假",
"startTime": "2025-01-20 08:00:00",
"endTime": "2025-01-22 18:00:00",
"leaveDuration": 3.0,
"isLeaveSchool": "1",
"needCancel": "1",
"emergencyContact": "张父",
"emergencyPhone": "13900139000",
"leaveReason": "家中有事需要处理",
"leaveLocation": "北京市朝阳区",
"attachmentOssIds": "123,456",
"approvalStatus": "finish",
"approvalOpinion": "同意请假",
"approvalTime": "2025-01-19 14:30:00",
"approvalBy": 1001,
"approvalByName": "李老师",
"cancelStatus": "1",
"cancelTime": "2025-01-22 16:30:00",
"cancelLocation": "北京市朝阳区",
"cancelPhotoOssIds": "789,101",
"cancelRemark": "已按时返校",
"leaveId": 2001
}
```
#### 响应数据
```json
{
"code": 200,
"msg": "新增成功",
"data": {
"id": 1,
"studentName": "张三",
"studentNo": "2023001001",
"cancelStatus": "1",
"cancelTime": "2025-01-22 16:30:00"
}
}
```
### 4. 修改销假 ⭐
- **接口路径**:`PUT /studentCancelLeave/studentCancelLeave`
- **权限标识**:`studentCancelLeave:studentCancelLeave:edit`
- **功能描述**:修改学生销假信息,并同步更新学生请假表中的销假相关字段
**⚠️ 重要说明**:此接口会自动同步更新学生请假表中的销假信息,确保数据一致性。
#### 请求参数
```json
{
"id": 1,
"cancelStatus": "1",
"cancelTime": "2025-01-22 16:30:00",
"cancelLocation": "北京市朝阳区",
"cancelPhotoOssIds": "789,101",
"cancelRemark": "已按时返校,状态良好",
"leaveId": 2001
}
```
#### 响应数据
```json
{
"code": 200,
"msg": "修改成功"
}
```
#### 同步更新说明
当修改销假信息时,系统会自动同步更新学生请假表中的以下字段:
| 字段名 | 说明 | 来源 |
| ------------------- | ------------ | ----------------------- |
| `cancel_status` | 销假状态 | 销假表的 `cancelStatus` |
| `cancel_time` | 销假时间 | 销假表的 `cancelTime` |
| `cancel_location` | 销假地理位置 | 销假表的 `cancelLocation` |
| `cancel_photo_oss_ids` | 销假照片 | 销假表的 `cancelPhotoOssIds` |
| `cancel_remark` | 销假备注 | 销假表的 `cancelRemark` |
**事务保证**:使用 `@Transactional` 注解确保两个表的更新操作要么全部成功,要么全部回滚。
### 5. 删除销假
- **接口路径**:`DELETE /studentCancelLeave/studentCancelLeave/{ids}`
- **权限标识**:`studentCancelLeave:studentCancelLeave:remove`
- **功能描述**:批量删除销假记录
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
| ------ | ------ | ---- | ------------------------ |
| ids | string | 是 | 销假ID列表,多个用逗号分隔 |
#### 响应数据
```json
{
"code": 200,
"msg": "删除成功"
}
```
### 6. 导出销假数据
- **接口路径**:`POST /studentCancelLeave/studentCancelLeave/export`
- **权限标识**:`studentCancelLeave:studentCancelLeave:export`
- **功能描述**:导出销假数据到Excel文件
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
| ---------------- | ------ | ---- | ------------------------ |
| studentName | string | 否 | 学生姓名(模糊查询) |
| studentNo | string | 否 | 学号 |
| className | string | 否 | 班级名称(模糊查询) |
| collegeName | string | 否 | 学院名称(模糊查询) |
| leaveTypeCode | string | 否 | 请假类型编码 |
| approvalStatus | string | 否 | 审批状态 |
| cancelStatus | string | 否 | 销假状态 |
| startTime | date | 否 | 开始时间 |
| endTime | date | 否 | 结束时间 |
#### 响应数据
返回Excel文件流,文件名格式:`学生销假_yyyyMMddHHmmss.xlsx`
### 7. 根据请假ID获取销假ID
- **接口路径**:`GET /studentCancelLeave/studentCancelLeave/getCancelLeaveId/{leaveId}`
- **权限标识**:`studentCancelLeave:studentCancelLeave:query`
- **功能描述**:根据请假ID查询对应的销假ID
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
| ------- | ---- | ---- | ------ |
| leaveId | long | 是 | 请假ID |
#### 响应数据
```json
{
"code": 200,
"msg": "查询成功",
"data": 1
}
```
---
## 📋 数据字典
### 销假状态 (cancelStatus)
| 值 | 说明 |
| --- | -------- |
| 0 | 未销假 |
| 1 | 已销假 |
| 2 | 逾期未销假 |
| 3 | 无需销假 |
### 审批状态 (approvalStatus)
| 值 | 说明 |
| --------- | -------- |
| draft | 草稿 |
| waiting | 待审核 |
| finish | 已完成 |
| cancel | 已撤销 |
| invalid | 已作废 |
| back | 已退回 |
| termination | 已终止 |
### 是否离校 (isLeaveSchool)
| 值 | 说明 |
| --- | ---- |
| 0 | 否 |
| 1 | 是 |
### 是否需要销假 (needCancel)
| 值 | 说明 |
| --- | ---- |
| 0 | 否 |
| 1 | 是 |
---
## 🔧 技术实现
### 数据同步机制
#### 1. 新增销假同步
在 `insertByBo` 方法中,新增销假记录成功后,会自动更新学生请假表的销假字段:
```java
@Transactional(rollbackFor = Exception.class)
public XgStudentCancelLeaveVo insertByBo(XgStudentCancelLeaveBo bo) {
// 新增销假记录
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
// 同步更新学生请假表中的销假相关字段
if (bo.getLeaveId() != null) {
XgStudentLeaveBo leaveBo = new XgStudentLeaveBo();
leaveBo.setId(bo.getLeaveId());
leaveBo.setCancelStatus(bo.getCancelStatus());
leaveBo.setCancelTime(bo.getCancelTime());
leaveBo.setCancelLocation(bo.getCancelLocation());
leaveBo.setCancelPhotoOssIds(bo.getCancelPhotoOssIds());
leaveBo.setCancelRemark(bo.getCancelRemark());
xgStudentLeaveService.updateByBo(leaveBo);
}
}
}
```
#### 2. 修改销假同步
在 `updateByBo` 方法中,修改销假记录成功后,也会同步更新学生请假表:
```java
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(XgStudentCancelLeaveBo bo) {
// 修改销假记录
boolean flag = baseMapper.updateById(update) > 0;
if (flag) {
// 同步更新学生请假表中的销假相关字段
if (bo.getLeaveId() != null) {
XgStudentLeaveBo leaveBo = new XgStudentLeaveBo();
leaveBo.setId(bo.getLeaveId());
leaveBo.setCancelStatus(bo.getCancelStatus());
leaveBo.setCancelTime(bo.getCancelTime());
leaveBo.setCancelLocation(bo.getCancelLocation());
leaveBo.setCancelPhotoOssIds(bo.getCancelPhotoOssIds());
leaveBo.setCancelRemark(bo.getCancelRemark());
xgStudentLeaveService.updateByBo(leaveBo);
}
}
return flag;
}
```
### 事务管理
- 使用 `@Transactional(rollbackFor = Exception.class)` 确保数据一致性
- 如果销假表更新失败或请假表更新失败,都会回滚整个事务
- 保证两个表的数据始终保持同步
### 关联关系
- 销假表通过 `leave_id` 字段关联学生请假表
- 一个请假记录只能对应一个销假记录
- 销假记录必须关联到有效的请假记录
---
## 🚀 使用示例
### 前端调用示例
```javascript
// 修改销假信息
const updateCancelLeave = async (data) => {
try {
const response = await request({
url: '/studentCancelLeave/studentCancelLeave',
method: 'put',
data: {
id: 1,
cancelStatus: '1',
cancelTime: '2025-01-22 16:30:00',
cancelLocation: '北京市朝阳区',
cancelPhotoOssIds: '789,101',
cancelRemark: '已按时返校',
leaveId: 2001
}
});
if (response.code === 200) {
console.log('销假信息修改成功,已同步更新请假表');
}
} catch (error) {
console.error('修改失败:', error);
}
};
```
### 后端调用示例
```java
// 修改销假信息
XgStudentCancelLeaveBo bo = new XgStudentCancelLeaveBo();
bo.setId(1L);
bo.setCancelStatus("1");
bo.setCancelTime(new Date());
bo.setCancelLocation("北京市朝阳区");
bo.setCancelRemark("已按时返校");
bo.setLeaveId(2001L);
boolean result = xgStudentCancelLeaveService.updateByBo(bo);
if (result) {
log.info("销假信息修改成功,已同步更新请假表");
}
```
---
## ⚠️ 注意事项
### 1. 数据一致性
- 销假信息修改时会自动同步更新学生请假表
- 确保 `leaveId` 字段正确关联到有效的请假记录
- 使用事务保证数据一致性
### 2. 权限控制
- 所有接口都需要相应的权限标识
- 建议在业务层面进行权限验证
- 注意数据访问范围的控制
### 3. 性能考虑
- 大量数据查询时建议使用分页
- 导出功能可能耗时较长,建议异步处理
- 注意缓存策略的使用
### 4. 错误处理
- 接口调用失败时会返回相应的错误码和错误信息
- 建议在前端进行适当的错误处理
- 记录详细的错误日志便于问题排查
---
## 📝 更新日志
| 版本 | 日期 | 更新内容 | 更新人 |
| ------ | ---------- | ---------------------------------- | ------ |
| v1.0 | 2025-01-27 | 初始版本,包含完整的CRUD接口 | zlwu |
| v1.1 | 2025-01-27 | 新增同步更新学生请假表功能 | zlwu |
---
**📋 文档维护**:本文档会随着接口的更新而持续维护,如有疑问请联系开发团队。