完成用户列表的前后端对接

This commit is contained in:
YunaiV 2021-01-10 12:19:39 +08:00
parent cdaa0d9195
commit f5b7142ab6
18 changed files with 480 additions and 319 deletions

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -31,27 +32,7 @@ import com.ruoyi.system.service.ISysUserService;
* @author ruoyi * @author ruoyi
*/ */
@Service @Service
public class SysUserServiceImpl implements ISysUserService public class SysUserServiceImpl implements ISysUserService {
{
private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
@Autowired
private SysUserMapper userMapper;
@Autowired
private SysRoleMapper roleMapper;
@Autowired
private SysPostMapper postMapper;
@Autowired
private SysUserRoleMapper userRoleMapper;
@Autowired
private SysUserPostMapper userPostMapper;
@Autowired
private ISysConfigService configService;
/** /**
* 根据条件分页查询用户列表 * 根据条件分页查询用户列表
@ -61,35 +42,10 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
@Override @Override
@DataScope(deptAlias = "d", userAlias = "u") @DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user) public List<SysUser> selectUserList(SysUser user) {
{
return userMapper.selectUserList(user); return userMapper.selectUserList(user);
} }
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
@Override
public SysUser selectUserByUserName(String userName)
{
return userMapper.selectUserByUserName(userName);
}
/**
* 通过用户ID查询用户
*
* @param userId 用户ID
* @return 用户对象信息
*/
@Override
public SysUser selectUserById(Long userId)
{
return userMapper.selectUserById(userId);
}
/** /**
* 查询用户所属角色组 * 查询用户所属角色组
* *
@ -97,16 +53,13 @@ public class SysUserServiceImpl implements ISysUserService
* @return 结果 * @return 结果
*/ */
@Override @Override
public String selectUserRoleGroup(String userName) public String selectUserRoleGroup(String userName) {
{
List<SysRole> list = roleMapper.selectRolesByUserName(userName); List<SysRole> list = roleMapper.selectRolesByUserName(userName);
StringBuffer idsStr = new StringBuffer(); StringBuffer idsStr = new StringBuffer();
for (SysRole role : list) for (SysRole role : list) {
{
idsStr.append(role.getRoleName()).append(","); idsStr.append(role.getRoleName()).append(",");
} }
if (StringUtils.isNotEmpty(idsStr.toString())) if (StringUtils.isNotEmpty(idsStr.toString())) {
{
return idsStr.substring(0, idsStr.length() - 1); return idsStr.substring(0, idsStr.length() - 1);
} }
return idsStr.toString(); return idsStr.toString();
@ -119,56 +72,18 @@ public class SysUserServiceImpl implements ISysUserService
* @return 结果 * @return 结果
*/ */
@Override @Override
public String selectUserPostGroup(String userName) public String selectUserPostGroup(String userName) {
{
List<SysPost> list = postMapper.selectPostsByUserName(userName); List<SysPost> list = postMapper.selectPostsByUserName(userName);
StringBuffer idsStr = new StringBuffer(); StringBuffer idsStr = new StringBuffer();
for (SysPost post : list) for (SysPost post : list) {
{
idsStr.append(post.getPostName()).append(","); idsStr.append(post.getPostName()).append(",");
} }
if (StringUtils.isNotEmpty(idsStr.toString())) if (StringUtils.isNotEmpty(idsStr.toString())) {
{
return idsStr.substring(0, idsStr.length() - 1); return idsStr.substring(0, idsStr.length() - 1);
} }
return idsStr.toString(); return idsStr.toString();
} }
/**
* 校验用户名称是否唯一
*
* @param userName 用户名称
* @return 结果
*/
@Override
public String checkUserNameUnique(String userName)
{
int count = userMapper.checkUserNameUnique(userName);
if (count > 0)
{
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 校验用户名称是否唯一
*
* @param user 用户信息
* @return
*/
@Override
public String checkPhoneUnique(SysUser user)
{
Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
{
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/** /**
* 校验email是否唯一 * 校验email是否唯一
* *
@ -176,12 +91,10 @@ public class SysUserServiceImpl implements ISysUserService
* @return * @return
*/ */
@Override @Override
public String checkEmailUnique(SysUser user) public String checkEmailUnique(SysUser user) {
{
Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
SysUser info = userMapper.checkEmailUnique(user.getEmail()); SysUser info = userMapper.checkEmailUnique(user.getEmail());
if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
{
return UserConstants.NOT_UNIQUE; return UserConstants.NOT_UNIQUE;
} }
return UserConstants.UNIQUE; return UserConstants.UNIQUE;
@ -193,10 +106,8 @@ public class SysUserServiceImpl implements ISysUserService
* @param user 用户信息 * @param user 用户信息
*/ */
@Override @Override
public void checkUserAllowed(SysUser user) public void checkUserAllowed(SysUser user) {
{ if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin())
{
throw new CustomException("不允许操作超级管理员用户"); throw new CustomException("不允许操作超级管理员用户");
} }
} }
@ -209,8 +120,7 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
@Override @Override
@Transactional @Transactional
public int insertUser(SysUser user) public int insertUser(SysUser user) {
{
// 新增用户信息 // 新增用户信息
int rows = userMapper.insertUser(user); int rows = userMapper.insertUser(user);
// 新增用户岗位关联 // 新增用户岗位关联
@ -228,8 +138,7 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
@Override @Override
@Transactional @Transactional
public int updateUser(SysUser user) public int updateUser(SysUser user) {
{
Long userId = user.getUserId(); Long userId = user.getUserId();
// 删除用户与角色关联 // 删除用户与角色关联
userRoleMapper.deleteUserRoleByUserId(userId); userRoleMapper.deleteUserRoleByUserId(userId);
@ -242,18 +151,6 @@ public class SysUserServiceImpl implements ISysUserService
return userMapper.updateUser(user); return userMapper.updateUser(user);
} }
/**
* 修改用户状态
*
* @param user 用户信息
* @return 结果
*/
@Override
public int updateUserStatus(SysUser user)
{
return userMapper.updateUser(user);
}
/** /**
* 修改用户基本信息 * 修改用户基本信息
* *
@ -261,8 +158,7 @@ public class SysUserServiceImpl implements ISysUserService
* @return 结果 * @return 结果
*/ */
@Override @Override
public int updateUserProfile(SysUser user) public int updateUserProfile(SysUser user) {
{
return userMapper.updateUser(user); return userMapper.updateUser(user);
} }
@ -270,12 +166,11 @@ public class SysUserServiceImpl implements ISysUserService
* 修改用户头像 * 修改用户头像
* *
* @param userName 用户名 * @param userName 用户名
* @param avatar 头像地址 * @param avatar 头像地址
* @return 结果 * @return 结果
*/ */
@Override @Override
public boolean updateUserAvatar(String userName, String avatar) public boolean updateUserAvatar(String userName, String avatar) {
{
return userMapper.updateUserAvatar(userName, avatar) > 0; return userMapper.updateUserAvatar(userName, avatar) > 0;
} }
@ -286,8 +181,7 @@ public class SysUserServiceImpl implements ISysUserService
* @return 结果 * @return 结果
*/ */
@Override @Override
public int resetPwd(SysUser user) public int resetPwd(SysUser user) {
{
return userMapper.updateUser(user); return userMapper.updateUser(user);
} }
@ -299,8 +193,7 @@ public class SysUserServiceImpl implements ISysUserService
* @return 结果 * @return 结果
*/ */
@Override @Override
public int resetUserPwd(String userName, String password) public int resetUserPwd(String userName, String password) {
{
return userMapper.resetUserPwd(userName, password); return userMapper.resetUserPwd(userName, password);
} }
@ -309,22 +202,18 @@ public class SysUserServiceImpl implements ISysUserService
* *
* @param user 用户对象 * @param user 用户对象
*/ */
public void insertUserRole(SysUser user) public void insertUserRole(SysUser user) {
{
Long[] roles = user.getRoleIds(); Long[] roles = user.getRoleIds();
if (StringUtils.isNotNull(roles)) if (StringUtils.isNotNull(roles)) {
{
// 新增用户与角色管理 // 新增用户与角色管理
List<SysUserRole> list = new ArrayList<SysUserRole>(); List<SysUserRole> list = new ArrayList<SysUserRole>();
for (Long roleId : roles) for (Long roleId : roles) {
{
SysUserRole ur = new SysUserRole(); SysUserRole ur = new SysUserRole();
ur.setUserId(user.getUserId()); ur.setUserId(user.getUserId());
ur.setRoleId(roleId); ur.setRoleId(roleId);
list.add(ur); list.add(ur);
} }
if (list.size() > 0) if (list.size() > 0) {
{
userRoleMapper.batchUserRole(list); userRoleMapper.batchUserRole(list);
} }
} }
@ -335,22 +224,18 @@ public class SysUserServiceImpl implements ISysUserService
* *
* @param user 用户对象 * @param user 用户对象
*/ */
public void insertUserPost(SysUser user) public void insertUserPost(SysUser user) {
{
Long[] posts = user.getPostIds(); Long[] posts = user.getPostIds();
if (StringUtils.isNotNull(posts)) if (StringUtils.isNotNull(posts)) {
{
// 新增用户与岗位管理 // 新增用户与岗位管理
List<SysUserPost> list = new ArrayList<SysUserPost>(); List<SysUserPost> list = new ArrayList<SysUserPost>();
for (Long postId : posts) for (Long postId : posts) {
{
SysUserPost up = new SysUserPost(); SysUserPost up = new SysUserPost();
up.setUserId(user.getUserId()); up.setUserId(user.getUserId());
up.setPostId(postId); up.setPostId(postId);
list.add(up); list.add(up);
} }
if (list.size() > 0) if (list.size() > 0) {
{
userPostMapper.batchUserPost(list); userPostMapper.batchUserPost(list);
} }
} }
@ -364,8 +249,7 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
@Override @Override
@Transactional @Transactional
public int deleteUserById(Long userId) public int deleteUserById(Long userId) {
{
// 删除用户与角色关联 // 删除用户与角色关联
userRoleMapper.deleteUserRoleByUserId(userId); userRoleMapper.deleteUserRoleByUserId(userId);
// 删除用户与岗位表 // 删除用户与岗位表
@ -381,10 +265,8 @@ public class SysUserServiceImpl implements ISysUserService
*/ */
@Override @Override
@Transactional @Transactional
public int deleteUserByIds(Long[] userIds) public int deleteUserByIds(Long[] userIds) {
{ for (Long userId : userIds) {
for (Long userId : userIds)
{
checkUserAllowed(new SysUser(userId)); checkUserAllowed(new SysUser(userId));
} }
// 删除用户与角色关联 // 删除用户与角色关联
@ -397,16 +279,14 @@ public class SysUserServiceImpl implements ISysUserService
/** /**
* 导入用户数据 * 导入用户数据
* *
* @param userList 用户数据列表 * @param userList 用户数据列表
* @param isUpdateSupport 是否更新支持如果已存在则进行更新数据 * @param isUpdateSupport 是否更新支持如果已存在则进行更新数据
* @param operName 操作用户 * @param operName 操作用户
* @return 结果 * @return 结果
*/ */
@Override @Override
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName) public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName) {
{ if (StringUtils.isNull(userList) || userList.size() == 0) {
if (StringUtils.isNull(userList) || userList.size() == 0)
{
throw new CustomException("导入用户数据不能为空!"); throw new CustomException("导入用户数据不能为空!");
} }
int successNum = 0; int successNum = 0;
@ -414,48 +294,36 @@ public class SysUserServiceImpl implements ISysUserService
StringBuilder successMsg = new StringBuilder(); StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder(); StringBuilder failureMsg = new StringBuilder();
String password = configService.selectConfigByKey("sys.user.initPassword"); String password = configService.selectConfigByKey("sys.user.initPassword");
for (SysUser user : userList) for (SysUser user : userList) {
{ try {
try
{
// 验证是否存在这个用户 // 验证是否存在这个用户
SysUser u = userMapper.selectUserByUserName(user.getUserName()); SysUser u = userMapper.selectUserByUserName(user.getUserName());
if (StringUtils.isNull(u)) if (StringUtils.isNull(u)) {
{
user.setPassword(SecurityUtils.encryptPassword(password)); user.setPassword(SecurityUtils.encryptPassword(password));
user.setCreateBy(operName); user.setCreateBy(operName);
this.insertUser(user); this.insertUser(user);
successNum++; successNum++;
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功"); successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
} } else if (isUpdateSupport) {
else if (isUpdateSupport)
{
user.setUpdateBy(operName); user.setUpdateBy(operName);
this.updateUser(user); this.updateUser(user);
successNum++; successNum++;
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功"); successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
} } else {
else
{
failureNum++; failureNum++;
failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在"); failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
} }
} } catch (Exception e) {
catch (Exception e)
{
failureNum++; failureNum++;
String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
failureMsg.append(msg + e.getMessage()); failureMsg.append(msg + e.getMessage());
log.error(msg, e); log.error(msg, e);
} }
} }
if (failureNum > 0) if (failureNum > 0) {
{
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new CustomException(failureMsg.toString()); throw new CustomException(failureMsg.toString());
} } else {
else
{
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
} }
return successMsg.toString(); return successMsg.toString();

View File

@ -4,7 +4,7 @@ import { praseStrEmpty } from "@/utils/ruoyi";
// 查询用户列表 // 查询用户列表
export function listUser(query) { export function listUser(query) {
return request({ return request({
url: '/system/user/list', url: '/system/user/page',
method: 'get', method: 'get',
params: query params: query
}) })
@ -13,7 +13,7 @@ export function listUser(query) {
// 查询用户详细 // 查询用户详细
export function getUser(userId) { export function getUser(userId) {
return request({ return request({
url: '/system/user/' + praseStrEmpty(userId), url: '/system/user/get?id=' + praseStrEmpty(userId),
method: 'get' method: 'get'
}) })
} }
@ -21,7 +21,7 @@ export function getUser(userId) {
// 新增用户 // 新增用户
export function addUser(data) { export function addUser(data) {
return request({ return request({
url: '/system/user', url: '/system/user/create',
method: 'post', method: 'post',
data: data data: data
}) })
@ -30,7 +30,7 @@ export function addUser(data) {
// 修改用户 // 修改用户
export function updateUser(data) { export function updateUser(data) {
return request({ return request({
url: '/system/user', url: '/system/user/update',
method: 'put', method: 'put',
data: data data: data
}) })
@ -39,7 +39,7 @@ export function updateUser(data) {
// 删除用户 // 删除用户
export function delUser(userId) { export function delUser(userId) {
return request({ return request({
url: '/system/user/' + userId, url: '/system/user/delete?id=' + userId,
method: 'delete' method: 'delete'
}) })
} }
@ -73,7 +73,7 @@ export function changeUserStatus(userId, status) {
status status
} }
return request({ return request({
url: '/system/user/changeStatus', url: '/system/user/updateStatus',
method: 'put', method: 'put',
data: data data: data
}) })

View File

@ -28,9 +28,9 @@
<!--用户数据--> <!--用户数据-->
<el-col :span="20" :xs="24"> <el-col :span="20" :xs="24">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名称" prop="userName"> <el-form-item label="用户名称" prop="username">
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.username"
placeholder="请输入用户名称" placeholder="请输入用户名称"
clearable clearable
size="small" size="small"
@ -38,9 +38,9 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item label="手机号码" prop="mobile">
<el-input <el-input
v-model="queryParams.phonenumber" v-model="queryParams.mobile"
placeholder="请输入手机号码" placeholder="请输入手机号码"
clearable clearable
size="small" size="small"
@ -57,10 +57,10 @@
style="width: 240px" style="width: 240px"
> >
<el-option <el-option
v-for="dict in statusOptions" v-for="dict in statusDictDatas"
:key="dict.dictValue" :key="parseInt(dict.value)"
:label="dict.dictLabel" :label="dict.label"
:value="dict.dictValue" :value="parseInt(dict.value)"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -92,26 +92,6 @@
v-hasPermi="['system:user:add']" v-hasPermi="['system:user:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:user:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:user:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="info" type="info"
@ -133,20 +113,19 @@
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="userList">
<el-table-column type="selection" width="50" align="center" /> <el-table-column label="用户编号" align="center" prop="id" />
<el-table-column label="用户编号" align="center" prop="userId" /> <el-table-column label="用户名称" align="center" prop="username" :show-overflow-tooltip="true" />
<el-table-column label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" /> <el-table-column label="用户昵称" align="center" prop="nickname" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" prop="nickName" :show-overflow-tooltip="true" /> <el-table-column label="部门" align="center" prop="dept.name" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" prop="dept.deptName" :show-overflow-tooltip="true" /> <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
<el-table-column label="手机号码" align="center" prop="phonenumber" width="120" />
<el-table-column label="状态" align="center"> <el-table-column label="状态" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch
v-model="scope.row.status" v-model="scope.row.status"
active-value="0" :active-value="0"
inactive-value="1" :inactive-value="1"
@change="handleStatusChange(scope.row)" @change="handleStatusChange(scope.row)"
></el-switch> ></el-switch>
</template> </template>
</el-table-column> </el-table-column>
@ -170,7 +149,7 @@
v-hasPermi="['system:user:edit']" v-hasPermi="['system:user:edit']"
>修改</el-button> >修改</el-button>
<el-button <el-button
v-if="scope.row.userId !== 1" v-if="scope.row.id !== 1"
size="mini" size="mini"
type="text" type="text"
icon="el-icon-delete" icon="el-icon-delete"
@ -191,7 +170,7 @@
<pagination <pagination
v-show="total>0" v-show="total>0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" :page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.pageSize"
@pagination="getList" @pagination="getList"
/> />
@ -203,8 +182,8 @@
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户昵称" prop="nickName"> <el-form-item label="用户昵称" prop="nickname">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" /> <el-input v-model="form.nickname" placeholder="请输入用户昵称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -215,8 +194,8 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item label="手机号码" prop="mobile">
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" /> <el-input v-model="form.mobile" placeholder="请输入手机号码" maxlength="11" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -227,12 +206,12 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName"> <el-form-item v-if="form.id === undefined" label="用户名称" prop="username">
<el-input v-model="form.userName" placeholder="请输入用户名称" /> <el-input v-model="form.username" placeholder="请输入用户名称" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password"> <el-form-item v-if="form.id === undefined" label="用户密码" prop="password">
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" /> <el-input v-model="form.password" placeholder="请输入用户密码" type="password" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -344,6 +323,11 @@ import { treeselect } from "@/api/system/dept";
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {listSimpleDepts} from "@/api/system/dept";
import {SysCommonStatusEnum} from "@/utils/constants";
import {DICT_TYPE, getDictDatas} from "@/utils/dict";
export default { export default {
name: "User", name: "User",
components: { Treeselect }, components: { Treeselect },
@ -351,12 +335,6 @@ export default {
return { return {
// //
loading: true, loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
// //
showSearch: true, showSearch: true,
// //
@ -387,7 +365,7 @@ export default {
form: {}, form: {},
defaultProps: { defaultProps: {
children: "children", children: "children",
label: "label" label: "name"
}, },
// //
upload: { upload: {
@ -406,19 +384,19 @@ export default {
}, },
// //
queryParams: { queryParams: {
pageNum: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
userName: undefined, username: undefined,
phonenumber: undefined, mobile: undefined,
status: undefined, status: undefined,
deptId: undefined deptId: undefined
}, },
// //
rules: { rules: {
userName: [ username: [
{ required: true, message: "用户名称不能为空", trigger: "blur" } { required: true, message: "用户名称不能为空", trigger: "blur" }
], ],
nickName: [ nickname: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" } { required: true, message: "用户昵称不能为空", trigger: "blur" }
], ],
password: [ password: [
@ -431,14 +409,19 @@ export default {
trigger: ["blur", "change"] trigger: ["blur", "change"]
} }
], ],
phonenumber: [ mobile: [
{ {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码", message: "请输入正确的手机号码",
trigger: "blur" trigger: "blur"
} }
] ]
} },
//
SysCommonStatusEnum: SysCommonStatusEnum,
//
statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),
}; };
}, },
watch: { watch: {
@ -450,12 +433,6 @@ export default {
created() { created() {
this.getList(); this.getList();
this.getTreeselect(); this.getTreeselect();
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_user_sex").then(response => {
this.sexOptions = response.data;
});
this.getConfigKey("sys.user.initPassword").then(response => { this.getConfigKey("sys.user.initPassword").then(response => {
this.initPassword = response.msg; this.initPassword = response.msg;
}); });
@ -464,23 +441,28 @@ export default {
/** 查询用户列表 */ /** 查询用户列表 */
getList() { getList() {
this.loading = true; this.loading = true;
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { listUser(this.addDateRange(this.queryParams, [
this.userList = response.rows; this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,
this.total = response.total; this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,
])).then(response => {
this.userList = response.data.list;
this.total = response.data.list;
this.loading = false; this.loading = false;
} }
); );
}, },
/** 查询部门下拉树结构 */ /** 查询部门下拉树结构 */
getTreeselect() { getTreeselect() {
treeselect().then(response => { listSimpleDepts().then(response => {
this.deptOptions = response.data; // menuOptions
this.deptOptions = [];
this.deptOptions.push(...this.handleTree(response.data, "id"));
}); });
}, },
// //
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data.label.indexOf(value) !== -1; return data.name.indexOf(value) !== -1;
}, },
// //
handleNodeClick(data) { handleNodeClick(data) {
@ -490,12 +472,12 @@ export default {
// //
handleStatusChange(row) { handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"; let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '""' + row.userName + '"用户吗?', "警告", { this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', "警告", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(function() {
return changeUserStatus(row.userId, row.status); return changeUserStatus(row.id, row.status);
}).then(() => { }).then(() => {
this.msgSuccess(text + "成功"); this.msgSuccess(text + "成功");
}).catch(function() { }).catch(function() {
@ -510,12 +492,12 @@ export default {
// //
reset() { reset() {
this.form = { this.form = {
userId: undefined, id: undefined,
deptId: undefined, deptId: undefined,
userName: undefined, username: undefined,
nickName: undefined, nickname: undefined,
password: undefined, password: undefined,
phonenumber: undefined, mobile: undefined,
email: undefined, email: undefined,
sex: undefined, sex: undefined,
status: "0", status: "0",
@ -536,12 +518,6 @@ export default {
this.resetForm("queryForm"); this.resetForm("queryForm");
this.handleQuery(); this.handleQuery();
}, },
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.userId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
@ -558,8 +534,8 @@ export default {
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();
this.getTreeselect(); this.getTreeselect();
const userId = row.userId || this.ids; const id = row.id;
getUser(userId).then(response => { getUser(id).then(response => {
this.form = response.data; this.form = response.data;
this.postOptions = response.posts; this.postOptions = response.posts;
this.roleOptions = response.roles; this.roleOptions = response.roles;
@ -572,11 +548,11 @@ export default {
}, },
/** 重置密码按钮操作 */ /** 重置密码按钮操作 */
handleResetPwd(row) { handleResetPwd(row) {
this.$prompt('请输入"' + row.userName + '"的新密码', "提示", { this.$prompt('请输入"' + row.username + '"的新密码', "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消" cancelButtonText: "取消"
}).then(({ value }) => { }).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => { resetUserPwd(row.id, value).then(response => {
this.msgSuccess("修改成功,新密码是:" + value); this.msgSuccess("修改成功,新密码是:" + value);
}); });
}).catch(() => {}); }).catch(() => {});
@ -585,7 +561,7 @@ export default {
submitForm: function() { submitForm: function() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
if (this.form.userId != undefined) { if (this.form.id != undefined) {
updateUser(this.form).then(response => { updateUser(this.form).then(response => {
this.msgSuccess("修改成功"); this.msgSuccess("修改成功");
this.open = false; this.open = false;
@ -603,13 +579,13 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const userIds = row.userId || this.ids; const ids = row.id || this.ids;
this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", { this.$confirm('是否确认删除用户编号为"' + ids + '"的数据项?', "警告", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(function() {
return delUser(userIds); return delUser(ids);
}).then(() => { }).then(() => {
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");

View File

@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@ApiModel("分页结果") @ApiModel("分页结果")
@ -17,4 +18,17 @@ public final class PageResult<T> implements Serializable {
@ApiModelProperty(value = "总量", required = true) @ApiModelProperty(value = "总量", required = true)
private Long total; private Long total;
public PageResult() {
}
public PageResult(List<T> list, Long total) {
this.list = list;
this.total = total;
}
public PageResult(Long total) {
this.list = new ArrayList<>();
this.total = total;
}
} }

View File

@ -21,7 +21,7 @@ public class LoginUser implements UserDetails {
/** /**
* 用户编号 * 用户编号
*/ */
private Long userId; private Long id;
/** /**
* 科室编号 * 科室编号
*/ */

View File

@ -6,7 +6,6 @@ import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
import cn.iocoder.dashboard.util.servlet.ServletUtils; import cn.iocoder.dashboard.util.servlet.ServletUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.ExceptionTranslationFilter; import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -36,7 +35,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
throws IOException, ServletException { throws IOException, ServletException {
// 打印 warn 的原因是不定期合并 warn看看有没恶意破坏 // 打印 warn 的原因是不定期合并 warn看看有没恶意破坏
log.warn("[commence][访问 URL({}) 时,用户({}) 权限不够]", request.getRequestURI(), log.warn("[commence][访问 URL({}) 时,用户({}) 权限不够]", request.getRequestURI(),
SecurityUtils.getLoginUser().getUserId(), e); SecurityUtils.getLoginUser().getId(), e);
// 返回 403 // 返回 403
ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED)); ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED));
} }

View File

@ -50,7 +50,7 @@ public class SecurityUtils {
* @return 用户编号 * @return 用户编号
*/ */
public static Long getLoginUserId() { public static Long getLoginUserId() {
return getLoginUser().getUserId(); return getLoginUser().getId();
} }
public static Set<Long> getLoginUserRoleIds() { public static Set<Long> getLoginUserRoleIds() {

View File

@ -1,18 +1,64 @@
package cn.iocoder.dashboard.modules.system.controller.user; package cn.iocoder.dashboard.modules.system.controller.user;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api(tags = "用户 API")
@RestController
@RequestMapping("/system/user")
public class SysUserController { public class SysUserController {
// /** @Resource
// * 获取用户列表 private SysUserService userService;
// */ @Resource
private SysDeptService deptService;
@ApiOperation("获得用户分页列表")
@GetMapping("/page")
// @PreAuthorize("@ss.hasPermi('system:user:list')") // @PreAuthorize("@ss.hasPermi('system:user:list')")
// @GetMapping("/list") public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(SysUserPageReqVO reqVO) {
// public TableDataInfo list(SysUser user) // 获得用户分页列表
// { PageResult<SysUserDO> pageResult = userService.pageUsers(reqVO);
// startPage(); if (CollUtil.isEmpty(pageResult.getList())) {
// List<SysUser> list = userService.selectUserList(user); return success(new PageResult<>(pageResult.getTotal())); // 返回空
// return getDataTable(list); }
// }
// 获得拼接需要的数据
Map<Long, SysDeptDO> deptMap;
Collection<Long> deptIds = CollectionUtils.convertList(pageResult.getList(), SysUserDO::getDeptId);
if (CollUtil.isNotEmpty(deptIds)) {
deptMap = CollectionUtils.convertMap(deptService.listDepts(deptIds), SysDeptDO::getId);
} else {
deptMap = Collections.emptyMap();
}
// 拼接结果返回
List<SysUserPageItemRespVO> userList = new ArrayList<>(pageResult.getList().size());
pageResult.getList().forEach(user -> {
SysUserPageItemRespVO respVO = SysUserConvert.INSTANCE.convert(user);
respVO.setDept(SysUserConvert.INSTANCE.convert(deptMap.get(user.getDeptId())));
userList.add(respVO);
});
return success(new PageResult<>(userList, pageResult.getTotal()));
}
// //
// @Log(title = "用户管理", businessType = BusinessType.EXPORT) // @Log(title = "用户管理", businessType = BusinessType.EXPORT)
// @PreAuthorize("@ss.hasPermi('system:user:export')") // @PreAuthorize("@ss.hasPermi('system:user:export')")

View File

@ -0,0 +1,34 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ApiModel(value = "用户分页时的信息 Response VO", description = "相比用户基本信息来说,会多部门信息")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SysUserPageItemRespVO extends SysUserRespVO {
/**
* 所在部门
*/
private Dept dept;
@ApiModel("部门")
@Data
public static class Dept {
@ApiModelProperty(value = "部门编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "部门名称", required = true, example = "研发部")
private String name;
}
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
import cn.iocoder.dashboard.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("用户分页 Request VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SysUserPageReqVO extends PageParam {
@ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
private String username;
@ApiModelProperty(value = "手机号码", example = "yudao", notes = "模糊匹配")
private String mobile;
@ApiModelProperty(value = "展示状态", example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
private Integer status;
@ApiModelProperty(value = "开始时间", example = "2020-10-24")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
@ApiModelProperty(value = "结束时间", example = "2020-10-24")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门")
private Long deptId;
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.dashboard.modules.system.convert.user;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface SysUserConvert {
SysUserConvert INSTANCE = Mappers.getMapper(SysUserConvert.class);
SysUserPageItemRespVO convert(SysUserDO bean);
SysUserPageItemRespVO.Dept convert(SysDeptDO bean);
@Mapping(source = "records", target = "list")
PageResult<SysUserDO> convertPage(IPage<SysUserDO> page);
}

View File

@ -1,10 +1,16 @@
package cn.iocoder.dashboard.modules.system.dal.mysql.dao.user; package cn.iocoder.dashboard.modules.system.dal.mysql.dao.user;
import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface SysUserMapper extends BaseMapper<SysUserDO> { public interface SysUserMapper extends BaseMapper<SysUserDO> {
@ -12,4 +18,14 @@ public interface SysUserMapper extends BaseMapper<SysUserDO> {
return selectOne(new QueryWrapper<SysUserDO>().eq("username", username)); return selectOne(new QueryWrapper<SysUserDO>().eq("username", username));
} }
default IPage<SysUserDO> selectList(SysUserPageReqVO reqVO, List<Long> deptIds) {
return selectPage(MyBatisUtils.buildPage(reqVO),
new QueryWrapperX<SysUserDO>().likeIfPresent("username", reqVO.getUsername())
.likeIfPresent("mobile", reqVO.getMobile())
.eqIfPresent("status", reqVO.getStatus())
.betweenIfPresent("create_time", reqVO.getBeginTime(), reqVO.getEndTime())
.inIfPresent("dept_id", deptIds));
}
} }

View File

@ -80,7 +80,7 @@ public class SysAuthServiceImpl implements SysAuthService {
// 创建 LoginUser 对象 // 创建 LoginUser 对象
LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user);
loginUser.setUpdateTime(new Date()); loginUser.setUpdateTime(new Date());
loginUser.setRoleIds(this.getUserRoleIds(loginUser.getUserId())); loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId()));
return loginUser; return loginUser;
} }
@ -94,7 +94,7 @@ public class SysAuthServiceImpl implements SysAuthService {
// 缓存登陆用户到 Redis // 缓存登陆用户到 Redis
String sessionId = IdUtil.fastSimpleUUID(); String sessionId = IdUtil.fastSimpleUUID();
loginUser.setUpdateTime(new Date()); loginUser.setUpdateTime(new Date());
loginUser.setRoleIds(this.getUserRoleIds(loginUser.getUserId())); loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId()));
loginUserRedisDAO.set(sessionId, loginUser); loginUserRedisDAO.set(sessionId, loginUser);
// 创建 Token // 创建 Token
@ -197,7 +197,7 @@ public class SysAuthServiceImpl implements SysAuthService {
} }
// 重新加载 SysUserDO 信息 // 重新加载 SysUserDO 信息
SysUserDO user = userService.getUser(loginUser.getUserId()); SysUserDO user = userService.getUser(loginUser.getId());
if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) {
throw exception(TOKEN_EXPIRED); // 校验 token 用户被禁用的情况下也认为 token 过期方便前端跳转到登陆界面 throw exception(TOKEN_EXPIRED); // 校验 token 用户被禁用的情况下也认为 token 过期方便前端跳转到登陆界面
} }
@ -205,7 +205,7 @@ public class SysAuthServiceImpl implements SysAuthService {
// 刷新 LoginUser 缓存 // 刷新 LoginUser 缓存
loginUser.setDeptId(user.getDeptId()); loginUser.setDeptId(user.getDeptId());
loginUser.setUpdateTime(new Date()); loginUser.setUpdateTime(new Date());
loginUser.setRoleIds(this.getUserRoleIds(loginUser.getUserId())); loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId()));
loginUserRedisDAO.set(sessionId, loginUser); loginUserRedisDAO.set(sessionId, loginUser);
} }

View File

@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.service.dept;
import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO; import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
@ -12,6 +13,11 @@ import java.util.List;
*/ */
public interface SysDeptService { public interface SysDeptService {
/**
* 初始化
*/
void init();
/** /**
* 获得所有部门列表 * 获得所有部门列表
* *
@ -19,6 +25,14 @@ public interface SysDeptService {
*/ */
List<SysDeptDO> listDepts(); List<SysDeptDO> listDepts();
/**
* 获得指定编号的部门列表
*
* @param ids 部门编号数组
* @return 部门列表
*/
List<SysDeptDO> listDepts(Collection<Long> ids);
/** /**
* 筛选部门列表 * 筛选部门列表
* *
@ -27,4 +41,13 @@ public interface SysDeptService {
*/ */
List<SysDeptDO> listDepts(SysDeptListReqVO reqVO); List<SysDeptDO> listDepts(SysDeptListReqVO reqVO);
/**
* 获得所有子部门从缓存中
*
* @param parentId 部门编号
* @param recursive 是否递归获取所有
* @return 子部门列表
*/
List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive);
} }

View File

@ -1,13 +1,22 @@
package cn.iocoder.dashboard.modules.system.service.dept.impl; package cn.iocoder.dashboard.modules.system.service.dept.impl;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO; import cn.iocoder.dashboard.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dept.SysDeptMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dept.SysDeptMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 部门 Service 实现类 * 部门 Service 实现类
@ -15,19 +24,94 @@ import java.util.List;
* @author 芋道源码 * @author 芋道源码
*/ */
@Service @Service
@Slf4j
public class SysDeptServiceImpl implements SysDeptService { public class SysDeptServiceImpl implements SysDeptService {
/**
* 部门缓存
* key部门编号 {@link SysDeptDO#getId()}
*
* 这里声明 volatile 修饰的原因是每次刷新时直接修改指向
*/
private volatile Map<Long, SysDeptDO> deptCache;
/**
* 父部门缓存
* key部门编号 {@link SysDeptDO#getParentId()}
* value: 直接子部门列表
*
* 这里声明 volatile 修饰的原因是每次刷新时直接修改指向
*/
private volatile Multimap<Long, SysDeptDO> parentDeptCache;
@Resource @Resource
private SysDeptMapper deptMapper; private SysDeptMapper deptMapper;
@Override
@PostConstruct
public void init() {
// 从数据库中读取
List<SysDeptDO> sysDeptDOList = deptMapper.selectList();
// 构建缓存
ImmutableMap.Builder<Long, SysDeptDO> builder = ImmutableMap.builder();
ImmutableMultimap.Builder<Long, SysDeptDO> parentBuilder = ImmutableMultimap.builder();
sysDeptDOList.forEach(sysRoleDO -> {
builder.put(sysRoleDO.getId(), sysRoleDO);
parentBuilder.put(sysRoleDO.getParentId(), sysRoleDO);
});
// 设置缓存
deptCache = builder.build();
parentDeptCache = parentBuilder.build();
log.info("[init][初始化 Dept 数量为 {}]", sysDeptDOList.size());
}
@Override @Override
public List<SysDeptDO> listDepts() { public List<SysDeptDO> listDepts() {
return deptMapper.selectList(); return deptMapper.selectList();
} }
@Override
public List<SysDeptDO> listDepts(Collection<Long> ids) {
return deptMapper.selectBatchIds(ids);
}
@Override @Override
public List<SysDeptDO> listDepts(SysDeptListReqVO reqVO) { public List<SysDeptDO> listDepts(SysDeptListReqVO reqVO) {
return deptMapper.selectList(reqVO); return deptMapper.selectList(reqVO);
} }
@Override
public List<SysDeptDO> listDeptsByParentIdFromCache(Long parentId, boolean recursive) {
List<SysDeptDO> result = new ArrayList<>();
// 递归简单粗暴
this.listDeptsByParentIdFromCache(result, parentId,
recursive ? Integer.MAX_VALUE : 1, // 如果递归获取则无限否则只递归 1
parentDeptCache);
return result;
}
/**
* 递归获取所有的子部门添加到 result 结果
*
* @param result 结果
* @param parentId 父编号
* @param recursiveCount 递归次数
* @param parentDeptMap 父部门 Map使用缓存避免变化
*/
private void listDeptsByParentIdFromCache(List<SysDeptDO> result, Long parentId, int recursiveCount,
Multimap<Long, SysDeptDO> parentDeptMap) {
// 递归次数为 0结束
if (recursiveCount == 0) {
return;
}
// 获得子部门
Collection<SysDeptDO> depts = parentDeptMap.get(parentId);
if (CollUtil.isEmpty(depts)) {
return;
}
result.addAll(depts);
// 继续递归
depts.forEach(dept -> listDeptsByParentIdFromCache(result, dept.getId(),
recursiveCount - 1, parentDeptMap));
}
} }

View File

@ -37,12 +37,6 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@Slf4j @Slf4j
public class SysRoleServiceImpl implements SysRoleService { public class SysRoleServiceImpl implements SysRoleService {
@Resource
private SysPermissionService permissionService;
@Resource
private SysRoleMapper roleMapper;
/** /**
* 角色缓存 * 角色缓存
* key角色编号 {@link SysRoleDO#getId()} * key角色编号 {@link SysRoleDO#getId()}
@ -51,6 +45,12 @@ public class SysRoleServiceImpl implements SysRoleService {
*/ */
private volatile Map<Long, SysRoleDO> roleCache; private volatile Map<Long, SysRoleDO> roleCache;
@Resource
private SysPermissionService permissionService;
@Resource
private SysRoleMapper roleMapper;
/** /**
* 初始化 {@link #roleCache} 缓存 * 初始化 {@link #roleCache} 缓存
*/ */

View File

@ -1,11 +1,13 @@
package cn.iocoder.dashboard.modules.system.service.user; package cn.iocoder.dashboard.modules.system.service.user;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
/** /**
* 用户 Service 接口 * 用户 Service 接口
* *
* @author ruoyi * @author 芋道源码
*/ */
public interface SysUserService { public interface SysUserService {
// /** // /**
@ -32,6 +34,14 @@ public interface SysUserService {
*/ */
SysUserDO getUser(Long userId); SysUserDO getUser(Long userId);
/**
* 获得用户分页列表
*
* @param reqVO 分页条件
* @return 分页列表
*/
PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO);
// //
// /** // /**
// * 根据用户ID查询用户所属角色组 // * 根据用户ID查询用户所属角色组

View File

@ -1,17 +1,25 @@
package cn.iocoder.dashboard.modules.system.service.user; package cn.iocoder.dashboard.modules.system.service.user;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.user.SysUserMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.dao.user.SysUserMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
import cn.iocoder.dashboard.util.collection.CollectionUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
/** /**
* 用户 业务层处理 * 用户 Service 实现类
* *
* @author ruoyi * @author 芋道源码
*/ */
@Service @Service
@Slf4j @Slf4j
@ -20,6 +28,9 @@ public class SysUserServiceImpl implements SysUserService {
@Resource @Resource
private SysUserMapper userMapper; private SysUserMapper userMapper;
@Resource
private SysDeptService deptService;
// @Autowired // @Autowired
// private SysUserMapper userMapper; // private SysUserMapper userMapper;
// //
@ -61,6 +72,19 @@ public class SysUserServiceImpl implements SysUserService {
return userMapper.selectById(userId); return userMapper.selectById(userId);
} }
@Override
public PageResult<SysUserDO> pageUsers(SysUserPageReqVO reqVO) {
// 处理部门查询条件
List<Long> deptIds = Collections.emptyList();
if (reqVO.getDeptId() != null) {
deptIds = CollectionUtils.convertList(deptService.listDeptsByParentIdFromCache(reqVO.getDeptId(), true),
SysDeptDO::getId);
deptIds.add(reqVO.getDeptId());
}
// 执行查询
return SysUserConvert.INSTANCE.convertPage(userMapper.selectList(reqVO, deptIds));
}
// /** // /**
// * 通过用户ID查询用户 // * 通过用户ID查询用户
// * // *