018-从零搭建微服务-系统服务(五)
写在最前
如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。
源码地址(后端):https://gitee.com/csps/mingyue
源码地址(前端):https://gitee.com/csps/mingyue-ui
文档地址:https://gitee.com/csps/mingyue/wikis
前情回顾
之前我们设计了权限模型并提交了数据库脚本,然后通过 mingyue-common-gen
模块 MingYueCommonGenDemo
生成了基础代码,接下来我们需要提供两个关键接口:
- 获取用户权限信息;
- 获取用户路由信息;
TIPS
为了严格按照 RESTful 接口风格设计,变更现有接口命名: getSysUserInfoByUsername => userInfo
、getSysUsers => list
,后续接口也将严格按照 RESTful 接口风格设计。
登录缓存用户信息
Session 会话
Session 是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能,例如:
// 在登录时缓存 user 对象
StpUtil.getSession().set("user", user);// 然后我们就可以在任意处使用这个 user 对象
SysUser user = (SysUser) StpUtil.getSession().get("user");
在 Sa-Token 中,Session 分为三种,分别是:
Account-Session
: 指的是框架为每个账号 id 分配的 SessionToken-Session
: 指的是框架为每个 token 分配的 SessionCustom-Session
: 指的是以一个特定的值作为 SessionId,来分配的 Session
Token-Session
缓存用户信息
public static void login(SysUser userInfo) {// 请求作用域:存储的数据只在一次请求内有效,请求结束后数据自动清除。SaStorage storage = SaHolder.getStorage();storage.set(LOGIN_USER_KEY, userInfo);storage.set(USER_KEY, userInfo.getUserId());// 第1步,先登录上StpUtil.login(userInfo.getUserId());// 第3步,缓存用户信息StpUtil.getTokenSession().set(LOGIN_USER_KEY, userInfo);
}
获取用户信息
public static SysUser getLoginUser() {SysUser loginUser = (SysUser) SaHolder.getStorage().get(LOGIN_USER_KEY);if (loginUser != null) {return loginUser;}loginUser = (SysUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);return loginUser;
}
接口测试
@GetMapping("info")
@Operation(summary = "获取当前用户全部信息")
public R<SysUser> userInfo() {SysUser sysUser = LoginHelper.getLoginUser();System.out.println("=============================");System.out.println(JSONUtil.toJsonStr(sysUser));System.out.println("=============================");return R.ok(null);
}
接口调用打印如下:
=============================
{"userId":1,"username":"mingyue","nickname":"明月","sex":"0","password":"123456","phone":"13288888888","status":"0","isDeleted":"0","createTime":1689757582000,"updateTime":1689757585000,"createBy":"mingyue","updateBy":"mingyue"}
=============================
获取用户权限信息
接口层
@GetMapping("info")
@Operation(summary = "获取当前登录用户全部信息")
public R<UserInfoVo> userInfo() {return R.ok(sysUserService.getUserInfo());
}
业务层
@Override
public UserInfoVo getUserInfo() {UserInfoVo result = new UserInfoVo();SysUser sysUser = LoginHelper.getLoginUser();// 密码置空sysUser.setPassword(null);result.setSysUser(sysUser);// 设置角色列表Set<String> rolePermission = sysRoleService.getRolePermission(sysUser.getUserId());result.setRoles(rolePermission);// 设置权限列表Set<String> menuPermission = sysMenuService.getMenuPermission(sysUser.getUserId());result.setRoles(menuPermission);return result;
}
测试接口
Authorization Token 通过登录接口获取
curl -X 'GET' \
'http://mingyue-gateway:9100/system/sysUser/info' \
-H 'accept: */*' \
-H 'Authorization: vXPJnADIcTPfKuP3reBYmmUAi4xjw8nf'
接口返回
{"code": 200,"msg": "操作成功","data": {"sysUser": {"userId": 1,"username": "mingyue","nickname": "明月","sex": "0","password": null,"phone": "13288888888","email": null,"avatar": null,"status": "0","isDeleted": "0","createTime": "2023-07-19T17:06:22","updateTime": "2023-07-19T17:06:25","createBy": "mingyue","updateBy": "mingyue"},"permissions": null,"roles": [null,"system:user:list"]}
}
获取用户路由信息
接口层
@GetMapping("getRouters")
@Operation(summary = "获取路由信息")
public R<List<RouterVo>> getRouters() {Long userId = LoginHelper.getLoginUser().getUserId();return R.ok(sysMenuService.getRouters(userId));
}
业务层
@Override
public List<RouterVo> getRouters(Long userId) {List<SysMenu> sysMenus = sysMenuMapper.selectMenuTreeByUserId(userId);return this.recursionMenu(sysMenus, -1L);
}/*** 递归菜单,构建菜单树*/
private List<RouterVo> recursionMenu(List<SysMenu> sysMenus, Long pid) {List<RouterVo> tree = CollUtil.newArrayList();for (SysMenu menu : sysMenus) {if (menu.getParentId().equals(pid)) {RouterVo router = new RouterVo();router.setPath("/" + menu.getPath());router.setName(menu.getPath());router.setComponent(menu.getComponent());router.setRedirect(menu.getRedirect());MetaVo metaVo = new MetaVo();metaVo.setTitle(menu.getMenuName());metaVo.setIsLink(menu.getIsLink());metaVo.setIsHide(UserConstants.IS_HIDE.equals(menu.getIsHide()));metaVo.setIsKeepAlive(UserConstants.IS_KEEP_ALIVE.equals(menu.getIsKeepAlive()));metaVo.setIsAffix(UserConstants.IS_AFFIX.equals(menu.getIsAffix()));metaVo.setIsIframe(UserConstants.IS_IFRAME.equals(menu.getIsIframe()));metaVo.setIcon(menu.getIcon());router.setMeta(metaVo);router.setChildren(recursionMenu(sysMenus, menu.getMenuId()));tree.add(router);}}return tree;
}
测试接口
curl -X 'GET' \
'http://mingyue-gateway:9100/system/sysMenu/getRouters' \
-H 'accept: */*'
-H 'Authorization: vXPJnADIcTPfKuP3reBYmmUAi4xjw8nf'
接口返回
{"code": 200,"msg": "操作成功","data": [{"path": "/system","name": "system","component": null,"redirect": null,"meta": {"title": "系统管理","isLink": "0","isHide": false,"isKeepAlive": false,"isAffix": false,"isIframe": false,"icon": "iconfont icon-xitongshezhi"},"children": [{"path": "/user","name": "user","component": "/system/user","redirect": null,"meta": {"title": "用户管理","isLink": "0","isHide": false,"isKeepAlive": false,"isAffix": false,"isIframe": false,"icon": "iconfont icon-icon-"},"children": []},...]}]
}
小结
现在用户已经拿到权限点了,接下来整合一下权限点与 Sa-Token 的使用,看看 Sa-Token 如何通过权限点控制接口访问。
相关文章:
018-从零搭建微服务-系统服务(五)
写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):https://gitee.com/csps/mingyue 源码地址(前端):https://gitee.com/csps…...

