点击部门树状图来进行条件查询
前端找到对应的页面,按照路由路径
里面有个handleNodeClick()点击事件,点进去看看
发现是复用了getList()方法,说明后台也是复用相应的方法
/**
* 获取用户列表
*/
//@PreAuthorize在调用方法前先检查有没有权限,通过Service层的@ss.hasPermi()方法来校验
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list);
}
之前点击用户管理,调用这个方法传入的参数是null,没有deptId,现在通过部门树状图点击,会传入一个参数deptId
那具体也不讲,也就是通过数据库根据条件部门id去查找的。
添加数据
添加用户的预加载
reset是表单重置
getTreeselect()获取部门树状图,奇怪为啥还要这个东西,原因是新增用户界面有一个部门选项
然后就是getUser()方法回传了role角色和rost岗位的参数,我们看下这个方法
然后我们从后端查看该方法,从url中可以看出是在user/下的,带有一个userId参数,很顺利也找到了对应的方法
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{
userService.checkUserDataScope(userId);
AjaxResult ajax = AjaxResult.success();
List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll());
if (StringUtils.isNotNull(userId))
{
ajax.put(AjaxResult.DATA_TAG, userService.selectUserById(userId));
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
}
return ajax;
}
这个方法主要是获取系统目前所有的角色集合(超级管理员除外)以及岗位信息集合。至于参数的userId是在修改用户信息时,才用到。
/**
* 校验用户是否有数据权限
*
* @param userId 用户id
*/
@Override
public void checkUserDataScope(Long userId)
{
if (!SysUser.isAdmin(SecurityUtils.getUserId()))
{
SysUser user = new SysUser();
user.setUserId(userId);
List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
// List<SysUser> users = selectUserList(user);
if (StringUtils.isEmpty(users))
{
throw new ServiceException("没有权限访问用户数据!");
}
}
}
首先先检查当前登录用户是否有数据权限,不过只要你能点击新增用户的按钮,这个检查肯定能过,因为传入的userId为null,它就会查询所有的用户出来,所以也不会抛出"没有权限访问用户数据!"的异常。估计是修改用户的时候才会起到作用。
回到controller,接下来就是把所有的角色信息和岗位信息封装成AjaxResult,返回给前端。
添加用户信息
当我们填写好新增用户信息时,是要按确认才能生效。一般方法应该是submit或则有注解是提交之类,
之里面做了一个判断,如果有userId的话,则是修改,不是的话则执行新增方法,我们看下新增方法
看到这里我也知道后端controller对应的方法在哪了,
/**
* 校验手机号码是否唯一
*
* @param user 用户信息
* @return
*/
@Override
public String checkPhoneUnique(SysUser user)
{
Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
//如果info为空,说明手机号肯定没重复,但如果是info不为空的,有可能是同一个用户,如果不是同一个用户则说明手机号重复。
if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
{
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
其中判断用户名是否重复是通过sql的count来判断,而手机号的重复性是通过查询该手机号对应的用户,如果结果是null,则说明手机号不重复,另一种情况是,查出来某个用户,但如果这个用户和参数的用户的userid相同,则说明是同一个人,估计修改的功能,说明该方法多次复用。
邮箱账号的重复性与手机号的判断类似。
然后就是加密,这里用springsecurity的BCryptPasswordEncoder(官方推荐)
最后是把新增用户信息保存数据库,运用了事务的原理
/**
* 新增保存用户信息
*
* @param user 用户信息
* @return 结果
*/
@Override
@Transactional
public int insertUser(SysUser user)
{
// 新增用户信息
int rows = userMapper.insertUser(user);
// 新增用户岗位关联
insertUserPost(user);
// 新增用户与角色管理
insertUserRole(user);
return rows;
}
这里不止插入了用户信息,还插入了中间表
因为用户与角色,与岗位是多对多的关系,所以需要中间表来记录各自的主键id。
举个岗位插入例子
/**
* 新增用户岗位信息
*
* @param user 用户对象
*/
public void insertUserPost(SysUser user)
{
Long[] posts = user.getPostIds();
if (StringUtils.isNotNull(posts))
{
// 新增用户与岗位管理
List<SysUserPost> list = new ArrayList<SysUserPost>();
for (Long postId : posts)
{
SysUserPost up = new SysUserPost();
up.setUserId(user.getUserId());
up.setPostId(postId);
list.add(up);
}
if (list.size() > 0)
{
userPostMapper.batchUserPost(list);
}
}
}
通过foreach循环记录多个SysUserPost ,然后封装成List,给mybatis,通过动态sql加上foreach标签来循环插入数据到中间表。
而userId是102,按理说执行玩mapper方法应该已经插入数据库,可是数据库却没变化
这是因为使用了事务的注解,使得这几行代码也有事务的特性。
回到controller层,最后把影响的行数返回给AjaxResult,如果row>0,则说明新增用户成功,返回一个AjaxResult给前端。