10.点赞 + 我收到的赞

1.点赞 

  • 点赞:支持对帖子、评论点赞;第1次点赞,第2次取消点赞
  • 首页点赞数量:统计帖子的点赞数量
  • 详情页点赞数量:统计点赞数量、显示点赞状态

1.1 生成 redis 工具类

将数据存入到 redis 中,以 key 为关键,使用 key 编程,所以为了使 key 能反复利用,给 redis 生成一个工具类(在 util 包下创建 RedisKeyUtil 类):

  • 提供静态方法访问即可
  • key 使用 :分开:声明常量
  • 存入帖子或者评论的赞(实体的赞):以某一个前缀开头,声明常量
  • 添加静态方法:传入变量拼接到常量中,得到完整 key(生成某个实体的赞)
  • 传入变量:传入实体类型、id
  • 拼接:like:entity:entityType:entityId -> set(userId)
package com.example.demo.util;/*** 生成 redis 工具*/
public class RedisKeyUtil {//key 使用 :分开:声明常量public static final String SPLIT = ".";//存入帖子或者评论的赞(实体的赞):以某一个前缀开头,声明常量public static final String PREFIX_ENTITY_LIKE = "like:entity";//添加静态方法:传入变量拼接到常量中,得到完整 key(生成某个实体的赞)public static String getEntityLikeKey(int entityType, int entityId) {return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;}
}

1.2 开发点赞业务组件

在 service 包下创建 LikeService 类:

  • 将数据存入 redis 中,注入 RedisTemplate
  • 实现点赞的业务方法:传入参数 userId、entityType、entityId
  • 实现:拼接存储的 key
  • 判断当前用户是否已经点赞(没点赞点赞,点赞了再次点取消):在 redis 存的是一个集合,判断 userId 是否在 redis 中即可 
  • 再添加 查询某实体类点赞的数量 方法:传入 entityType、entityId、判断 key 中有多少个 userId 就是有多少点赞数量
  • 再添加 查询某人对某实体的点赞状态 的方法:传入参数 userId、entityType、entityId
package com.example.demo.service;import com.example.demo.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;/*** 点赞业务组件*/
@Service
public class LikeService {@Autowiredprivate RedisTemplate redisTemplate;//实现点赞的业务方法:传入参数 userId、entityType、entityIdpublic void like(int userId, int entityType, int entityId) {//拼接存储的 keyString entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);//判断当前用户是否已经点赞(没点赞点赞,点赞了再次点取消):在 redis 存的是一个集合,判断 userId 是否在 redis 中即可boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey, userId);if (isMember) {redisTemplate.opsForSet().remove(entityLikeKey, userId);} else {redisTemplate.opsForSet().add(entityLikeKey, userId);}}//查询某实体类点赞的数量:传入 entityType、entityId、判断 key 中有多少个 userId 就是有多少点赞数量public long findEntityLikeCount(int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().size(entityLikeKey);}// 查询某人对某实体的点赞状态public int findEntityLikeStatus(int userId, int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().isMember(entityLikeKey, userId) ? 1 : 0;}}

1.3 处理表现层

点赞是在帖子详情页面操作,是一个异步请求,整个页面不刷新,动态改变已赞的数量;在 controller 包下新建 LikeController 类

  • 调用点赞业务,注入 LikeService
  • 当前用户点赞,为了得到当前用户,注入 HostHolder
  • 添加处理异步请求方法:声明访问路径、POST 请求、异步请求添加注解 @RequestMapping
  • 点赞针对某个实体,传入 entityType、entityId 参数
  • 获取当前用户
  • 实现点赞:调用 LikeService
  • 统计点赞数量、点赞状态返回页面,页面根据返回值做数量和状态显示 
package com.example.demo.controller;import com.example.demo.entity.User;
import com.example.demo.service.LikeService;
import com.example.demo.util.CommunityUtil;
import com.example.demo.util.HostHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.HashMap;
import java.util.Map;/*** 点赞请求*/
@Controller
public class LikeController {//调用点赞业务,注入 LikeServiceprivate LikeService likeService;//当前用户点赞,为了得到当前用户,注入 HostHolderprivate HostHolder hostHolder;//添加处理异步请求方法:声明访问路径、POST 请求、异步请求添加注解 @RequestMapping@RequestMapping(path = "/like", method = RequestMethod.POST)//点赞针对某个实体,传入 entityType、entityId 参数public String like(int entityType, int entityId) {//获取当前用户User user = hostHolder.getUser();//实现点赞:调用 LikeServicelikeService.like(user.getId(), entityType, entityId);//统计点赞数量、点赞状态返回页面,页面根据返回值做数量和状态显示// 数量long likeCount = likeService.findEntityLikeCount(entityType, entityId);// 状态int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);// 返回的结果(用 Map 封装)Map<String, Object> map = new HashMap<>();map.put("likeCount", likeCount);map.put("likeStatus", likeStatus);//返回页面return CommunityUtil.getJSONString(0, null, map);}
}

前端页面 discuss-detail.html 需要处理的是:对帖子点赞,评论点赞、回复点赞