HarmonyOS 开发基础(三)登录页面单向数据绑定(父组件向子组件传参)
一、目录结构认识 开发软件目录截图部分文件夹说明 文件组织结构图 二、完成单向数据绑定 index.etx // 导出方式直接从文件夹 import MyInput from "../common/commons/myInput" Entry Component /* 组件可以基于struct实现,组件不能有继承关系&am…...

发npm包
重点文件 .github -> workflow -> .yml文件 发自己的包 新建dev分支,合并到master后自动执行 fork别人的包 fork -> base dev新建本地rebase-dev分支 -> 提交push后合并至dev -> dev合并至master后自动执行 值得注意的是,fork别人的…...
<el-empty>
<el-empty> 是 Element UI 框架中提供的一个组件,用于显示空状态的占位内容。Element UI 是一套基于 Vue.js 的组件库,用于构建响应式和易用的用户界面。 <el-empty> 组件在应用中常用于以下场景: 当数据为空时,可以…...

IO流(4)- 序列化流与反序列化流
目录 1. 序列化流与反序列化流的基本介绍 2. 序列化流的基本用法? 3. 序列化流的作用? 4. 反序列化流的基本用法? 5. 反序列化流的作用 6. 序列化流与反序列化流使用时需要注意的细节(非常重要) 6.1 被序列化的…...
人工智能如何应对 DevOps 监控和可观测性挑战
自 ChatGPT 横空出世之后,AIGC 已成为不可逆转的时代浪潮。在之前的文章中,我们介绍了DevOps 领域中AI的用例,需要回顾可以点击下方链接。在本篇文章中,我将简单聊聊人工智能(AI)如何通过分析日志和指标来预…...

