权限控制导入到项目中
在项目中应用
进行认证和授权需要前面课程中提到的权限模型涉及的7张表支撑,因为用户信息、权限信息、菜单信息、角色信息、关联信息等都保存在这7张表中,也就是这些表中的数据是进行认证和授权的依据。所以在真正进行认证和授权之前需要对这些数据进行管理,即需要开发如下一些功能:
1、权限数据管理(增删改查)
2、菜单数据管理(增删改查)
3、角色数据管理(增删改查、角色关联权限、角色关联菜单)
4、用户数据管理(增删改查、用户关联角色)
导入Spring Security环境
第一步:在health_parent父工程的pom.xml中导入Spring Security的maven坐标
第二步:在health_backend工程的web.xml文件中配置用于整合Spring Security框架的过滤器DelegatingFilterProxy
实现认证和授权
第一步:在health_backend工程中按照Spring Security框架要求提供SpringSecurityUserService,并且实现UserDetailsService接口
第二步:创建UserService服务接口、服务实现类、Dao接口、Mapper映射文件等
第三步:修改health_backend工程中的springmvc.xml文件,修改dubbo批量扫描的包路径
第四步:在health_backend工程中提供spring-security.xml配置文件
第五步:在springmvc.xml文件中引入spring-security.xml文件

<!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问--><security:frame-options policy="SAMEORIGIN"></security:frame-options>
显示用户名
第一步:在main.html页面中修改,定义username模型数据基于VUE的数据绑定展示用户名,发送ajax请求获取username
第二步:创建UserController并提供getUsername方法
注意此处的User对象是使用到框架提供的User对象,框架通过session获得模型数据的信息
@RestController
@RequestMapping("/user")
public class UserController {//获取当前登录用户的用户名@RequestMapping("/getUsername")public Result getUsername()throws Exception{try{org.springframework.security.core.userdetails.User user =(org.springframework.security.core.userdetails.User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();return new Result(true, MessageConstant.GET_USERNAME_SUCCESS,user.getUsername());}catch (Exception e){return new Result(false, MessageConstant.GET_USERNAME_FAIL);}}
}
用户退出
第一步:在main.html中提供的退出菜单上加入超链接
第二步:在spring-security.xml文件中配置
Echarts图表
动态显示图标的x轴为具体的yyyy-MM格式
导入ECharts库
第一步:将echarts.js文件复制到health_backend工程的plugins目录下
第二步:在report_member.html页面引入echarts.js文件
<script src="../plugins/echarts/echarts.js"></script>
参照官方实例导入折线图
<div class="box"><!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --><div id="chart1" style="height:600px;"></div>
</div>
// 基于准备好的dom,初始化echarts实例var myChart1 = echarts.init(document.getElementById('chart1'));//发送ajax请求获取动态数据axios.get("/report/getMemberReport.do").then((res)=>{myChart1.setOption({title: {text: '会员数量'},tooltip: {},legend: {data:['会员数量']},xAxis: {data: res.data.data.months},yAxis: {type:'value'},series: [{name: '会员数量',type: 'line',data: res.data.data.memberCount}]});});
</script>
后台代码
controller
/*** 统计报表*/
@RestController
@RequestMapping("/report")
public class ReportController {@Referenceprivate MemberService memberService;/*** 会员数量统计* @return*/@RequestMapping("/getMemberReport")public Result getMemberReport(){Calendar calendar = Calendar.getInstance();calendar.add(Calendar.MONTH,-12);//获得当前日期之前12个月的日期List<String> list = new ArrayList<>();for(int i=0;i<12;i++){calendar.add(Calendar.MONTH,1);list.add(new SimpleDateFormat("yyyy.MM").format(calendar.getTime()));}Map<String,Object> map = new HashMap<>();map.put("months",list);List<Integer> memberCount = memberService.findMemberCountByMonth(list);map.put("memberCount",memberCount);return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);}
}
注意Mapper文件中的转义字符

在mysql8.0中上述sql查询语句会显示日期出错,更改查询方式
'%Y.%m'不等于'%Y-%m'
图形报表
导入饼形图步骤
1.设置一个div

2.导入官方文档的option
3.明确Contrller响应的数据格式
4.书写controller
//套餐预定占比饼形图@RequestMapping("/getSetmealReport")public Result getSetmealReport(){//模拟数据测试什么样的java对象转为饼形图所需的json数据格式Map<String,Object> data = new HashMap<>();try{List<Map<String,Object>> setmealCount = setmealService.findSetmealCount();data.put("setmealCount",setmealCount);//遍历集合中的map得到名称List<String> setmealNames = new ArrayList<>();for(Map<String,Object> map : setmealCount){String name = (String) map.get("name");//套餐名称setmealNames.add(name);}data.put("setmealNames",setmealNames);return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,data);}catch (Exception e){e.printStackTrace();return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);}}
后续完善service,ServiceImpl,Dao,Mapper文件
POI报表
前端代码
定义模型数据
定义数据模型,通过VUE的数据绑定展示数据

Controller返回的数据格式应该如下
{"data":{"todayVisitsNumber":0,"reportDate":"2019-04-25","todayNewMember":0,"thisWeekVisitsNumber":0,"thisMonthNewMember":2,"thisWeekNewMember":0,"totalMember":10,"thisMonthOrderNumber":2,"thisMonthVisitsNumber":0,"todayOrderNumber":0,"thisWeekOrderNumber":0,"hotSetmeal":[{"proportion":0.4545,"name":"粉红珍爱(女)升级TM12项筛查体检套餐","setmeal_count":5},{"proportion":0.1818,"name":"阳光爸妈升级肿瘤12项筛查体检套餐","setmeal_count":2},{"proportion":0.1818,"name":"珍爱高端升级肿瘤12项筛查","setmeal_count":2},{"proportion":0.0909,"name":"孕前检查套餐","setmeal_count":1}],},"flag":true,"message":"获取运营统计数据成功"
}
在Controller类中调用Service,Service的实现类
public Map<String, Object> getBusinessReportData() throws Exception {//获得当前日期String today = DateUtils.parseDate2String(DateUtils.getToday());//获得本周一的日期String monday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());//获得本月第一天的日期String firstDay4ThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());//本日新增会员数Integer todayNewMember = memberDao.findMemberCountByDate(today);//总会员数Integer totalMember = memberDao.findMemberTotalCount();//本周新增会员数Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(monday);//本月新增会员数Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth);//热门套餐(取前4)List<Map> hotSetmeal = orderDao.findHotSetmeal();//报表产生日期Map<String,Object> result = new HashMap<>();result.put("reportDate",today);result.put("todayNewMember",todayNewMember);result.put("totalMember",totalMember);result.put("thisWeekNewMember",thisWeekNewMember);result.put("thisMonthNewMember",thisMonthNewMember);result.put("hotSetmeal",hotSetmeal);return result;}
补充相关的Dao和Mapper文件
报表导出
上面的Excel效果可以看到,表格比较复杂,涉及到合并单元格、字体、字号、字体加粗、对齐方式等的设置。如果通过POI编程的方式来设置这些效果代码会非常繁琐。
在企业实际开发中,对于这种比较复杂的表格导出一般会提前设计一个Excel模板文件,在这个模板文件中提前将表格的结构和样式设置好,程序只需要读取这个文件并在文件中的相应位置写入具体的值就可以了。

前端代码
<div class="excelTitle" ><el-button @click="exportExcel">导出Excel</el-button>运营数据统计</div>
methods:{exportExcel(){window.location.href = '/report/exportBusinessReport.do';}}
后端代码
try{Map<String,Object> result = reportService.getBusinessReportData();//取出返回结果数据,准备将报表数据写入到Excel文件中String reportDate = (String) result.get("reportDate");Integer todayNewMember = (Integer) result.get("todayNewMember");Integer totalMember = (Integer) result.get("totalMember");Integer thisWeekNewMember = (Integer) result.get("thisWeekNewMember");Integer thisMonthNewMember = (Integer) result.get("thisMonthNewMember");List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal");//获得Excel模板文件绝对路径String filepath = request.getSession().getServletContext().getRealPath("template") + File.separator + "report_template.xlsx";//基于提供的Excel模板文件在内存中创建一个Excel表格对象XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File(filepath)));//读取第一个工作表XSSFSheet sheet = excel.getSheetAt(0);//获得第三行的第六个单元格XSSFRow row = sheet.getRow(2);XSSFCell cell = row.getCell(5);cell.setCellValue(reportDate);//日期在Excel中对应的单元格位置row = sheet.getRow(4);row.getCell(5).setCellValue(todayNewMember);//新增会员数(本日)row.getCell(7).setCellValue(totalMember);//总会员数row = sheet.getRow(5);row.getCell(5).setCellValue(thisWeekNewMember);//本周新增会员数row.getCell(7).setCellValue(thisMonthNewMember);//本月新增会员数int rowNum = 12;for(Map map : hotSetmeal){//热门套餐String name = (String) map.get("name");Long setmeal_count = (Long) map.get("setmeal_count");BigDecimal proportion = (BigDecimal) map.get("proportion");row = sheet.getRow(rowNum ++);row.getCell(4).setCellValue(name);//套餐名称row.getCell(5).setCellValue(setmeal_count);//预约数量row.getCell(6).setCellValue(proportion.doubleValue());//占比}//通过输出流进行文件下载,基于浏览器作为客户端下载ServletOutputStream out = response.getOutputStream();response.setContentType("application/vnd.ms-excel");//代表excel类型,向客户端声明文件类型response.setHeader("content-Disposition", "attachment;filename=report.xlsx");//指定以附件形式下载excel.write(out);out.flush();out.close();excel.close();return null;}catch (Exception e){return new Result(true,MessageConstant.GET_BUSINESS_REPORT_FAIL);}
相关文章:
权限控制导入到项目中
在项目中应用 进行认证和授权需要前面课程中提到的权限模型涉及的7张表支撑,因为用户信息、权限信息、菜单信息、角色信息、关联信息等都保存在这7张表中,也就是这些表中的数据是进行认证和授权的依据。所以在真正进行认证和授权之前需要对这些数据进行…...
CVPR2020:训练多视图三维点云配准
CVPR2020:训练多视图三维点云配准 Learning Multiview 3D Point Cloud Registration 源代码和预训练模型:https://github.com/zgojcic/3D_multiview_reg 论文地址: https://openaccess.thecvf.com/content_CVPR_2020/papers/Gojcic_Learn…...
string容器及其简单使用
string容器 概述声明和初始化获取字符串长度字符串拼接字符串比较字符串插入和删除字符串转换 概述 string是C中的一个标准库容器,用于处理字符串。它提供了一系列的操作函数,使得我们可以像处理其他容器一样方便地处理字符串。下面是string容器的详细介…...
芴甲氧羰酰基-氨基-聚乙二醇-巯基吡啶Fmoc-NH-PEG-OPSS
修饰性PEG芴甲氧羰基-氨基-聚乙二醇-巯基吡啶Fmoc-NH-PEG-OPSS是保护氨基的PEG衍生物之一 结构式: 芴甲氧羰酰基-氨基-聚乙二醇-巯基吡啶Fmoc-NH-PEG-OPSS聚乙二醇化可以提高聚乙二醇分子的稳定性,降低其免疫原性,仅用于科研实验。 FMOC-NH…...
【JavaWeb】Servlet(崔老师版)
文章目录 1.概述1.1 JavaWeb三大组件1.2 Servlet作用 2.ServletConfig接口3.Servlet接口3.1 实现Servlet的方式3.2 Servlet生命周期 4.HttpServlet抽象类5.ServletContext5.1 概述5.2 获取ServletContext5.3 JavaWeb四大域对象5.4 获取应用初始化参数5.5 ServletContext获取资源…...
ITSS服务经理 、服务工程师线上开班在即
为了促进企业信息技术服务-运行维护服务能力,全面系统的提升员工的IT服务知识和技能水平,且更好的满足参训企业的时间需求,我司将于5月份开展ITSS服务经理、服务工程师线上班。 日期和形式 五月份:ITSS服务项目经理:…...
【LeetCode】199.二叉树的右视图
1.问题 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 示例 2: 输入: [1,null,3] 输出: [1,3] 示例 3: 输入: [] 输出: []…...
Shell编程(三)grep sed awk文本处理三剑客
上一章: Shell编程(二)_做测试的喵酱的博客-CSDN博客 一、ps命令 指令: ps作用: 主要是查看服务器的进程信息选项含义: -e:等价于 ‘-A’ ,表示列出全部的进程 -f:显示全部的列&am…...
一步步带你学习Python编程:从零开始的查缺补漏
在快节奏的生活中,很难找到时间来学习新的技能。但有时候,我们会突然发现自己有一些空闲时间,而又不想虚度光阴。无聊的时候,我们可以选择学习一项新技能来充实自己。最近,我就因为有些无聊,决定重新学习Py…...
常见容器的方法
常见容器 向量 (vector)常用方法代码实例 列表 (list)常用方法 集合 (set)常用方法 映射 (map)方法 向量 (vector) 常用方法 vector::push_back(): 将元素插入向量尾部。 vector::pop_back(): 弹出向量尾部的元素。 vector::insert(): 在指定位置插入元素。 vector::erase():…...
【Linux】线程
1.理解地址空间和页表 1.地址空间是进程能够看到的资源窗口 2.页表决定进程真正拥有的资源情况 3.合理的对地址空间和页表进行资源划分就可以对一个进程的所有资源进行划分:过地址空间分为栈区、堆区…通过页表映射到不同的物理内存。 在32位平台下,…...
ASP.NET Core MVC 从入门到精通之wwwroot和客户端库
随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,…...
Oracle OCI 修改 Compute Instance Hostname
Oracle OCI 修改 Compute Instance Hostname Oracle Linux 7 及之后的版本 Oracle Linux 7 及之后的版本 1, Update the /etc/hostname file with below command. hostnamectl set-hostname <new name>2, Edit the oci configuration file for hostnames as given belo…...
垃圾收集算法面试总结
垃圾收集算法 标记 - 清除算法 首先标记出所有需要被回收的对象,标记完后统一回收所有被标记的对象。 后续的收集算法都是基于这种思路并对其不足进行改进而得到的。 这种方法主要有两个缺点: 一个是效率问题,标记和清除两个过程的效率都…...
grep替换指定字符串方法
在 Linux 命令行中,可以使用 grep 命令来查找匹配某个模式的字符串,并将其替换为另一个字符串。具体方法如下: grep -rl <pattern> <directory> | xargs sed -i s/<old_string>/<new_string>/g其中,<…...
主从模式、哨兵模式、集群模式(cluster)
主从模式、哨兵模式、集群模式(cluster) redis 实现高可用的方式分为 主从模式、哨兵模式、集群模式(cluster) 1. 主从模式(又称为主从复制) 表现为1个主节点,多个从节点,主节点负…...
题目3180:蓝桥杯2023年第十四届省赛真题-互质数的个数======及探讨互质专题
原题链接 https://www.dotcpp.com/oj/problem3162.html 想直接看题解的,跳转到第三次尝试即可。 已AC。 解析: (1)首先大家要知道什么叫互质: 以及它们的性质: 欧拉函数 在数论中,对正整…...
Java 文件操作
字符流-Writer和Reader用于读取文本-BufferedReader(new FileReader("path")) 读取文本文件-BufferedWriter(new FileWriter("path")) 写入到文本文件 字节流-InputStream和OutputStream图片、二进制文件-BufferedInputStream(new FileInputStream(new F…...
二叉树OJ题(C++实现)
文章目录 1.二叉树的层序遍历2. 二叉树的最近公共祖先3.二叉搜索树与双向链表4.从前序与中序遍历序列构造二叉树 1.二叉树的层序遍历 二叉树的层序遍历 OJ连接 主要思路是借助一个队列,将每一层的数据以size统计,当size为0时说明该层数据已经输入完&…...
grep -nr 命令查询字符串方式
grep -nr “搜索内容” 文件路径 其中: -n:显示行号-r:递归查找子目录中的文件“搜索内容”:要搜索的内容文件路径:要搜索的文件路径,可以是单个文件或目录路径(将会递归搜索该目录下的所有文…...
如何在macOS上运行Windows应用:Whisky完整使用指南
如何在macOS上运行Windows应用:Whisky完整使用指南 【免费下载链接】Whisky A modern Wine wrapper for macOS built with SwiftUI 项目地址: https://gitcode.com/gh_mirrors/wh/Whisky 想要在Mac上运行Windows专属软件和游戏?厌倦了虚拟机的高资…...
告别硬盘数据丢失焦虑!电脑专属5种恢复方法,无踩坑,速存
日常使用电脑时,文件误删是高频突发状况——辛苦整理的办公文档、珍藏的生活影像、重要的程序安装包,一旦不小心删除,难免让人手足无措。好在2026年,随着数据存储技术的迭代与恢复工具的升级,电脑误删文件的恢复成功率…...
手把手教你用MPU6050和nRF52832做手环计步:避开数据读取卡死的坑
手把手教你用MPU6050和nRF52832实现稳定计步:从硬件调试到算法优化全攻略 在可穿戴设备开发中,计步功能看似基础却暗藏玄机。许多开发者在使用MPU6050加速度传感器搭配nRF52832主控时,都会遇到一个令人头疼的问题——系统运行一段时间后莫名卡…...
Unity实战:利用TriLib插件实现运行时动态加载外部3D模型
1. TriLib插件基础入门 第一次接触TriLib插件时,我也被它强大的功能惊艳到了。这个插件最大的价值在于,它能让我们在Unity运行时动态加载各种主流3D模型格式,比如FBX、OBJ、GLTF等,而不需要提前在编辑器中导入。想象一下ÿ…...
macOS微信防撤回终极指南:3分钟轻松安装WeChatIntercept插件
macOS微信防撤回终极指南:3分钟轻松安装WeChatIntercept插件 【免费下载链接】WeChatIntercept 微信防撤回插件,一键安装,仅MAC可用,支持v3.7.0微信 项目地址: https://gitcode.com/gh_mirrors/we/WeChatIntercept 还在为微…...
工业级RS-485收发器自主设计:从电路原理到PCB布局的实战指南
1. 项目概述与核心价值 在工业自动化、楼宇控制、能源监控这些领域里,设备之间要“说话”,RS-485总线绝对是那个最可靠、最耐用的“方言”。你可能在PLC、变频器、智能电表或者一堆传感器上见过那两个标着A、B的端子,背后驱动它们的ÿ…...
从AwesomeCursorPrompt看提示工程:构建高效AI编程协作工作流
1. 项目概述:从“AwesomeCursorPrompt”看提示工程的演进最近在GitHub上看到一个挺有意思的项目,叫“AwesomeCursorPrompt”。光看名字,可能很多朋友会有点懵——“Cursor”是那个AI代码编辑器,“Prompt”是提示词,那这…...
别再手动输数据了!手把手教你用Fluent的Profile功能导入实验数据(附CSV文件模板)
别再手动输数据了!手把手教你用Fluent的Profile功能导入实验数据(附CSV文件模板) 在计算流体力学(CFD)分析中,准确导入实验数据或第三方软件的计算结果作为边界条件,往往是确保仿真可靠性的关键…...
【SimMechanics实战】从零搭建Matlab机械臂仿真模型:模块详解与坐标系规划
1. SimMechanics入门:为什么选择它做机械臂仿真 第一次接触机械臂仿真时,我试过几种不同的工具,最后发现SimMechanics真是个好帮手。它和Matlab/Simulink无缝集成,数据处理特别方便,不像有些专业仿真软件需要频繁导入导…...
嵌入式系统遥测框架设计:从数据采集到实时可视化的工程实践
1. 项目概述:从“黑盒”到“白盒”的工程实践在嵌入式系统、机器人控制乃至任何涉及复杂硬件交互的软件开发中,我们常常面临一个共同的困境:系统运行起来后,内部到底发生了什么?当电机没有按预期转动,当传感…...
