Spring Boot + Apache Shrio + JWT前后端分离项目
Posted 在奋斗的大道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot + Apache Shrio + JWT前后端分离项目相关的知识,希望对你有一定的参考价值。
权限类说明:
ShiroConfig.java : Apache Shrio 配置对象
UserRealm.java: 自定义认证类
JWTToken.java: 自定义凭证类
JWTFilter.java: 自定义权限验证拦截器
JWTUtils.java: 生成和校验token 工具类
权限类源码:
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean("securityManager")
public DefaultWebSecurityManager getManager(UserRealm realm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
// 使用自己的realm
manager.setRealm(realm);
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
manager.setSubjectDAO(subjectDAO);
return manager;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<>();
filterMap.put("jwt", new JWTFilter());
factoryBean.setFilters(filterMap);
factoryBean.setSecurityManager(securityManager);
/*
* 自定义url规则
* http://shiro.apache.org/web.html#urls-
*/
Map<String, String> filterRuleMap = new HashMap<>();
// 所有请求通过我们自己的JWT Filter
filterRuleMap.put("/**", "jwt");
// 访问401和404页面不通过我们的Filter
filterRuleMap.put("/system/user/login", "anon");
filterRuleMap.put("/user/imgCode", "anon");
//开放API文档接口
filterRuleMap.put("/swagger-ui.html", "anon");
filterRuleMap.put("/webjars/**","anon");
filterRuleMap.put("/swagger-resources/**","anon");
filterRuleMap.put("/v2/**","anon");
filterRuleMap.put("/static/**","anon");
//sql监控
filterRuleMap.put("/druid/**","anon");
factoryBean.setFilterChainDefinitionMap(filterRuleMap);
return factoryBean;
}
/**
* 下面的代码是添加注解支持
*/
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
// https://zhuanlan.zhihu.com/p/29161098
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
import com.zzg.common.model.system.Menu;
import com.zzg.common.model.system.Role;
import com.zzg.common.model.system.User;
import com.zzg.common.response.ActiveUser;
import com.zzg.common.utils.JWTUtils;
import com.zzg.system.service.UserService;
import lombok.SneakyThrows;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 大坑!,必须重写此方法,不然Shiro会报错
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JWTToken;
}
/**
* 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
if(activeUser.getUser().getType()==0){
authorizationInfo.addStringPermission("*:*");
}else {
List<String> permissions = new ArrayList<>(activeUser.getPermissions());
List<Role> roleList = activeUser.getRoles();
//授权角色
if (!CollectionUtils.isEmpty(roleList)) {
for (Role role : roleList) {
authorizationInfo.addRole(role.getRoleName());
}
}
//授权权限
if (!CollectionUtils.isEmpty(permissions)) {
for (String permission : permissions) {
if (permission != null && !"".equals(permission)) {
authorizationInfo.addStringPermission(permission);
}
}
}
}
return authorizationInfo;
}
/**
* 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
*/
@SneakyThrows
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
String token = (String) auth.getCredentials();
// 解密获得username,用于和数据库进行对比
String username = JWTUtils.getUsername(token);
if (username == null) {
throw new AuthenticationException(" token错误,请重新登入!");
}
User userBean = userService.findUserByName(username);
if (userBean == null) {
throw new AccountException("账号不存在!");
}
if(JWTUtils.isExpire(token)){
throw new AuthenticationException(" token过期,请重新登入!");
}
if (! JWTUtils.verify(token, username, userBean.getPassword())) {
throw new CredentialsException("密码错误!");
}
if(userBean.getStatus()==0){
throw new LockedAccountException("账号已被锁定!");
}
//如果验证通过,获取用户的角色
List<Role> roles= userService.findRolesById(userBean.getId());
//查询用户的所有菜单(包括了菜单和按钮)
List<Menu> menus=userService.findMenuByRoles(roles);
Set<String> urls=new HashSet<>();
Set<String> perms=new HashSet<>();
if(!CollectionUtils.isEmpty(menus)){
for (Menu menu : menus) {
String url = menu.getUrl();
String per = menu.getPerms();
if(menu.getType()==0&& !StringUtils.isEmpty(url)){
urls.add(menu.getUrl());
}
if(menu.getType()==1&&!StringUtils.isEmpty(per)){
perms.add(menu.getPerms());
}
}
}
//过滤出url,和用户的权限
ActiveUser activeUser = new ActiveUser();
activeUser.setRoles(roles);
activeUser.setUser(userBean);
activeUser.setMenus(menus);
activeUser.setUrls(urls);
activeUser.setPermissions(perms);
return new SimpleAuthenticationInfo(activeUser, token, getName());
}
}
import org.apache.shiro.authc.AuthenticationToken;
public class JWTToken implements AuthenticationToken {
// 密钥
private String token;
public JWTToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
import com.zzg.common.error.SystemCodeEnum;
import com.zzg.common.response.ResponseBean;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
@Component
@Slf4j
public class JWTFilter extends BasicHttpAuthenticationFilter {
/**
* 认证之前执行该方法
* @param request
* @param response
* @param mappedValue
* @return
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
Subject subject = SecurityUtils.getSubject();
return null != subject && subject.isAuthenticated();
}
/**
* 认证未通过执行该方法
* @param request
* @param response
* @return
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response){
//完成token登入
//1.检查请求头中是否含有token
HttpServletRequest httpServletRequest= (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Authorization");
//2. 如果客户端没有携带token,拦下请求
if(null==token||"".equals(token)){
responseTokenError(response,"Token无效,您无权访问该接口");
return false;
}
//3. 如果有,对进行进行token验证
JWTToken jwtToken = new JWTToken(token);
try {
SecurityUtils.getSubject().login(jwtToken);
} catch (AuthenticationException e) {
log.error(e.getMessage());
responseTokenError(response,e.getMessage());
return false;
}
return true;
}
/**
* 对跨域提供支持
*/
//@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
/**
* 无需转发,直接返回Response信息 Token认证错误
*/
private void responseTokenError(ServletResponse response, String msg) {
HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
httpServletResponse.setStatus(HttpStatus.OK.value());
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
try (PrintWriter out = httpServletResponse.getWriter()) {
HashMap<String, Object> errorData = new HashMap<>();
errorData.put("errorCode", SystemCodeEnum.TOKEN_ERROR.getErrorCode());
errorData.put("errorMsg",SystemCodeEnum.TOKEN_ERROR.getErrorMsg());
ResponseBean<HashMap<String, Object>> result = ResponseBean.error(errorData);
String data = new Gson().toJson(result);
out.append(data);
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
}
package com.zzg.common.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.UnsupportedEncodingException;
import java.util.Date;
public class JWTUtils {
/**
* 过期时间6小时
*/
private static final long EXPIRE_TIME = 6*60*60*1000;
/**
* 校验token是否正确
* @param token 密钥
* @param secret 用户的密码
* @return 是否正确
*/
public static boolean verify(String token, String username, String secret) {
try {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("username", username)
.build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
/**
* 获得token中的信息无需secret解密也能获得
* @return token中包含的用户名
*/
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("username").asString();
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 生成签名,2min后过期
* @param username 用户名
* @param secret 用户的密码
* @return 加密的token
*/
public static String sign(String username, String secret) {
try {
Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create()
.withClaim("username", username)
.withExpiresAt(date)
.sign(algorithm);
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* 判断过期
* @param token
* @return
*/
public static boolean isExpire(String token){
DecodedJWT jwt = JWT.decode(token);
return System.currentTimeMillis()>jwt.getExpiresAt().getTime();
}
}
RABC 数据库实体类说明:
User.java:用户表
Role.java: 角色表
UserRole.java: 用户关联角色表
Menu.java: 菜单表
RoleMenu.java: 角色关联菜单表
Department.java: 机构表
RABC 数据库模型截图:
RABC 数据库初始化脚本:
/*
Navicat mysql Data Transfer
Source Server : 192.168.1.73
Source Server Type : MySQL
Source Server Version : 80015
Source Host : 192.168.1.73:3306
Source Schema : xinguan
Target Server Type : MySQL
Target Server Version : 80015
File Encoding : 65001
Date: 11/10/2021 15:00:00
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_department
-- ----------------------------
DROP TABLE IF EXISTS `tb_department`;
CREATE TABLE `tb_department` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '系名',
`phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '系办公电话',
`address` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '办公室地点',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_department
-- ----------------------------
INSERT INTO `tb_department` VALUES (1, '物资管理部', '15045741241', '负责系统物资的管理。', '2020-03-16 00:00:00', '2020-08-19 16:48:16');
INSERT INTO `tb_department` VALUES (12, '采购部', '15079451241', '采购中心', '2020-03-16 00:00:00', '2020-08-19 16:48:20');
INSERT INTO `tb_department` VALUES (14, '信息技术部', '18214521412', '3楼405房间', '2020-03-19 00:00:00', '2020-08-19 16:48:23');
INSERT INTO `tb_department` VALUES (15, '行政部', '15079457458', '3栋504房间', '2020-03-19 00:00:00', '2020-03-25 11:27:35');
-- ----------------------------
-- Table structure for tb_menu
-- ----------------------------
DROP TABLE IF EXISTS `tb_menu`;
CREATE TABLE `tb_menu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单/按钮ID',
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT '上级菜单ID',
`menu_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单/按钮名称',
`url` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单URL',
`perms` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '权限标识',
`icon` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图标',
`type` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '类型 0菜单 1按钮',
`order_num` bigint(20) NULL DEFAULT NULL COMMENT '排序',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`modified_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`available` int(11) NULL DEFAULT 1 COMMENT '0:不可用,1:可用',
`open` int(1) NULL DEFAULT 1 COMMENT '0:不展开,1:展开',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 344 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜单表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_menu
-- ----------------------------
INSERT INTO `tb_menu` VALUES (1, 0, '系统管理', '', NULL, 'el-icon-setting', '0', 1, '2020-03-07 17:41:30', '2020-08-19 17:57:20', 1, 0);
INSERT INTO `tb_menu` VALUES (4, 1, '菜单权限', '/system/menus', 'menus', 'el-icon-help', '0', 3, '2020-03-07 18:57:42', '2020-12-15 17:25:02', 1, 0);
INSERT INTO `tb_menu` VALUES (5, 0, '监控中心', '', NULL, 'el-icon-camera', '0', 6, '2020-03-07 18:58:18', '2020-12-15 19:34:38', 1, 1);
INSERT INTO `tb_menu` VALUES (226, 1, '用户管理', '/system/users', 'users', 'el-icon-user', '0', 2, '2020-03-10 05:27:54', '2020-12-15 17:24:22', 1, 0);
INSERT INTO `tb_menu` VALUES (230, 312, '入库记录', '/business/product/in-stocks', 'el-icon-date', 'el-icon-date', '0', 1, '2020-03-10 05:34:28', '2020-12-15 19:57:21', 1, 0);
INSERT INTO `tb_menu` VALUES (234, 226, '用户添加', '', 'user:add', 'el-icon-plus', '1', 1, '2020-03-10 05:50:44', '2020-03-10 07:51:56', 1, 0);
INSERT INTO `tb_menu` VALUES (235, 1, '角色管理', '/system/roles', 'roles', 'el-icon-postcard', '0', 3, '2020-03-10 05:51:28', '2020-12-15 17:24:41', 1, 0);
INSERT INTO `tb_menu` VALUES (239, 226, '用户删除', '', 'user:delete', 'el-icon-picture', '1', 1, '2020-03-10 06:05:30', '2020-03-10 08:10:19', 1, 0);
INSERT INTO `tb_menu` VALUES (240, 226, '用户编辑', '', 'user:edit', 'el-icon-video-camera-solid', '1', 1, '2020-03-10 06:06:30', '2020-03-10 07:52:28', 1, 0);
INSERT INTO `tb_menu` VALUES (241, 235, '角色编辑', '', 'role:edit', 'el-icon-s-promotion', '1', 2, '2020-03-10 06:11:03', '2020-03-11 11:40:19', 1, 0);
INSERT INTO `tb_menu` VALUES (242, 235, '角色删除', '', 'role:delete', 'el-icon-s-marketing', '1', 3, '2020-03-10 06:15:29', '2020-03-11 11:43:36', 1, 0);
INSERT INTO `tb_menu` VALUES (247, 4, '添加菜单', '', 'menu:add', 'el-icon-s-opportunity', '1', 1, '2020-03-10 07:55:10', '2020-04-27 09:59:43', 1, 0);
INSERT INTO `tb_menu` VALUES (249, 4, '修改菜单', '', 'menu:update', 'el-icon-share', '1', 2, '2020-03-10 07:56:55', '2020-03-15 13:29:29', 1, 0);
INSERT INTO `tb_menu` VALUES (250, 4, '删除菜单', '', 'menu:delete', 'el-icon-folder-opened', '1', 3, '2020-03-10 07:57:38', '2020-03-15 13:29:41', 1, 0);
INSERT INTO `tb_menu` VALUES (251, 235, '分配权限', '', 'role:authority', 'el-icon-document-add', '1', 1, '2020-03-10 08:13:22', '2020-03-11 11:39:30', 1, 0);
INSERT INTO `tb_menu` VALUES (253, 1, '控制面板', '/system/welcome', 'welcome:view', 'el-icon-star-off', '0', 1, '2020-03-10 08:46:44', '2020-12-15 19:22:46', 1, 0);
INSERT INTO `tb_menu` VALUES (254, 226, '分配角色', '', 'user:assign', 'el-icon-s-tools', '1', 3, '2020-03-11 01:32:29', '2020-04-27 10:58:30', 1, 0);
INSERT INTO `tb_menu` VALUES (255, 235, '添加角色', '', 'role:add', 'el-icon-help', '1', 1, '2020-03-11 01:34:18', '2020-03-11 01:34:18', 1, 0);
INSERT INTO `tb_menu` VALUES (256, 226, '禁用用户', '', 'user:status', 'el-icon-circle-close', '1', 1, '2020-03-11 06:50:04', '2020-03-14 05:05:49', 1, 0);
INSERT INTO `tb_menu` VALUES (258, 226, '用户更新', '', 'user:update', 'el-icon-refresh', '1', 1, '2020-03-11 08:26:54', '2020-03-11 08:26:54', 1, 0);
INSERT INTO `tb_menu` VALUES (259, 235, '角色更新', '', 'role:update', 'el-icon-refresh-left', '1', 1, '2020-03-11 11:45:20', '2020-03-11 11:45:20', 1, 0);
INSERT INTO `tb_menu` VALUES (260, 235, '状态更新', '', 'role:status', 'el-icon-refresh', '1', 1, '2020-03-14 05:07:02', '2020-03-14 05:07:24', 1, 0);
INSERT INTO `tb_menu` VALUES (261, 1, '部门管理', '/system/departments', '', 'el-icon-s-home', '0', 3, '2020-03-15 06:05:48', '2020-12-15 17:25:18', 1, 0);
INSERT INTO `tb_menu` VALUES (262, 261, '添加部门', '', 'department:add', 'el-icon-plus', '1', 1, '2020-03-15 11:57:42', '2020-03-21 12:37:21', 1, 0);
INSERT INTO `tb_menu` VALUES (263, 261, '编辑院系', '', 'department:edit', 'el-icon-edit', '1', 1, '2020-03-15 11:59:52', '2020-03-15 12:16:36', 1, 0);
INSERT INTO `tb_menu` VALUES (264, 261, '更新院系', '', 'department:update', 'el-icon-refresh', '1', 1, '2020-03-15 12:02:34', '2020-03-15 12:16:32', 1, 0);
INSERT INTO `tb_menu` VALUES (265, 261, '删除院系', NULL, 'department:delete', 'el-icon-delete', '1', 1, '2020-03-15 12:03:21', '2020-03-15 12:03:21', 1, 0);
INSERT INTO `tb_menu` VALUES (267, 312, '物资资料', '/business/product/list', '', 'el-icon-goods', '0', 2, '2020-03-16 09:01:02', '2020-12-15 19:51:38', 1, 0);
INSERT INTO `tb_menu` VALUES (268, 312, '物资类别', '/business/product/categories', '', 'el-icon-star-off', '0', 2, '2020-03-16 09:01:48', '2020-12-15 19:51:44', 1, 0);
INSERT INTO `tb_menu` VALUES (269, 312, '物资来源', '/business/product/suppliers', '', 'el-icon-coordinate', '0', 5, '2020-03-16 12:35:10', '2020-12-15 19:52:19', 1, 0);
INSERT INTO `tb_menu` VALUES (270, 312, '发放记录', '/business/product/out-stocks', '', 'el-icon-goods', '0', 5, '2020-03-16 13:55:49', '2020-12-15 19:57:34', 1, 1);
INSERT INTO `tb_menu` VALUES (271, 5, '登入日志', '/monitor/login-log', 'login:log', 'el-icon-date', '0', 1, '2020-03-20 10:31:12', '2020-12-15 18:28:47', 1, 0);
INSERT INTO `tb_menu` VALUES (273, 303, '全国疫情', '/covid19/map', 'map:view', 'el-icon-s-opportunity', '0', 1, '2020-03-20 11:32:02', '2020-12-15 20:15:48', 1, 1);
INSERT INTO `tb_menu` VALUES (274, 267, '添加物资', '', 'product:add', 'el-icon-s-opportunity', '1', 1, '2020-03-21 02:04:24', '2020-03-21 02:04:24', 1, 0);
INSERT INTO `tb_menu` VALUES (276, 267, '上传图片', NULL, 'upload:image', 'el-icon-finished', '1', 2, '2020-03-21 02:05:21', '2020-03-21 02:05:21', 1, 0);
INSERT INTO `tb_menu` VALUES (277, 267, '更新物资', NULL, 'product:update', 'el-icon-folder', '1', 3, '2020-03-21 02:05:56', '2020-03-21 02:05:56', 1, 0);
INSERT INTO `tb_menu` VALUES (278, 267, '编辑物资', NULL, 'product:edit', 'el-icon-edit', '1', 1, '2020-03-21 02:06:23', '2020-03-21 02:06:23', 1, 0);
INSERT INTO `tb_menu` VALUES (279, 269, '删除来源', '', 'supplier:delete', 'el-icon-document-delete', '1', 1, '2020-03-21 02:17:29', '2020-03-21 12:32:22', 1, 0);
INSERT INTO `tb_menu` VALUES (280, 269, '更新来源', '', 'supplier:update', 'el-icon-paperclip', '1', 1, '2020-03-21 02:18:34', '2020-03-21 12:36:41', 1, 0);
INSERT INTO `tb_menu` VALUES (281, 269, '添加来源', NULL, 'supplier:add', 'el-icon-document-add', '1', 1, '2020-03-21 02:19:02', '2020-03-21 02:19:02', 1, 1);
INSERT INTO `tb_menu` VALUES (282, 269, '编辑来源', NULL, 'supplier:edit', 'el-icon-scissors', '1', 2, '2020-03-21 02:19:36', '2020-03-21 02:19:36', 1, 1);
INSERT INTO `tb_menu` VALUES (283, 268, '添加类别', '', 'productCategory:add', ' el-icon-folder-add', '1', 1, '2020-03-21 02:26:12', '2020-03-21 02:44:22', 1, 0);
INSERT INTO `tb_menu` VALUES (284, 268, '删除类别', NULL, 'productCategory:delete', 'el-icon-delete', '1', 1, '2020-03-21 02:27:05', '2020-03-21 02:28:49', 1, 0);
INSERT INTO `tb_menu` VALUES (285, 268, '编辑类别', NULL, 'productCategory:edit', 'el-icon-scissors', '1', 2, '2020-03-21 02:27:42', '2020-03-21 02:27:42', 1, 0);
INSERT INTO `tb_menu` VALUES (286, 268, '更新类别', NULL, 'productCategory:update', ' el-icon-coordinate', '1', 1, '2020-03-21 02:28:17', '2020-03-21 02:28:17', 1, 0);
INSERT INTO `tb_menu` VALUES (296, 295, 'swagger文档', '/monitor/swagger-ui', NULL, 'el-icon-document', '0', 2, '2020-03-22 01:22:48', '2020-12-15 18:32:54', 1, 0);
INSERT INTO `tb_menu` VALUES (298, 5, 'SQL监控', '/monitor/druid', NULL, 'el-icon-view', '0', 1, '2020-03-22 02:48:05', '2020-12-15 19:42:32', 1, 0);
INSERT INTO `tb_menu` VALUES (299, 271, '删除日志', '', 'loginLog:delete', 'el-icon-delete', '1', 1, '2020-03-22 21:55:44', '2020-03-22 21:55:44', 1, 0);
INSERT INTO `tb_menu` VALUES (300, 271, '批量删除', '', 'loginLog:batchDelete', 'el-icon-delete-solid', '1', 1, '2020-03-22 22:19:26', '2020-03-22 22:19:26', 1, 0);
INSERT INTO `tb_menu` VALUES (301, 4, '编辑菜单', '', 'menu:edit', 'el-icon-edit', '1', 1, '2020-03-22 23:12:25', '2020-03-22 23:12:25', 1, 0);
INSERT INTO `tb_menu` VALUES (303, 0, '健康报备', '', '', 'el-icon-platform-eleme', '0', 3, '2020-03-24 10:11:53', '2020-12-15 20:15:30', 1, 1);
INSERT INTO `tb_menu` VALUES (304, 303, '健康打卡', '/covid19/health', '', 'el-icon-s-cooperation', '0', 1, '2020-03-24 10:12:57', '2020-12-15 20:19:14', 1, 0);
INSERT INTO `tb_menu` VALUES (307, 5, '操作日志', '/monitor/logs', '', 'el-icon-edit', '0', 1, '2020-04-04 19:04:53', '2020-12-15 18:34:36', 1, 0);
INSERT INTO `tb_menu` VALUES (308, 307, '删除日志', '', 'log:delete', 'el-icon-circle-close', '1', 1, '2020-04-04 19:59:20', '2020-04-04 19:59:20', 1, 1);
INSERT INTO `tb_menu` VALUES (309, 307, '批量删除', NULL, 'log:batchDelete', 'el-icon-document-delete', '1', 2, '2020-04-04 19:59:59', '2020-04-04 19:59:59', 1, 0);
INSERT INTO `tb_menu` VALUES (310, 312, '物资去处', '/business/product/consumers', '', 'el-icon-edit', '0', 1, '2020-04-05 10:08:21', '2020-12-15 19:52:10', 1, 0);
INSERT INTO `tb_menu` VALUES (312, 0, '业务管理', NULL, NULL, 'el-icon-s-goods', '0', 2, '2020-04-05 10:19:07', '2020-08-19 17:57:27', 1, 1);
INSERT INTO `tb_menu` VALUES (316, 312, '物资库存', '/business/product/stocks', '', 'el-icon-tickets', '0', 5, '2020-04-16 08:45:08', '2020-12-15 19:51:58', 1, 0);
INSERT INTO `tb_menu` VALUES (317, 226, '导出表格', '', 'user:export', 'el-icon-edit', '1', 1, '2020-04-17 18:02:05', '2020-04-17 18:02:05', 1, 0);
INSERT INTO `tb_menu` VALUES (318, 1, '图标管理', '/system/icon', '', 'el-icon-star-off', '0', 7, '2020-04-21 12:06:33', '2020-12-17 21:47:49', 1, 1);
INSERT INTO `tb_menu` VALUES (321, 1, '文件管理', '/system/files', '', 'el-icon-picture-outline', '0', 2, '2020-04-25 10:52:17', '2020-12-15 19:21:15', 1, 1);
INSERT INTO `tb_menu` VALUES (322, 310, '添加去处', '', 'consumer:add', 'el-icon-plus', '1', 2, '2020-04-27 16:57:04', '2020-04-27 16:58:21', 1, 1);
INSERT INTO `tb_menu` VALUES (323, 310, '删除去处', NULL, 'consumer:delete', 'el-icon-delete', '1', 1, '2020-04-27 16:57:42', '2020-04-27 16:57:42', 1, 0);
INSERT INTO `tb_menu` VALUES (324, 310, '编辑去处', '', 'consumer:edit', 'el-icon-edit', '1', 1, '2020-04-27 16:59:17', '2020-04-27 16:59:17', 1, 0);
INSERT INTO `tb_menu` VALUES (325, 310, '更新去处', NULL, 'consumer:update', 'el-icon-star-off', '1', 1, '2020-04-27 17:00:18', '2020-04-27 17:00:18', 1, 1);
INSERT INTO `tb_menu` VALUES (326, 230, '添加入库', '', 'inStock:in', 'el-icon-plus', '1', 3, '2020-04-27 17:07:04', '2020-08-19 17:57:15', 1, 1);
INSERT INTO `tb_menu` VALUES (328, 230, '入库明细', NULL, 'inStock:detail', 'el-icon-zoom-in', '1', 2, '2020-04-27 17:08:25', '2020-04-27 17:08:25', 1, 0);
INSERT INTO `tb_menu` VALUES (329, 4, '导出菜单', NULL, 'menu:export', 'el-icon-edit', '1', 1, '2020-04-27 17:26:40', '2020-04-27 17:26:40', 1, 0);
INSERT INTO `tb_menu` VALUES (331, 267, '删除物资', NULL, 'product:delete', 'el-icon-delete', '1', 1, '2020-04-30 18:27:02', '2020-04-30 19:05:31', 1, 0);
INSERT INTO `tb_menu` VALUES (332, 267, '回收物资', '', 'product:remove', 'el-icon-remove', '1', 1, '2020-04-30 18:56:48', '2020-04-30 18:56:48', 1, 1);
INSERT INTO `tb_menu` VALUES (333, 267, '物资审核', NULL, 'product:publish', 'el-icon-edit', '1', 1, '2020-04-30 18:58:38', '2020-04-30 19:05:42', 1, 0);
INSERT INTO `tb_menu` VALUES (336, 267, '物资还原', NULL, 'product:back', 'el-icon-top-left', '1', 1, '2020-04-30 19:06:22', '2020-04-30 19:06:22', 1, 0);
INSERT INTO `tb_menu` VALUES (337, 230, '入库回收', '', 'inStock:remove', 'el-icon-remove', '1', 3, '2020-04-30 19:12:56', '2020-08-19 17:57:55', 1, 1);
INSERT INTO `tb_menu` VALUES (338, 230, '入库审核', NULL, 'inStock:publish', 'el-icon-edit', '1', 2, '2020-04-30 19:13:32', '2020-08-19 17:57:32', 1, 0);
INSERT INTO `tb_menu` VALUES (339, 230, '删除记录', NULL, 'inStock:delete', 'el-icon-delete', '1', 4, '2020-04-30 19:14:03', '2020-08-19 17:57:42', 1, 0);
INSERT INTO `tb_menu` VALUES (340, 230, '入库还原', '', 'inStock:back', 'el-icon-d-arrow-left', '1', 3, '2020-04-30 19:17:27', '2020-08-19 17:57:49', 1, 0);
INSERT INTO `tb_menu` VALUES (341, 295, '个人博客', '/blog', '', 'el-icon-view', '0', 1, '2020-05-07 19:34:31', '2020-05-07 19:34:31', 1, 0);
INSERT INTO `tb_menu` VALUES (343, 304, '健康上报', '', 'health:report', 'el-icon-edit', '1', 1, '2020-05-14 20:21:09', '2020-05-14 20:21:09', 1, 0);
INSERT INTO `tb_menu` VALUES (344, 5, '项目接口', '/monitor/swagger-ui', '', 'el-icon-edit', '0', 1, '2020-12-15 18:35:18', '2020-12-15 18:35:18', 1, 1);
-- ----------------------------
-- Table structure for tb_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色描述',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`modified_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`status` int(1) NULL DEFAULT 1 COMMENT '是否可用,0:不可用,1:可用',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_role
-- ----------------------------
INSERT INTO `tb_role` VALUES (145, '测试角色', '用于测试的账号', '2020-12-17 00:00:00', '2020-12-17 20:33:46', 1);
-- ----------------------------
-- Table structure for tb_role_menu
-- ----------------------------
DROP TABLE IF EXISTS `tb_role_menu`;
CREATE TABLE `tb_role_menu` (
`role_id` bigint(20) NOT NULL COMMENT '角色ID',
`menu_id` bigint(20) NOT NULL COMMENT '菜单/按钮ID'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色菜单关联表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_role_menu
-- ----------------------------
INSERT INTO `tb_role_menu` VALUES (145, 253);
INSERT INTO `tb_role_menu` VALUES (145, 234);
INSERT INTO `tb_role_menu` VALUES (145, 239);
INSERT INTO `tb_role_menu` VALUES (145, 240);
INSERT INTO `tb_role_menu` VALUES (145, 258);
INSERT INTO `tb_role_menu` VALUES (145, 317);
INSERT INTO `tb_role_menu` VALUES (145, 318);
INSERT INTO `tb_role_menu` VALUES (145, 321);
INSERT INTO `tb_role_menu` VALUES (145, 247);
INSERT INTO `tb_role_menu` VALUES (145, 301);
INSERT INTO `tb_role_menu` VALUES (145, 329);
INSERT INTO `tb_role_menu` VALUES (145, 255);
INSERT INTO `tb_role_menu` VALUES (145, 259);
INSERT INTO `tb_role_menu` VALUES (145, 241);
INSERT INTO `tb_role_menu` VALUES (145, 261);
INSERT INTO `tb_role_menu` VALUES (145, 262);
INSERT INTO `tb_role_menu` VALUES (145, 264);
INSERT INTO `tb_role_menu` VALUES (145, 312);
INSERT INTO `tb_role_menu` VALUES (145, 230);
INSERT INTO `tb_role_menu` VALUES (145, 328);
INSERT INTO `tb_role_menu` VALUES (145, 338);
INSERT INTO `tb_role_menu` VALUES (145, 326);
INSERT INTO `tb_role_menu` VALUES (145, 337);
INSERT INTO `tb_role_menu` VALUES (145, 340);
INSERT INTO `tb_role_menu` VALUES (145, 339);
INSERT INTO `tb_role_menu` VALUES (145, 310);
INSERT INTO `tb_role_menu` VALUES (145, 323);
INSERT INTO `tb_role_menu` VALUES (145, 324);
INSERT INTO `tb_role_menu` VALUES (145, 325);
INSERT INTO `tb_role_menu` VALUES (145, 322);
INSERT INTO `tb_role_menu` VALUES (145, 267);
INSERT INTO `tb_role_menu` VALUES (145, 274);
INSERT INTO `tb_role_menu` VALUES (145, 278);
INSERT INTO `tb_role_menu` VALUES (145, 331);
INSERT INTO `tb_role_menu` VALUES (145, 332);
INSERT INTO `tb_role_menu` VALUES (145, 333);
INSERT INTO `tb_role_menu` VALUES (145, 336);
INSERT INTO `tb_role_menu` VALUES (145, 276);
INSERT INTO `tb_role_menu` VALUES (145, 277);
INSERT INTO `tb_role_menu` VALUES (145, 268);
INSERT INTO `tb_role_menu` VALUES (145, 283);
INSERT INTO `tb_role_menu` VALUES (145, 284);
INSERT INTO `tb_role_menu` VALUES (145, 286);
INSERT INTO `tb_role_menu` VALUES (145, 285);
INSERT INTO `tb_role_menu` VALUES (145, 269);
INSERT INTO `tb_role_menu` VALUES (145, 279);
INSERT INTO `tb_role_menu` VALUES (145, 280);
INSERT INTO `tb_role_menu` VALUES (145, 281);
INSERT INTO `tb_role_menu` VALUES (145, 282);
INSERT INTO `tb_role_menu` VALUES (145, 270);
INSERT INTO `tb_role_menu` VALUES (145, 316);
INSERT INTO `tb_role_menu` VALUES (145, 303);
INSERT INTO `tb_role_menu` VALUES (145, 273);
INSERT INTO `tb_role_menu` VALUES (145, 304);
INSERT INTO `tb_role_menu` VALUES (145, 343);
INSERT INTO `tb_role_menu` VALUES (145, 5);
INSERT INTO `tb_role_menu` VALUES (145, 271);
INSERT INTO `tb_role_menu` VALUES (145, 299);
INSERT INTO `tb_role_menu` VALUES (145, 300);
INSERT INTO `tb_role_menu` VALUES (145, 298);
INSERT INTO `tb_role_menu` VALUES (145, 307);
INSERT INTO `tb_role_menu` VALUES (145, 308);
INSERT INTO `tb_role_menu` VALUES (145, 309);
INSERT INTO `tb_role_menu` VALUES (145, 344);
INSERT INTO `tb_role_menu` VALUES (145, 1);
INSERT INTO `tb_role_menu` VALUES (145, 226);
INSERT INTO `tb_role_menu` VALUES (145, 4);
INSERT INTO `tb_role_menu` VALUES (145, 235);
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`nickname` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`avatar` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '头像',
`phone_number` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系电话',
`status` int(1) NOT NULL COMMENT '状态 0锁定 1有效',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`modified_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
`sex` int(1) NULL DEFAULT NULL COMMENT '性别 0男 1女 2保密',
`salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '盐',
`type` int(11) NOT NULL DEFAULT 1 COMMENT '0:超级管理员,1:系统用户',
`password` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`birth` date NULL DEFAULT NULL,
`department_id` bigint(20) NULL DEFAULT 1 COMMENT '部门id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 199 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (5, 'admin', '小章鱼', 'Jana@126.com', 'http://thirdqq.qlogo.cn/g?b=oidb&k=icTYjyV5afABvE1v4ge9SLg&s=100&t=1584195695', '17744444444', 1, '2019-06-14 21:12:16', '2020-03-19 04:20:40', 0, 'cfbf6d34-d3e4-4653-86f0-e33d4595d52b', 0, 'd7b9c28cac022955cff27947eafce0ad', '2020-03-27', 1);
INSERT INTO `tb_user` VALUES (196, 'jack', 'testetst', 'test@qq.com', 'http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg', '15045414141', 1, '2020-08-19 17:41:20', '2020-08-19 17:41:20', 1, '303191e1-4082-4d2d-8976-5a93426a', 1, '49bdaf7293cc9bd6fc9f50c3b03b7d6d', '2020-08-17', 12);
INSERT INTO `tb_user` VALUES (197, '3333333', '33333', '333@qq.com', 'http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg', '15041414141', 0, '2020-12-16 21:32:22', '2020-12-16 21:32:22', 1, '62a6dd8f-9efd-4ae4-98f3-c0382299', 1, '2168d955d03701181dd6b3bab7647694', '2020-12-29', 1);
INSERT INTO `tb_user` VALUES (198, 'test', 'testnickn', 'test@qq.com', 'http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg', '15074857474', 1, '2020-12-17 18:49:59', '2020-12-17 18:50:08', 1, '7cb34dcf-62a7-4404-b802-93ebcb1f', 1, '9b9013e2729f0c23852ef2801cd5344b', '2020-12-15', 12);
INSERT INTO `tb_user` VALUES (199, '蔡徐坤', '偶像练习生', 'caixukun@qq.com', 'http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg', '15041414514', 0, '2020-12-17 21:31:44', '2020-12-17 21:31:44', 1, '9fb8c514-7484-4f6e-a155-6c90ca16', 1, 'd0e8cf620adb72d66e975e932afb960b', '2020-12-16', 14);
-- ----------------------------
-- Table structure for tb_user_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_user_role`;
CREATE TABLE `tb_user_role` (
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`role_id` bigint(20) NOT NULL COMMENT '角色ID'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色关联表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_user_role
-- ----------------------------
INSERT INTO `tb_user_role` VALUES (194, 125);
INSERT INTO `tb_user_role` VALUES (196, 145);
INSERT INTO `tb_user_role` VALUES (199, 145);
SET FOREIGN_KEY_CHECKS = 1;
RABC 业务功能代码(entity)
import com.wuwenze.poi.annotation.Excel;
import com.wuwenze.poi.annotation.ExcelField;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Excel("department")
@Data
@Table(name = "tb_department")
public class Department {
@Id
@ExcelField(value = "编号", width = 50)
private Long id;
@ExcelField(value = "部门名称", width = 100)
private String name;
@ExcelField(value = "联系电话", width = 120)
private String phone;
@ExcelField(value = "部门地址", width = 150)
private String address;
@ExcelField(value = "创建时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date createTime;
@ExcelField(value = "修改时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date modifiedTime;
}
import com.wuwenze.poi.annotation.Excel;
import com.wuwenze.poi.annotation.ExcelField;
import lombok.Data;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data
@Excel(value = "菜单表格")
@Table(name = "tb_menu")
public class Menu {
@Id
@ExcelField(value = "编号", width = 50)
@GeneratedValue(generator = "JDBC")
private Long id;
@ExcelField(value = "父级id", width = 50)
private Long parentId;
@ExcelField(value = "菜单名称", width = 100)
private String menuName;
@ExcelField(value = "菜单url", width = 100)
private String url;
@ExcelField(value = "菜单图标", width = 80)
private String icon;
@ExcelField(value = "是否展开", width = 50)
private Integer open;
@ExcelField(value = "菜单类型", width = 80)
private Integer type;
@ExcelField(value = "排序", width = 90)
private Long orderNum;
@ExcelField(value = "创建时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date createTime;
@ExcelField(value = "修改时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date modifiedTime;
@ExcelField(value = "是否可用",width = 80)
private Integer available;
@ExcelField(value = "权限编码", width = 180)
private String perms;
}
import com.wuwenze.poi.annotation.Excel;
import com.wuwenze.poi.annotation.ExcelField;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Excel(value = "角色表格")
@Data
@Table(name = "tb_role")
public class Role {
@Id
@ExcelField(value = "编号", width = 50)
private Long id;
@ExcelField(value = "角色名称", width = 100)
private String roleName;
@ExcelField(value = "备注信息", width = 180)
private String remark;
@ExcelField(value = "创建时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date createTime;
@ExcelField(value = "修改时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date modifiedTime;
@ExcelField(value = "禁用状态", width = 50)
private Integer status;
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\\'' +
'}';
}
}
import lombok.Data;
import javax.persistence.Table;
@Data
@Table(name = "tb_role_menu")
public class RoleMenu {
private Long roleId;
private Long menuId;
}
import com.wuwenze.poi.annotation.Excel;
import com.wuwenze.poi.annotation.ExcelField;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data
@Excel("user")
@Table(name = "tb_user")
public class User {
@Id
@ExcelField(value = "编号", width = 50)
private Long id;
@ExcelField(value = "用户名", width = 100)
private String username;
@ExcelField(value = "昵称", width = 100)
private String nickname;
@ExcelField(value = "邮箱", width = 150)
private String email;
@ExcelField(value = "电话号码", width = 100)
private String phoneNumber;
private Integer status;
@ExcelField(value = "创建时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss", width = 180)
private Date createTime;
@ExcelField(value = "修改时间", dateFormat = "yyyy年MM月dd日 HH:mm:ss",width = 180)
private Date modifiedTime;
@ExcelField(//
value = "性别",
readConverterExp = "男=1,女=0",
writeConverterExp = "1=男,0=女"
,width = 50
)
private Integer sex;
@ExcelField(value = "密码盐值", width = 100)
private String salt;
@ExcelField(//
value = "用户类型",
readConverterExp = "超级管理员=0,普通用户=1",
writeConverterExp = "0=超级管理员,1=普通用户"
,width = 80
)
private Integer type;
@ExcelField(value = "用户密码", width = 100)
private String password;
@ExcelField(value = "出生日期", dateFormat = "yyyy/MM/dd",width = 100)
private Date birth;
private Long departmentId;
@ExcelField(value = "头像url", width = 200)
private String avatar;
}
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Table(name = "tb_user_role")
public class UserRole {
@Id
private Long userId;
private Long roleId;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
}
温馨提示:@Excel及其@ExcelField 标签使用开源excel 导入导出工具包ExcelKit
RABC 前端视图功能代码(VO)
import lombok.Data;
@Data
public class DeanVO {
private Long id;
private String name;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.Date;
@Data
public class DepartmentVO {
private Long id;
@NotBlank(message = "院系名称不能为空")
private String name;
@NotBlank(message = "办公电话不能为空")
private String phone;
@NotBlank(message = "办公地址不能为空")
private String address;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
private Date createTime;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
private Date modifiedTime;
/** 部门内人数**/
private int total;
}
import lombok.Data;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Data
public class MenuNodeVO {
private Long id;
private Long parentId;
private String menuName;
private String url=null;
private String icon;
private Long orderNum;
private Integer open;
private boolean disabled;
private String perms;
private Integer type;
private List<MenuNodeVO> children=new ArrayList<>();
/*
* 排序,根据order排序
*/
public static Comparator<MenuNodeVO> order(){
Comparator<MenuNodeVO> comparator = (o1, o2) -> {
if(o1.getOrderNum() != o2.getOrderNum()){
return (int) (o1.getOrderNum() - o2.getOrderNum());
}
return 0;
};
return comparator;
}
}
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
public class MenuVO {
private Long id;
@NotNull(message = "父级ID必须")
private Long parentId;
@NotBlank(message = "菜单名称不能为空")
private String menuName;
private String url;
private String icon;
@NotNull(message = "菜单类型不为空")
private Integer type;
@NotNull(message = "排序数不能为空")
private Long orderNum;
private Date createTime;
private Date modifiedTime;
@NotNull(message = "菜单状态不能为空")
private boolean disabled;
private Integer open;
private String perms;
}
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class PageVO<T> {
private long total;
private List<T> rows=new ArrayList<>();
public PageVO(long total, List<T> data) {
this.total = total;
this.rows = data;
}
}
import lombok.Data;
@Data
public class RoleTransferItemVO {
private Long key;
private String label;
private boolean disabled;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.Date;
@Data
public class RoleVO {
private Long id;
@NotBlank(message = "角色名必填")
private String roleName;
@NotBlank(message = "角色描述信息必填")
private String remark;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
private Date createTime;
private Date modifiedTime;
private Boolean status;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
public class UserEditVO {
private Long id;
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "昵称不能为空")
private String nickname;
@Email(message = "请输入正确的邮箱格式")
private String email;
@NotBlank(message = "电话号码不能为空")
private String phoneNumber;
@NotNull(message = "性别不能为空")
private Integer sex;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy年MM月dd日")
@NotNull(message = "生日不能为空")
private Date birth;
@NotNull(message = "部门不能为空")
private Long departmentId;
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Set;
@Data
@ApiModel(value = "用户登入信息")
public class UserInfoVO {
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "头像")
private String avatar;
@ApiModelProperty(value = "菜单")
private Set<String> url;
@ApiModelProperty(value = "权限")
private Set<String> perms;
@ApiModelProperty(value = "角色集合")
private List<String> roles;
@ApiModelProperty(value = "所在部门")
private String department;
@ApiModelProperty(value = "是否是超管")
private Boolean isAdmin=false;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
public class UserVO{
private Long id;
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "昵称不能为空")
private String nickname;
@Email(message = "请输入正确的邮箱格式")
private String email;
@NotBlank(message = "电话号码不能为空")
private String phoneNumber;
private Boolean status;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@NotNull(message = "性别不能为空")
private Integer sex;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy年MM月dd日")
@NotNull(message = "生日不能为空")
private Date birth;
@NotBlank(message = "密码不能为空")
private String password;
private String departmentName;
@NotNull(message = "部门id不能为空")
private Long departmentId;
}
RABC 业务功能代码(Mapper)
import com.zzg.common.model.system.Department;
import tk.mybatis.mapper.common.Mapper;
public interface DepartmentMapper extends Mapper<Department> {
}
import com.zzg.common.model.system.Menu;
import tk.mybatis.mapper.common.BaseMapper;
public interface MenuMapper extends BaseMapper<Menu> {
}
import com.zzg.common.model.system.Role;
import tk.mybatis.mapper.common.Mapper;
public interface RoleMapper extends Mapper<Role> {
}
import com.zzg.common.model.system.RoleMenu;
import tk.mybatis.mapper.common.Mapper;
public interface RoleMenuMapper extends Mapper<RoleMenu> {
}
import com.zzg.common.model.system.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper<User> {
}
import com.zzg.common.model.system.UserRole;
import tk.mybatis.mapper.common.Mapper;
public interface UserRoleMapper extends Mapper<UserRole> {
}
RABC 业务功能代码(Service)
import com.zzg.common.error.SystemException;
import com.zzg.common.model.system.Department;
import com.zzg.common.vo.system.DeanVO;
import com.zzg.common.vo.system.DepartmentVO;
import com.zzg.common.vo.system.PageVO;
import java.util.List;
public interface DepartmentService {
/**
* 部门列表
* @param pageNum
* @param pageSize
* @param departmentVO
* @return
*以上是关于Spring Boot + Apache Shrio + JWT前后端分离项目的主要内容,如果未能解决你的问题,请参考以下文章
Apache Ignite 使用 Spring-Boot 加载两次?
apache-shiro 的怪事通过 spring-boot 集成到 spring-mvc 中
mybatis-spring-boot, org.apache.ibatis.binding.BindingException: 无效的绑定语句