java后台通用权限管理系统(springboot)
推荐:200多套后台管理系统模板打包下载(https://blog.csdn.net/zwx19921215/article/details/102935205)推荐:Java秒杀系统优化(高性能高并发)(https://blog.csdn.net/zwx19921215/article/details/103270209)说明:这是本人正在使用的一款通用权限管理系统。来源......
推荐:Java秒杀系统优化(高性能高并发)(Java秒杀系统优化(高性能高并发)_Garry1115的博客-CSDN博客)
说明:这是本人正在使用的一款通用权限管理系统。
来源:通过对网上优秀开源项目组件的合并与重构实现自身需求和功能。
技术架构:Springboot2.x + Shiro + MyBatis Plus + Layui
整个项目(初级版)的功能包括:用户管理、角色管理、菜单管理、字典管理、参数设置、通知公告、操作日志、登录日志、服务监控、资源分类等。
高级版的功能在初级版之上会增加:部门管理、岗位管理、在线用户、定时任务、代码生成、系统接口、邮件管理、短信管理等。
数据库表设计:
初级版数据库表:用户表、角色表、菜单表、用户角色表、角色菜单表、字典数据表、配置信息表、通知公告表、操作日志表、登陆日志表等。
高级版新增数据库表:新增部门表、岗位表、用户岗位表、角色部门表、短信配置模板、短信发送日志、邮件配置模板、邮件发送日志、定时任务管理、定时任务日志表等。
项目结构:
realm类
package com.xiaofeng.shiro.realm;
import com.google.common.collect.Sets;
import com.xiaofeng.shiro.entity.SysUser;
import com.xiaofeng.shiro.service.ISysLoginService;
import com.xiaofeng.shiro.service.ISysMenuService;
import com.xiaofeng.shiro.service.ISysRoleService;
import com.xiaofeng.shiro.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
/**
* @author xiaofeng
* @version V1.0
* @title: UserRealm
* @package: com.xiaofeng.share.shiro
* @description: 自定义Realm 处理登录 权限
* @date 2019/7/4 9:44
*/
public class UserRealm extends AuthorizingRealm {
private static final Logger log = LoggerFactory.getLogger(UserRealm.class);
@Autowired
private ISysMenuService menuService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysLoginService loginService;
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
SysUser user = ShiroUtils.getSysUser();
// 角色列表
Set<String> roles = Sets.newHashSet();
// 功能列表
Set<String> menus = Sets.newHashSet();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 管理员拥有所有权限
if (user.isAdmin()) {
info.addRole("admin");
info.addStringPermission("*:*:*");
} else {
roles = roleService.selectRoleKeys(user.getId().longValue());
menus = menuService.selectPermssionByUserId(user.getId().longValue());
// 角色加入AuthorizationInfo认证对象
info.setRoles(roles);
// 权限加入AuthorizationInfo认证对象
info.setStringPermissions(menus);
}
return info;
}
/**
* 登录认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = "";
if (upToken.getPassword() != null) {
password = new String(upToken.getPassword());
}
SysUser user = null;
try {
user = loginService.login(username, password);
} catch (Exception e) {
log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
throw new AuthenticationException(e.getMessage(), e);
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info;
}
/**
* 清理缓存权限
*/
public void clearCachedAuthorizationInfo() {
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
}
}
废话不多说,直接上效果图:
后台主页:
用户管理模块:
角色管理模块:
菜单管理模块:
操作日志模块:
用户模块Controller:
package com.xiaofeng.shiro.controller;
import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.view.PoiBaseView;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Maps;
import com.xiaofeng.shiro.aspectj.annotation.Log;
import com.xiaofeng.shiro.common.response.AjaxResult;
import com.xiaofeng.shiro.common.response.TableDataInfo;
import com.xiaofeng.shiro.constant.UserConstants;
import com.xiaofeng.shiro.entity.SysRole;
import com.xiaofeng.shiro.entity.SysUser;
import com.xiaofeng.shiro.enums.LogType;
import com.xiaofeng.shiro.service.ISysRoleService;
import com.xiaofeng.shiro.service.ISysUserService;
import com.xiaofeng.shiro.service.impl.SysPasswordService;
import com.xiaofeng.shiro.util.DateUtil;
import com.xiaofeng.shiro.util.ShiroUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* <p>
* 用户信息表 前端控制器
* </p>
*
* @author xiaofeng
* @since 2019-07-03
*/
@Controller
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
private String prefix = "system/user";
@Autowired
private ISysUserService userService;
@Autowired
private ISysRoleService roleService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("system:user:view")
@GetMapping()
public String user() {
return prefix + "/user";
}
@Log(title = "用户查询", logType = LogType.SELECT)
@RequiresPermissions("system:user:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysUser user) {
IPage<SysUser> page = getPage();
userService.pageList(page, user);
return getDataTable(page.getRecords(), page.getSize());
}
@Log(title = "用户管理", logType = LogType.EXPORT)
@RequiresPermissions("system:user:export")
@GetMapping("/export")
public void export(SysUser user, HttpServletRequest request, HttpServletResponse response) {
List<SysUser> list = userService.list(user);
if (CollectionUtils.isEmpty(list)) {
return;
}
String title = "用户信息";
Map<String, Object> map = Maps.newHashMap();
ExportParams params = new ExportParams(title, title, ExcelType.HSSF);
map.put(NormalExcelConstants.DATA_LIST, list);
map.put(NormalExcelConstants.CLASS, SysUser.class);
map.put(NormalExcelConstants.PARAMS, params);
map.put("fileName", DateUtil.getNowDateTime());
PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
}
/**
* 新增用户
*/
@GetMapping("/add")
public String add(ModelMap mmap) {
List<SysRole> roleList = roleService.list(new LambdaQueryWrapper<SysRole>().eq(SysRole::getDelFlag, 0));
mmap.put("roles", roleList);
return prefix + "/add";
}
/**
* 新增保存用户
*/
@RequiresPermissions("system:user:add")
@Log(title = "用户管理", logType = LogType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysUser user) {
if (user.getId() != null && SysUser.isAdmin(ShiroUtils.getSysUser().getUserType())) {
return error("不允许修改超级管理员用户");
}
String nameUnique = userService.checkLoginNameUnique(user.getUserName());
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(nameUnique)) {
return error("保存用户'" + user.getUserName() + "'失败,登录账号已存在");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getUserName(), user.getPassword(), user.getSalt()));
user.setCreateBy(ShiroUtils.getLoginName());
user.setCreateTime(DateUtil.getNowTimestamp());
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Long userId, ModelMap mmap) {
mmap.put("user", userService.getById(userId));
mmap.put("roles", roleService.selectRolesByUserId(userId));
return prefix + "/edit";
}
/**
* 修改保存用户
*/
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", logType = LogType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysUser user) {
if (user.getId() != null && SysUser.isAdmin(ShiroUtils.getSysUser().getUserType())) {
return error("不允许修改超级管理员用户");
}
user.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(userService.updateUser(user));
}
@RequiresPermissions("system:user:resetPwd")
@Log(title = "重置密码", logType = LogType.UPDATE)
@GetMapping("/resetPwd/{userId}")
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) {
mmap.put("user", userService.getById(userId));
return prefix + "/resetPwd";
}
@RequiresPermissions("system:user:resetPwd")
@Log(title = "重置密码", logType = LogType.UPDATE)
@PostMapping("/resetPwd")
@ResponseBody
public AjaxResult resetPwdSave(SysUser user) {
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getUserName(), user.getPassword(), user.getSalt()));
return toAjax(userService.updateById(user));
}
@RequiresPermissions("system:user:remove")
@Log(title = "用户管理", logType = LogType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids) {
try {
if (StringUtils.isNoneBlank(ids)) {
String[] split = ids.split(",");
return toAjax(userService.batchDeleteUser(Arrays.asList(split)));
}
} catch (Exception e) {
return error(e.getMessage());
}
return error();
}
/**
* 校验用户名
*/
@PostMapping("/checkLoginNameUnique")
@ResponseBody
public String checkLoginNameUnique(SysUser user) {
String nameUnique = userService.checkLoginNameUnique(user.getUserName());
return nameUnique;
}
/**
* 校验手机号码
*/
@PostMapping("/checkPhoneUnique")
@ResponseBody
public String checkPhoneUnique(SysUser user) {
String phoneUnique = userService.checkPhoneUnique(user);
return phoneUnique;
}
/**
* 校验email邮箱
*/
@PostMapping("/checkEmailUnique")
@ResponseBody
public String checkEmailUnique(SysUser user) {
return userService.checkEmailUnique(user);
}
/**
* 用户状态修改
*/
@Log(title = "用户管理", logType = LogType.UPDATE)
@RequiresPermissions("system:user:edit")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysUser user) {
if (SysUser.isAdmin(ShiroUtils.getSysUser().getUserType())) {
return error("不允许修改超级管理员用户");
}
return toAjax(userService.updateUser(user));
}
}
用户模块service实现:
package com.xiaofeng.shiro.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaofeng.shiro.constant.Constants;
import com.xiaofeng.shiro.constant.UserConstants;
import com.xiaofeng.shiro.entity.SysRole;
import com.xiaofeng.shiro.entity.SysUser;
import com.xiaofeng.shiro.entity.SysUserRole;
import com.xiaofeng.shiro.mapper.SysRoleMapper;
import com.xiaofeng.shiro.mapper.SysUserMapper;
import com.xiaofeng.shiro.mapper.SysUserRoleMapper;
import com.xiaofeng.shiro.service.ISysUserRoleService;
import com.xiaofeng.shiro.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* <p>
* 用户信息表 服务实现类
* </p>
*
* @author xiaofeng
* @since 2019-07-03
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
@Autowired
SysUserMapper sysUserMapper;
@Autowired
SysUserRoleMapper sysUserRoleMapper;
@Autowired
SysRoleMapper sysRoleMapper;
@Autowired
ISysUserRoleService userRoleService;
@Override
public IPage<SysUser> pageList(IPage<SysUser> iPage, SysUser user) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
queryWrapper
.like(StringUtils.isNoneBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
.like(StringUtils.isNoneBlank(user.getTelephone()), SysUser::getTelephone, user.getTelephone())
.ge(user.getParams().get(Constants.START_TIME) != null && StringUtils.isNoneBlank(user.getParams().get(Constants.START_TIME).toString()), SysUser::getCreateTime, user.getParams().get(Constants.START_TIME))
.le(user.getParams().get(Constants.END_TIME) != null && StringUtils.isNoneBlank(user.getParams().get(Constants.END_TIME).toString()), SysUser::getCreateTime, user.getParams().get(Constants.END_TIME));
page(iPage, queryWrapper);
return iPage;
}
/**
* 不分页查询
*
* @param user
* @return
*/
@Override
public List<SysUser> list(SysUser user) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
queryWrapper
.like(StringUtils.isNoneBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
.like(StringUtils.isNoneBlank(user.getTelephone()), SysUser::getTelephone, user.getTelephone())
.like(StringUtils.isNoneBlank(user.getSearchValue()), SysUser::getUserName, user.getSearchValue())
.like(StringUtils.isNoneBlank(user.getSearchValue()), SysUser::getTelephone, user.getSearchValue())
.ge(user.getParams().get(Constants.START_TIME) != null && StringUtils.isNoneBlank(user.getParams().get(Constants.START_TIME).toString()), SysUser::getCreateTime, user.getParams().get(Constants.START_TIME))
.le(user.getParams().get(Constants.END_TIME) != null && StringUtils.isNoneBlank(user.getParams().get(Constants.END_TIME).toString()), SysUser::getCreateTime, user.getParams().get(Constants.END_TIME));
List<SysUser> list = list(queryWrapper);
return list;
}
/**
* 校验用户名称是否唯一
*
* @param loginName 登录名称
* @return 结果
*/
@Override
public String checkLoginNameUnique(String loginName) {
int count = count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, loginName));
return count > 0 ? UserConstants.USER_NAME_NOT_UNIQUE : UserConstants.USER_NAME_UNIQUE;
}
/**
* 校验手机号码是否唯一
*
* @param user 用户信息
* @return 结果
*/
@Override
public String checkPhoneUnique(SysUser user) {
Long userId = user.getId() == null ? -1L : user.getId();
SysUser sysUser = getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getTelephone, user.getTelephone()));
String s = sysUser != null && !userId.equals(sysUser.getId()) ? UserConstants.USER_NAME_NOT_UNIQUE : UserConstants.USER_NAME_UNIQUE;
return s;
}
/**
* 校验email是否唯一
*
* @param user 用户信息
* @return 结果
*/
@Override
public String checkEmailUnique(SysUser user) {
Long userId = user.getId() == null ? -1L : user.getId();
SysUser sysUser = getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));
String s = sysUser != null && !userId.equals(sysUser.getId()) ? UserConstants.USER_NAME_NOT_UNIQUE : UserConstants.USER_NAME_UNIQUE;
return s;
}
@Override
public List<SysUser> selectAllocatedList(SysUser user) {
return sysUserMapper.selectAllocatedList(user);
}
@Override
public List<SysUser> selectUnallocatedList(SysUser user) {
return sysUserMapper.selectUnallocatedList(user);
}
/**
* 新增保存用户信息
*
* @param user 用户信息
* @return 结果
*/
@Override
public int insertUser(SysUser user) {
// 新增用户信息
int rows = sysUserMapper.insert(user);
// 新增用户与角色管理
insertUserRole(user);
return rows;
}
/**
* 修改保存用户信息
*
* @param user 用户信息
* @return 结果
*/
@Override
public int updateUser(SysUser user) {
// 删除用户与角色关联
sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, user.getId()));
// 新增用户与角色管理
insertUserRole(user);
boolean b = updateById(user);
return b ? 1 : 0;
}
/**
* 查询用户所属角色组
*
* @param userId 用户ID
* @return 结果
*/
@Override
public String selectUserRoleGroup(Long userId) {
List<SysRole> sysRoles = sysRoleMapper.selectRolesByUserId(userId);
StringBuffer idsStr = new StringBuffer();
for (SysRole role : sysRoles) {
idsStr.append(role.getRoleName()).append(",");
}
if (StringUtils.isNotEmpty(idsStr.toString())) {
return idsStr.substring(0, idsStr.length() - 1);
}
return idsStr.toString();
}
/**
* 查询用户所属岗位组
*
* @param userId 用户ID
* @return 结果
*/
@Override
public String selectUserPostGroup(Long userId) {
return "";
}
/**
* 删除
*
* @param userId
* @return
*/
@Override
public int deleteUser(Long userId) {
//删除用户角色关联
sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
//删除用户信息
boolean b = removeById(userId);
return b ? 1 : 0;
}
/**
* 批量删除
*
* @param userId
* @return
*/
@Override
public int batchDeleteUser(Collection<? extends Serializable> userId) {
//删除用户角色关联
sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userId));
//删除用户
boolean b = removeByIds(userId);
return b ? 1 : 0;
}
/**
* 新增用户角色信息
*
* @param user 用户对象
*/
public void insertUserRole(SysUser user) {
Long[] roles = user.getRoleIds();
if (roles != null) {
// 新增用户与角色管理
List<SysUserRole> list = new ArrayList<SysUserRole>();
for (Long roleId : roles) {
SysUserRole ur = new SysUserRole();
ur.setUserId(user.getId());
ur.setRoleId(roleId.intValue());
list.add(ur);
}
if (list.size() > 0) {
userRoleService.saveBatch(list);
}
}
}
}
Shiro权限:
package com.xiaofeng.share.shiro;
import com.google.common.collect.Sets;
import com.xiaofeng.share.entity.SysUser;
import com.xiaofeng.share.service.ISysLoginService;
import com.xiaofeng.share.service.ISysMenuService;
import com.xiaofeng.share.service.ISysRoleService;
import com.xiaofeng.share.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
/**
* @author xiaofeng
* @version V1.0
* @title: UserRealm
* @package: com.xiaofeng.share.shiro
* @description: 自定义Realm 处理登录 权限
* @date 2019/7/4 9:44
*/
public class UserRealm extends AuthorizingRealm {
private static final Logger log = LoggerFactory.getLogger(UserRealm.class);
@Autowired
private ISysMenuService menuService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysLoginService loginService;
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
SysUser user = ShiroUtils.getSysUser();
// 角色列表
Set<String> roles = Sets.newHashSet();
// 功能列表
Set<String> menus = Sets.newHashSet();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 管理员拥有所有权限
if (user.isAdmin()) {
info.addRole("admin");
info.addStringPermission("*:*:*");
} else {
roles = roleService.selectRoleKeys(user.getId().longValue());
menus = menuService.selectPermssionByUserId(user.getId().longValue());
// 角色加入AuthorizationInfo认证对象
info.setRoles(roles);
// 权限加入AuthorizationInfo认证对象
info.setStringPermissions(menus);
}
return info;
}
/**
* 登录认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = "";
if (upToken.getPassword() != null) {
password = new String(upToken.getPassword());
}
SysUser user = null;
try {
user = loginService.login(username, password);
} catch (Exception e) {
log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
throw new AuthenticationException(e.getMessage(), e);
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info;
}
/**
* 清理缓存权限
*/
public void clearCachedAuthorizationInfo() {
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
}
}
核心配置文件:
更新日志:
多环境配置:
多数据源配置(动态数据源):
--------------------------------------------------------------20190926----------------------------------------------------------------------
2019年9月26,今天主要更新了2个功能模块:代码生成工具、在线会话数统计、同一个用户多设备登录限制(默认踢出前一个),sftp文件上传配置修复(用于图片上传),邮件发送配置更新等。
更新日志:
代码生成工具:
采用velocity模板工具生成代码
CodeGenerateController
package com.xiaofeng.sys.controller.tool;
import com.xiaofeng.sys.common.TableDataInfo;
import com.xiaofeng.sys.controller.BaseController;
import com.xiaofeng.sys.entity.generate.TableInfo;
import com.xiaofeng.sys.service.IGenerateService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @author xiaofeng
* @version V1.0
* @title: CodeGenerateController
* @package: com.xiaofeng.code.generate.controller
* @description: 代码生成 操作处理
* @date 2019/9/20 13:47
*/
@Controller
@RequestMapping("/tool/gen")
public class CodeGenerateController extends BaseController {
private String prefix = "tool/gen";
@Autowired
private IGenerateService generateService;
@RequiresPermissions("tool:gen:view")
@GetMapping()
public String gen() {
return prefix + "/gen";
}
@GetMapping("/test")
public String test() {
return "test";
}
@RequiresPermissions("tool:gen:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(TableInfo tableInfo) {
List<TableInfo> list = generateService.selectTableList(tableInfo);
return getDataTable(list);
}
/**
* 生成代码
*/
@RequiresPermissions("tool:gen:code")
@GetMapping("/genCode/{tableName}")
public void genCode(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException {
byte[] data = generateService.generatorCode(tableName);
genCode(response, data);
}
/**
* 批量生成代码
*/
@RequiresPermissions("tool:gen:code")
@GetMapping("/batchGenCode")
@ResponseBody
public void batchGenCode(HttpServletResponse response, String tables) throws IOException {
if (StringUtils.isBlank(tables)) {
return;
}
String[] tableNames = tables.split(",");
byte[] data = generateService.generatorCode(tableNames);
genCode(response, data);
}
/**
* 生成zip文件
*
* @param response
* @param data
* @throws IOException
*/
private void genCode(HttpServletResponse response, byte[] data) throws IOException {
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"xiaofeng-code-generate.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
}
在线会话统计:
采用shiro session存储用户会话信息,会话信息存在系统session中,退出即销毁
OnlineSessionFilter(在线session过滤器)
package com.xiaofeng.sys.shiro;
import com.xiaofeng.sys.common.constant.ShiroConstants;
import com.xiaofeng.sys.common.enums.OnlineStatus;
import com.xiaofeng.sys.entity.SysUser;
import com.xiaofeng.sys.util.ShiroUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* @author xiaofeng
* @version V1.0
* @title: OnlineSessionFilter
* @package: com.xiaofeng.sys.shiro
* @description: 在线session过滤器
* @date 2019/9/26 16:00
*/
public class OnlineSessionFilter extends AccessControlFilter {
/**
* 强制退出后重定向的地址
*/
private String forceLogoutUrl;
private SessionDAO sessionDAO;
public String getForceLogoutUrl() {
return forceLogoutUrl;
}
public void setForceLogoutUrl(String forceLogoutUrl) {
this.forceLogoutUrl = forceLogoutUrl;
}
public void setSessionDAO(SessionDAO sessionDAO) {
this.sessionDAO = sessionDAO;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
Subject subject = getSubject(request, response);
if (subject == null || subject.getSession() == null) {
return true;
}
Session session = sessionDAO.readSession(subject.getSession().getId());
if (session != null && session instanceof OnlineSession) {
OnlineSession onlineSession = (OnlineSession) session;
request.setAttribute(ShiroConstants.ONLINE_SESSION, onlineSession);
// 把user id设置进去
//boolean isGuest = onlineSession.getUserId() == null ;
if (onlineSession.getUserId() == null) {
SysUser user = ShiroUtils.getSysUser();
if (user != null) {
onlineSession.setUserId(user.getUserId().longValue());
onlineSession.setLoginName(user.getLoginName());
onlineSession.setAvatar(user.getAvatar());
onlineSession.markAttributeChanged();
}
}
if (onlineSession.getStatus() == OnlineStatus.off_line) {
return false;
}
}
return true;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
if (subject != null) {
subject.logout();
}
saveRequestAndRedirectToLogin(request, response);
return true;
}
@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
WebUtils.issueRedirect(request, response, getForceLogoutUrl());
}
}
SFTP上传配置:
在线用户统计
代码生成
文件管理主要包括:文件上传、文件编辑、文件下载、文件删除,后续会增加文件预览等功能。
文件上传到自主服务器linux目录,通过nginx配置反向代理映射处理,采用sftp协议实现上传、下载、删除等功能。
效果如下:
点击上传(将文件上传到服务器)
点击下载(将文件下载到本地)
由于篇幅有限,无法粘贴所有核心代码。
初级版download:java web基础权限系统 (resourcecode.cn)
高级版download:springboot完整版权限系统 (resourcecode.cn)
qq:193459197
更多推荐
所有评论(0)