update auth

master
zhengqingya 2 years ago
parent 345ec09be5
commit 2ef1f22555
  1. 5
      smallboot-api/common/auth/src/main/resources/application-auth.yml
  2. 11
      smallboot-api/common/base/src/main/java/com/zhengqing/common/base/model/bo/JwtUserBO.java
  3. 4
      smallboot-api/common/core/src/main/java/com/zhengqing/common/core/config/WebAppConfig.java
  4. 67
      smallboot-api/common/core/src/main/java/com/zhengqing/common/core/config/interceptor/HandlerInterceptorForToken.java
  5. 55
      smallboot-api/doc/smallboot.sql
  6. 15
      smallboot-api/system/src/main/java/com/zhengqing/system/api/SysMenuController.java
  7. 13
      smallboot-api/system/src/main/java/com/zhengqing/system/service/impl/AuthServiceImpl.java
  8. BIN
      smallboot-web/src/assets/404_images/404.png
  9. BIN
      smallboot-web/src/assets/404_images/404_cloud.png
  10. 5
      smallboot-web/src/permission.ts
  11. 18
      smallboot-web/src/router/index.ts
  12. 30
      smallboot-web/src/views/error-page/401.vue
  13. 227
      smallboot-web/src/views/error-page/404.vue
  14. 3
      smallboot-web/src/views/system/role/list.vue

@ -13,15 +13,16 @@ sa-token:
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false is-concurrent: false
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
# tips: 使用 jwt-simple 模式后,is-share=false 恒等于 false。
is-share: false is-share: false
# token风格 # token风格
token-style: random-128 # token-style: random-128
# 是否从cookie中读取token # 是否从cookie中读取token
is-read-cookie: false is-read-cookie: false
# 是否从请求体里读取token # 是否从请求体里读取token
is-read-body: false is-read-body: false
# 是否从head中读取token # 是否从head中读取token
is-read-head: true # is-read-head: true
# 是否输出操作日志 # 是否输出操作日志
is-log: true is-log: true
# 是否在初始化配置时打印版本字符画 # 是否在初始化配置时打印版本字符画

@ -7,6 +7,8 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import java.util.List;
/** /**
* <p> * <p>
* 用户token信息 * 用户token信息
@ -22,15 +24,18 @@ import lombok.experimental.SuperBuilder;
@AllArgsConstructor @AllArgsConstructor
public class JwtUserBO extends BaseBO { public class JwtUserBO extends BaseBO {
@ApiModelProperty(value = "认证来源") @ApiModelProperty("认证来源")
private AuthSourceEnum authSourceEnum; private AuthSourceEnum authSourceEnum;
@ApiModelProperty(value = "用户ID") @ApiModelProperty("用户ID")
private String userId; private String userId;
@ApiModelProperty(value = "用户名") @ApiModelProperty("用户名")
private String userName; private String userName;
@ApiModelProperty("角色编码")
private List<String> roleCodeList;
/** /**
* 获取B端用户ID * 获取B端用户ID
*/ */

@ -1,6 +1,6 @@
package com.zhengqing.common.core.config; package com.zhengqing.common.core.config;
import com.zhengqing.common.core.config.interceptor.HandlerInterceptorForTokenUser; import com.zhengqing.common.core.config.interceptor.HandlerInterceptorForToken;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -20,7 +20,7 @@ public class WebAppConfig implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
// 可添加多个 // 可添加多个
registry.addInterceptor(new HandlerInterceptorForTokenUser()).addPathPatterns("/**"); registry.addInterceptor(new HandlerInterceptorForToken()).addPathPatterns("/**");
} }
} }