数字化新时代,VR全景拍摄与制作
导语: 随着科技的飞速发展,数字化图片正在引领新的时代潮流。在这个数字化图片的新时代,VR全景拍摄与制作技术正以其独特的特点和无限的优势,成为数字影像领域的一颗璀璨明星。让我们深入了解VR全景拍摄与制作的特点和优势&#…...
uniapp 权限说明
android.permission.ACCESS_CHECKIN_PROPERTIES 访问登记属性 读取或写入登记check-in数据库属性表的权限 android.permission.ACCESS_COARSE_LOCATION 获取错略位置 通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米 android.permission.ACCESS…...

3D Web轻量化渲染开发工具HOOPS Communicator是什么?
HOOPS Communicator是Tech Soft 3D旗下的主流产品之一,具有强大的、专用的高性能图形内核,是一款专注于基于Web端的高级3D工程应用程序。由HOOPS Server和HOOPS Web Viewer两大部分组成,提供了HOOPS Convertrer、Data Authoring的模型转换和编…...

心法利器[93] | 谈校招:技术面
心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会,与大家一起成长。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。 2022年新一版的文章合集已经发布,累计已经60w字了,获取方式看这里&…...

excel英语翻译让你的数据更容易被理解
从前有一个名叫小明的办公室职员,他每天都要处理大量的数据和报表。然而,由于工作需要,他经常收到来自不同国家的Excel表格,这些表格上的内容都是用各种各样的语言编写的,让他很难理解其中的意思。这时,小明…...
RK3588S之CPU--benchmark(二)
目录 一、引言 二、benchmark测试工具 ------>2.1、Geekbench ------------>2.1.1、下载移植 ------------>2.1.2、跑分结果 ------------>2.1.3、跑分榜 ------>2.2、Spec06 ------------>2.2.1、spec06介绍 ------------>2.2.2、下载移植(包含…...
入侵检查基础
一、结合以下问题对当天内容进行总结 1. 什么是IDS? 2. IDS和防火墙有什么不同? 3. IDS工作原理? 4. IDS的主要检测方法有哪些详细说明? 5. IDS的部署方式有哪些? 6. IDS的签名是什么意思?签名过滤器有什么…...

JAVA开发工具-maven的安装与配置(最新最详细教程)
引言 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具 软件。 Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较 高的可重用性,所以常常用两…...

linux系统编程重点复习--进程的控制
目录 1 复习目标 2 进程相关概念 2.2 并行和并发 2.3 PCB-进程控制块 2.4 进程状态(面试考) 3 创建进程 3.2 ps命令和kill命令 3.3 getpid/getppid 3.4 练习题 4 exec函数族 4.1 函数作用和函数介绍 4.1.1 execl函数 4.1.2 execlp函数 4.2 exec函数族原理介绍 4.3 …...

12-1_Qt 5.9 C++开发指南_自定义插件和库-自定义Widget组件(提升法(promotion)创建自定义定制化组件)
当UI设计器提供的界面组件不满足实际设计需求时,可以从 QWidget 继承自定义界面组件。 有两种方法使用自定义界面组件: 一种是提升法(promotion),例如在8.3 节将一个QGraphicsView组件提升为自定义的 QWGraphicsView 类,提升法用…...

【软件测试学习】—软件测试的基本认识(一)
【软件测试学习】—软件测试的基本认识(一) 文章目录 【软件测试学习】—软件测试的基本认识(一)一、什么是软件测试二、软件测试的目的三、测试的原则四、测试的标准五、测试的基本要求六、bug的由来七、测试的流程八、开发模式九…...
Unity AI项目笔记
一、创建虚拟环境 在开始进行Unity AI项目之前,首先需要设置一个适当的虚拟环境。以下步骤将会指导你如何创建: 下载Python 3.7。下载Anaconda 2020.11。可以在清华大学开源软件镜像站找到镜像资源:https://mirrors.tuna.tsinghua.edu.cn/a…...

如何在地图上寻找峨眉山零公里的龙洞湖
爬峨眉山的需要,住在零公里附近。 据说这附近有个好玩的地方叫龙洞湖,我们住得远,想步行去看看。拿出地图,搜龙洞湖,尴尬了。搜不到具体位置。细想,人家整个村就叫龙洞村,地图上居然没有标识&a…...

cloudstack平台host加入后,显示CPU speed为0GHz
一、环境说明 操作系统:openEuler 22.03CPU:Kunpeng-920,arm v8cloudstack:4.18libvirtd:6.2.0 二、问题描述 cloudstack平台初始化完成后,第一次加入host,系统虚拟机一直无法正常创建&#…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...