系列文章目录
《SpringBoot整合SpringSecurity实现权限控制(一):实现原理》
《SpringBoot整合SpringSecurity实现权限控制(二):权限数据基本模型设计》
《SpringBoot整合SpringSecurity实现权限控制(三):前端动态装载路由与菜单》
《SpringBoot整合SpringSecurity实现权限控制(四):角色管理》
系统的使用者称为用户,仅可在被赋予的权限范围之内操作系统。
管理员是一种特殊的用户,拥有系统操作的最高权限。
/** * 用户表 * * @author zhuhuix * @date 2020-04-03 */
@ApiModel(value = "用户信息")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user")
public class SysUser implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String userName;
@JsonIgnore
private String password;
private String nickName;
/** * 性别 0-未知 1-male,2-female */
private Integer gender;
/** * 头像地址 */
private String avatarUrl;
private String country;
private String province;
private String city;
@Email
private String email;
private String phone;
private String remarks;
@TableLogic
private Boolean enabled;
private Timestamp lastPasswordResetTime;
private Timestamp createTime;
@Builder.Default
private Timestamp updateTime = Timestamp.valueOf(LocalDateTime.now());
}
/** * 用户角色表 * * @author zhuhuix * @date 2021-09-29 */
@ApiModel(value = "用户角色信息")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user_role")
public class SysUserRole {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long userId;
private Long roleId;
private Timestamp createTime;
}
/** * 用户DAO接口 * * @author zhuhuix * @date 2021-07-19 */
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
/** * 查询用户角色 * @param userId 用户id * @return 角色信息 */
@Select("select r.id,r.role_code,r.role_name,r.description,r.enabled,r.create_time,r.update_time " +
"from sys_role r " +
"INNER JOIN sys_user_role ur ON r.id=ur.role_id where ur.user_id=#{userId} ")
List<SysRole> selectUserRoles(Long userId);
/** * 查询用户权限 * @param userId 用户id * @return 权限信息 */
@Select("SELECT m.id, m.`path`, m.`name`, m.`component`, m.`icon`, m.`cache`, m.`hidden`, m.`redirect`, m.p_id " +
"FROM " +
"sys_menu m " +
"INNER JOIN sys_permission p ON p.menu_id = m.id " +
"INNER JOIN sys_user_role ur ON ur.role_id = p.role_id " +
"INNER JOIN sys_user u ON u.id = ur.user_id " +
"INNER JOIN sys_role r ON r.id = ur.role_id where ur.user_id=#{userId}"+
" and m.enabled=1 " +
" order by m.sort "
)
List<PermissionDto> selectUserPermission(Long userId);
}
/** * 用户角色DAO接口 * * @author zhuhuix * @date 2021-09-29 */
@Mapper
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
}
/** * 用户管理服务接口 * * @author zhuhuix * @date 2020-04-03 */
public interface SysUserService {
/** * 增加用户 * * @param user 待新增的用户 * @return 增加成功的用户 */
SysUser create(SysUser user);
/** * 删除用户 * * @param user 待删除的用户 * @return 删除成功的用户 */
SysUser delete(SysUser user);
/** * 修改用户 * * @param user 待修改的用户 * @return 修改成功的用户 */
SysUser update(SysUser user);
/** * 根据id查找用户 * * @param id 用户id * @return 用户信息 */
SysUser findById(Long id);
/** * 根据userName查找用户 * * @param userName 用户帐号 * @return 用户帐号对应的用户 */
SysUser findByUserName(String userName);
/** * 判断注册使用的邮箱是否存在 * * @param email 邮箱号 * @return 是否找到 */
boolean registerEmailExist(String email);
/** * 获取用户信息 * * @return 用户信息 */
UserDetails getUserInfo();
/** * 修改用户头像 * * @param file 文件 * @return json */
Map<String, String> updateAvatar(MultipartFile file);
/** * 获取用户角色信息 * * @param userId 用户id * @return 角色信息 */
List<SysRole> getUserRoles(Long userId);
/** * 保存用户角色 * * @param userId 用户id * @param roleIds 角色id列表 * @return 是否成功 */
Boolean saveUserRoles(Long userId,Set<Long> roleIds);
/** * 获取用户权限信息 * * @param userId 用户id * @return 权限信息 */
List<PermissionDto> getUserPermission(Long userId);
/** * 根据条件查询用户信息 * * @param sysUserQueryDto 查询条件 * @return 用户列表 */
List<SysUser> list(SysUserQueryDto sysUserQueryDto);
/** * 批量删除用户 * * @param ids 待删除的用户id列表 * @return 是否成功 */
Boolean delete(Set<Long> ids);
}
/** * 用户管理服务实现类 * * @author zhuhuix * @date 2020-04-03 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysUserServiceImpl implements SysUserService {
private final SysUserMapper sysUserMapper;
private final SysUserRoleMapper sysUserRoleMapper;
private final UploadFileTool uploadFileTool;
@Override
@Transactional(rollbackFor = Exception.class)
public SysUser create(SysUser user) {
if (sysUserMapper.insert(user) > 0) {
return user;
}
throw new RuntimeException("增加用户信息失败");
}
@Override
@Transactional(rollbackFor = Exception.class)
public SysUser delete(SysUser user) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysUser::getUserName, user.getUserName());
if (sysUserMapper.delete(queryWrapper) > 0) {
return user;
}
throw new RuntimeException("删除用户信息失败");
}
@Override
@Transactional(rollbackFor = Exception.class)
public SysUser update(SysUser user) {
if (sysUserMapper.updateById(user) > 0) {
return user;
}
throw new RuntimeException("更新用户信息失败");
}
@Override
public SysUser findById(Long id) {
return sysUserMapper.selectById(id);
}
@Override
public SysUser findByUserName(String userName) {
return sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUserName, userName));
}
@Override
public boolean registerEmailExist(String email) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysUser::getEmail, email);
return sysUserMapper.selectOne(queryWrapper) != null;
}
@Override
public UserDetails getUserInfo() {
UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);
return userDetailsService.loadUserByUsername(getCurrentLoginUserName());
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, String> updateAvatar(MultipartFile file) {
SysUser sysUser = findByUserName(getCurrentLoginUserName());
UploadFile uploadFile = uploadFileTool.upload(sysUser.getUserName(), file.getOriginalFilename(), file);
sysUser.setAvatarUrl(uploadFile.getType() + File.separator + uploadFile.getFileName());
update(sysUser);
return new HashMap<String, String>(1) {{
put("avatar", uploadFile.getFileName());
}};
}
@Override
public List<PermissionDto> getUserPermission(Long userId) {
return sysUserMapper.selectUserPermission(userId);
}
@Override
public List<SysRole> getUserRoles(Long userId) {
return sysUserMapper.selectUserRoles(userId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUserRoles(Long userId, Set<Long> roleIds) {
// 首先清除该用户原有的角色信息
QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysUserRole::getUserId, userId);
sysUserRoleMapper.delete(queryWrapper);
// 再进行添加
for (Long roleId : roleIds) {
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(roleId);
sysUserRole.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
sysUserRoleMapper.insert(sysUserRole);
}
return true;
}
private String getCurrentLoginUserName() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new RuntimeException("登录状态已过期");
}
if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
return (userDetails.getUsername());
}
throw new RuntimeException("找不到当前登录的信息");
}
@Override
public List<SysUser> list(SysUserQueryDto sysUserQueryDto) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(sysUserQueryDto.getUserName())) {
queryWrapper.lambda().like(SysUser::getUserName, sysUserQueryDto.getUserName())
.or().like(SysUser::getNickName, sysUserQueryDto.getUserName());
}
if (!StringUtils.isEmpty(sysUserQueryDto.getCreateTimeStart())
&& !StringUtils.isEmpty(sysUserQueryDto.getCreateTimeEnd())) {
queryWrapper.and(wrapper -> wrapper.lambda().between(SysUser::getCreateTime,
new Timestamp(sysUserQueryDto.getCreateTimeStart()),
new Timestamp(sysUserQueryDto.getCreateTimeEnd())));
}
return sysUserMapper.selectList(queryWrapper);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean delete(Set<Long> ids) {
if (sysUserMapper.deleteBatchIds(ids) > 0) {
return true;
}
throw new RuntimeException("删除用户信息失败");
}
}
/** * api用户信息 * * @author zhuhuix * @date 2021-08-16 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/api/user")
@Api(tags = "用户信息接口")
public class SysUserController {
private final SysUserService sysUserService;
@ApiOperation("获取当前登录用户信息")
@GetMapping()
public ResponseEntity<Object> getUserInfo() {
return ResponseEntity.ok(sysUserService.getUserInfo());
}
@ApiOperation("根据id获取用户信息")
@GetMapping("/{id}")
public ResponseEntity<Object> getUserInfo(@PathVariable Long id) {
return ResponseEntity.ok(sysUserService.findById(id));
}
@ApiOperation("更新用户信息")
@PostMapping()
public ResponseEntity<Object> saveUser(@RequestBody SysUser user) {
return ResponseEntity.ok(sysUserService.update(user));
}
@PreAuthorize("hasAuthority('user:updateAvatar')")
@ApiOperation("修改用户头像")
@PostMapping(value = "/updateAvatar")
public ResponseEntity<Object> updateAvatar(@RequestParam MultipartFile avatar) {
return ResponseEntity.ok(sysUserService.updateAvatar(avatar));
}
@ApiOperation("根据条件查询用户列表")
@PostMapping("/list")
public ResponseEntity<Object> getSysUserList(@RequestBody SysUserQueryDto sysUserQueryDto) {
return ResponseEntity.ok(sysUserService.list(sysUserQueryDto));
}
@ApiOperation("批量删除用户")
@DeleteMapping
public ResponseEntity<Object> deleteUsers(@RequestBody Set<Long> ids) {
return ResponseEntity.ok(sysUserService.delete(ids));
}
@ApiOperation("获取用户角色")
@GetMapping("/roles/{userId}")
public ResponseEntity<Object> getUserRoles(@PathVariable Long userId) {
return ResponseEntity.ok(sysUserService.getUserRoles(userId));
}
@ApiOperation("保存用户角色")
@PostMapping("/roles/{userId}")
public ResponseEntity<Object> saveUserRoles(@PathVariable Long userId, @RequestBody Set<Long> ids) {
return ResponseEntity.ok(sysUserService.saveUserRoles(userId, ids));
}
@ApiOperation("获取用户权限")
@GetMapping("/permission/{userId}")
public ResponseEntity<Object> getUserPermission(@PathVariable Long userId) {
return ResponseEntity.ok(sysUserService.getUserPermission(userId));
}
}
import request from '@/utils/request'
// 登录
export function login(data) {
return request({
url: '/api/auth/login',
method: 'post',
data
})
}
// 注销
export function logout() {
return request({
url: '/api/auth/logout',
method: 'delete'
})
}
// 获取当前登录用户信息
export function getInfo() {
return request({
url: '/api/user',
method: 'get'
})
}
// 根据用户id获取用户信息
export function getInfoById(id) {
return request({
url: '/api/user/' + id,
method: 'get'
})
}
// 保存并更新用户
export function saveUser(data) {
return request({
url: '/api/user',
method: 'post',
data
})
}
// 根据用户id列表批量删除用户
export function deleteUser(ids) {
return request({
url: '/api/user',
method: 'delete',
data: ids
})
}
// 根据条件查询获取用户列表
export function getUserList(params) {
return request({
url: '/api/user/list',
method: 'post',
data: JSON.stringify(params)
})
}
// 根据用户id获取用户权限
export function getUserPermission(userId) {
return request({
url: '/api/user/permission/' + userId,
method: 'get'
})
}
// 获取用户角色
export function getUserRoles(userId) {
return request({
url: '/api/user/roles/' + userId,
method: 'get'
})
}
// 分配用户角色
export function saveUserRoles(userId, roleIds) {
return request({
url: '/api/user/roles/' + userId,
method: 'post',
data: roleIds
})
}
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<!-- 搜索 -->
<el-input
v-model="userName"
size="small"
clearable
placeholder="输入账号或用户名称搜索"
style="width: 200px"
class="filter-item"
@keyup.enter.native="doQuery"
/>
<el-date-picker
v-model="createTime"
:default-time="['00:00:00', '23:59:59']"
type="daterange"
range-separator=":"
size="small"
class="date-item"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button
class="filter-item"
size="mini"
type="success"
icon="el-icon-search"
@click="doQuery"
>搜索</el-button>
<el-button
class="filter-item"
size="mini"
type="danger"
icon="el-icon-circle-plus-outline"
:disabled="selections.length===0"
@click="doDelete"
>删除</el-button>
</div>
<el-row>
<!--角色分配表单-->
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="showDialog" title="角色分配" width="600px">
<el-form ref="form" :inline="true" :model="form" size="small" label-width="76px">
<el-form-item label="登录账号" prop="userName">
<el-input v-model="form.userName" :disabled="true" />
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" :disabled="true" />
</el-form-item>
<el-form-item style="margin-bottom: 0;" label="角色" prop="userRoles">
<el-select
v-model="userRoles"
style="width: 455px"
multiple
filterable
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeRole"
>
<el-option
v-for="item in roles"
:key="item.roleCode"
:label="item.roleName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="doCancel">取消</el-button>
<el-button :loading="formLoading" type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="用户列表" name="userList">
<el-table ref="table" v-loading="loading" :data="users" style="width: 100%; font-size: 12px;" @selection-change="selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" width="150" prop="userName" label="登录账号" />
<el-table-column :show-overflow-tooltip="true" width="150" prop="nickName" label="用户昵称" />
<el-table-column prop="gender" width="60" label="性别">
<template slot-scope="scope">
<el-tag v-if="scope.row.gender===1" type="success">男</el-tag>
<el-tag v-if="scope.row.gender===2" type="warning">女</el-tag>
<el-tag v-if="scope.row.gender===0" type="info">未知</el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="phone" width="150" label="电话" />
<el-table-column :show-overflow-tooltip="true" prop="city" label="所在地区">
<template slot-scope="scope">
<span>{{ scope.row.province }} {{ scope.row.city }} {{ scope.row.country }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="avatarUrl" width="80" label="头像">
<template slot-scope="scope">
<img
:src="
scope.row.avatarUrl
? baseApi + '/file/' + scope.row.avatarUrl
: Avatar
"
class="avatar"
>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="155" label="注册日期">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="160"
align="center"
fixed="right"
>
<template slot-scope="scope">
<el-button size="mini" type="text" round @click="doAssignRole(scope.row.id)">分配角色</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Avatar from '@/assets/images/avatar.png'
import { parseTime } from '@/utils/index'
import { getUserList, deleteUser, getInfoById, getUserRoles, saveUserRoles } from '@/api/user'
import { getRoleList } from '@/api/role'
export default {
name: 'User',
data() {
return {
Avatar: Avatar,
activeName: 'userList',
showDialog: false,
loading: false,
formLoading: true,
form: {},
users: [],
selections: [],
userName: '',
createTime: null,
roles: [],
userRoles: []
}
},
computed: {
...mapGetters([
'baseApi'
])
},
created() {
},
methods: {
parseTime,
doQuery() {
this.users = []
var param = { userName: this.userName }
if (this.createTime != null) {
param.createTimeStart = Date.parse(this.createTime[0])
param.createTimeEnd = Date.parse(this.createTime[1])
}
getUserList(param).then(res => {
if (res) {
this.users = res
}
})
},
doDelete() {
const ids = []
this.selections.forEach((res) => {
ids.push(res.id)
})
this.$confirm(`确认删除这些用户吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() =>
deleteUser(ids).then(res => {
if (res) {
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
this.doQuery()
}
})
).catch(() => {
})
},
// 选择改变
selectionChangeHandler(val) {
this.selections = val
},
doAssignRole(id) {
this.form = {}
this.userRoles = []
this.roles = []
this.showDialog = true
this.formLoading = true
getInfoById(id).then((res) => {
this.form = { id: res.id, userName: res.userName, nickName: res.nickName, gender: res.gender, phone: res.phone }
var param = { }
getRoleList(param).then(res => {
if (res) {
this.roles = res
}
getUserRoles(id).then((res) => {
if (res) {
res.forEach(role => {
this.userRoles.push(role.id)
})
}
this.formLoading = false
})
})
})
},
doCancel() {
this.showDialog = false
this.form = {}
},
doSubmit() {
this.formLoading = true
saveUserRoles(this.form.id, this.userRoles).then(() => {
this.showDialog = false
this.$notify({
title: '保存成功',
type: 'success',
duration: 2500
})
})
},
deleteTag(value) {
this.userRoles.forEach(function(data, index) {
if (data.id === value) {
this.userRoles.splice(index, value)
}
})
},
changeRole(value) {
// console.log(this.userRoles)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.avatar {
width: 32px;
height: 32px;
border-radius: 50%;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://zhuhuix.blog.csdn.net/article/details/120450964
内容来源于网络,如有侵权,请联系作者删除!