@ -1,19 +1,29 @@
package com.zhengqing.common.core.config.interceptor; package com.zhengqing.common.core.config.interceptor;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.zhengqing.common.base.constant.AppConstant; import com.zhengqing.common.base.constant.AppConstant;
import com.zhengqing.common.base.constant.SecurityConstant;
import com.zhengqing.common.base.context.JwtUserContext; import com.zhengqing.common.base.context.JwtUserContext;
import com.zhengqing.common.base.context.SysUserContext; import com.zhengqing.common.base.context.SysUserContext;
import com.zhengqing.common.base.context.UmsUserContext; import com.zhengqing.common.base.context.UmsUserContext;
import com.zhengqing.common.base.enums.ApiResultCodeEnum;
import com.zhengqing.common.base.exception.MyException;
import com.zhengqing.common.base.model.bo.JwtUserBO; import com.zhengqing.common.base.model.bo.JwtUserBO;
import com.zhengqing.common.core.config.WebAppConfig; import com.zhengqing.common.core.config.WebAppConfig;
import com.zhengqing.common.redis.util.RedisUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/** /**
* <p> 拦截器 -- token用户信息 </p> * <p> 拦截器 -- token用户信息 </p>
@ -22,7 +32,7 @@ import javax.servlet.http.HttpServletResponse;
* @description 注册使用参考 {@link WebAppConfig} * @description 注册使用参考 {@link WebAppConfig}
* @date 2022/1/10 16:28 * @date 2022/1/10 16:28
*/ */
public class HandlerInterceptorForTokenUser implements HandlerInterceptor { public class HandlerInterceptorForToken implements HandlerInterceptor {
/** /**
* 在业务处理器处理请求之前被调用预处理可以进行编码安全控制权限校验等处理 * 在业务处理器处理请求之前被调用预处理可以进行编码安全控制权限校验等处理
@ -35,6 +45,10 @@ public class HandlerInterceptorForTokenUser implements HandlerInterceptor {
return true; return true;
} }
JwtUserBO jwtUserBO = JSONUtil.toBean(StpUtil.getLoginId().toString(), JwtUserBO.class); JwtUserBO jwtUserBO = JSONUtil.toBean(StpUtil.getLoginId().toString(), JwtUserBO.class);
// 校验权限
this.checkPermission(request, jwtUserBO);
JwtUserContext.set(jwtUserBO); JwtUserContext.set(jwtUserBO);
switch (jwtUserBO.getAuthSourceEnum()) { switch (jwtUserBO.getAuthSourceEnum()) {
case B: case B:
@ -51,6 +65,57 @@ public class HandlerInterceptorForTokenUser implements HandlerInterceptor {
return true; return true;
} }
/**
* 校验权限
*
* @param request 请求
* @param jwtUserBO 用户信息
* @return void
* @author zhengqingya
* @date 2023/2/13 15:52
*/
private void checkPermission(HttpServletRequest request, JwtUserBO jwtUserBO) {
String method = request.getMethod();
String path = request.getRequestURI();
// "GET:/web/api/user/*"
String restfulPath = method + ":" + path;
/**
* URL鉴权
* [URL-角色集合]
* [{'key':'GET:/web/api/user/*','value':['ADMIN','TEST']},...]
*/
Map<Object, Object> urlPermReRoleMap = RedisUtil.hGetAll(SecurityConstant.URL_PERM_RE_ROLES);
// 根据请求路径获取有访问权限的角色列表
List<String> authorizedRoleList = Lists.newLinkedList();
// 是否需要鉴权,默认未设置拦截规则不需鉴权
boolean isCheck = false;
PathMatcher pathMatcher = new AntPathMatcher();
for (Map.Entry<Object, Object> permRoles : urlPermReRoleMap.entrySet()) {
String perm = (String) permRoles.getKey();
if (pathMatcher.match(perm, restfulPath)) {
List<String> roleCodeList = JSONUtil.toList((String) permRoles.getValue(), String.class);
authorizedRoleList.addAll(roleCodeList);
isCheck = true;
}
}
if (!isCheck) {
return;
}
if (CollectionUtil.isNotEmpty(authorizedRoleList)) {
List<String> roleCodeList = jwtUserBO.getRoleCodeList();
for (String roleCodeItem : roleCodeList) {
if (authorizedRoleList.contains(roleCodeItem)) {
return;
}
}
}
throw new MyException(ApiResultCodeEnum.UN_LOGIN.getCode(), "无操作权限");
}
/** /**
* 在业务处理器处理请求执行完成后生成视图之前执行 * 在业务处理器处理请求执行完成后生成视图之前执行
* 后处理调用了Service并返回ModelAndView但未进行页面渲染有机会修改ModelAndView * 后处理调用了Service并返回ModelAndView但未进行页面渲染有机会修改ModelAndView

@ -1,17 +1,17 @@
/* /*
Navicat Premium Data Transfer Navicat Premium Data Transfer
Source Server : 3306 Source Server : localhost_mysql_3306
Source Server Type : MySQL Source Server Type : MySQL
Source Server Version : 50726 Source Server Version : 50726 (5.7.26-log)
Source Host : localhost:3306 Source Host : 127.0.0.1:3306
Source Schema : smallboot Source Schema : smallboot
Target Server Type : MySQL Target Server Type : MySQL
Target Server Version : 50726 Target Server Version : 50726 (5.7.26-log)
File Encoding : 65001 File Encoding : 65001
Date: 10/02/2023 15:08:30 Date: 13/02/2023 18:17:22
*/ */
SET NAMES utf8mb4; SET NAMES utf8mb4;
@ -73,7 +73,7 @@ INSERT INTO `t_sys_dict` VALUES (172, 3, 'element_icon', 'ArrowRight', 'ArrowRig
INSERT INTO `t_sys_dict` VALUES (173, 3, 'element_icon', 'ArrowRightBold', 'ArrowRightBold', 1, 9, '', 1, '2020-08-30 03:16:51', 1, '2022-07-22 09:59:13', 0); INSERT INTO `t_sys_dict` VALUES (173, 3, 'element_icon', 'ArrowRightBold', 'ArrowRightBold', 1, 9, '', 1, '2020-08-30 03:16:51', 1, '2022-07-22 09:59:13', 0);
INSERT INTO `t_sys_dict` VALUES (174, 3, 'element_icon', 'ArrowUp', 'ArrowUp', 1, 10, '', 1, '2020-08-30 03:18:32', 1, '2022-07-22 09:59:19', 0); INSERT INTO `t_sys_dict` VALUES (174, 3, 'element_icon', 'ArrowUp', 'ArrowUp', 1, 10, '', 1, '2020-08-30 03:18:32', 1, '2022-07-22 09:59:19', 0);
INSERT INTO `t_sys_dict` VALUES (180, 1, 'permission_btn', '设计表', 'design_table', 1, 31, NULL, 1, '2020-09-06 19:09:40', 0, '2021-08-28 00:03:02', 0); INSERT INTO `t_sys_dict` VALUES (180, 1, 'permission_btn', '设计表', 'design_table', 1, 31, NULL, 1, '2020-09-06 19:09:40', 0, '2021-08-28 00:03:02', 0);
INSERT INTO `t_sys_dict` VALUES (181, 6, 'oauth_type', 'gitee', '1', 1, 1, NULL, 1, '2020-12-06 13:16:39', 0, '2021-08-28 00:03:02', 0); INSERT INTO `t_sys_dict` VALUES (181, 6, 'oauth_type', 'gitee', '1', 1, 1, '', 1, '2020-12-06 13:16:39', 0, '2023-02-13 11:17:41', 0);
INSERT INTO `t_sys_dict` VALUES (182, 6, 'oauth_type', 'github', '2', 1, 2, NULL, 1, '2020-12-06 13:16:54', 0, '2021-08-28 00:03:02', 0); INSERT INTO `t_sys_dict` VALUES (182, 6, 'oauth_type', 'github', '2', 1, 2, NULL, 1, '2020-12-06 13:16:54', 0, '2021-08-28 00:03:02', 0);
INSERT INTO `t_sys_dict` VALUES (183, 6, 'oauth_type', 'qq', '3', 1, 3, NULL, 1, '2020-12-06 13:17:03', 0, '2021-08-28 00:03:02', 0); INSERT INTO `t_sys_dict` VALUES (183, 6, 'oauth_type', 'qq', '3', 1, 3, NULL, 1, '2020-12-06 13:17:03', 0, '2021-08-28 00:03:02', 0);
INSERT INTO `t_sys_dict` VALUES (184, 3, 'element_icon', 'Monitor', 'Monitor', 1, 11, NULL, 0, '2023-02-01 16:42:06', 0, '2023-02-01 16:42:06', 0); INSERT INTO `t_sys_dict` VALUES (184, 3, 'element_icon', 'Monitor', 'Monitor', 1, 11, NULL, 0, '2023-02-01 16:42:06', 0, '2023-02-01 16:42:06', 0);
@ -143,8 +143,8 @@ INSERT INTO `t_sys_menu` VALUES (5, '角色管理', 'role', NULL, 'role', 2, 3,
INSERT INTO `t_sys_menu` VALUES (6, '角色权限', 'roleForm', NULL, 'roleForm', 2, 8, 'system/role/form', 1, NULL, 1, 0, 1, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0); INSERT INTO `t_sys_menu` VALUES (6, '角色权限', 'roleForm', NULL, 'roleForm', 2, 8, 'system/role/form', 1, NULL, 1, 0, 1, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0);
INSERT INTO `t_sys_menu` VALUES (8, '个人中心', 'personal-center', NULL, 'personal-center', 2, 2, 'system/personal-center/index', 0, NULL, 1, 0, 0, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0); INSERT INTO `t_sys_menu` VALUES (8, '个人中心', 'personal-center', NULL, 'personal-center', 2, 2, 'system/personal-center/index', 0, NULL, 1, 0, 0, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0);
INSERT INTO `t_sys_menu` VALUES (10, '数据字典', 'dict', NULL, 'dict', 2, 10, 'system/dict/index', 0, NULL, 1, 0, 0, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0); INSERT INTO `t_sys_menu` VALUES (10, '数据字典', 'dict', NULL, 'dict', 2, 10, 'system/dict/index', 0, NULL, 1, 0, 0, 1, 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51', 0);
INSERT INTO `t_sys_menu` VALUES (11, '首页', 'dashboard', 'Loading', '/', 0, 0, 'Layout', 0, '/dashboard', 1, 0, 0, 0, 1, '2020-08-22 15:01:51', 0, '2023-02-01 16:39:06', 0); INSERT INTO `t_sys_menu` VALUES (11, '首页', 'dashboard', 'Loading', '/', 0, 0, 'Layout', 0, 'dashboard', 1, 0, 0, 0, 1, '2020-08-22 15:01:51', 0, '2023-02-01 16:39:06', 0);
INSERT INTO `t_sys_menu` VALUES (12, '首页', 'Dashboard', '', '/dashboard', 11, 1, 'dashboard/index', 0, '', 1, 0, 0, 0, 1, '2020-08-22 15:01:51', 1, '2022-07-15 16:53:46', 0); INSERT INTO `t_sys_menu` VALUES (12, '首页', 'Dashboard', '', 'dashboard', 11, 1, 'dashboard/index', 0, '', 1, 0, 0, 0, 1, '2020-08-22 15:01:51', 1, '2022-07-15 16:53:46', 0);
-- ---------------------------- -- ----------------------------
-- Table structure for t_sys_oauth_client -- Table structure for t_sys_oauth_client
@ -192,16 +192,15 @@ CREATE TABLE `t_sys_permission` (
`update_by` int(11) NOT NULL COMMENT '修改人', `update_by` int(11) NOT NULL COMMENT '修改人',
`update_time` datetime NOT NULL COMMENT '修改时间', `update_time` datetime NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统管理-菜单关联权限表' ROW_FORMAT = COMPACT; ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统管理-菜单关联权限表' ROW_FORMAT = COMPACT;
-- ---------------------------- -- ----------------------------
-- Records of t_sys_permission -- Records of t_sys_permission
-- ---------------------------- -- ----------------------------
INSERT INTO `t_sys_permission` VALUES (1, '查看用户', 4, 78, 'sys:user:view', 'GET:/web/api/user/*', 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51'); INSERT INTO `t_sys_permission` VALUES (1, '查看用户分页列表', 4, 78, 'sys:user:list:page', 'GET:/web/api/system/user/listPage', 1, '2020-08-22 15:01:51', 1, '2023-02-13 16:54:33');
INSERT INTO `t_sys_permission` VALUES (2, '编辑用户', 4, 75, 'sys:user:edit', 'PUT:/web/api/user/*', 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51'); INSERT INTO `t_sys_permission` VALUES (2, '编辑用户', 4, 75, 'sys:user:edit', 'PUT:/web/api/system/user', 1, '2020-08-22 15:01:51', 1, '2023-02-13 16:51:45');
INSERT INTO `t_sys_permission` VALUES (3, '新增用户', 4, 76, 'sys:user:add', 'POST:/web/api/user', 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51'); INSERT INTO `t_sys_permission` VALUES (3, '新增用户', 4, 76, 'sys:user:add', 'POST:/web/api/system/user', 1, '2020-08-22 15:01:51', 1, '2023-02-13 16:13:06');
INSERT INTO `t_sys_permission` VALUES (4, '删除用户', 4, 77, 'sys:user:delete', 'DELETE:/web/api/user/*', 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51'); INSERT INTO `t_sys_permission` VALUES (4, '删除用户', 4, 77, 'sys:user:delete', 'DELETE:/web/api/system/user', 1, '2020-08-22 15:01:51', 1, '2023-02-13 16:13:16');
INSERT INTO `t_sys_permission` VALUES (5, 'demo测试', 4, 77, 'sys:demo:test', 'GET:/demo/web/api/demo/demo/*', 1, '2020-08-22 15:01:51', 1, '2020-08-22 15:01:51');
-- ---------------------------- -- ----------------------------
-- Table structure for t_sys_property -- Table structure for t_sys_property
@ -262,28 +261,18 @@ CREATE TABLE `t_sys_role_menu` (
`update_by` int(11) NOT NULL COMMENT '修改人', `update_by` int(11) NOT NULL COMMENT '修改人',
`update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 141 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统管理-角色菜单关联表' ROW_FORMAT = COMPACT; ) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统管理-角色菜单关联表' ROW_FORMAT = COMPACT;
-- ---------------------------- -- ----------------------------
-- Records of t_sys_role_menu -- Records of t_sys_role_menu
-- ---------------------------- -- ----------------------------
INSERT INTO `t_sys_role_menu` VALUES (124, 1, 11, 0, '2023-02-01 16:39:27', 0, '2023-02-01 16:39:27'); INSERT INTO `t_sys_role_menu` VALUES (141, 9, 2, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (125, 1, 12, 0, '2023-02-01 16:39:27', 0, '2023-02-01 16:39:27'); INSERT INTO `t_sys_role_menu` VALUES (142, 9, 4, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (126, 1, 27, 0, '2023-02-01 16:39:27', 0, '2023-02-01 16:39:27'); INSERT INTO `t_sys_role_menu` VALUES (143, 9, 8, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (127, 1, 41, 0, '2023-02-01 16:39:27', 0, '2023-02-01 16:39:27'); INSERT INTO `t_sys_role_menu` VALUES (144, 9, 5, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (128, 1, 42, 0, '2023-02-01 16:39:27', 0, '2023-02-01 16:39:27'); INSERT INTO `t_sys_role_menu` VALUES (145, 9, 6, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (129, 9, 11, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32'); INSERT INTO `t_sys_role_menu` VALUES (146, 9, 3, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (130, 9, 12, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32'); INSERT INTO `t_sys_role_menu` VALUES (147, 9, 10, 1, '2023-02-13 18:05:59', 1, '2023-02-13 18:05:59');
INSERT INTO `t_sys_role_menu` VALUES (131, 9, 2, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (132, 9, 4, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (133, 9, 8, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (134, 9, 5, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (135, 9, 6, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (136, 9, 3, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (137, 9, 10, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (138, 9, 27, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (139, 9, 41, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
INSERT INTO `t_sys_role_menu` VALUES (140, 9, 42, 0, '2023-02-01 16:39:32', 0, '2023-02-01 16:39:32');
-- ---------------------------- -- ----------------------------
-- Table structure for t_sys_role_permission -- Table structure for t_sys_role_permission
@ -339,7 +328,7 @@ CREATE TABLE `t_sys_user` (
-- Records of t_sys_user -- Records of t_sys_user
-- ---------------------------- -- ----------------------------
INSERT INTO `t_sys_user` VALUES (1, 'admin', '3014dcb9ee3639535d5d9301b32c840c', '郑清', 1, '15188888888', 'zhengqingya@it.com', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80', 1, '2020-08-22 15:01:51', 0, '2023-02-10 14:30:54', 0); INSERT INTO `t_sys_user` VALUES (1, 'admin', '3014dcb9ee3639535d5d9301b32c840c', '郑清', 1, '15188888888', 'zhengqingya@it.com', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80', 1, '2020-08-22 15:01:51', 0, '2023-02-10 14:30:54', 0);
INSERT INTO `t_sys_user` VALUES (2, 'test', '3014dcb9ee3639535d5d9301b32c840c', '测试号', 1, '', '', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80', 1, '2020-08-22 15:01:51', 0, '2023-02-10 15:04:56', 0); INSERT INTO `t_sys_user` VALUES (2, 'test', '3014dcb9ee3639535d5d9301b32c840c', '测试号', 1, '', '', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80', 1, '2020-08-22 15:01:51', 1, '2023-02-13 11:56:39', 0);
-- ---------------------------- -- ----------------------------
-- Table structure for t_sys_user_re_oauth -- Table structure for t_sys_user_re_oauth

@ -9,14 +9,15 @@ import com.zhengqing.system.model.dto.SysMenuSaveDTO;
import com.zhengqing.system.model.vo.SysMenuReBtnPermListVO; import com.zhengqing.system.model.vo.SysMenuReBtnPermListVO;
import com.zhengqing.system.model.vo.SysMenuTreeVO; import com.zhengqing.system.model.vo.SysMenuTreeVO;
import com.zhengqing.system.service.ISysMenuService; import com.zhengqing.system.service.ISysMenuService;
import com.zhengqing.system.service.ISysPermissionBusinessService;
import com.zhengqing.system.service.ISysPermissionService; import com.zhengqing.system.service.ISysPermissionService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List; import java.util.List;
/** /**
@ -30,15 +31,16 @@ import java.util.List;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequiredArgsConstructor
@RequestMapping(ServiceConstant.SERVICE_API_PREFIX_WEB_SYSTEM + "/menu") @RequestMapping(ServiceConstant.SERVICE_API_PREFIX_WEB_SYSTEM + "/menu")
@Api(tags = "系统管理 - 菜单表接口") @Api(tags = "系统管理 - 菜单表接口")
public class SysMenuController extends BaseController { public class SysMenuController extends BaseController {
@Resource private final ISysMenuService menuService;
private ISysMenuService menuService;
@Resource private final ISysPermissionService sysPermissionService;
private ISysPermissionService sysPermissionService;
private final ISysPermissionBusinessService sysPermissionBusinessService;
// @GetMapping("/listPage") // @GetMapping("/listPage")
// @ApiOperation("列表分页") // @ApiOperation("列表分页")
@ -90,6 +92,7 @@ public class SysMenuController extends BaseController {
@ApiOperation("菜单关联按钮权限-删除") @ApiOperation("菜单关联按钮权限-删除")
public void deleteMenuReBtnPerm(@RequestParam Integer id) { public void deleteMenuReBtnPerm(@RequestParam Integer id) {
this.sysPermissionService.removeById(id); this.sysPermissionService.removeById(id);
this.sysPermissionBusinessService.refreshRedisPerm();
} }
@NoRepeatSubmit @NoRepeatSubmit
@ -98,6 +101,7 @@ public class SysMenuController extends BaseController {
public void addMenuReBtnPerm(@Validated @RequestBody SysMenuReBtnPermSaveDTO params) { public void addMenuReBtnPerm(@Validated @RequestBody SysMenuReBtnPermSaveDTO params) {
params.setId(null); params.setId(null);
this.sysPermissionService.addOrUpdateData(params); this.sysPermissionService.addOrUpdateData(params);
this.sysPermissionBusinessService.refreshRedisPerm();
} }
@NoRepeatSubmit @NoRepeatSubmit
@ -105,6 +109,7 @@ public class SysMenuController extends BaseController {
@ApiOperation("菜单关联按钮权限-更新") @ApiOperation("菜单关联按钮权限-更新")
public void updateMenuReBtnPerm(@Validated(UpdateGroup.class) @RequestBody SysMenuReBtnPermSaveDTO params) { public void updateMenuReBtnPerm(@Validated(UpdateGroup.class) @RequestBody SysMenuReBtnPermSaveDTO params) {
this.sysPermissionService.addOrUpdateData(params); this.sysPermissionService.addOrUpdateData(params);
this.sysPermissionBusinessService.refreshRedisPerm();
} }
} }

@ -8,7 +8,8 @@ import com.zhengqing.common.auth.model.vo.AuthLoginVO;
import com.zhengqing.common.auth.service.IAuthService; import com.zhengqing.common.auth.service.IAuthService;
import com.zhengqing.common.base.enums.AuthSourceEnum; import com.zhengqing.common.base.enums.AuthSourceEnum;
import com.zhengqing.common.base.model.bo.JwtUserBO; import com.zhengqing.common.base.model.bo.JwtUserBO;
import com.zhengqing.system.entity.SysUser; import com.zhengqing.system.model.dto.SysUserPermDTO;
import com.zhengqing.system.model.vo.SysUserPermVO;
import com.zhengqing.system.service.ISysUserService; import com.zhengqing.system.service.ISysUserService;
import com.zhengqing.system.util.PasswordUtil; import com.zhengqing.system.util.PasswordUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -36,9 +37,8 @@ public class AuthServiceImpl implements IAuthService {
String username = params.getUsername(); String username = params.getUsername();
String password = params.getPassword(); String password = params.getPassword();
SysUser sysUser = this.sysUserService.getUserByUsername(username); SysUserPermVO userPerm = this.sysUserService.getUserPerm(SysUserPermDTO.builder().username(username).build());
Assert.notNull(sysUser, "账号不存在!"); boolean isValid = PasswordUtil.isValidPassword(password, userPerm.getPassword());
boolean isValid = PasswordUtil.isValidPassword(password, sysUser.getPassword());
// 校验原始密码是否正确 // 校验原始密码是否正确
Assert.isTrue(isValid, "密码错误!"); Assert.isTrue(isValid, "密码错误!");
@ -47,8 +47,9 @@ public class AuthServiceImpl implements IAuthService {
StpUtil.login(JSONUtil.toJsonStr( StpUtil.login(JSONUtil.toJsonStr(
JwtUserBO.builder() JwtUserBO.builder()
.authSourceEnum(AuthSourceEnum.B) .authSourceEnum(AuthSourceEnum.B)
.userId(String.valueOf(sysUser.getUserId())) .userId(String.valueOf(userPerm.getUserId()))
.userName(sysUser.getUsername()) .userName(userPerm.getUsername())
.roleCodeList(userPerm.getRoleCodeList())
.build() .build()
)); ));
return AuthLoginVO.builder() return AuthLoginVO.builder()

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

@ -6,8 +6,9 @@ import 'nprogress/nprogress.css'
NProgress.configure({ showSpinner: false }) // 进度环显示/隐藏 NProgress.configure({ showSpinner: false }) // 进度环显示/隐藏
// 白名单路由 // 白名单路由
const whiteList = ['/login', '/auth-redirect', '/bus/model/detail'] const whiteList = ['/login', '/auth-redirect']
// 全局守卫
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
NProgress.start() NProgress.start()
const { user, permission } = useStore() const { user, permission } = useStore()
@ -31,7 +32,7 @@ router.beforeEach(async (to, from, next) => {
const roleNames = user.roleNames const roleNames = user.roleNames
const accessRoutes: any = await permission.generateRoutes(roleNames) const accessRoutes: any = await permission.generateRoutes(roleNames)
accessRoutes.forEach((route: any) => { accessRoutes.forEach((route: any) => {
router.addRoute(route) router.addRoute(route) // 动态添加可访问路由表
}) })
next({ ...to, replace: true }) next({ ...to, replace: true })
} catch (error) { } catch (error) {

@ -1,8 +1,23 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import useStore from '@/store' import useStore from '@/store'
export const Layout = () => import('@/layout/index.vue');
// 静态路由 // 静态路由
export const constantRoutes: Array<RouteRecordRaw> = [ export const constantRoutes: Array<RouteRecordRaw> = [
{
path: '/',
component: Layout,
redirect: 'dashboard',
children: [
{
path: 'dashboard',
component: () => import('@/views/dashboard/index.vue'),
name: 'Dashboard',
meta: { title: '首页', icon: 'House', affix: true }
}
]
},
{ {
path: '/login', path: '/login',
component: () => import('@/views/login/index.vue'), component: () => import('@/views/login/index.vue'),
@ -12,7 +27,8 @@ export const constantRoutes: Array<RouteRecordRaw> = [
component: () => import('@/views/test/index.vue'), component: () => import('@/views/test/index.vue'),
}, },
{ {
path: '/404', // path: '/404',
path: '/:pathMatch(.*)*', // 防止浏览器刷新时路由未找到警告提示: vue-router.mjs:35 [Vue Router warn]: No match found for location with path "/xxx"
component: () => import('@/views/error-page/404.vue'), component: () => import('@/views/error-page/404.vue'),
}, },
{ {

@ -1,4 +1,30 @@
\
<template> <template>
<h1>401</h1> <base-wraper class="container">
<div>
<h1 class="text-jumbo text-ginormous">401错误!</h1>
<h1>对不起您没有访问权限请不要进行非法操作</h1>
<h1>您可以返回 <router-link to="/" class="index"> 首页 </router-link></h1>
</div>
</base-wraper>
</template> </template>
<script>
export default {
name: 'Page401',
data() {
return {}
},
methods: {},
}
</script>
<style lang="scss" scoped>
.container {
display: flex;
justify-content: center;
align-items: center;
.index {
color: blue;
}
}
</style>

@ -1,3 +1,228 @@
<template> <template>
<h1>404</h1> <div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" />
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" />
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" />
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" />
</div>
<div class="bullshit">
<div class="bullshit__oops">404错误!</div>
<div class="bullshit__headline">
{{ message }}
</div>
<div class="bullshit__info">
对不起您正在寻找的页面不存在尝试检查URL的错误然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容
</div>
<router-link to="/" class="bullshit__return-home"> 返回首页 </router-link>
</div>
</div>
</div>
</template> </template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return '找不到网页!'
},
},
}
</script>
<style lang="scss" scoped>
.wscn-http404-container {
transform: translate(-50%, -50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

@ -99,5 +99,4 @@ async function deleteData(id: number) {
refreshTableData() refreshTableData()
} }
</script> </script>
<style scoped> <style scoped></style>
</style>

Loading…
Cancel
Save