消息队列存储数据
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package com.yupi.springbootinit.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yupi.springbootinit.model.entity.NewHosts;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2025/6/10 19:04
|
||||
*/
|
||||
public interface HostInfoService extends IService<NewHosts> {
|
||||
|
||||
public CompletableFuture<Void> saveHostInfo(List<NewHosts> newHosts);
|
||||
|
||||
public CompletableFuture<Void> processHosts(List<NewHosts> hosts);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.yupi.springbootinit.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yupi.springbootinit.model.entity.Post;
|
||||
import com.yupi.springbootinit.model.entity.PostFavour;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
|
||||
/**
|
||||
* 帖子收藏服务
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
public interface PostFavourService extends IService<PostFavour> {
|
||||
|
||||
/**
|
||||
* 帖子收藏
|
||||
*
|
||||
* @param postId
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
int doPostFavour(long postId, User loginUser);
|
||||
|
||||
/**
|
||||
* 分页获取用户收藏的帖子列表
|
||||
*
|
||||
* @param page
|
||||
* @param queryWrapper
|
||||
* @param favourUserId
|
||||
* @return
|
||||
*/
|
||||
Page<Post> listFavourPostByPage(IPage<Post> page, Wrapper<Post> queryWrapper,
|
||||
long favourUserId);
|
||||
|
||||
/**
|
||||
* 帖子收藏(内部服务)
|
||||
*
|
||||
* @param userId
|
||||
* @param postId
|
||||
* @return
|
||||
*/
|
||||
int doPostFavourInner(long userId, long postId);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.yupi.springbootinit.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yupi.springbootinit.model.dto.post.PostQueryRequest;
|
||||
import com.yupi.springbootinit.model.entity.Post;
|
||||
import com.yupi.springbootinit.model.vo.PostVO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 帖子服务
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
public interface PostService extends IService<Post> {
|
||||
|
||||
/**
|
||||
* 校验
|
||||
*
|
||||
* @param post
|
||||
* @param add
|
||||
*/
|
||||
void validPost(Post post, boolean add);
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @param postQueryRequest
|
||||
* @return
|
||||
*/
|
||||
QueryWrapper<Post> getQueryWrapper(PostQueryRequest postQueryRequest);
|
||||
|
||||
/**
|
||||
* 从 ES 查询
|
||||
*
|
||||
* @param postQueryRequest
|
||||
* @return
|
||||
*/
|
||||
Page<Post> searchFromEs(PostQueryRequest postQueryRequest);
|
||||
|
||||
/**
|
||||
* 获取帖子封装
|
||||
*
|
||||
* @param post
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
PostVO getPostVO(Post post, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 分页获取帖子封装
|
||||
*
|
||||
* @param postPage
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
Page<PostVO> getPostVOPage(Page<Post> postPage, HttpServletRequest request);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.yupi.springbootinit.service;
|
||||
|
||||
import com.yupi.springbootinit.model.entity.PostThumb;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
|
||||
/**
|
||||
* 帖子点赞服务
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
public interface PostThumbService extends IService<PostThumb> {
|
||||
|
||||
/**
|
||||
* 点赞
|
||||
*
|
||||
* @param postId
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
int doPostThumb(long postId, User loginUser);
|
||||
|
||||
/**
|
||||
* 帖子点赞(内部服务)
|
||||
*
|
||||
* @param userId
|
||||
* @param postId
|
||||
* @return
|
||||
*/
|
||||
int doPostThumbInner(long userId, long postId);
|
||||
}
|
||||
121
src/main/java/com/yupi/springbootinit/service/UserService.java
Normal file
121
src/main/java/com/yupi/springbootinit/service/UserService.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package com.yupi.springbootinit.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yupi.springbootinit.model.dto.user.UserQueryRequest;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
import com.yupi.springbootinit.model.vo.LoginUserVO;
|
||||
import com.yupi.springbootinit.model.vo.UserVO;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
public interface UserService extends IService<User> {
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
*
|
||||
* @param userAccount 用户账户
|
||||
* @param userPassword 用户密码
|
||||
* @param checkPassword 校验密码
|
||||
* @return 新用户 id
|
||||
*/
|
||||
long userRegister(String userAccount, String userPassword, String checkPassword);
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param userAccount 用户账户
|
||||
* @param userPassword 用户密码
|
||||
* @param request
|
||||
* @return 脱敏后的用户信息
|
||||
*/
|
||||
LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 用户登录(微信开放平台)
|
||||
*
|
||||
* @param wxOAuth2UserInfo 从微信获取的用户信息
|
||||
* @param request
|
||||
* @return 脱敏后的用户信息
|
||||
*/
|
||||
LoginUserVO userLoginByMpOpen(WxOAuth2UserInfo wxOAuth2UserInfo, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
User getLoginUser(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取当前登录用户(允许未登录)
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
User getLoginUserPermitNull(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 是否为管理员
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
boolean isAdmin(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 是否为管理员
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean isAdmin(User user);
|
||||
|
||||
/**
|
||||
* 用户注销
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
boolean userLogout(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取脱敏的已登录用户信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LoginUserVO getLoginUserVO(User user);
|
||||
|
||||
/**
|
||||
* 获取脱敏的用户信息
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
UserVO getUserVO(User user);
|
||||
|
||||
/**
|
||||
* 获取脱敏的用户信息
|
||||
*
|
||||
* @param userList
|
||||
* @return
|
||||
*/
|
||||
List<UserVO> getUserVO(List<User> userList);
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @param userQueryRequest
|
||||
* @return
|
||||
*/
|
||||
QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.yupi.springbootinit.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.yupi.springbootinit.mapper.NewHostsMapper;
|
||||
import com.yupi.springbootinit.model.entity.NewHosts;
|
||||
import com.yupi.springbootinit.service.HostInfoService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/*
|
||||
* @author: ziin
|
||||
* @date: 2025/6/10 19:04
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class HostInfoServiceImpl extends ServiceImpl<NewHostsMapper, NewHosts> implements HostInfoService {
|
||||
|
||||
|
||||
@Override
|
||||
@Async("taskExecutor")
|
||||
|
||||
public CompletableFuture<Void> saveHostInfo(List<NewHosts> newHosts) {
|
||||
try {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
saveBatch(newHosts);
|
||||
stopWatch.stop();
|
||||
long totalTimeMillis = stopWatch.getTotalTimeMillis();
|
||||
log.info(" 存储花费: {}ms", totalTimeMillis);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} catch (Exception e) {
|
||||
// 将异常包装到Future,使调用方能处理
|
||||
return CompletableFuture.failedFuture(e); // Java9+
|
||||
}
|
||||
}
|
||||
|
||||
// public void processHosts(List<NewHosts> hosts) {
|
||||
// List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
// // 分片提交(避免单批次过大)
|
||||
// Lists.partition(hosts, 1500).forEach(batch -> {
|
||||
// CompletableFuture<Void> future = this.saveHostInfo(batch);
|
||||
// futures.add(future);
|
||||
// });
|
||||
// CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
// .whenComplete((result, ex) -> {
|
||||
// if (ex != null) {
|
||||
// log.error("部分批次处理失败", ex);
|
||||
// } else {
|
||||
// log.info("所有批次处理完成");
|
||||
// }
|
||||
// // 这里可以触发其他业务逻辑(如发送通知)
|
||||
// });
|
||||
// }
|
||||
public CompletableFuture<Void> processHosts(List<NewHosts> hosts) {
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
// 分片提交(避免单批次过大)
|
||||
Lists.partition(hosts, 1500).forEach(batch -> {
|
||||
CompletableFuture<Void> future = this.saveHostInfo(batch);
|
||||
futures.add(future);
|
||||
});
|
||||
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.whenComplete((result, ex) -> {
|
||||
if (ex != null) {
|
||||
log.error("部分批次处理失败", ex);
|
||||
} else {
|
||||
log.info("所有批次处理完成");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.yupi.springbootinit.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yupi.springbootinit.common.ErrorCode;
|
||||
import com.yupi.springbootinit.exception.BusinessException;
|
||||
import com.yupi.springbootinit.mapper.PostFavourMapper;
|
||||
import com.yupi.springbootinit.model.entity.Post;
|
||||
import com.yupi.springbootinit.model.entity.PostFavour;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
import com.yupi.springbootinit.service.PostFavourService;
|
||||
import com.yupi.springbootinit.service.PostService;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 帖子收藏服务实现
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
@Service
|
||||
public class PostFavourServiceImpl extends ServiceImpl<PostFavourMapper, PostFavour>
|
||||
implements PostFavourService {
|
||||
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
/**
|
||||
* 帖子收藏
|
||||
*
|
||||
* @param postId
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int doPostFavour(long postId, User loginUser) {
|
||||
// 判断是否存在
|
||||
Post post = postService.getById(postId);
|
||||
if (post == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
|
||||
}
|
||||
// 是否已帖子收藏
|
||||
long userId = loginUser.getId();
|
||||
// 每个用户串行帖子收藏
|
||||
// 锁必须要包裹住事务方法
|
||||
PostFavourService postFavourService = (PostFavourService) AopContext.currentProxy();
|
||||
synchronized (String.valueOf(userId).intern()) {
|
||||
return postFavourService.doPostFavourInner(userId, postId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Post> listFavourPostByPage(IPage<Post> page, Wrapper<Post> queryWrapper, long favourUserId) {
|
||||
if (favourUserId <= 0) {
|
||||
return new Page<>();
|
||||
}
|
||||
return baseMapper.listFavourPostByPage(page, queryWrapper, favourUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装了事务的方法
|
||||
*
|
||||
* @param userId
|
||||
* @param postId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int doPostFavourInner(long userId, long postId) {
|
||||
PostFavour postFavour = new PostFavour();
|
||||
postFavour.setUserId(userId);
|
||||
postFavour.setPostId(postId);
|
||||
QueryWrapper<PostFavour> postFavourQueryWrapper = new QueryWrapper<>(postFavour);
|
||||
PostFavour oldPostFavour = this.getOne(postFavourQueryWrapper);
|
||||
boolean result;
|
||||
// 已收藏
|
||||
if (oldPostFavour != null) {
|
||||
result = this.remove(postFavourQueryWrapper);
|
||||
if (result) {
|
||||
// 帖子收藏数 - 1
|
||||
result = postService.update()
|
||||
.eq("id", postId)
|
||||
.gt("favourNum", 0)
|
||||
.setSql("favourNum = favourNum - 1")
|
||||
.update();
|
||||
return result ? -1 : 0;
|
||||
} else {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
} else {
|
||||
// 未帖子收藏
|
||||
result = this.save(postFavour);
|
||||
if (result) {
|
||||
// 帖子收藏数 + 1
|
||||
result = postService.update()
|
||||
.eq("id", postId)
|
||||
.setSql("favourNum = favourNum + 1")
|
||||
.update();
|
||||
return result ? 1 : 0;
|
||||
} else {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
package com.yupi.springbootinit.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yupi.springbootinit.common.ErrorCode;
|
||||
import com.yupi.springbootinit.constant.CommonConstant;
|
||||
import com.yupi.springbootinit.exception.BusinessException;
|
||||
import com.yupi.springbootinit.exception.ThrowUtils;
|
||||
import com.yupi.springbootinit.mapper.PostFavourMapper;
|
||||
import com.yupi.springbootinit.mapper.PostMapper;
|
||||
import com.yupi.springbootinit.mapper.PostThumbMapper;
|
||||
import com.yupi.springbootinit.model.dto.post.PostEsDTO;
|
||||
import com.yupi.springbootinit.model.dto.post.PostQueryRequest;
|
||||
import com.yupi.springbootinit.model.entity.Post;
|
||||
import com.yupi.springbootinit.model.entity.PostFavour;
|
||||
import com.yupi.springbootinit.model.entity.PostThumb;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
import com.yupi.springbootinit.model.vo.PostVO;
|
||||
import com.yupi.springbootinit.model.vo.UserVO;
|
||||
import com.yupi.springbootinit.service.PostService;
|
||||
import com.yupi.springbootinit.service.UserService;
|
||||
import com.yupi.springbootinit.utils.SqlUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.SearchHit;
|
||||
import org.springframework.data.elasticsearch.core.SearchHits;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 帖子服务实现
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Resource
|
||||
private PostThumbMapper postThumbMapper;
|
||||
|
||||
@Resource
|
||||
private PostFavourMapper postFavourMapper;
|
||||
|
||||
@Resource
|
||||
private ElasticsearchRestTemplate elasticsearchRestTemplate;
|
||||
|
||||
@Override
|
||||
public void validPost(Post post, boolean add) {
|
||||
if (post == null) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
String title = post.getTitle();
|
||||
String content = post.getContent();
|
||||
String tags = post.getTags();
|
||||
// 创建时,参数不能为空
|
||||
if (add) {
|
||||
ThrowUtils.throwIf(StringUtils.isAnyBlank(title, content, tags), ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
// 有参数则校验
|
||||
if (StringUtils.isNotBlank(title) && title.length() > 80) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
|
||||
}
|
||||
if (StringUtils.isNotBlank(content) && content.length() > 8192) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询包装类
|
||||
*
|
||||
* @param postQueryRequest
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public QueryWrapper<Post> getQueryWrapper(PostQueryRequest postQueryRequest) {
|
||||
QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
|
||||
if (postQueryRequest == null) {
|
||||
return queryWrapper;
|
||||
}
|
||||
String searchText = postQueryRequest.getSearchText();
|
||||
String sortField = postQueryRequest.getSortField();
|
||||
String sortOrder = postQueryRequest.getSortOrder();
|
||||
Long id = postQueryRequest.getId();
|
||||
String title = postQueryRequest.getTitle();
|
||||
String content = postQueryRequest.getContent();
|
||||
List<String> tagList = postQueryRequest.getTags();
|
||||
Long userId = postQueryRequest.getUserId();
|
||||
Long notId = postQueryRequest.getNotId();
|
||||
// 拼接查询条件
|
||||
if (StringUtils.isNotBlank(searchText)) {
|
||||
queryWrapper.and(qw -> qw.like("title", searchText).or().like("content", searchText));
|
||||
}
|
||||
queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
|
||||
queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
|
||||
if (CollUtil.isNotEmpty(tagList)) {
|
||||
for (String tag : tagList) {
|
||||
queryWrapper.like("tags", "\"" + tag + "\"");
|
||||
}
|
||||
}
|
||||
queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
|
||||
queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
|
||||
queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
|
||||
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
|
||||
sortField);
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Post> searchFromEs(PostQueryRequest postQueryRequest) {
|
||||
Long id = postQueryRequest.getId();
|
||||
Long notId = postQueryRequest.getNotId();
|
||||
String searchText = postQueryRequest.getSearchText();
|
||||
String title = postQueryRequest.getTitle();
|
||||
String content = postQueryRequest.getContent();
|
||||
List<String> tagList = postQueryRequest.getTags();
|
||||
List<String> orTagList = postQueryRequest.getOrTags();
|
||||
Long userId = postQueryRequest.getUserId();
|
||||
// es 起始页为 0
|
||||
long current = postQueryRequest.getCurrent() - 1;
|
||||
long pageSize = postQueryRequest.getPageSize();
|
||||
String sortField = postQueryRequest.getSortField();
|
||||
String sortOrder = postQueryRequest.getSortOrder();
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
// 过滤
|
||||
boolQueryBuilder.filter(QueryBuilders.termQuery("isDelete", 0));
|
||||
if (id != null) {
|
||||
boolQueryBuilder.filter(QueryBuilders.termQuery("id", id));
|
||||
}
|
||||
if (notId != null) {
|
||||
boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", notId));
|
||||
}
|
||||
if (userId != null) {
|
||||
boolQueryBuilder.filter(QueryBuilders.termQuery("userId", userId));
|
||||
}
|
||||
// 必须包含所有标签
|
||||
if (CollUtil.isNotEmpty(tagList)) {
|
||||
for (String tag : tagList) {
|
||||
boolQueryBuilder.filter(QueryBuilders.termQuery("tags", tag));
|
||||
}
|
||||
}
|
||||
// 包含任何一个标签即可
|
||||
if (CollUtil.isNotEmpty(orTagList)) {
|
||||
BoolQueryBuilder orTagBoolQueryBuilder = QueryBuilders.boolQuery();
|
||||
for (String tag : orTagList) {
|
||||
orTagBoolQueryBuilder.should(QueryBuilders.termQuery("tags", tag));
|
||||
}
|
||||
orTagBoolQueryBuilder.minimumShouldMatch(1);
|
||||
boolQueryBuilder.filter(orTagBoolQueryBuilder);
|
||||
}
|
||||
// 按关键词检索
|
||||
if (StringUtils.isNotBlank(searchText)) {
|
||||
boolQueryBuilder.should(QueryBuilders.matchQuery("title", searchText));
|
||||
boolQueryBuilder.should(QueryBuilders.matchQuery("description", searchText));
|
||||
boolQueryBuilder.should(QueryBuilders.matchQuery("content", searchText));
|
||||
boolQueryBuilder.minimumShouldMatch(1);
|
||||
}
|
||||
// 按标题检索
|
||||
if (StringUtils.isNotBlank(title)) {
|
||||
boolQueryBuilder.should(QueryBuilders.matchQuery("title", title));
|
||||
boolQueryBuilder.minimumShouldMatch(1);
|
||||
}
|
||||
// 按内容检索
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
boolQueryBuilder.should(QueryBuilders.matchQuery("content", content));
|
||||
boolQueryBuilder.minimumShouldMatch(1);
|
||||
}
|
||||
// 排序
|
||||
SortBuilder<?> sortBuilder = SortBuilders.scoreSort();
|
||||
if (StringUtils.isNotBlank(sortField)) {
|
||||
sortBuilder = SortBuilders.fieldSort(sortField);
|
||||
sortBuilder.order(CommonConstant.SORT_ORDER_ASC.equals(sortOrder) ? SortOrder.ASC : SortOrder.DESC);
|
||||
}
|
||||
// 分页
|
||||
PageRequest pageRequest = PageRequest.of((int) current, (int) pageSize);
|
||||
// 构造查询
|
||||
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
|
||||
.withPageable(pageRequest).withSorts(sortBuilder).build();
|
||||
SearchHits<PostEsDTO> searchHits = elasticsearchRestTemplate.search(searchQuery, PostEsDTO.class);
|
||||
Page<Post> page = new Page<>();
|
||||
page.setTotal(searchHits.getTotalHits());
|
||||
List<Post> resourceList = new ArrayList<>();
|
||||
// 查出结果后,从 db 获取最新动态数据(比如点赞数)
|
||||
if (searchHits.hasSearchHits()) {
|
||||
List<SearchHit<PostEsDTO>> searchHitList = searchHits.getSearchHits();
|
||||
List<Long> postIdList = searchHitList.stream().map(searchHit -> searchHit.getContent().getId())
|
||||
.collect(Collectors.toList());
|
||||
List<Post> postList = baseMapper.selectBatchIds(postIdList);
|
||||
if (postList != null) {
|
||||
Map<Long, List<Post>> idPostMap = postList.stream().collect(Collectors.groupingBy(Post::getId));
|
||||
postIdList.forEach(postId -> {
|
||||
if (idPostMap.containsKey(postId)) {
|
||||
resourceList.add(idPostMap.get(postId).get(0));
|
||||
} else {
|
||||
// 从 es 清空 db 已物理删除的数据
|
||||
String delete = elasticsearchRestTemplate.delete(String.valueOf(postId), PostEsDTO.class);
|
||||
log.info("delete post {}", delete);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
page.setRecords(resourceList);
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PostVO getPostVO(Post post, HttpServletRequest request) {
|
||||
PostVO postVO = PostVO.objToVo(post);
|
||||
long postId = post.getId();
|
||||
// 1. 关联查询用户信息
|
||||
Long userId = post.getUserId();
|
||||
User user = null;
|
||||
if (userId != null && userId > 0) {
|
||||
user = userService.getById(userId);
|
||||
}
|
||||
UserVO userVO = userService.getUserVO(user);
|
||||
postVO.setUser(userVO);
|
||||
// 2. 已登录,获取用户点赞、收藏状态
|
||||
User loginUser = userService.getLoginUserPermitNull(request);
|
||||
if (loginUser != null) {
|
||||
// 获取点赞
|
||||
QueryWrapper<PostThumb> postThumbQueryWrapper = new QueryWrapper<>();
|
||||
postThumbQueryWrapper.in("postId", postId);
|
||||
postThumbQueryWrapper.eq("userId", loginUser.getId());
|
||||
PostThumb postThumb = postThumbMapper.selectOne(postThumbQueryWrapper);
|
||||
postVO.setHasThumb(postThumb != null);
|
||||
// 获取收藏
|
||||
QueryWrapper<PostFavour> postFavourQueryWrapper = new QueryWrapper<>();
|
||||
postFavourQueryWrapper.in("postId", postId);
|
||||
postFavourQueryWrapper.eq("userId", loginUser.getId());
|
||||
PostFavour postFavour = postFavourMapper.selectOne(postFavourQueryWrapper);
|
||||
postVO.setHasFavour(postFavour != null);
|
||||
}
|
||||
return postVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<PostVO> getPostVOPage(Page<Post> postPage, HttpServletRequest request) {
|
||||
List<Post> postList = postPage.getRecords();
|
||||
Page<PostVO> postVOPage = new Page<>(postPage.getCurrent(), postPage.getSize(), postPage.getTotal());
|
||||
if (CollUtil.isEmpty(postList)) {
|
||||
return postVOPage;
|
||||
}
|
||||
// 1. 关联查询用户信息
|
||||
Set<Long> userIdSet = postList.stream().map(Post::getUserId).collect(Collectors.toSet());
|
||||
Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
|
||||
.collect(Collectors.groupingBy(User::getId));
|
||||
// 2. 已登录,获取用户点赞、收藏状态
|
||||
Map<Long, Boolean> postIdHasThumbMap = new HashMap<>();
|
||||
Map<Long, Boolean> postIdHasFavourMap = new HashMap<>();
|
||||
User loginUser = userService.getLoginUserPermitNull(request);
|
||||
if (loginUser != null) {
|
||||
Set<Long> postIdSet = postList.stream().map(Post::getId).collect(Collectors.toSet());
|
||||
loginUser = userService.getLoginUser(request);
|
||||
// 获取点赞
|
||||
QueryWrapper<PostThumb> postThumbQueryWrapper = new QueryWrapper<>();
|
||||
postThumbQueryWrapper.in("postId", postIdSet);
|
||||
postThumbQueryWrapper.eq("userId", loginUser.getId());
|
||||
List<PostThumb> postPostThumbList = postThumbMapper.selectList(postThumbQueryWrapper);
|
||||
postPostThumbList.forEach(postPostThumb -> postIdHasThumbMap.put(postPostThumb.getPostId(), true));
|
||||
// 获取收藏
|
||||
QueryWrapper<PostFavour> postFavourQueryWrapper = new QueryWrapper<>();
|
||||
postFavourQueryWrapper.in("postId", postIdSet);
|
||||
postFavourQueryWrapper.eq("userId", loginUser.getId());
|
||||
List<PostFavour> postFavourList = postFavourMapper.selectList(postFavourQueryWrapper);
|
||||
postFavourList.forEach(postFavour -> postIdHasFavourMap.put(postFavour.getPostId(), true));
|
||||
}
|
||||
// 填充信息
|
||||
List<PostVO> postVOList = postList.stream().map(post -> {
|
||||
PostVO postVO = PostVO.objToVo(post);
|
||||
Long userId = post.getUserId();
|
||||
User user = null;
|
||||
if (userIdUserListMap.containsKey(userId)) {
|
||||
user = userIdUserListMap.get(userId).get(0);
|
||||
}
|
||||
postVO.setUser(userService.getUserVO(user));
|
||||
postVO.setHasThumb(postIdHasThumbMap.getOrDefault(post.getId(), false));
|
||||
postVO.setHasFavour(postIdHasFavourMap.getOrDefault(post.getId(), false));
|
||||
return postVO;
|
||||
}).collect(Collectors.toList());
|
||||
postVOPage.setRecords(postVOList);
|
||||
return postVOPage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.yupi.springbootinit.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yupi.springbootinit.common.ErrorCode;
|
||||
import com.yupi.springbootinit.exception.BusinessException;
|
||||
import com.yupi.springbootinit.mapper.PostThumbMapper;
|
||||
import com.yupi.springbootinit.model.entity.Post;
|
||||
import com.yupi.springbootinit.model.entity.PostThumb;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
import com.yupi.springbootinit.service.PostService;
|
||||
import com.yupi.springbootinit.service.PostThumbService;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 帖子点赞服务实现
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
@Service
|
||||
public class PostThumbServiceImpl extends ServiceImpl<PostThumbMapper, PostThumb>
|
||||
implements PostThumbService {
|
||||
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
/**
|
||||
* 点赞
|
||||
*
|
||||
* @param postId
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int doPostThumb(long postId, User loginUser) {
|
||||
// 判断实体是否存在,根据类别获取实体
|
||||
Post post = postService.getById(postId);
|
||||
if (post == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
|
||||
}
|
||||
// 是否已点赞
|
||||
long userId = loginUser.getId();
|
||||
// 每个用户串行点赞
|
||||
// 锁必须要包裹住事务方法
|
||||
PostThumbService postThumbService = (PostThumbService) AopContext.currentProxy();
|
||||
synchronized (String.valueOf(userId).intern()) {
|
||||
return postThumbService.doPostThumbInner(userId, postId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装了事务的方法
|
||||
*
|
||||
* @param userId
|
||||
* @param postId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int doPostThumbInner(long userId, long postId) {
|
||||
PostThumb postThumb = new PostThumb();
|
||||
postThumb.setUserId(userId);
|
||||
postThumb.setPostId(postId);
|
||||
QueryWrapper<PostThumb> thumbQueryWrapper = new QueryWrapper<>(postThumb);
|
||||
PostThumb oldPostThumb = this.getOne(thumbQueryWrapper);
|
||||
boolean result;
|
||||
// 已点赞
|
||||
if (oldPostThumb != null) {
|
||||
result = this.remove(thumbQueryWrapper);
|
||||
if (result) {
|
||||
// 点赞数 - 1
|
||||
result = postService.update()
|
||||
.eq("id", postId)
|
||||
.gt("thumbNum", 0)
|
||||
.setSql("thumbNum = thumbNum - 1")
|
||||
.update();
|
||||
return result ? -1 : 0;
|
||||
} else {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
} else {
|
||||
// 未点赞
|
||||
result = this.save(postThumb);
|
||||
if (result) {
|
||||
// 点赞数 + 1
|
||||
result = postService.update()
|
||||
.eq("id", postId)
|
||||
.setSql("thumbNum = thumbNum + 1")
|
||||
.update();
|
||||
return result ? 1 : 0;
|
||||
} else {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
package com.yupi.springbootinit.service.impl;
|
||||
|
||||
import static com.yupi.springbootinit.constant.UserConstant.USER_LOGIN_STATE;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yupi.springbootinit.common.ErrorCode;
|
||||
import com.yupi.springbootinit.constant.CommonConstant;
|
||||
import com.yupi.springbootinit.exception.BusinessException;
|
||||
import com.yupi.springbootinit.mapper.UserMapper;
|
||||
import com.yupi.springbootinit.model.dto.user.UserQueryRequest;
|
||||
import com.yupi.springbootinit.model.entity.User;
|
||||
import com.yupi.springbootinit.model.enums.UserRoleEnum;
|
||||
import com.yupi.springbootinit.model.vo.LoginUserVO;
|
||||
import com.yupi.springbootinit.model.vo.UserVO;
|
||||
import com.yupi.springbootinit.service.UserService;
|
||||
import com.yupi.springbootinit.utils.SqlUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
/**
|
||||
* 用户服务实现
|
||||
*
|
||||
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
|
||||
* @from <a href="https://yupi.icu">编程导航知识星球</a>
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
|
||||
/**
|
||||
* 盐值,混淆密码
|
||||
*/
|
||||
public static final String SALT = "yupi";
|
||||
|
||||
@Override
|
||||
public long userRegister(String userAccount, String userPassword, String checkPassword) {
|
||||
// 1. 校验
|
||||
if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
|
||||
}
|
||||
if (userAccount.length() < 4) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
|
||||
}
|
||||
if (userPassword.length() < 8 || checkPassword.length() < 8) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
|
||||
}
|
||||
// 密码和校验密码相同
|
||||
if (!userPassword.equals(checkPassword)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
|
||||
}
|
||||
synchronized (userAccount.intern()) {
|
||||
// 账户不能重复
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("userAccount", userAccount);
|
||||
long count = this.baseMapper.selectCount(queryWrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
|
||||
}
|
||||
// 2. 加密
|
||||
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
|
||||
// 3. 插入数据
|
||||
User user = new User();
|
||||
user.setUserAccount(userAccount);
|
||||
user.setUserPassword(encryptPassword);
|
||||
boolean saveResult = this.save(user);
|
||||
if (!saveResult) {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
|
||||
}
|
||||
return user.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
|
||||
// 1. 校验
|
||||
if (StringUtils.isAnyBlank(userAccount, userPassword)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
|
||||
}
|
||||
if (userAccount.length() < 4) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
|
||||
}
|
||||
if (userPassword.length() < 8) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
|
||||
}
|
||||
// 2. 加密
|
||||
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
|
||||
// 查询用户是否存在
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("userAccount", userAccount);
|
||||
queryWrapper.eq("userPassword", encryptPassword);
|
||||
User user = this.baseMapper.selectOne(queryWrapper);
|
||||
// 用户不存在
|
||||
if (user == null) {
|
||||
log.info("user login failed, userAccount cannot match userPassword");
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
|
||||
}
|
||||
// 3. 记录用户的登录态
|
||||
request.getSession().setAttribute(USER_LOGIN_STATE, user);
|
||||
return this.getLoginUserVO(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUserVO userLoginByMpOpen(WxOAuth2UserInfo wxOAuth2UserInfo, HttpServletRequest request) {
|
||||
String unionId = wxOAuth2UserInfo.getUnionId();
|
||||
String mpOpenId = wxOAuth2UserInfo.getOpenid();
|
||||
// 单机锁
|
||||
synchronized (unionId.intern()) {
|
||||
// 查询用户是否已存在
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("unionId", unionId);
|
||||
User user = this.getOne(queryWrapper);
|
||||
// 被封号,禁止登录
|
||||
if (user != null && UserRoleEnum.BAN.getValue().equals(user.getUserRole())) {
|
||||
throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, "该用户已被封,禁止登录");
|
||||
}
|
||||
// 用户不存在则创建
|
||||
if (user == null) {
|
||||
user = new User();
|
||||
user.setUnionId(unionId);
|
||||
user.setMpOpenId(mpOpenId);
|
||||
user.setUserAvatar(wxOAuth2UserInfo.getHeadImgUrl());
|
||||
user.setUserName(wxOAuth2UserInfo.getNickname());
|
||||
boolean result = this.save(user);
|
||||
if (!result) {
|
||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "登录失败");
|
||||
}
|
||||
}
|
||||
// 记录用户的登录态
|
||||
request.getSession().setAttribute(USER_LOGIN_STATE, user);
|
||||
return getLoginUserVO(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public User getLoginUser(HttpServletRequest request) {
|
||||
// 先判断是否已登录
|
||||
Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
|
||||
User currentUser = (User) userObj;
|
||||
if (currentUser == null || currentUser.getId() == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 从数据库查询(追求性能的话可以注释,直接走缓存)
|
||||
long userId = currentUser.getId();
|
||||
currentUser = this.getById(userId);
|
||||
if (currentUser == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户(允许未登录)
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public User getLoginUserPermitNull(HttpServletRequest request) {
|
||||
// 先判断是否已登录
|
||||
Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
|
||||
User currentUser = (User) userObj;
|
||||
if (currentUser == null || currentUser.getId() == null) {
|
||||
return null;
|
||||
}
|
||||
// 从数据库查询(追求性能的话可以注释,直接走缓存)
|
||||
long userId = currentUser.getId();
|
||||
return this.getById(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为管理员
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isAdmin(HttpServletRequest request) {
|
||||
// 仅管理员可查询
|
||||
Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
|
||||
User user = (User) userObj;
|
||||
return isAdmin(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(User user) {
|
||||
return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注销
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
@Override
|
||||
public boolean userLogout(HttpServletRequest request) {
|
||||
if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
|
||||
}
|
||||
// 移除登录态
|
||||
request.getSession().removeAttribute(USER_LOGIN_STATE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUserVO getLoginUserVO(User user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
LoginUserVO loginUserVO = new LoginUserVO();
|
||||
BeanUtils.copyProperties(user, loginUserVO);
|
||||
return loginUserVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO getUserVO(User user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
UserVO userVO = new UserVO();
|
||||
BeanUtils.copyProperties(user, userVO);
|
||||
return userVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserVO> getUserVO(List<User> userList) {
|
||||
if (CollUtil.isEmpty(userList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return userList.stream().map(this::getUserVO).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
|
||||
if (userQueryRequest == null) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
|
||||
}
|
||||
Long id = userQueryRequest.getId();
|
||||
String unionId = userQueryRequest.getUnionId();
|
||||
String mpOpenId = userQueryRequest.getMpOpenId();
|
||||
String userName = userQueryRequest.getUserName();
|
||||
String userProfile = userQueryRequest.getUserProfile();
|
||||
String userRole = userQueryRequest.getUserRole();
|
||||
String sortField = userQueryRequest.getSortField();
|
||||
String sortOrder = userQueryRequest.getSortOrder();
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq(id != null, "id", id);
|
||||
queryWrapper.eq(StringUtils.isNotBlank(unionId), "unionId", unionId);
|
||||
queryWrapper.eq(StringUtils.isNotBlank(mpOpenId), "mpOpenId", mpOpenId);
|
||||
queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
|
||||
queryWrapper.like(StringUtils.isNotBlank(userProfile), "userProfile", userProfile);
|
||||
queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
|
||||
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
|
||||
sortField);
|
||||
return queryWrapper;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user