                        <div class="text-muted mt-3">发布于 <b th:text="${#dates.format(post.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b><ul class="d-inline float-right"><li class="d-inline ml-2"><a href="javascript:;" th:onclick="|like(this,1,${post.id});|" class="text-primary"><b th:text="${likeStatus==1?'已赞':'赞'}">赞</b> <i th:text="${likeCount}">11</i></a></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2"><a href="#replyform" class="text-primary">回帖 <i th:text="${post.commentCount}">7</i></a></li></ul></div>
                            <div class="mt-4 text-muted font-size-12"><span>发布于 <b th:text="${#dates.format(cvo.comment.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b></span><ul class="d-inline float-right"><li class="d-inline ml-2"><a href="javascript:;" th:onclick="|like(this,2,${cvo.comment.id});|" class="text-primary"><b th:text="${cvo.likeStatus==1?'已赞':'赞'}">赞</b>(<i th:text="${cvo.likeCount}">1</i>)</a></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2"><a href="#" class="text-primary">回复(<i th:text="${cvo.replyCount}">2</i>)</a></li></ul></div>
                                        <ul class="d-inline float-right"><li class="d-inline ml-2"><a href="javascript:;" th:onclick="|like(this,2,${rvo.reply.id});|" class="text-primary"><b th:text="${rvo.likeStatus==1?'已赞':'赞'}">赞</b>(<i th:text="${rvo.likeCount}">1</i>)</a></li><li class="d-inline ml-2">|</li><li class="d-inline ml-2"><a th:href="|#huifu-${rvoStat.count}|" data-toggle="collapse" class="text-primary">回复</a></li></ul>
<!-- 创建单独js  帖子详情页面-->
<script th:src="@{/js/discuss.js}"></script>

在 static 下创建 discuss.js:

function like(btn, entityType, entityId) {$.post(CONTEXT_PATH + "/like",{"entityType":entityType,"entityId":entityId},function(data) {data = $.parseJSON(data);if(data.code == 0) {$(btn).children("i").text(data.likeCount);$(btn).children("b").text(data.likeStatus==1?'已赞':"赞");} else {alert(data.msg);}});
}

1.4 处理显示首页赞的数量

打开 HomeController 类添加赞的数量:

    @Autowiredprivate LikeService likeService;@RequestMapping(path = "/index", method = RequestMethod.GET)//访问首页路径public String getIndexPage(Model model, Page page) {// 方法调用之前,SpringMVC会自动实例化Model和Page,并将Page注入Model.// 所以,在thymeleaf中可以直接访问Page对象中的数据.//加入分页功能page.setRows(discussPostService.findDiscussPostRows(0));//设置总行数page.setPath("/index");//访问路径//只是查询到 userId,不是用户名,但是我们需要展示用户名List<DiscussPost> list = discussPostService.findDiscussPosts(0, page.getOffset(), page.getLimit());//遍历集合,针对每一个 DiscussPost 的 userId 查询到 user,再把数据组装放到新的集合返回给页面//新建集合,能够封装 DiscussPost 和 User 对象List<Map<String, Object>> discussPosts = new ArrayList<>();if (list != null) {for (DiscussPost post : list) {Map<String, Object> map = new HashMap<>();//最终结果放到 Map 中,实例化 Mapmap.put("post", post);User user = userService.findUserById(post.getUserId());//得到 user 的完整数据map.put("user", user);//查询赞的数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId());map.put("likeCount", likeCount);discussPosts.add(map);}}model.addAttribute("discussPosts", discussPosts);return "/index";//返回模板路径}

index.html 找到显示赞进行修改:

<li class="d-inline ml-2">赞 <span th:text="${map.likeCount}">11</span></li>

1.5 处理帖子详情页面赞的数量和状态

