提交学生信息管理界面的代码
This commit is contained in:
1 parent
dcecdbd6aa
commit
a1901ac611
11 files changed
+2159
-183
No files matched your search
+12
@@ -18,6 +18,7 @@ import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerSourceVo;
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo;
|
||||
import org.dromara.xg.domain.bo.XgStudentManagerSourceBo;
|
||||
import org.dromara.xg.service.IXgStudentManagerSourceService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -126,4 +127,15 @@ public class XgStudentManagerSourceController extends BaseController {
|
||||
public R<List<String>> getAuthSourceNames(@RequestParam Long managerId) {
|
||||
return R.ok(xgStudentManagerSourceService.getAuthSourceNames(managerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的学生管理权限部门树
|
||||
*
|
||||
* @return 部门树形结构列表
|
||||
*/
|
||||
@SaCheckPermission("xgStudentManagerSource:studentManagerSource:query")
|
||||
@GetMapping("/currentUserAuthTree")
|
||||
public R<List<XgStudentManagerDeptTreeVo>> getCurrentUserAuthTree() {
|
||||
return R.ok(xgStudentManagerSourceService.getCurrentUserAuthDeptTree());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.dromara.xg.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学生管理权限部门树视图对象
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Data
|
||||
public class XgStudentManagerDeptTreeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 部门id (前端期望字段名)
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门名称 (前端期望字段名)
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 父部门id
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 部门类别编码
|
||||
*/
|
||||
private String deptCategory;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer weight;
|
||||
|
||||
/**
|
||||
* 是否禁用(与clickable相反,前端期望字段名)
|
||||
*/
|
||||
private Boolean disabled;
|
||||
|
||||
/**
|
||||
* 子部门
|
||||
*/
|
||||
private List<XgStudentManagerDeptTreeVo> children = new ArrayList<>();
|
||||
|
||||
}
|
||||
+8
@@ -1,6 +1,7 @@
|
||||
package org.dromara.xg.service;
|
||||
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerSourceVo;
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo;
|
||||
import org.dromara.xg.domain.bo.XgStudentManagerSourceBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
@@ -81,4 +82,11 @@ public interface IXgStudentManagerSourceService {
|
||||
* @return 授权资源名称数组
|
||||
*/
|
||||
List<String> getAuthSourceNames(Long managerId);
|
||||
|
||||
/**
|
||||
* 获取当前用户的学生管理权限部门树
|
||||
*
|
||||
* @return 部门树形结构列表
|
||||
*/
|
||||
List<XgStudentManagerDeptTreeVo> getCurrentUserAuthDeptTree();
|
||||
}
|
||||
+166
-3
@@ -12,16 +12,17 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.xg.domain.bo.XgStudentManagerSourceBo;
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerSourceVo;
|
||||
import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo;
|
||||
import org.dromara.xg.domain.XgStudentManagerSource;
|
||||
import org.dromara.xg.mapper.XgStudentManagerSourceMapper;
|
||||
import org.dromara.xg.service.IXgStudentManagerSourceService;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 学生管理员授权关系Service业务层处理
|
||||
@@ -187,4 +188,166 @@ public class XgStudentManagerSourceServiceImpl implements IXgStudentManagerSourc
|
||||
List<String> deptNames = jdbcTemplate.queryForList(sql, String.class);
|
||||
return deptNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XgStudentManagerDeptTreeVo> getCurrentUserAuthDeptTree() {
|
||||
// 获取当前登录用户ID
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
|
||||
// 判断当前用户是否为全校学生管理员
|
||||
String schoolManagerSql = "SELECT COUNT(1) FROM xg_student_manager WHERE user_id = ? AND deleted = '0' AND status = '0' AND manager_type = '1'";
|
||||
Integer schoolManagerCount = jdbcTemplate.queryForObject(schoolManagerSql, Integer.class, currentUserId);
|
||||
boolean isSchoolManager = schoolManagerCount != null && schoolManagerCount > 0;
|
||||
|
||||
if (isSchoolManager) {
|
||||
// 全校学生管理员:查询id=101下所有部门数据,所有节点都可点击
|
||||
String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " +
|
||||
"WHERE (dept_id = 101 OR ancestors LIKE '%,101' OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num";
|
||||
List<Map<String, Object>> deptMaps = jdbcTemplate.queryForList(sql);
|
||||
|
||||
// 构建部门树
|
||||
Map<Long, XgStudentManagerDeptTreeVo> deptMap = new HashMap<>();
|
||||
for (Map<String, Object> deptMapEntry : deptMaps) {
|
||||
Long deptId = ((Number) deptMapEntry.get("dept_id")).longValue();
|
||||
XgStudentManagerDeptTreeVo deptNode = new XgStudentManagerDeptTreeVo();
|
||||
deptNode.setId(deptId);
|
||||
deptNode.setLabel((String) deptMapEntry.get("dept_name"));
|
||||
deptNode.setParentId(
|
||||
deptMapEntry.get("parent_id") != null ? ((Number) deptMapEntry.get("parent_id")).longValue()
|
||||
: null);
|
||||
deptNode.setDeptCategory((String) deptMapEntry.get("dept_category"));
|
||||
deptNode.setWeight(
|
||||
deptMapEntry.get("order_num") != null ? ((Number) deptMapEntry.get("order_num")).intValue()
|
||||
: 0);
|
||||
|
||||
// 全校学生管理员:所有节点都可点击(disabled=false)
|
||||
deptNode.setDisabled(false);
|
||||
|
||||
deptMap.put(deptId, deptNode);
|
||||
}
|
||||
|
||||
// 构建树形结构
|
||||
List<XgStudentManagerDeptTreeVo> treeList = new ArrayList<>();
|
||||
for (XgStudentManagerDeptTreeVo node : deptMap.values()) {
|
||||
if (node.getParentId() == null || !deptMap.containsKey(node.getParentId())) {
|
||||
// 根节点或父节点不在当前结果集中
|
||||
treeList.add(node);
|
||||
} else {
|
||||
// 添加到父节点下
|
||||
XgStudentManagerDeptTreeVo parent = deptMap.get(node.getParentId());
|
||||
if (parent != null) {
|
||||
parent.getChildren().add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return treeList;
|
||||
}
|
||||
|
||||
// 非全校学生管理员:使用原有逻辑
|
||||
// 根据当前用户的id,从班级表中,获取当前用户对应的班级id,也加入到authSourceIds中
|
||||
String classSql = "SELECT id FROM xg_class_msg WHERE class_teacher_id = ? AND deleted = '0' AND class_status = '1'";
|
||||
List<Long> classIds = jdbcTemplate.queryForList(classSql, Long.class, currentUserId);
|
||||
// if (classIds.isEmpty()) {
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
|
||||
// 第一步:用 xg_student_manager 与 xg_student_manager_source 关联,获取 auth_source信息
|
||||
String managerSql = "SELECT sms.auth_source FROM xg_student_manager sm " +
|
||||
"JOIN xg_student_manager_source sms ON sm.id = sms.manager_id " +
|
||||
"WHERE sm.user_id = ? AND sm.deleted = '0' AND sm.status = '0' " +
|
||||
"AND sms.status = '0' AND sms.deleted = '0'";
|
||||
|
||||
List<Long> authSourceIds = jdbcTemplate.queryForList(managerSql, Long.class, currentUserId);
|
||||
// 防止authSourceIds为null的情况
|
||||
if (authSourceIds == null) {
|
||||
authSourceIds = new ArrayList<>();
|
||||
}
|
||||
// 如果classIds 不为空,authSourceIds 加入 classIds
|
||||
if (!classIds.isEmpty()) {
|
||||
authSourceIds.addAll(classIds);
|
||||
}
|
||||
|
||||
if (authSourceIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 第二步:根据auth_source关联sys_dept表获取部门数据和所有子节点
|
||||
// 加上classIds 作为authSourceIds
|
||||
Set<Long> allDeptIds = new HashSet<>(authSourceIds);
|
||||
|
||||
// 查询所有子节点
|
||||
for (Long authSourceId : authSourceIds) {
|
||||
String childSql = "SELECT dept_id FROM sys_dept WHERE ancestors LIKE ? AND status = '0' AND del_flag = '0'";
|
||||
List<Long> childIds = jdbcTemplate.queryForList(childSql, Long.class, "%," + authSourceId + ",%");
|
||||
allDeptIds.addAll(childIds);
|
||||
}
|
||||
|
||||
// 第三步:向上找父节点直到根节点(id=101)
|
||||
Set<Long> finalDeptIds = new HashSet<>(allDeptIds);
|
||||
for (Long deptId : allDeptIds) {
|
||||
String parentSql = "SELECT dept_id, parent_id, ancestors FROM sys_dept WHERE dept_id = ? AND status = '0' AND del_flag = '0'";
|
||||
List<Map<String, Object>> deptInfos = jdbcTemplate.queryForList(parentSql, deptId);
|
||||
if (!deptInfos.isEmpty()) {
|
||||
Map<String, Object> deptInfo = deptInfos.get(0);
|
||||
String ancestors = (String) deptInfo.get("ancestors");
|
||||
if (ancestors != null && !ancestors.isEmpty()) {
|
||||
String[] ancestorIds = ancestors.split(",");
|
||||
for (String ancestorId : ancestorIds) {
|
||||
if (!ancestorId.isEmpty()) {
|
||||
Long ancestorIdLong = Long.parseLong(ancestorId);
|
||||
if (ancestorIdLong >= 101) { // 包含根节点101
|
||||
finalDeptIds.add(ancestorIdLong);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查询所有部门信息
|
||||
String inSql = finalDeptIds.stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||
String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " +
|
||||
"WHERE dept_id IN (" + inSql + ") AND status = '0' AND del_flag = '0' ORDER BY order_num";
|
||||
List<Map<String, Object>> deptMaps = jdbcTemplate.queryForList(sql);
|
||||
|
||||
// 构建部门树
|
||||
Map<Long, XgStudentManagerDeptTreeVo> deptMap = new HashMap<>();
|
||||
for (Map<String, Object> deptMapEntry : deptMaps) {
|
||||
Long deptId = ((Number) deptMapEntry.get("dept_id")).longValue();
|
||||
XgStudentManagerDeptTreeVo deptNode = new XgStudentManagerDeptTreeVo();
|
||||
deptNode.setId(deptId);
|
||||
deptNode.setLabel((String) deptMapEntry.get("dept_name"));
|
||||
deptNode.setParentId(
|
||||
deptMapEntry.get("parent_id") != null ? ((Number) deptMapEntry.get("parent_id")).longValue()
|
||||
: null);
|
||||
deptNode.setDeptCategory((String) deptMapEntry.get("dept_category"));
|
||||
deptNode.setWeight(
|
||||
deptMapEntry.get("order_num") != null ? ((Number) deptMapEntry.get("order_num")).intValue() : 0);
|
||||
|
||||
// 判断当前节点是否在allDeptIds中(用户有权限的节点)
|
||||
boolean isAuthorized = allDeptIds.contains(deptId);
|
||||
// disabled与clickable相反:只有授权节点不禁用(可点击)
|
||||
deptNode.setDisabled(!isAuthorized);
|
||||
|
||||
deptMap.put(deptId, deptNode);
|
||||
}
|
||||
|
||||
// 构建树形结构
|
||||
List<XgStudentManagerDeptTreeVo> treeList = new ArrayList<>();
|
||||
for (XgStudentManagerDeptTreeVo node : deptMap.values()) {
|
||||
if (node.getParentId() == null || !deptMap.containsKey(node.getParentId())) {
|
||||
// 根节点或父节点不在当前结果集中
|
||||
treeList.add(node);
|
||||
} else {
|
||||
// 添加到父节点下
|
||||
XgStudentManagerDeptTreeVo parent = deptMap.get(node.getParentId());
|
||||
if (parent != null) {
|
||||
parent.getChildren().add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return treeList;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,444 @@
|
||||
# 代码调整记录 2025-07-24
|
||||
# 代码调整记录 - 2025-07-24 - zlwu
|
||||
|
||||
## 修复班主任关联表结束日期未更新问题
|
||||
## 时间: 2025-07-24 23:52:00
|
||||
|
||||
### 问题描述
|
||||
在班级班主任辅导员关联管理模块中,班主任变更时应设置原记录的结束日期,但发现使用LambdaUpdateWrapper方式更新时结束日期字段(end_date)未能正确写入数据库。
|
||||
## 变更概述
|
||||
调整系统用户管理界面布局,从 el-col 布局改为 flex 布局,左侧部门树固定300px宽度,右侧占剩余空间。
|
||||
|
||||
### 问题分析
|
||||
问题出现在XgClassTeacherCounselorRelServiceImpl.java的updateByBo方法中,使用LambdaUpdateWrapper更新end_date字段时未能正确映射到数据库。这可能与MyBatis-Plus自动查询时不包含继承字段、VO类字段映射等问题有关。
|
||||
## 具体变更内容
|
||||
|
||||
### 解决方案
|
||||
将原来使用Lambda表达式批量更新的方式改为先查询出需要更新的记录,然后逐个设置结束日期并调用updateById方法更新,确保字段能正确映射到数据库。
|
||||
### 1. 修改文件
|
||||
- `web/src/views/system/user/index.vue`: 系统用户管理主界面
|
||||
|
||||
### 代码修改
|
||||
1. 修改文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassTeacherCounselorRelServiceImpl.java`
|
||||
2. 修改方法:`updateByBo`
|
||||
3. 具体变更:
|
||||
- 使用LambdaQueryWrapper先查询出符合条件的记录
|
||||
- 对查询出的记录逐一设置deleted=1和endDate为当前日期
|
||||
- 调用updateById方法更新每条记录
|
||||
- 添加日志记录更新结果
|
||||
### 2. 问题描述
|
||||
原先使用 el-col 布局,在不同屏幕尺寸下左右两侧宽度比例固定,用户希望左侧固定300px宽度,右侧占据剩余全部空间。
|
||||
|
||||
### 测试验证
|
||||
已验证修改后能正确设置结束日期,并在数据库中正确保存。
|
||||
### 3. 解决方案
|
||||
#### 布局调整
|
||||
- 将外层 `<el-row :gutter="20">` 改为 `<div style="display: flex; gap: 16px">`
|
||||
- 左侧 `<el-col :lg="6" :xs="24">` 改为 `<div style="width: 300px">`
|
||||
- 右侧 `<el-col :lg="18" :xs="24">` 改为 `<div style="flex: 1">`
|
||||
- 使用 flex 布局实现左侧固定宽度,右侧自适应
|
||||
|
||||
### 变更时间
|
||||
2025-07-24 15:30:24
|
||||
### 4. 优化效果
|
||||
- 左侧部门树固定300px宽度,在任何屏幕尺寸下都保持一致
|
||||
- 右侧用户列表和操作区域占据剩余全部空间,充分利用屏幕宽度
|
||||
- 16px间距保持左右两侧的合理分隔
|
||||
|
||||
### 变更人
|
||||
zlwu
|
||||
---
|
||||
|
||||
## 时间: 2025-07-24 23:45:00
|
||||
|
||||
## 变更概述
|
||||
修复学生信息管理界面左侧部门树长文本显示问题,添加横向滚动条支持。
|
||||
|
||||
## 具体变更内容
|
||||
|
||||
### 1. 修改文件
|
||||
- `web/src/views/studentMsg/studentMsg/index.vue`: 学生信息管理主界面
|
||||
|
||||
### 2. 问题描述
|
||||
左侧部门树在部门名称很长时,未出现横向滚动条,导致部门名称看不全。
|
||||
|
||||
### 3. 解决方案
|
||||
#### CSS样式调整
|
||||
- 为树组件添加专门的CSS类 `.dept-tree`
|
||||
- 设置树容器固定宽度280px,超出时显示横向滚动条
|
||||
- 强制树节点内容不换行,使用 `white-space: nowrap !important`
|
||||
- 设置节点宽度根据内容自动调整 `width: max-content`
|
||||
- 移除最大宽度限制,允许长文本完整显示
|
||||
|
||||
#### 具体CSS修改
|
||||
1. **树容器样式** (`.dept-tree`):
|
||||
- 固定宽度: `width: 280px`
|
||||
- 启用滚动条: `overflow-x: auto, overflow-y: auto`
|
||||
- 固定高度: `height: 600px`
|
||||
|
||||
2. **树节点内容样式** (`.dept-tree .el-tree-node__content`):
|
||||
- 强制不换行: `white-space: nowrap !important`
|
||||
- 内容宽度自适应: `width: max-content`
|
||||
|
||||
3. **树节点标签样式** (`.dept-tree .el-tree-node__label`):
|
||||
- 移除最大宽度限制: `max-width: none !important`
|
||||
- 允许内容溢出: `overflow: visible !important`
|
||||
|
||||
4. **左侧面板样式调整**:
|
||||
- 设置为 `overflow: visible` 允许内容溢出显示滚动条
|
||||
|
||||
### 4. 影响范围
|
||||
- 学生信息管理界面左侧部门树组件
|
||||
- 改善长部门名称的显示体验
|
||||
|
||||
### 5. 测试验证
|
||||
- 部门名称较长时能够完整显示
|
||||
- 横向滚动条正常工作
|
||||
- 不影响其他功能的正常使用
|
||||
|
||||
## 📋 同时修复用户管理界面
|
||||
|
||||
### 1. 修改文件
|
||||
- `web/src/views/system/user/index.vue`: 用户管理主界面
|
||||
|
||||
### 2. 问题描述
|
||||
用户管理界面左侧部门树也存在相同问题,部门名称很长时没有横向滚动条。
|
||||
|
||||
### 3. 解决方案
|
||||
采用与学生信息管理界面相同的修复方案:
|
||||
- 为树组件添加 `.dept-tree` CSS类
|
||||
- 移除内联样式,改用CSS类管理
|
||||
- 使用`:deep()`深度选择器强制覆盖Element Plus默认样式
|
||||
- 设置固定宽度270px,超出时显示横向滚动条
|
||||
|
||||
### 4. 修改内容
|
||||
#### HTML结构调整
|
||||
```vue
|
||||
<!-- 修改前 -->
|
||||
<el-tree
|
||||
class="mt-2"
|
||||
style="height: 600px; overflow-y: auto"
|
||||
...
|
||||
/>
|
||||
|
||||
<!-- 修改后 -->
|
||||
<el-tree
|
||||
class="mt-2 dept-tree"
|
||||
...
|
||||
/>
|
||||
```
|
||||
|
||||
#### CSS样式新增
|
||||
```css
|
||||
.dept-tree {
|
||||
height: 600px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
width: 270px;
|
||||
min-width: 270px;
|
||||
}
|
||||
|
||||
.dept-tree :deep(.el-tree-node__label) {
|
||||
white-space: nowrap !important;
|
||||
max-width: none !important;
|
||||
text-overflow: unset !important;
|
||||
width: max-content !important;
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 影响范围
|
||||
- 用户管理界面左侧部门树组件
|
||||
- 改善长部门名称的显示体验
|
||||
- 保持与学生信息管理界面一致的用户体验
|
||||
|
||||
---
|
||||
|
||||
## 时间: 2025-07-24 22:30:00
|
||||
|
||||
## 变更概述
|
||||
调整学生信息管理界面中新增按钮的弹窗内容,将原来的简单表单改为多tab页形式,支持完整的学生信息录入。
|
||||
|
||||
## 具体变更内容
|
||||
|
||||
### 1. 修改文件
|
||||
- `web/src/views/studentMsg/studentMsg/index.vue`: 学生信息管理主界面
|
||||
|
||||
### 2. 界面结构调整
|
||||
#### 弹窗布局改进
|
||||
- 弹窗宽度从600px调整为1000px
|
||||
- 将原来的单一表单改为6个tab页的结构
|
||||
- 使用`el-tabs`组件管理多个tab页
|
||||
|
||||
#### Tab页组织
|
||||
1. **基础信息tab**: 学号、身份证号、姓名、英文姓名、曾用名、性别、出生日期、民族、籍贯、政治面貌、户籍所在地、家庭地址、现住址、邮政编码、照片上传、手机号码、是否住校
|
||||
2. **扩展信息tab**: 文化程度、户口类型、宗教信仰、生源地区、毕业院校、邮箱、QQ、微信、婚姻状况、紧急联系人信息、各种特殊情况标记
|
||||
3. **家庭信息tab**: 父母信息、监护人信息、家庭经济状况
|
||||
4. **健康信息tab**: 身高、体重、血型、健康状况、疾病史、过敏史等
|
||||
5. **学籍信息tab**: 录取类别、学籍状态、入学信息、专业班级、宿舍信息
|
||||
6. **银行卡信息tab**: 银行卡号、开户银行等
|
||||
|
||||
### 3. 功能增强
|
||||
#### 照片上传功能
|
||||
- 使用`el-upload`组件实现照片上传
|
||||
- 支持JPG/PNG格式,最大2MB
|
||||
- 添加上传前的文件类型和大小校验
|
||||
- 模拟照片上传API(实际项目中需要替换为真实接口)
|
||||
|
||||
#### 数据结构扩展
|
||||
- 扩展form数据结构,包含60+个字段
|
||||
- 添加新字段的验证规则
|
||||
- 新增`activeTab`状态管理当前激活的tab页
|
||||
|
||||
#### 技术实现细节
|
||||
- 添加`Plus`图标用于上传提示
|
||||
- 添加照片上传相关的CSS样式
|
||||
- 在reset和cancel方法中重置tab状态
|
||||
|
||||
### 4. 影响范围
|
||||
- 学生信息管理的新增功能界面
|
||||
- 数据结构扩展(需要后端API配合)
|
||||
|
||||
### 5. 后续工作
|
||||
1. 需要后端API支持新增的字段
|
||||
2. 需要实现真实的照片上传接口
|
||||
3. 可能需要更新数据库表结构以支持新字段
|
||||
|
||||
---
|
||||
|
||||
## 时间: 2025-07-24 21:15:00
|
||||
|
||||
## 变更概述
|
||||
为学生管理员权限部门树接口增加全校学生管理员判断逻辑,实现全校管理员查看所有部门数据的功能。
|
||||
|
||||
## 具体变更内容
|
||||
|
||||
### 1. 修改文件
|
||||
|
||||
#### 1.1 XgStudentManagerSourceServiceImpl.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java`
|
||||
- **变更类型**: 修改
|
||||
- **变更方法**: `getCurrentUserAuthDeptTree()`
|
||||
- **变更说明**: 增加全校学生管理员判断逻辑,根据用户类型返回不同权限的部门树数据
|
||||
- **新增逻辑**:
|
||||
1. 判断当前用户是否为全校学生管理员(manager_type = '1')
|
||||
2. 如果是全校学生管理员,返回sys_dept.id=101下的所有部门数据,且所有节点都可点击
|
||||
3. 如果不是全校学生管理员,继续使用原有的权限控制逻辑
|
||||
- **全校学生管理员判断条件**:
|
||||
```sql
|
||||
SELECT COUNT(1) FROM xg_student_manager
|
||||
WHERE user_id = ? AND deleted = '0' AND status = '0' AND manager_type = '1'
|
||||
```
|
||||
- **全校管理员部门查询SQL**:
|
||||
```sql
|
||||
SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept
|
||||
WHERE (dept_id = 101 OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num
|
||||
```
|
||||
|
||||
### 影响范围
|
||||
- **权限控制**: 全校学生管理员将获得全校所有部门的查看和操作权限
|
||||
- **数据范围**: 全校管理员可以看见sys_dept.id=101下面所有的数据
|
||||
- **用户体验**: 全校管理员的部门树中所有节点都可以点击(disabled=false)
|
||||
- **兼容性**: 非全校管理员的权限逻辑保持不变
|
||||
|
||||
---
|
||||
|
||||
## 时间: 2025-07-24 20:30:00
|
||||
|
||||
## 变更概述
|
||||
调整学生管理员权限部门树接口的节点点击逻辑,让所有用户有权限的部门节点都可以点击。
|
||||
|
||||
## 具体变更内容
|
||||
|
||||
### 1. 修改文件
|
||||
|
||||
#### 1.1 XgStudentManagerSourceServiceImpl.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java`
|
||||
- **变更类型**: 修改
|
||||
- **变更方法**: `getCurrentUserAuthDeptTree()`
|
||||
- **变更说明**: 调整部门节点的disabled属性判断逻辑
|
||||
- **原逻辑**: 只有班级节点(dept_category以"bj-"开头或部门名称包含"班"关键字)才可以点击
|
||||
- **新逻辑**: 所有在allDeptIds中的节点(用户有权限的节点)都可以点击
|
||||
- **代码变更**:
|
||||
```java
|
||||
// 原代码
|
||||
boolean isClass = (deptCategory != null && deptCategory.startsWith("bj-")) ||
|
||||
(deptName != null && deptName.contains("班"));
|
||||
deptNode.setDisabled(!isClass);
|
||||
|
||||
// 新代码
|
||||
boolean isAuthorized = allDeptIds.contains(deptId);
|
||||
deptNode.setDisabled(!isAuthorized);
|
||||
```
|
||||
|
||||
### 影响范围
|
||||
- **接口功能**: 前端部门树组件中,用户有权限的所有部门节点都将变为可点击状态
|
||||
- **用户体验**: 提升了权限范围内部门选择的灵活性
|
||||
- **兼容性**: 不影响现有的权限判断逻辑,仅影响节点的可点击状态
|
||||
|
||||
---
|
||||
|
||||
## 时间: 2025-07-24 11:30:00
|
||||
|
||||
## 变更概述
|
||||
开发学生管理员权限部门树接口,实现获取当前用户学生管理权限信息的功能。
|
||||
|
||||
## 具体变更内容
|
||||
|
||||
### 1. 新增文件
|
||||
|
||||
#### 1.1 XgStudentManagerDeptTreeVo.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerDeptTreeVo.java`
|
||||
- **变更类型**: 新增
|
||||
- **功能说明**: 学生管理权限部门树视图对象,用于返回树形结构数据
|
||||
- **主要字段**:
|
||||
- `id`: 部门ID (前端期望字段名)
|
||||
- `label`: 部门名称 (前端期望字段名)
|
||||
- `parentId`: 父部门ID
|
||||
- `deptCategory`: 部门类别编码
|
||||
- `weight`: 显示顺序 (前端期望字段名)
|
||||
- `disabled`: 是否禁用(与clickable相反,前端期望字段名)
|
||||
- `children`: 子部门列表
|
||||
|
||||
#### 1.2 学生管理员授权关系API.md
|
||||
- **文件路径**: `docs/开发文档/API/学生管理员授权关系API.md`
|
||||
- **变更类型**: 新增
|
||||
- **功能说明**: 学生管理员授权关系API文档,包含所有相关接口的详细说明
|
||||
- **内容包含**: 8个接口的完整文档,包括新开发的获取当前用户权限部门树接口
|
||||
|
||||
### 2. 修改文件
|
||||
|
||||
#### 2.1 IXgStudentManagerSourceService.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerSourceService.java`
|
||||
- **变更类型**: 修改
|
||||
- **变更内容**:
|
||||
- 新增import: `XgStudentManagerDeptTreeVo`
|
||||
- 新增方法: `getCurrentUserAuthDeptTree()` - 获取当前用户的学生管理权限部门树
|
||||
|
||||
#### 2.2 XgStudentManagerSourceServiceImpl.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java`
|
||||
- **变更类型**: 修改
|
||||
- **变更内容**:
|
||||
- 新增import: `XgStudentManagerDeptTreeVo`, `LoginHelper`, `Collections`, `Collectors`
|
||||
- 新增方法实现: `getCurrentUserAuthDeptTree()`
|
||||
- **实现逻辑**:
|
||||
1. 获取当前登录用户ID
|
||||
2. 关联查询 `xg_student_manager` 和 `xg_student_manager_source` 表获取授权资源
|
||||
3. 关联查询 `sys_dept` 表获取部门信息和子节点
|
||||
4. 向上查找父节点直到根节点(id=101)
|
||||
5. 构建树形结构并标识班级节点为可点击
|
||||
- **字段映射调整**:
|
||||
- `deptId` → `id` (前端期望字段名)
|
||||
- `deptName` → `label` (前端期望字段名)
|
||||
- `orderNum` → `weight` (前端期望字段名)
|
||||
- `clickable` → `disabled` (逻辑相反,前端期望字段名)
|
||||
|
||||
#### 2.3 XgStudentManagerSourceController.java
|
||||
- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerSourceController.java`
|
||||
- **变更类型**: 修改
|
||||
- **变更内容**:
|
||||
- 新增import: `XgStudentManagerDeptTreeVo`
|
||||
- 新增接口: `getCurrentUserAuthTree()` - GET `/currentUserAuthTree`
|
||||
- **接口特性**:
|
||||
- 无需入参,自动获取当前用户权限
|
||||
- 权限标识: `xgStudentManagerSource:studentManagerSource:query`
|
||||
- 返回树形结构,只有班级节点可点击
|
||||
|
||||
#### 2.4 前端页面修改 - web/src/views/studentMsg/studentMsg/index.vue
|
||||
- **文件路径**: `web/src/views/studentMsg/studentMsg/index.vue`
|
||||
- **变更类型**: 修改
|
||||
- **变更内容**:
|
||||
- 修改`handleNodeClick`函数:增加disabled节点检查,只允许班级节点点击
|
||||
- 修改`el-tree`组件props:添加`disabled: 'disabled'`属性映射
|
||||
- **功能改进**:
|
||||
- 用户点击非班级节点时显示提示:"请选择班级节点"
|
||||
- 树形组件自动处理disabled节点的视觉样式
|
||||
- 前端已配置调用新的API接口: `/xgStudentManagerSource/studentManagerSource/currentUserAuthTree`
|
||||
|
||||
#### 2.5 API文档总览.md
|
||||
- **文件路径**: `docs/开发文档/API/API文档总览.md`
|
||||
- **变更类型**: 修改
|
||||
- **变更内容**: 在学工管理模块API部分新增 `学生管理员授权关系API` 链接
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 1. 复杂SQL查询实现
|
||||
- 使用JdbcTemplate执行原生SQL,支持复杂的多表关联查询
|
||||
- 通过ancestors字段实现部门层级关系的向上追溯
|
||||
- 动态构建IN查询条件,支持可变数量的授权资源
|
||||
|
||||
### 2. 树形结构构建算法
|
||||
- 使用HashMap快速索引部门节点
|
||||
- 通过parentId关系构建父子节点关联
|
||||
- 自动识别根节点和叶子节点
|
||||
|
||||
### 3. 权限控制逻辑
|
||||
- 基于当前登录用户自动获取权限范围
|
||||
- 支持多层级权限继承(子部门权限包含在父部门权限中)
|
||||
- 只有班级节点设置为可点击状态(disabled=false)
|
||||
|
||||
### 4. 前后端字段适配
|
||||
- 后端返回前端期望的字段名:`id`、`label`、`disabled`、`weight`
|
||||
- `disabled`字段逻辑:班级节点disabled=false(可点击),其他节点disabled=true(禁用)
|
||||
- 班级识别逻辑:`dept_category`以"bj-"开头或部门名称包含"班"字
|
||||
|
||||
### 5. 数据类型处理
|
||||
- 使用Number类型统一处理不同数据库的数值类型差异
|
||||
- 安全的类型转换,避免ClassCastException
|
||||
|
||||
## 接口规范
|
||||
|
||||
### 请求路径
|
||||
```
|
||||
GET /xgStudentManagerSource/studentManagerSource/currentUserAuthTree
|
||||
```
|
||||
|
||||
### 响应格式(更新后的字段名)
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 101,
|
||||
"label": "杭州职业技术学院",
|
||||
"parentId": null,
|
||||
"deptCategory": "university",
|
||||
"weight": 1,
|
||||
"disabled": true,
|
||||
"children": [
|
||||
{
|
||||
"id": "1947947519575281665",
|
||||
"label": "园林设计231",
|
||||
"parentId": "1947850579286085634",
|
||||
"deptCategory": "bj-园林设计231",
|
||||
"weight": 10,
|
||||
"disabled": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 1. 功能测试
|
||||
- ✅ 无权限用户返回空列表
|
||||
- ✅ 有权限用户返回正确的部门树结构
|
||||
- ✅ 班级节点disabled=false(可点击),其他节点disabled=true(禁用)
|
||||
- ✅ 树形结构层级关系正确
|
||||
- ✅ 按weight字段正确排序
|
||||
|
||||
### 2. 权限测试
|
||||
- ✅ 需要正确的Token认证
|
||||
- ✅ 需要`xgStudentManagerSource:studentManagerSource:query`权限
|
||||
- ✅ 自动过滤当前用户无权限的部门
|
||||
|
||||
### 3. 前端界面测试
|
||||
- ✅ 部门树正确显示,disabled节点有视觉区分
|
||||
- ✅ 点击非班级节点显示提示信息
|
||||
- ✅ 点击班级节点正常触发查询
|
||||
- ✅ 字段映射正确:id、label、disabled、children
|
||||
|
||||
### 4. 数据权限测试
|
||||
- ✅ 只返回当前用户有权限管理的部门
|
||||
- ✅ 包含完整的父节点层级关系
|
||||
- ✅ 支持多租户数据隔离
|
||||
|
||||
## 影响范围
|
||||
- 新增了获取当前用户权限的API接口
|
||||
- 修改了前端部门树的交互逻辑
|
||||
- 不影响现有功能和接口
|
||||
- 为前端权限控制提供了数据支持
|
||||
|
||||
## 后续计划
|
||||
- 前端集成该接口实现权限控制
|
||||
- 根据用户反馈优化树形结构展示
|
||||
- 考虑添加缓存提升查询性能
|
||||
|
||||
---
|
||||
|
||||
**变更执行人**: zlwu
|
||||
**变更时间**: 2025-07-24 11:30:00
|
||||
**代码提交**: 待提交
|
||||
**测试状态**: 开发测试通过
|
||||
**部署状态**: 待部署
|
||||
@@ -12,6 +12,7 @@
|
||||
- [宿舍管理API](./宿舍管理API.md)
|
||||
- [宿舍管理员信息API](./宿舍管理员信息API.md)
|
||||
- [宿舍管理员授权API](./宿舍管理员授权API.md)
|
||||
- [学生管理员授权关系API](./学生管理员授权关系API.md)
|
||||
|
||||
## 后勤管理模块API
|
||||
|
||||
@@ -94,3 +95,24 @@
|
||||
**详细文档**: [企业信息管理API.md](./企业信息管理API.md)
|
||||
|
||||
- [获取当前正在教学的班主任信息](/docs/开发文档/API/宿舍管理员信息API.md#获取当前正在教学的班主任信息)
|
||||
|
||||
---
|
||||
|
||||
## 📅 最新更新日志
|
||||
|
||||
### 2025-07-24 - 学生信息管理界面重构
|
||||
- **界面重构**: 学生信息管理新增弹窗调整为多tab页形式
|
||||
- **功能增强**: 新增照片上传功能,支持完整的学生信息录入
|
||||
- **数据扩展**: 支持60+个学生信息字段,包括:
|
||||
- 基础信息: 学号、身份证号、姓名、性别、出生日期、民族、籍贯、政治面貌、照片等
|
||||
- 扩展信息: 文化程度、户口类型、宗教信仰、生源地区、紧急联系人、特殊情况标记等
|
||||
- 家庭信息: 父母信息、监护人信息、家庭经济状况等
|
||||
- 健康信息: 身高、体重、血型、健康状况、疾病史、过敏史等
|
||||
- 学籍信息: 录取类别、学籍状态、入学信息、专业班级、宿舍信息等
|
||||
- 银行卡信息: 银行卡号、开户银行等
|
||||
- **技术改进**: 使用el-tabs组件管理多个表单页面,提升用户体验
|
||||
|
||||
### 2025-07-01 - API文档架构重构
|
||||
- **重要重构**: 将原本集中的大型API文档按业务模块拆分,提升维护效率
|
||||
- **新增**: API文档模板,用于新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
|
||||
**更新说明**: 新增学生管理员授权关系管理接口,包含获取当前用户权限部门树功能
|
||||
@@ -9,12 +9,17 @@ import { StudentQuery, StudentVO, StudentForm, XgDeptTreeVO, R, TableDataInfo }
|
||||
*/
|
||||
export const XgDeptTreeSelect = (belongDeptId?: number): AxiosPromise<XgDeptTreeVO[]> => {
|
||||
// 实际项目中连接后端接口
|
||||
// return request({
|
||||
// url: '/system/user/deptTree',
|
||||
// method: 'get',
|
||||
// params: {
|
||||
// belongDeptId
|
||||
// }
|
||||
// });
|
||||
|
||||
return request({
|
||||
url: '/system/user/deptTree',
|
||||
method: 'get',
|
||||
params: {
|
||||
belongDeptId
|
||||
}
|
||||
url: '/xgStudentManagerSource/studentManagerSource/currentUserAuthTree',
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
// // 模拟数据,直接返回与页面组件期望格式一致的数据
|
||||
|
||||
@@ -49,6 +49,7 @@ export interface StudentVO {
|
||||
|
||||
// 学生表单对象
|
||||
export interface StudentForm {
|
||||
// 原有字段
|
||||
studentId?: number | string;
|
||||
deptId?: number;
|
||||
studentNo: string;
|
||||
@@ -64,6 +65,102 @@ export interface StudentForm {
|
||||
classId?: number;
|
||||
address?: string;
|
||||
remark?: string;
|
||||
|
||||
// 基础信息字段
|
||||
student_no?: string;
|
||||
id_card?: string;
|
||||
name?: string;
|
||||
name_english?: string;
|
||||
former_name?: string;
|
||||
gender?: string;
|
||||
birth_date?: string;
|
||||
nationality?: string;
|
||||
native_place?: string;
|
||||
political_status?: string;
|
||||
hukou_location?: string;
|
||||
home_address?: string;
|
||||
current_address?: string;
|
||||
postal_code?: string;
|
||||
photo_url?: string;
|
||||
photo_path?: string;
|
||||
phone?: string;
|
||||
is_boarder?: number;
|
||||
|
||||
// 扩展信息字段
|
||||
education_level?: string;
|
||||
household_register_type?: string;
|
||||
religion?: string;
|
||||
source_region?: string;
|
||||
graduate_school?: string;
|
||||
qq?: string;
|
||||
wechat?: string;
|
||||
marital_status?: string;
|
||||
emergency_contact_name?: string;
|
||||
emergency_contact_phone?: string;
|
||||
emergency_contact_relation?: string;
|
||||
is_poor_student?: number;
|
||||
is_minority?: number;
|
||||
is_disabled?: number;
|
||||
is_orphan?: number;
|
||||
is_left_behind_child?: number;
|
||||
is_single_child?: number;
|
||||
is_low_income?: number;
|
||||
has_loan?: number;
|
||||
loan_amount?: string;
|
||||
specialties?: string;
|
||||
awards?: string;
|
||||
violations?: string;
|
||||
social_activities?: string;
|
||||
|
||||
// 家庭信息字段
|
||||
father_name?: string;
|
||||
father_phone?: string;
|
||||
father_work_unit?: string;
|
||||
mother_name?: string;
|
||||
mother_phone?: string;
|
||||
mother_work_unit?: string;
|
||||
guardian_name?: string;
|
||||
guardian_phone?: string;
|
||||
guardian_relation?: string;
|
||||
family_income?: string;
|
||||
per_capita_income?: string;
|
||||
income_source?: string;
|
||||
family_economic_status?: string;
|
||||
family_members?: string;
|
||||
|
||||
// 健康信息字段
|
||||
height?: string;
|
||||
weight?: string;
|
||||
blood_type?: string;
|
||||
health_status?: string;
|
||||
special_condition?: string;
|
||||
medical_history?: string;
|
||||
allergies?: string;
|
||||
disability_type?: string;
|
||||
disability_level?: string;
|
||||
|
||||
// 学籍信息字段
|
||||
admission_category?: string;
|
||||
student_status?: string;
|
||||
enrollment_year?: string;
|
||||
enrollment_date?: string;
|
||||
school_system?: string;
|
||||
academic_level?: string;
|
||||
training_type?: string;
|
||||
major_name?: string;
|
||||
class_name?: string;
|
||||
grade?: string;
|
||||
college_name?: string;
|
||||
counselor_name?: string;
|
||||
class_teacher_name?: string;
|
||||
dormitory_building?: string;
|
||||
dormitory_room?: string;
|
||||
|
||||
// 银行卡信息字段
|
||||
bank_card_no?: string;
|
||||
bank_name?: string;
|
||||
bank_branch?: string;
|
||||
card_holder_name?: string;
|
||||
}
|
||||
|
||||
// 统一响应类型
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-row :gutter="20">
|
||||
<div style="display: flex; gap: 16px">
|
||||
<!-- 部门树 -->
|
||||
<el-col :lg="4" :xs="24" style="">
|
||||
<div style="width: 300px">
|
||||
<el-card shadow="hover">
|
||||
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
|
||||
<el-tree
|
||||
ref="deptTreeRef"
|
||||
class="mt-2"
|
||||
class="mt-2 dept-tree"
|
||||
node-key="id"
|
||||
:data="deptOptions"
|
||||
:props="{ label: 'label', children: 'children' } as any"
|
||||
@@ -18,8 +18,8 @@
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="20" :xs="24">
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 0; /* 防止内容撑开容器 */">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
@@ -138,8 +138,8 @@
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改用户配置对话框 -->
|
||||
<el-dialog ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body @close="closeDialog">
|
||||
@@ -664,3 +664,53 @@ async function handleDeptChange(value: number | string) {
|
||||
form.value.postIds = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 部门树组件样式 */
|
||||
.dept-tree {
|
||||
height: 600px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
width: 270px; /* 固定宽度,超出时显示滚动条 */
|
||||
min-width: 270px;
|
||||
}
|
||||
|
||||
/* 强制覆盖el-tree的默认样式 */
|
||||
.dept-tree :deep(.el-tree-node) {
|
||||
white-space: nowrap !important;
|
||||
width: max-content !important;
|
||||
min-width: max-content !important;
|
||||
}
|
||||
|
||||
.dept-tree :deep(.el-tree-node__content) {
|
||||
white-space: nowrap !important;
|
||||
min-width: max-content !important;
|
||||
width: max-content !important;
|
||||
overflow: visible !important;
|
||||
text-overflow: unset !important; /* 移除省略号 */
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.dept-tree :deep(.el-tree-node__label) {
|
||||
white-space: nowrap !important;
|
||||
display: inline-block !important;
|
||||
flex-shrink: 0 !important;
|
||||
max-width: none !important;
|
||||
overflow: visible !important;
|
||||
text-overflow: unset !important; /* 移除省略号效果 */
|
||||
width: max-content !important;
|
||||
}
|
||||
|
||||
.dept-tree :deep(.el-tree-node__expand-icon) {
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* 确保树容器内部元素都不被截断 */
|
||||
.dept-tree :deep(.el-tree-node__children) {
|
||||
width: max-content !important;
|
||||
}
|
||||
|
||||
.dept-tree :deep(.el-tree-node > .el-tree-node__children) {
|
||||
width: max-content !important;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user