  • 查询帖子的赞
    @Autowiredprivate LikeService likeService;//查询请求方法@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {// 帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post", post);//第一种方法:在查询的时候使用关联查询 。优点:查询快;缺点:可能存在冗余、耦合//第二种方法:先查出帖子数据,根据 id 调用 Userservice 查询 User,再通过 Model 将 User 发送给 模板,// 这样模板得到了帖子,也得到了模板。优点:查询两次,没有冗余;缺点:查询慢//在这里使用第二种情况,查询慢可以使用 Redis 来优化// 作者User user = userService.findUserById(post.getUserId());// 把作者传给模板model.addAttribute("user", user);// 点赞数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeCount", likeCount);// 点赞状态int likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeStatus", likeStatus);...................if (commentList != null) {for (Comment comment : commentList) {// 评论VO:创建一个 Map,用来封装呈现给页面数据(也就是一个评论,将遍历的评论存入、将评论的作者存入)Map<String, Object> commentVo = new HashMap<>();// 评论存入commentVo.put("comment", comment);// 作者存入commentVo.put("user", userService.findUserById(comment.getUserId()));// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeStatus", likeStatus);....................if (replyList != null) {for (Comment reply: replyList) {Map<String, Object> replyVo = new HashMap<>();// 回复replyVo.put("reply", reply);// 作者replyVo.put("user", userService.findUserById(reply.getUserId()));//评论是没有回复目标的,但是评论的评论也就是回复,才会有回复目标(给那个帖子回复),所以给回复添加回复目标// 回复目标User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());replyVo.put("target", target);// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeStatus", likeStatus);.........

2.我收到的赞

  • 重构点赞功能:以用户为 key,记录点赞数量;increment(key)、decrement(key)
  • 开发个人主页:以用户为 key,查询点赞数量

在 util 包下的 RedisKeyUtil 增加 key:

  • 新增前缀 key ,声明常量
  • 添加某个用户的赞的方法
  • 拼接:like:user:userId -> int
     

2.1 改造点赞的业务方法

在 LikeService 类下重构点赞方法:

  • 需要添加一个维度记录收到的赞的数量,一个业务中需要执行两次的更新操作需要保证事务性,redis保证事务(编程),重构代码
  • 添加实体 key
  • 添加 User key(需要的是被赞的人,传入实体作者参数)
  • 查询当前用户是否已经点赞
  • 查询放在事务之外(在事务过程中执行的所有命令不会立刻执行,而是把命令放入队列中,提交事务的时候统一提交,再执行)
  •  开启事务
  • 执行两次修改操作:没点赞点赞(实体类),那么结果+1(User);点赞了再次点取消(实体类),那么结果-1(User)
  • 执行事务
  • 补充查询某个用户获得赞的数量:拼接 key,统计数量 
    public void like(int userId, int entityType, int entityId, int entityUserId {/*//拼接存储的 keyString entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);//判断当前用户是否已经点赞(没点赞点赞,点赞了再次点取消):在 redis 存的是一个集合,判断 userId 是否在 redis 中即可boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey, userId);if (isMember) {redisTemplate.opsForSet().remove(entityLikeKey, userId);} else {redisTemplate.opsForSet().add(entityLikeKey, userId);}*///需要添加一个维度记录收到的赞的数量,一个业务中需要执行两次的更新操作需要保证事务性,redis保证事务(编程),重构代码redisTemplate.execute(new SessionCallback() {@Overridepublic Object execute(RedisOperations operations) throws DataAccessException {//添加实体 key//添加 User key(需要的是被赞的人,传入实体作者参数)String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);String userLikeKey = RedisKeyUtil.getUserLikeKey(entityUserId);//查询当前用户是否已经点赞//查询放在事务之外(在事务过程中执行的所有命令不会立刻执行,而是把命令放入队列中,提交事务的时候统一提交,再执行)boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);//开启事务operations.multi();//执行两次修改操作:没点赞点赞(实体类),那么结果+1(User);点赞了再次点取消(实体类),那么结果-1(User)if (isMember) {operations.opsForSet().remove(entityLikeKey, userId);operations.opsForValue().decrement(userLikeKey);} else {operations.opsForSet().add(entityLikeKey, userId);operations.opsForValue().increment(userLikeKey);}//执行事务return operations.exec();}});}//补充查询某个用户获得赞的数量:拼接 key,统计数量public int findUserLikeCount(int userId) {String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);return count == null ? 0 : count.intValue();}

2.2 重构表现层

在 LikeController 类中修改方法:

  • 添加实体类作者参数
@Controller
public class LikeController {......public String like(int entityType, int entityId, int entityUserId) {//获取当前用户User user = hostHolder.getUser();//实现点赞:调用 LikeServicelikeService.like(user.getId(), entityType, entityId, entityUserId);......}
}

修改前端点赞页面 discuss-detail.html:

<!-- 点赞 -->
<b th:text="${likeStatus==1?'已赞':'赞'}">赞</b> <i th:text="${likeCount}">11</i><!-- 评论 -->
<a href="javascript:;" th:onclick="|like(this,2,${cvo.comment.id},${cvo.comment.userId});|" class="text-primary"><!-- 回复 -->
<a href="javascript:;" th:onclick="|like(this,2,${rvo.reply.id},${rvo.reply.userId});|" class="text-primary">

discuss-detail.js:

function like(btn, entityType, entityId, entityUserId) {$.post(CONTEXT_PATH + "/like",{"entityType":entityType,"entityId":entityId,"entityUserId":entityUserId},function(data) {data = $.parseJSON(data);if(data.code == 0) {$(btn).children("i").text(data.likeCount);$(btn).children("b").text(data.likeStatus==1?'已赞':"赞");} else {alert(data.msg);}});
}

2.3 在主页显示

在 UserController 类中新增个人主页方法

  • 设置返回路径,可以是任意用户主页
  • 使用 @PathVariable 解析
  • 给页面携带参数,添加 Model 参数
  • 查找当前用户,然后传给页面
  • 查询用户点赞数量(注入 LikeService),然后传给页面,最后返回模板
    //新增个人主页方法注入 LikeService@Autowiredprivate LikeService likeService;// 个人主页@RequestMapping(path = "/profile/{userId}", method = RequestMethod.GET)public String getProfilePage(@PathVariable("userId") int userId, Model model) {User user = userService.findUserById(userId);if (user == null) {throw new RuntimeException("该用户不存在!");}// 用户model.addAttribute("user", user);// 点赞数量int likeCount = likeService.findUserLikeCount(userId);model.addAttribute("likeCount", likeCount);return "/site/profile";}

处理模板 index.html (个人主页添加路径、帖子列表中每一个用户头像应该有一个超链接到主页中):

<!-- 个人主页添加路径 -->
<a class="dropdown-item text-center" th:href="@{|/user/profile/${loginUser.id}|}">个人主页</a><!-- 帖子列表中每一个用户头像应该有一个超链接到主页中 -->
<a th:href="@{|/user/profile/${map.user.id}|}">

最后处理 profile.html:

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="icon" href="https://static.nowcoder.com/images/logo_87_87.png"/><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous"><link rel="stylesheet" th:href="@{/css/global.css}" /><title>个人主页</title>
</head>
<body><div class="nk-container"><!-- 头部 --><header class="bg-dark sticky-top" th:replace="index::header"><div class="container">..................<!-- 个人信息 --><div class="media mt-5"><img th:src="${user.headerUrl}" class="align-self-start mr-4 rounded-circle" alt="用户头像" style="width:50px;"><div class="media-body"><h5 class="mt-0 text-warning"><span th:utext="${user.username}">nowcoder</span><button type="button" class="btn btn-info btn-sm float-right mr-5 follow-btn">关注TA</button></h5><div class="text-muted mt-3"><span>注册于 <i class="text-muted" th:text="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}">2015-06-12 15:20:12</i></span></div><div class="text-muted mt-3 mb-5"><span>关注了 <a class="text-primary" href="followee.html">5</a> 人</span><span class="ml-4">关注者 <a class="text-primary" href="follower.html">123</a> 人</span><span class="ml-4">获得了 <i class="text-danger" th:text="${likeCount}">87</i> 个赞</span></div></div></div></div></div>..................<script th:src="@{/js/global.js}"></script><script th:src="@{/js/profile.js}"></script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/229375.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

万人拼团团购小程序源码系统+拼团设置+拼团管理 附带完整的搭建教程

随着互联网的快速发展&#xff0c;电子商务和社交电商的兴起&#xff0c;团购作为一种高效的营销策略和消费方式&#xff0c;受到了广大消费者的热烈欢迎。在此背景下&#xff0c;我们开发了一款基于微信小程序的万人拼团团购系统&#xff0c;旨在为用户提供一种更加便捷、高效…

区域人员超限AI算法的介绍及TSINGSEE视频智能分析技术的行业应用

视频AI智能分析已经渗透到人类生活及社会发展的各个方面。从生活中的人脸识别、停车场的车牌识别、工厂园区的翻越围栏识别、入侵识别、工地的安全帽识别、车间流水线产品的品质缺陷AI检测等&#xff0c;AI智能分析技术无处不在。在某些场景中&#xff0c;重点区域的人数统计与…

Leetcode算法之哈希表

目录 1.两数之和2.判定是否互为字符重排3.存在重复元素I4.存在重复元素II5.字母异位词分组 1.两数之和 两数之和 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> hash;for(int i0;i<nums.si…

深信服防火墙设置应用控制策略(菜鸟必看)

PS&#xff1a;前几天发布了关于深信服防火墙路由部署的流程&#xff1a;深信服防火墙路由模式开局部署-手把手教学&#xff08;小白篇&#xff09;-CSDN博客 昨天晚上有csdn的朋友联系我&#xff0c;说有一个关于ACL访问的问题要帮忙看一下 解决了以后&#xff0c;写个大概的…

数字人透明屏幕是如何工作的?

数字人透明屏幕是一种令人兴奋的科技产品&#xff0c;它结合了人脸识别、全息影像技术以及透明屏幕&#xff0c;为人们带来了全新的互动体验。本文将详细介绍数字人透明屏幕的工作原理以及其应用场景。 工作原理 数字人透明屏幕的工作原理主要包括人脸识别和全息影像技术。人脸…

U-boot(六):命令体系,环境变量,iNand/SD卡驱动

本文主要探讨210的uboot命令体系&#xff0c;黄金变量,iNand/SD卡驱动相关知识。 命令体系 uboot命令体系 位置:uboot/common/ 参数:uboot命令支持传递参数(argc,argv) 函数:xxx命令的实现算数为do_xxx /** Use puts() inst…

不要被各种专业术语吓倒

有一个东西&#xff0c;是如此奇妙&#xff0c;今天我们需要讲讲。 在不同的函数中&#xff0c;这个东西有着不同的名字&#xff0c;但实际它都是同一个东西。 例如&#xff0c; RegisterWaitForSingleObject 这个 API&#xff0c;它的原型如下&#xff1a; BOOL RegisterWai…

第15关 K8s HPA:自动水平伸缩Pod,实现弹性扩展和资源优化

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维&#xff0c;这节课带来k8s的HPA 自动水平伸缩pod&#xff08; 视频后面有彩蛋 : ) &#xff09;。 我们知道&#xff0c;初始Pod的数量是可以设置的&#xff0c;同时业务也分流量高峰和低峰&a…

Redis实战命令

实战命令 单值缓存 set key value get key 对象缓存 &#xff08;1&#xff09;set user:1 value(json格式) &#xff08;2&#xff09;mset user:1:name junfeng user:1:age 18 mget user:1:name user:1:age 分布式锁 分布式锁解决了什么问题&#xff1f; 分布式锁解…

nodejs+vue+elementui图书馆教室自习室座位预约管理系统93c8r

本系统利用nodejsVue技术进行开发自习室预约管理系统是未来的趋势。该系统使用的编程语言是nodejs&#xff0c;数据库采用的是MySQL数据库&#xff0c;基本完成了系统设定的目标&#xff0c;建立起了一个较为完整的系统。建立的自习室预约管理系统用户使用浏览器就可以对其进行…

SpringBoot : ch10 整合Elasticsearch

前言 欢迎阅读本文&#xff0c;本文将介绍如何在Spring Boot应用程序中整合Elasticsearch。随着信息量的不断增加&#xff0c;对数据的高效管理和检索变得尤为重要。Elasticsearch作为一个强大的开源搜索和分析引擎&#xff0c;为我们提供了一个灵活且高效的解决方案。 在本文…

泛微 E-Office sample权限绕过+文件上传组合漏洞Getshell

0x01 产品简介 泛微E-Office是一款标准化的协同 OA 办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 0x02 漏…