master
parent
c462d0b9e4
commit
a7209da760
@ -0,0 +1,57 @@
|
||||
package com.aurora.controller;
|
||||
|
||||
import com.aurora.annotation.OptLog;
|
||||
import com.aurora.model.dto.FriendLinkAdminDTO;
|
||||
import com.aurora.model.dto.FriendLinkDTO;
|
||||
import com.aurora.model.vo.ResultVO;
|
||||
import com.aurora.service.FriendLinkService;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.FriendLinkVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.aurora.constant.OptTypeConstant.*;
|
||||
|
||||
@Api(tags = "友链模块")
|
||||
@RestController
|
||||
public class FriendLinkController {
|
||||
|
||||
@Autowired
|
||||
private FriendLinkService friendLinkService;//调用Service层的友链业务方法
|
||||
|
||||
@ApiOperation(value = "查看友链列表")//用于前台展示
|
||||
@GetMapping("/links")
|
||||
public ResultVO<List<FriendLinkDTO>> listFriendLinks() {
|
||||
return ResultVO.ok(friendLinkService.listFriendLinks());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看后台友链列表")
|
||||
@GetMapping("/admin/links")
|
||||
public ResultVO<PageResultDTO<FriendLinkAdminDTO>> listFriendLinkDTO(ConditionVO conditionVO) {
|
||||
//ConditionVO conditionVO:封装后台查询友链的条件(比如友链名称关键词、分页信息等)
|
||||
return ResultVO.ok(friendLinkService.listFriendLinksAdmin(conditionVO));
|
||||
}
|
||||
|
||||
@OptLog(optType = SAVE_OR_UPDATE)
|
||||
@ApiOperation(value = "保存或修改友链")
|
||||
@PostMapping("/admin/links")
|
||||
public ResultVO<?> saveOrUpdateFriendLink(@Valid @RequestBody FriendLinkVO friendLinkVO) {
|
||||
//FriendLinkVO friendLinkVO:封装友链保存/修改的参数,且会被@Valid校验
|
||||
friendLinkService.saveOrUpdateFriendLink(friendLinkVO);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
|
||||
@OptLog(optType = DELETE)
|
||||
@ApiOperation(value = "删除友链")
|
||||
@DeleteMapping("/admin/links")
|
||||
public ResultVO<?> deleteFriendLink(@RequestBody List<Integer> linkIdList) {
|
||||
friendLinkService.removeByIds(linkIdList);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.aurora.controller;
|
||||
|
||||
import com.aurora.annotation.OptLog;
|
||||
import com.aurora.model.dto.RoleDTO;
|
||||
import com.aurora.model.dto.UserRoleDTO;
|
||||
import com.aurora.model.vo.ResultVO;
|
||||
import com.aurora.service.RoleService;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.RoleVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.aurora.constant.OptTypeConstant.*;
|
||||
|
||||
@Api(tags = "角色模块")
|
||||
@RestController
|
||||
public class RoleController {
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@ApiOperation(value = "查询用户角色选项")
|
||||
@GetMapping("/admin/users/role")
|
||||
public ResultVO<List<UserRoleDTO>> listUserRoles() {
|
||||
//返回所有可用的用户角色选项列表
|
||||
return ResultVO.ok(roleService.listUserRoles());
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "查询角色列表")//用于后台管理角色,分页的角色列表
|
||||
@GetMapping("/admin/roles")
|
||||
public ResultVO<PageResultDTO<RoleDTO>> listRoles(ConditionVO conditionVO) {
|
||||
return ResultVO.ok(roleService.listRoles(conditionVO));
|
||||
}
|
||||
|
||||
@OptLog(optType = SAVE_OR_UPDATE)
|
||||
@ApiOperation(value = "保存或更新角色")
|
||||
@PostMapping("/admin/role")
|
||||
public ResultVO<?> saveOrUpdateRole(@RequestBody @Valid RoleVO roleVO) {
|
||||
roleService.saveOrUpdateRole(roleVO);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
|
||||
@OptLog(optType = DELETE)
|
||||
@ApiOperation(value = "删除角色")
|
||||
@DeleteMapping("/admin/roles")
|
||||
public ResultVO<?> deleteRoles(@RequestBody List<Integer> roleIdList) {
|
||||
roleService.deleteRoles(roleIdList);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.aurora.controller;
|
||||
|
||||
|
||||
import com.aurora.annotation.OptLog;
|
||||
import com.aurora.model.dto.TagAdminDTO;
|
||||
import com.aurora.model.dto.TagDTO;
|
||||
import com.aurora.model.vo.ResultVO;
|
||||
import com.aurora.service.TagService;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.TagVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.aurora.constant.OptTypeConstant.*;
|
||||
|
||||
@Api(tags = "标签模块")
|
||||
@RestController
|
||||
public class TagController {
|
||||
@Autowired
|
||||
private TagService tagService;
|
||||
|
||||
@ApiOperation("获取所有标签")//获取系统中所有的标签列表
|
||||
@GetMapping("/tags/all")
|
||||
public ResultVO<List<TagDTO>> getAllTags() {
|
||||
return ResultVO.ok(tagService.listTags());
|
||||
}
|
||||
|
||||
@ApiOperation("获取前十个标签")//获取前10个标签
|
||||
@GetMapping("/tags/topTen")
|
||||
public ResultVO<List<TagDTO>> getTopTenTags() {
|
||||
return ResultVO.ok(tagService.listTopTenTags());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查询后台标签列表")//获取后台管理用的标签分页列表
|
||||
@GetMapping("/admin/tags")
|
||||
public ResultVO<PageResultDTO<TagAdminDTO>> listTagsAdmin(ConditionVO conditionVO) {
|
||||
return ResultVO.ok(tagService.listTagsAdmin(conditionVO));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "搜索文章标签")
|
||||
@GetMapping("/admin/tags/search")
|
||||
public ResultVO<List<TagAdminDTO>> listTagsAdminBySearch(ConditionVO condition) {
|
||||
return ResultVO.ok(tagService.listTagsAdminBySearch(condition));
|
||||
}
|
||||
|
||||
@OptLog(optType = SAVE_OR_UPDATE)
|
||||
@ApiOperation(value = "添加或修改标签")
|
||||
@PostMapping("/admin/tags")
|
||||
public ResultVO<?> saveOrUpdateTag(@Valid @RequestBody TagVO tagVO) {
|
||||
tagService.saveOrUpdateTag(tagVO);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
|
||||
@OptLog(optType = DELETE)
|
||||
@ApiOperation(value = "删除标签")
|
||||
@DeleteMapping("/admin/tags")
|
||||
public ResultVO<?> deleteTag(@RequestBody List<Integer> tagIdList) {
|
||||
tagService.deleteTag(tagIdList);
|
||||
return ResultVO.ok();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.Photo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PhotoMapper extends BaseMapper<Photo> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.Resource;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ResourceMapper extends BaseMapper<Resource> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.RoleMenu;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface RoleMenuMapper extends BaseMapper<RoleMenu> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.RoleResource;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface RoleResourceMapper extends BaseMapper<RoleResource> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.model.dto.TalkAdminDTO;
|
||||
import com.aurora.model.dto.TalkDTO;
|
||||
import com.aurora.entity.Talk;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface TalkMapper extends BaseMapper<Talk> {
|
||||
|
||||
List<TalkDTO> listTalks(@Param("current") Long current, @Param("size") Long size);
|
||||
|
||||
TalkDTO getTalkById(@Param("talkId") Integer talkId);
|
||||
|
||||
List<TalkAdminDTO> listTalksAdmin(@Param("current") Long current, @Param("size") Long size, @Param("conditionVO") ConditionVO conditionVO);
|
||||
|
||||
TalkAdminDTO getTalkByIdAdmin(@Param("talkId") Integer talkId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.UserInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserInfoMapper extends BaseMapper<UserInfo> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.aurora.mapper;
|
||||
|
||||
import com.aurora.entity.UserRole;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRoleMapper extends BaseMapper<UserRole> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.entity.ArticleTag;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface ArticleTagService extends IService<ArticleTag> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.ExceptionLogDTO;
|
||||
import com.aurora.entity.ExceptionLog;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
//主要用于处理异常日志的查询、分页展示等核心业务逻辑,通常与全局异常处理器或 AOP 切面配合使用
|
||||
public interface ExceptionLogService extends IService<ExceptionLog> {
|
||||
//分页获取异常日志列表(支持条件查询,通常用于后台管理系统的日志查看界面)
|
||||
PageResultDTO<ExceptionLogDTO> listExceptionLogs(ConditionVO conditionVO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.FriendLinkAdminDTO;
|
||||
import com.aurora.model.dto.FriendLinkDTO;
|
||||
import com.aurora.entity.FriendLink;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.FriendLinkVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface FriendLinkService extends IService<FriendLink> {
|
||||
|
||||
List<FriendLinkDTO> listFriendLinks();//获取所有友情链接列表(通常用于前台展示,如友情链接页面或侧边栏)
|
||||
|
||||
PageResultDTO<FriendLinkAdminDTO> listFriendLinksAdmin(ConditionVO conditionVO);//分页获取后台友情链接管理列表(支持条件查询,用于管理员控制台)
|
||||
|
||||
void saveOrUpdateFriendLink(FriendLinkVO friendLinkVO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.LabelOptionDTO;
|
||||
import com.aurora.model.dto.MenuDTO;
|
||||
import com.aurora.model.dto.UserMenuDTO;
|
||||
import com.aurora.entity.Menu;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.IsHiddenVO;
|
||||
import com.aurora.model.vo.MenuVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
//主要用于处理菜单的增删改查、层级结构构建、权限过滤和状态管理等核心业务逻辑
|
||||
public interface MenuService extends IService<Menu> {
|
||||
|
||||
List<MenuDTO> listMenus(ConditionVO conditionVO);//根据条件查询菜单列表(支持动态筛选,用于后台管理系统),常返回菜单的层级结构数据
|
||||
|
||||
void saveOrUpdateMenu(MenuVO menuVO);
|
||||
|
||||
void updateMenuIsHidden(IsHiddenVO isHiddenVO);//该方法通常需要权限校验,确保只有管理员可操作菜单的显示状态
|
||||
|
||||
void deleteMenu(Integer menuId);
|
||||
|
||||
List<LabelOptionDTO> listMenuOptions();
|
||||
|
||||
List<UserMenuDTO> listUserMenus();
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.OperationLogDTO;
|
||||
import com.aurora.entity.OperationLog;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface OperationLogService extends IService<OperationLog> {
|
||||
|
||||
PageResultDTO<OperationLogDTO> listOperationLogs(ConditionVO conditionVO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.PhotoAlbumAdminDTO;
|
||||
import com.aurora.model.dto.PhotoAlbumDTO;
|
||||
import com.aurora.entity.PhotoAlbum;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.PhotoAlbumVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PhotoAlbumService extends IService<PhotoAlbum> {
|
||||
|
||||
void saveOrUpdatePhotoAlbum(PhotoAlbumVO photoAlbumVO);
|
||||
|
||||
PageResultDTO<PhotoAlbumAdminDTO> listPhotoAlbumsAdmin(ConditionVO condition);
|
||||
|
||||
List<PhotoAlbumDTO> listPhotoAlbumInfosAdmin();
|
||||
|
||||
PhotoAlbumAdminDTO getPhotoAlbumByIdAdmin(Integer albumId);
|
||||
|
||||
void deletePhotoAlbumById(Integer albumId);
|
||||
|
||||
List<PhotoAlbumDTO> listPhotoAlbums();//返回结果通常按相册的创建时间或排序权重进行排序,包含前台展示所需的核心信息
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.entity.RoleMenu;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface RoleMenuService extends IService<RoleMenu> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.entity.RoleResource;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface RoleResourceService extends IService<RoleResource> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.TagAdminDTO;
|
||||
import com.aurora.model.dto.TagDTO;
|
||||
import com.aurora.entity.Tag;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.TagVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TagService extends IService<Tag> {
|
||||
|
||||
List<TagDTO> listTags();
|
||||
|
||||
List<TagDTO> listTopTenTags();
|
||||
|
||||
PageResultDTO<TagAdminDTO> listTagsAdmin(ConditionVO conditionVO);
|
||||
|
||||
List<TagAdminDTO> listTagsAdminBySearch(ConditionVO conditionVO);
|
||||
|
||||
void saveOrUpdateTag(TagVO tagVO);
|
||||
|
||||
void deleteTag(List<Integer> tagIds);
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.model.dto.UniqueViewDTO;
|
||||
import com.aurora.entity.UniqueView;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UniqueViewService extends IService<UniqueView> {
|
||||
|
||||
List<UniqueViewDTO> listUniqueViews();
|
||||
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.aurora.service;
|
||||
|
||||
import com.aurora.entity.UserRole;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface UserRoleService extends IService<UserRole> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,376 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aurora.model.dto.*;
|
||||
import com.aurora.entity.Article;
|
||||
import com.aurora.entity.ArticleTag;
|
||||
import com.aurora.entity.Category;
|
||||
import com.aurora.entity.Tag;
|
||||
import com.aurora.enums.FileExtEnum;
|
||||
import com.aurora.enums.FilePathEnum;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.ArticleMapper;
|
||||
import com.aurora.mapper.ArticleTagMapper;
|
||||
import com.aurora.mapper.CategoryMapper;
|
||||
import com.aurora.mapper.TagMapper;
|
||||
import com.aurora.service.ArticleService;
|
||||
import com.aurora.service.ArticleTagService;
|
||||
import com.aurora.service.RedisService;
|
||||
import com.aurora.service.TagService;
|
||||
import com.aurora.strategy.context.SearchStrategyContext;
|
||||
import com.aurora.strategy.context.UploadStrategyContext;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.util.UserUtil;
|
||||
import com.aurora.model.vo.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.RabbitMQConstant.SUBSCRIBE_EXCHANGE;
|
||||
import static com.aurora.constant.RedisConstant.*;
|
||||
import static com.aurora.enums.ArticleStatusEnum.*;
|
||||
import static com.aurora.enums.StatusCodeEnum.ARTICLE_ACCESS_FAIL;
|
||||
|
||||
@Service
|
||||
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
|
||||
|
||||
@Autowired
|
||||
private ArticleMapper articleMapper;
|
||||
|
||||
@Autowired
|
||||
private ArticleTagMapper articleTagMapper;
|
||||
|
||||
@Autowired
|
||||
private CategoryMapper categoryMapper;
|
||||
|
||||
@Autowired
|
||||
private TagMapper tagMapper;
|
||||
|
||||
@Autowired
|
||||
private TagService tagService;
|
||||
|
||||
@Autowired
|
||||
private ArticleTagService articleTagService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Autowired
|
||||
private UploadStrategyContext uploadStrategyContext;
|
||||
|
||||
@Autowired
|
||||
private SearchStrategyContext searchStrategyContext;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public TopAndFeaturedArticlesDTO listTopAndFeaturedArticles() {
|
||||
List<ArticleCardDTO> articleCardDTOs = articleMapper.listTopAndFeaturedArticles();
|
||||
if (articleCardDTOs.size() == 0) {
|
||||
return new TopAndFeaturedArticlesDTO();
|
||||
} else if (articleCardDTOs.size() > 3) {
|
||||
articleCardDTOs = articleCardDTOs.subList(0, 3);
|
||||
}
|
||||
TopAndFeaturedArticlesDTO topAndFeaturedArticlesDTO = new TopAndFeaturedArticlesDTO();
|
||||
topAndFeaturedArticlesDTO.setTopArticle(articleCardDTOs.get(0));
|
||||
articleCardDTOs.remove(0);
|
||||
topAndFeaturedArticlesDTO.setFeaturedArticles(articleCardDTOs);
|
||||
return topAndFeaturedArticlesDTO;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<ArticleCardDTO> listArticles() {
|
||||
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>()
|
||||
.eq(Article::getIsDelete, 0)
|
||||
.in(Article::getStatus, 1, 2);
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> articleMapper.selectCount(queryWrapper));
|
||||
List<ArticleCardDTO> articles = articleMapper.listArticles(PageUtil.getLimitCurrent(), PageUtil.getSize());
|
||||
return new PageResultDTO<>(articles, asyncCount.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<ArticleCardDTO> listArticlesByCategoryId(Integer categoryId) {
|
||||
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>().eq(Article::getCategoryId, categoryId);
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> articleMapper.selectCount(queryWrapper));
|
||||
List<ArticleCardDTO> articles = articleMapper.getArticlesByCategoryId(PageUtil.getLimitCurrent(), PageUtil.getSize(), categoryId);
|
||||
return new PageResultDTO<>(articles, asyncCount.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public ArticleDTO getArticleById(Integer articleId) {
|
||||
Article articleForCheck = articleMapper.selectOne(new LambdaQueryWrapper<Article>().eq(Article::getId, articleId));
|
||||
if (Objects.isNull(articleForCheck)) {
|
||||
return null;
|
||||
}
|
||||
if (articleForCheck.getStatus().equals(2)) {
|
||||
Boolean isAccess;
|
||||
try {
|
||||
isAccess = redisService.sIsMember(ARTICLE_ACCESS + UserUtil.getUserDetailsDTO().getId(), articleId);
|
||||
} catch (Exception exception) {
|
||||
throw new BizException(ARTICLE_ACCESS_FAIL);
|
||||
}
|
||||
if (isAccess.equals(false)) {
|
||||
throw new BizException(ARTICLE_ACCESS_FAIL);
|
||||
}
|
||||
}
|
||||
updateArticleViewsCount(articleId);
|
||||
CompletableFuture<ArticleDTO> asyncArticle = CompletableFuture.supplyAsync(() -> articleMapper.getArticleById(articleId));
|
||||
CompletableFuture<ArticleCardDTO> asyncPreArticle = CompletableFuture.supplyAsync(() -> {
|
||||
ArticleCardDTO preArticle = articleMapper.getPreArticleById(articleId);
|
||||
if (Objects.isNull(preArticle)) {
|
||||
preArticle = articleMapper.getLastArticle();
|
||||
}
|
||||
return preArticle;
|
||||
});
|
||||
CompletableFuture<ArticleCardDTO> asyncNextArticle = CompletableFuture.supplyAsync(() -> {
|
||||
ArticleCardDTO nextArticle = articleMapper.getNextArticleById(articleId);
|
||||
if (Objects.isNull(nextArticle)) {
|
||||
nextArticle = articleMapper.getFirstArticle();
|
||||
}
|
||||
return nextArticle;
|
||||
});
|
||||
ArticleDTO article = asyncArticle.get();
|
||||
if (Objects.isNull(article)) {
|
||||
return null;
|
||||
}
|
||||
Double score = redisService.zScore(ARTICLE_VIEWS_COUNT, articleId);
|
||||
if (Objects.nonNull(score)) {
|
||||
article.setViewCount(score.intValue());
|
||||
}
|
||||
article.setPreArticleCard(asyncPreArticle.get());
|
||||
article.setNextArticleCard(asyncNextArticle.get());
|
||||
return article;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accessArticle(ArticlePasswordVO articlePasswordVO) {
|
||||
Article article = articleMapper.selectOne(new LambdaQueryWrapper<Article>().eq(Article::getId, articlePasswordVO.getArticleId()));
|
||||
if (Objects.isNull(article)) {
|
||||
throw new BizException("文章不存在");
|
||||
}
|
||||
if (article.getPassword().equals(articlePasswordVO.getArticlePassword())) {
|
||||
redisService.sAdd(ARTICLE_ACCESS + UserUtil.getUserDetailsDTO().getId(), articlePasswordVO.getArticleId());
|
||||
} else {
|
||||
throw new BizException("密码错误");
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<ArticleCardDTO> listArticlesByTagId(Integer tagId) {
|
||||
LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<ArticleTag>().eq(ArticleTag::getTagId, tagId);
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> articleTagMapper.selectCount(queryWrapper));
|
||||
List<ArticleCardDTO> articles = articleMapper.listArticlesByTagId(PageUtil.getLimitCurrent(), PageUtil.getSize(), tagId);
|
||||
return new PageResultDTO<>(articles, asyncCount.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<ArchiveDTO> listArchives() {
|
||||
LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<Article>().eq(Article::getIsDelete, 0).eq(Article::getStatus, 1);
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> articleMapper.selectCount(queryWrapper));
|
||||
List<ArticleCardDTO> articles = articleMapper.listArchives(PageUtil.getLimitCurrent(), PageUtil.getSize());
|
||||
HashMap<String, List<ArticleCardDTO>> map = new HashMap<>();
|
||||
for (ArticleCardDTO article : articles) {
|
||||
LocalDateTime createTime = article.getCreateTime();
|
||||
int month = createTime.getMonth().getValue();
|
||||
int year = createTime.getYear();
|
||||
String key = year + "-" + month;
|
||||
if (Objects.isNull(map.get(key))) {
|
||||
List<ArticleCardDTO> articleCardDTOS = new ArrayList<>();
|
||||
articleCardDTOS.add(article);
|
||||
map.put(key, articleCardDTOS);
|
||||
} else {
|
||||
map.get(key).add(article);
|
||||
}
|
||||
}
|
||||
List<ArchiveDTO> archiveDTOs = new ArrayList<>();
|
||||
map.forEach((key, value) -> archiveDTOs.add(ArchiveDTO.builder().Time(key).articles(value).build()));
|
||||
archiveDTOs.sort((o1, o2) -> {
|
||||
String[] o1s = o1.getTime().split("-");
|
||||
String[] o2s = o2.getTime().split("-");
|
||||
int o1Year = Integer.parseInt(o1s[0]);
|
||||
int o1Month = Integer.parseInt(o1s[1]);
|
||||
int o2Year = Integer.parseInt(o2s[0]);
|
||||
int o2Month = Integer.parseInt(o2s[1]);
|
||||
if (o1Year > o2Year) {
|
||||
return -1;
|
||||
} else if (o1Year < o2Year) {
|
||||
return 1;
|
||||
} else return Integer.compare(o2Month, o1Month);
|
||||
});
|
||||
return new PageResultDTO<>(archiveDTOs, asyncCount.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<ArticleAdminDTO> listArticlesAdmin(ConditionVO conditionVO) {
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> articleMapper.countArticleAdmins(conditionVO));
|
||||
List<ArticleAdminDTO> articleAdminDTOs = articleMapper.listArticlesAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
Map<Object, Double> viewsCountMap = redisService.zAllScore(ARTICLE_VIEWS_COUNT);
|
||||
articleAdminDTOs.forEach(item -> {
|
||||
Double viewsCount = viewsCountMap.get(item.getId());
|
||||
if (Objects.nonNull(viewsCount)) {
|
||||
item.setViewsCount(viewsCount.intValue());
|
||||
}
|
||||
});
|
||||
return new PageResultDTO<>(articleAdminDTOs, asyncCount.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveOrUpdateArticle(ArticleVO articleVO) {
|
||||
Category category = saveArticleCategory(articleVO);
|
||||
Article article = BeanCopyUtil.copyObject(articleVO, Article.class);
|
||||
if (Objects.nonNull(category)) {
|
||||
article.setCategoryId(category.getId());
|
||||
}
|
||||
article.setUserId(UserUtil.getUserDetailsDTO().getUserInfoId());
|
||||
this.saveOrUpdate(article);
|
||||
saveArticleTag(articleVO, article.getId());
|
||||
if (article.getStatus().equals(1)) {
|
||||
rabbitTemplate.convertAndSend(SUBSCRIBE_EXCHANGE, "*", new Message(JSON.toJSONBytes(article.getId()), new MessageProperties()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArticleTopAndFeatured(ArticleTopFeaturedVO articleTopFeaturedVO) {
|
||||
Article article = Article.builder()
|
||||
.id(articleTopFeaturedVO.getId())
|
||||
.isTop(articleTopFeaturedVO.getIsTop())
|
||||
.isFeatured(articleTopFeaturedVO.getIsFeatured())
|
||||
.build();
|
||||
articleMapper.updateById(article);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArticleDelete(DeleteVO deleteVO) {
|
||||
List<Article> articles = deleteVO.getIds().stream()
|
||||
.map(id -> Article.builder()
|
||||
.id(id)
|
||||
.isDelete(deleteVO.getIsDelete())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
this.updateBatchById(articles);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteArticles(List<Integer> articleIds) {
|
||||
articleTagMapper.delete(new LambdaQueryWrapper<ArticleTag>()
|
||||
.in(ArticleTag::getArticleId, articleIds));
|
||||
articleMapper.deleteBatchIds(articleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ArticleAdminViewDTO getArticleByIdAdmin(Integer articleId) {
|
||||
Article article = articleMapper.selectById(articleId);
|
||||
Category category = categoryMapper.selectById(article.getCategoryId());
|
||||
String categoryName = null;
|
||||
if (Objects.nonNull(category)) {
|
||||
categoryName = category.getCategoryName();
|
||||
}
|
||||
List<String> tagNames = tagMapper.listTagNamesByArticleId(articleId);
|
||||
ArticleAdminViewDTO articleAdminViewDTO = BeanCopyUtil.copyObject(article, ArticleAdminViewDTO.class);
|
||||
articleAdminViewDTO.setCategoryName(categoryName);
|
||||
articleAdminViewDTO.setTagNames(tagNames);
|
||||
return articleAdminViewDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> exportArticles(List<Integer> articleIds) {
|
||||
List<Article> articles = articleMapper.selectList(new LambdaQueryWrapper<Article>()
|
||||
.select(Article::getArticleTitle, Article::getArticleContent)
|
||||
.in(Article::getId, articleIds));
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Article article : articles) {
|
||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(article.getArticleContent().getBytes())) {
|
||||
String url = uploadStrategyContext.executeUploadStrategy(article.getArticleTitle() + FileExtEnum.MD.getExtName(), inputStream, FilePathEnum.MD.getPath());
|
||||
urls.add(url);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new BizException("导出文章失败");
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArticleSearchDTO> listArticlesBySearch(ConditionVO condition) {
|
||||
return searchStrategyContext.executeSearchStrategy(condition.getKeywords());
|
||||
}
|
||||
|
||||
public void updateArticleViewsCount(Integer articleId) {
|
||||
redisService.zIncr(ARTICLE_VIEWS_COUNT, articleId, 1D);
|
||||
}
|
||||
|
||||
private Category saveArticleCategory(ArticleVO articleVO) {
|
||||
Category category = categoryMapper.selectOne(new LambdaQueryWrapper<Category>()
|
||||
.eq(Category::getCategoryName, articleVO.getCategoryName()));
|
||||
if (Objects.isNull(category) && !articleVO.getStatus().equals(DRAFT.getStatus())) {
|
||||
category = Category.builder()
|
||||
.categoryName(articleVO.getCategoryName())
|
||||
.build();
|
||||
categoryMapper.insert(category);
|
||||
}
|
||||
return category;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveArticleTag(ArticleVO articleVO, Integer articleId) {
|
||||
if (Objects.nonNull(articleVO.getId())) {
|
||||
articleTagMapper.delete(new LambdaQueryWrapper<ArticleTag>()
|
||||
.eq(ArticleTag::getArticleId, articleVO.getId()));
|
||||
}
|
||||
List<String> tagNames = articleVO.getTagNames();
|
||||
if (CollectionUtils.isNotEmpty(tagNames)) {
|
||||
List<Tag> existTags = tagService.list(new LambdaQueryWrapper<Tag>()
|
||||
.in(Tag::getTagName, tagNames));
|
||||
List<String> existTagNames = existTags.stream()
|
||||
.map(Tag::getTagName)
|
||||
.collect(Collectors.toList());
|
||||
List<Integer> existTagIds = existTags.stream()
|
||||
.map(Tag::getId)
|
||||
.collect(Collectors.toList());
|
||||
tagNames.removeAll(existTagNames);
|
||||
if (CollectionUtils.isNotEmpty(tagNames)) {
|
||||
List<Tag> tags = tagNames.stream().map(item -> Tag.builder()
|
||||
.tagName(item)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
tagService.saveBatch(tags);
|
||||
List<Integer> tagIds = tags.stream()
|
||||
.map(Tag::getId)
|
||||
.collect(Collectors.toList());
|
||||
existTagIds.addAll(tagIds);
|
||||
}
|
||||
List<ArticleTag> articleTags = existTagIds.stream().map(item -> ArticleTag.builder()
|
||||
.articleId(articleId)
|
||||
.tagId(item)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
articleTagService.saveBatch(articleTags);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.entity.ArticleTag;
|
||||
import com.aurora.mapper.ArticleTagMapper;
|
||||
import com.aurora.service.ArticleTagService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ArticleTagServiceImpl extends ServiceImpl<ArticleTagMapper, ArticleTag> implements ArticleTagService {
|
||||
|
||||
}
|
||||
@ -0,0 +1,207 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aurora.model.dto.*;
|
||||
import com.aurora.entity.*;
|
||||
import com.aurora.mapper.*;
|
||||
import com.aurora.service.AuroraInfoService;
|
||||
import com.aurora.service.RedisService;
|
||||
import com.aurora.service.UniqueViewService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.IpUtil;
|
||||
import com.aurora.model.vo.AboutVO;
|
||||
import com.aurora.model.vo.WebsiteConfigVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import eu.bitwalker.useragentutils.Browser;
|
||||
import eu.bitwalker.useragentutils.OperatingSystem;
|
||||
import eu.bitwalker.useragentutils.UserAgent;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.*;
|
||||
import static com.aurora.constant.RedisConstant.*;
|
||||
|
||||
@Service
|
||||
public class AuroraInfoServiceImpl implements AuroraInfoService {
|
||||
|
||||
@Autowired
|
||||
private WebsiteConfigMapper websiteConfigMapper;
|
||||
|
||||
@Autowired
|
||||
private ArticleMapper articleMapper;
|
||||
|
||||
@Autowired
|
||||
private CategoryMapper categoryMapper;
|
||||
|
||||
@Autowired
|
||||
private TagMapper tagMapper;
|
||||
|
||||
@Autowired
|
||||
private CommentMapper commentMapper;
|
||||
|
||||
@Autowired
|
||||
private TalkMapper talkMapper;
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private AboutMapper aboutMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private UniqueViewService uniqueViewService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Override
|
||||
public void report() {
|
||||
String ipAddress = IpUtil.getIpAddress(request);
|
||||
UserAgent userAgent = IpUtil.getUserAgent(request);
|
||||
Browser browser = userAgent.getBrowser();
|
||||
OperatingSystem operatingSystem = userAgent.getOperatingSystem();
|
||||
String uuid = ipAddress + browser.getName() + operatingSystem.getName();
|
||||
String md5 = DigestUtils.md5DigestAsHex(uuid.getBytes());
|
||||
if (!redisService.sIsMember(UNIQUE_VISITOR, md5)) {
|
||||
String ipSource = IpUtil.getIpSource(ipAddress);
|
||||
if (StringUtils.isNotBlank(ipSource)) {
|
||||
String ipProvince = IpUtil.getIpProvince(ipSource);
|
||||
redisService.hIncr(VISITOR_AREA, ipProvince, 1L);
|
||||
} else {
|
||||
redisService.hIncr(VISITOR_AREA, UNKNOWN, 1L);
|
||||
}
|
||||
redisService.incr(BLOG_VIEWS_COUNT, 1);
|
||||
redisService.sAdd(UNIQUE_VISITOR, md5);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public AuroraHomeInfoDTO getAuroraHomeInfo() {
|
||||
CompletableFuture<Integer> asyncArticleCount = CompletableFuture.supplyAsync(() -> articleMapper.selectCount(new LambdaQueryWrapper<Article>().eq(Article::getIsDelete, FALSE)));
|
||||
CompletableFuture<Integer> asyncCategoryCount = CompletableFuture.supplyAsync(() -> categoryMapper.selectCount(null));
|
||||
CompletableFuture<Integer> asyncTagCount = CompletableFuture.supplyAsync(() -> tagMapper.selectCount(null));
|
||||
CompletableFuture<Integer> asyncTalkCount = CompletableFuture.supplyAsync(() -> talkMapper.selectCount(null));
|
||||
CompletableFuture<WebsiteConfigDTO> asyncWebsiteConfig = CompletableFuture.supplyAsync(this::getWebsiteConfig);
|
||||
CompletableFuture<Integer> asyncViewCount = CompletableFuture.supplyAsync(() -> {
|
||||
Object count = redisService.get(BLOG_VIEWS_COUNT);
|
||||
return Integer.parseInt(Optional.ofNullable(count).orElse(0).toString());
|
||||
});
|
||||
return AuroraHomeInfoDTO.builder()
|
||||
.articleCount(asyncArticleCount.get())
|
||||
.categoryCount(asyncCategoryCount.get())
|
||||
.tagCount(asyncTagCount.get())
|
||||
.talkCount(asyncTalkCount.get())
|
||||
.websiteConfigDTO(asyncWebsiteConfig.get())
|
||||
.viewCount(asyncViewCount.get()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuroraAdminInfoDTO getAuroraAdminInfo() {
|
||||
Object count = redisService.get(BLOG_VIEWS_COUNT);
|
||||
Integer viewsCount = Integer.parseInt(Optional.ofNullable(count).orElse(0).toString());
|
||||
Integer messageCount = commentMapper.selectCount(new LambdaQueryWrapper<Comment>().eq(Comment::getType, 2));
|
||||
Integer userCount = userInfoMapper.selectCount(null);
|
||||
Integer articleCount = articleMapper.selectCount(new LambdaQueryWrapper<Article>()
|
||||
.eq(Article::getIsDelete, FALSE));
|
||||
List<UniqueViewDTO> uniqueViews = uniqueViewService.listUniqueViews();
|
||||
List<ArticleStatisticsDTO> articleStatisticsDTOs = articleMapper.listArticleStatistics();
|
||||
List<CategoryDTO> categoryDTOs = categoryMapper.listCategories();
|
||||
List<TagDTO> tagDTOs = BeanCopyUtil.copyList(tagMapper.selectList(null), TagDTO.class);
|
||||
Map<Object, Double> articleMap = redisService.zReverseRangeWithScore(ARTICLE_VIEWS_COUNT, 0, 4);
|
||||
AuroraAdminInfoDTO auroraAdminInfoDTO = AuroraAdminInfoDTO.builder()
|
||||
.articleStatisticsDTOs(articleStatisticsDTOs)
|
||||
.tagDTOs(tagDTOs)
|
||||
.viewsCount(viewsCount)
|
||||
.messageCount(messageCount)
|
||||
.userCount(userCount)
|
||||
.articleCount(articleCount)
|
||||
.categoryDTOs(categoryDTOs)
|
||||
.uniqueViewDTOs(uniqueViews)
|
||||
.build();
|
||||
if (CollectionUtils.isNotEmpty(articleMap)) {
|
||||
List<ArticleRankDTO> articleRankDTOList = listArticleRank(articleMap);
|
||||
auroraAdminInfoDTO.setArticleRankDTOs(articleRankDTOList);
|
||||
}
|
||||
return auroraAdminInfoDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateWebsiteConfig(WebsiteConfigVO websiteConfigVO) {
|
||||
WebsiteConfig websiteConfig = WebsiteConfig.builder()
|
||||
.id(DEFAULT_CONFIG_ID)
|
||||
.config(JSON.toJSONString(websiteConfigVO))
|
||||
.build();
|
||||
websiteConfigMapper.updateById(websiteConfig);
|
||||
redisService.del(WEBSITE_CONFIG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebsiteConfigDTO getWebsiteConfig() {
|
||||
WebsiteConfigDTO websiteConfigDTO;
|
||||
Object websiteConfig = redisService.get(WEBSITE_CONFIG);
|
||||
if (Objects.nonNull(websiteConfig)) {
|
||||
websiteConfigDTO = JSON.parseObject(websiteConfig.toString(), WebsiteConfigDTO.class);
|
||||
} else {
|
||||
String config = websiteConfigMapper.selectById(DEFAULT_CONFIG_ID).getConfig();
|
||||
websiteConfigDTO = JSON.parseObject(config, WebsiteConfigDTO.class);
|
||||
redisService.set(WEBSITE_CONFIG, config);
|
||||
}
|
||||
return websiteConfigDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateAbout(AboutVO aboutVO) {
|
||||
About about = About.builder()
|
||||
.id(DEFAULT_ABOUT_ID)
|
||||
.content(JSON.toJSONString(aboutVO))
|
||||
.build();
|
||||
aboutMapper.updateById(about);
|
||||
redisService.del(ABOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AboutDTO getAbout() {
|
||||
AboutDTO aboutDTO;
|
||||
Object about = redisService.get(ABOUT);
|
||||
if (Objects.nonNull(about)) {
|
||||
aboutDTO = JSON.parseObject(about.toString(), AboutDTO.class);
|
||||
} else {
|
||||
String content = aboutMapper.selectById(DEFAULT_ABOUT_ID).getContent();
|
||||
aboutDTO = JSON.parseObject(content, AboutDTO.class);
|
||||
redisService.set(ABOUT, content);
|
||||
}
|
||||
return aboutDTO;
|
||||
}
|
||||
|
||||
private List<ArticleRankDTO> listArticleRank(Map<Object, Double> articleMap) {
|
||||
List<Integer> articleIds = new ArrayList<>(articleMap.size());
|
||||
articleMap.forEach((key, value) -> articleIds.add((Integer) key));
|
||||
return articleMapper.selectList(new LambdaQueryWrapper<Article>()
|
||||
.select(Article::getId, Article::getArticleTitle)
|
||||
.in(Article::getId, articleIds))
|
||||
.stream().map(article -> ArticleRankDTO.builder()
|
||||
.articleTitle(article.getArticleTitle())
|
||||
.viewsCount(articleMap.get(article.getId()).intValue())
|
||||
.build())
|
||||
.sorted(Comparator.comparingInt(ArticleRankDTO::getViewsCount).reversed())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.CategoryAdminDTO;
|
||||
import com.aurora.model.dto.CategoryDTO;
|
||||
import com.aurora.model.dto.CategoryOptionDTO;
|
||||
import com.aurora.entity.Article;
|
||||
import com.aurora.entity.Category;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.ArticleMapper;
|
||||
import com.aurora.mapper.CategoryMapper;
|
||||
import com.aurora.service.CategoryService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.CategoryVO;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
|
||||
|
||||
@Autowired
|
||||
private CategoryMapper categoryMapper;
|
||||
|
||||
@Autowired
|
||||
private ArticleMapper articleMapper;
|
||||
|
||||
@Override
|
||||
public List<CategoryDTO> listCategories() {
|
||||
return categoryMapper.listCategories();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<CategoryAdminDTO> listCategoriesAdmin(ConditionVO conditionVO) {
|
||||
Integer count = categoryMapper.selectCount(new LambdaQueryWrapper<Category>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Category::getCategoryName, conditionVO.getKeywords()));
|
||||
if (count == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<CategoryAdminDTO> categoryList = categoryMapper.listCategoriesAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
return new PageResultDTO<>(categoryList, count);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<CategoryOptionDTO> listCategoriesBySearch(ConditionVO conditionVO) {
|
||||
List<Category> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Category::getCategoryName, conditionVO.getKeywords())
|
||||
.orderByDesc(Category::getId));
|
||||
return BeanCopyUtil.copyList(categoryList, CategoryOptionDTO.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteCategories(List<Integer> categoryIds) {
|
||||
Integer count = articleMapper.selectCount(new LambdaQueryWrapper<Article>()
|
||||
.in(Article::getCategoryId, categoryIds));
|
||||
if (count > 0) {
|
||||
throw new BizException("删除失败,该分类下存在文章");
|
||||
}
|
||||
categoryMapper.deleteBatchIds(categoryIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdateCategory(CategoryVO categoryVO) {
|
||||
Category existCategory = categoryMapper.selectOne(new LambdaQueryWrapper<Category>()
|
||||
.select(Category::getId)
|
||||
.eq(Category::getCategoryName, categoryVO.getCategoryName()));
|
||||
if (Objects.nonNull(existCategory) && !existCategory.getId().equals(categoryVO.getId())) {
|
||||
throw new BizException("分类名已存在");
|
||||
}
|
||||
Category category = Category.builder()
|
||||
.id(categoryVO.getId())
|
||||
.categoryName(categoryVO.getCategoryName())
|
||||
.build();
|
||||
this.saveOrUpdate(category);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,328 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aurora.model.dto.*;
|
||||
import com.aurora.entity.Article;
|
||||
import com.aurora.entity.Comment;
|
||||
import com.aurora.entity.Talk;
|
||||
import com.aurora.entity.UserInfo;
|
||||
import com.aurora.enums.CommentTypeEnum;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.ArticleMapper;
|
||||
import com.aurora.mapper.CommentMapper;
|
||||
import com.aurora.mapper.TalkMapper;
|
||||
import com.aurora.mapper.UserInfoMapper;
|
||||
import com.aurora.service.AuroraInfoService;
|
||||
import com.aurora.service.CommentService;
|
||||
import com.aurora.util.HTMLUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.util.UserUtil;
|
||||
import com.aurora.model.vo.CommentVO;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.ReviewVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.*;
|
||||
import static com.aurora.constant.RabbitMQConstant.EMAIL_EXCHANGE;
|
||||
import static com.aurora.enums.CommentTypeEnum.*;
|
||||
|
||||
@Service
|
||||
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
|
||||
|
||||
@Value("${website.url}")
|
||||
private String websiteUrl;
|
||||
|
||||
@Autowired
|
||||
private CommentMapper commentMapper;
|
||||
|
||||
@Autowired
|
||||
private ArticleMapper articleMapper;
|
||||
|
||||
@Autowired
|
||||
private TalkMapper talkMapper;
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private AuroraInfoService auroraInfoService;
|
||||
|
||||
@Autowired
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
private static final List<Integer> types = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
CommentTypeEnum[] values = CommentTypeEnum.values();
|
||||
for (CommentTypeEnum value : values) {
|
||||
types.add(value.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveComment(CommentVO commentVO) {
|
||||
checkCommentVO(commentVO);
|
||||
WebsiteConfigDTO websiteConfig = auroraInfoService.getWebsiteConfig();
|
||||
Integer isCommentReview = websiteConfig.getIsCommentReview();
|
||||
commentVO.setCommentContent(HTMLUtil.filter(commentVO.getCommentContent()));
|
||||
Comment comment = Comment.builder()
|
||||
.userId(UserUtil.getUserDetailsDTO().getUserInfoId())
|
||||
.replyUserId(commentVO.getReplyUserId())
|
||||
.topicId(commentVO.getTopicId())
|
||||
.commentContent(commentVO.getCommentContent())
|
||||
.parentId(commentVO.getParentId())
|
||||
.type(commentVO.getType())
|
||||
.isReview(isCommentReview == TRUE ? FALSE : TRUE)
|
||||
.build();
|
||||
commentMapper.insert(comment);
|
||||
String fromNickname = UserUtil.getUserDetailsDTO().getNickname();
|
||||
if (websiteConfig.getIsEmailNotice().equals(TRUE)) {
|
||||
CompletableFuture.runAsync(() -> notice(comment, fromNickname));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDTO<CommentDTO> listComments(CommentVO commentVO) {
|
||||
Integer commentCount = commentMapper.selectCount(new LambdaQueryWrapper<Comment>()
|
||||
.eq(Objects.nonNull(commentVO.getTopicId()), Comment::getTopicId, commentVO.getTopicId())
|
||||
.eq(Comment::getType, commentVO.getType())
|
||||
.isNull(Comment::getParentId)
|
||||
.eq(Comment::getIsReview, TRUE));
|
||||
if (commentCount == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<CommentDTO> commentDTOs = commentMapper.listComments(PageUtil.getLimitCurrent(), PageUtil.getSize(), commentVO);
|
||||
if (CollectionUtils.isEmpty(commentDTOs)) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<Integer> commentIds = commentDTOs.stream()
|
||||
.map(CommentDTO::getId)
|
||||
.collect(Collectors.toList());
|
||||
List<ReplyDTO> replyDTOS = commentMapper.listReplies(commentIds);
|
||||
Map<Integer, List<ReplyDTO>> replyMap = replyDTOS.stream()
|
||||
.collect(Collectors.groupingBy(ReplyDTO::getParentId));
|
||||
commentDTOs.forEach(item -> item.setReplyDTOs(replyMap.get(item.getId())));
|
||||
return new PageResultDTO<>(commentDTOs, commentCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReplyDTO> listRepliesByCommentId(Integer commentId) {
|
||||
return commentMapper.listReplies(Collections.singletonList(commentId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommentDTO> listTopSixComments() {
|
||||
return commentMapper.listTopSixComments();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<CommentAdminDTO> listCommentsAdmin(ConditionVO conditionVO) {
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> commentMapper.countComments(conditionVO));
|
||||
List<CommentAdminDTO> commentBackDTOList = commentMapper.listCommentsAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
return new PageResultDTO<>(commentBackDTOList, asyncCount.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCommentsReview(ReviewVO reviewVO) {
|
||||
List<Comment> comments = reviewVO.getIds().stream().map(item -> Comment.builder()
|
||||
.id(item)
|
||||
.isReview(reviewVO.getIsReview())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
this.updateBatchById(comments);
|
||||
}
|
||||
|
||||
public void checkCommentVO(CommentVO commentVO) {
|
||||
if (!types.contains(commentVO.getType())) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
if (Objects.requireNonNull(getCommentEnum(commentVO.getType())) == ARTICLE || Objects.requireNonNull(getCommentEnum(commentVO.getType())) == TALK) {
|
||||
if (Objects.isNull(commentVO.getTopicId())) {
|
||||
throw new BizException("参数校验异常");
|
||||
} else {
|
||||
if (Objects.requireNonNull(getCommentEnum(commentVO.getType())) == ARTICLE) {
|
||||
Article article = articleMapper.selectOne(new LambdaQueryWrapper<Article>().select(Article::getId, Article::getUserId).eq(Article::getId, commentVO.getTopicId()));
|
||||
if (Objects.isNull(article)) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
}
|
||||
if (Objects.requireNonNull(getCommentEnum(commentVO.getType())) == TALK) {
|
||||
Talk talk = talkMapper.selectOne(new LambdaQueryWrapper<Talk>().select(Talk::getId, Talk::getUserId).eq(Talk::getId, commentVO.getTopicId()));
|
||||
if (Objects.isNull(talk)) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Objects.requireNonNull(getCommentEnum(commentVO.getType())) == LINK
|
||||
|| Objects.requireNonNull(getCommentEnum(commentVO.getType())) == ABOUT
|
||||
|| Objects.requireNonNull(getCommentEnum(commentVO.getType())) == MESSAGE) {
|
||||
if (Objects.nonNull(commentVO.getTopicId())) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
}
|
||||
if (Objects.isNull(commentVO.getParentId())) {
|
||||
if (Objects.nonNull(commentVO.getReplyUserId())) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
}
|
||||
if (Objects.nonNull(commentVO.getParentId())) {
|
||||
Comment parentComment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().select(Comment::getId, Comment::getParentId, Comment::getType).eq(Comment::getId, commentVO.getParentId()));
|
||||
if (Objects.isNull(parentComment)) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
if (Objects.nonNull(parentComment.getParentId())) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
if (!commentVO.getType().equals(parentComment.getType())) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
if (Objects.isNull(commentVO.getReplyUserId())) {
|
||||
throw new BizException("参数校验异常");
|
||||
} else {
|
||||
UserInfo existUser = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().select(UserInfo::getId).eq(UserInfo::getId, commentVO.getReplyUserId()));
|
||||
if (Objects.isNull(existUser)) {
|
||||
throw new BizException("参数校验异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notice(Comment comment, String fromNickname) {
|
||||
if (comment.getUserId().equals(comment.getReplyUserId())) {
|
||||
if (Objects.nonNull(comment.getParentId())) {
|
||||
Comment parentComment = commentMapper.selectById(comment.getParentId());
|
||||
if (parentComment.getUserId().equals(comment.getUserId())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (comment.getUserId().equals(BLOGGER_ID) && Objects.isNull(comment.getParentId())) {
|
||||
return;
|
||||
}
|
||||
if (Objects.nonNull(comment.getParentId())) {
|
||||
Comment parentComment = commentMapper.selectById(comment.getParentId());
|
||||
if (!comment.getReplyUserId().equals(parentComment.getUserId())
|
||||
&& !comment.getReplyUserId().equals(comment.getUserId())) {
|
||||
UserInfo userInfo = userInfoMapper.selectById(comment.getUserId());
|
||||
UserInfo replyUserinfo = userInfoMapper.selectById(comment.getReplyUserId());
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
String topicId = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
|
||||
String url = websiteUrl + getCommentPath(comment.getType()) + topicId;
|
||||
map.put("content", userInfo.getNickname() + "在" + Objects.requireNonNull(getCommentEnum(comment.getType())).getDesc()
|
||||
+ "的评论区@了你,"
|
||||
+ "<a style=\"text-decoration:none;color:#12addb\" href=\"" + url + "\">点击查看</a>");
|
||||
EmailDTO emailDTO = EmailDTO.builder()
|
||||
.email(replyUserinfo.getEmail())
|
||||
.subject(MENTION_REMIND)
|
||||
.template("common.html")
|
||||
.commentMap(map)
|
||||
.build();
|
||||
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
|
||||
}
|
||||
if (comment.getUserId().equals(parentComment.getUserId())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String title;
|
||||
Integer userId = BLOGGER_ID;
|
||||
String topicId = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
|
||||
if (Objects.nonNull(comment.getReplyUserId())) {
|
||||
userId = comment.getReplyUserId();
|
||||
} else {
|
||||
switch (Objects.requireNonNull(getCommentEnum(comment.getType()))) {
|
||||
case ARTICLE:
|
||||
userId = articleMapper.selectById(comment.getTopicId()).getUserId();
|
||||
break;
|
||||
case TALK:
|
||||
userId = talkMapper.selectById(comment.getTopicId()).getUserId();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Objects.requireNonNull(getCommentEnum(comment.getType())).equals(ARTICLE)) {
|
||||
title = articleMapper.selectById(comment.getTopicId()).getArticleTitle();
|
||||
} else {
|
||||
title = Objects.requireNonNull(getCommentEnum(comment.getType())).getDesc();
|
||||
}
|
||||
UserInfo userInfo = userInfoMapper.selectById(userId);
|
||||
if (StringUtils.isNotBlank(userInfo.getEmail())) {
|
||||
EmailDTO emailDTO = getEmailDTO(comment, userInfo, fromNickname, topicId, title);
|
||||
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
|
||||
}
|
||||
}
|
||||
|
||||
private EmailDTO getEmailDTO(Comment comment, UserInfo userInfo, String fromNickname, String topicId, String title) {
|
||||
EmailDTO emailDTO = new EmailDTO();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (comment.getIsReview().equals(TRUE)) {
|
||||
String url = websiteUrl + getCommentPath(comment.getType()) + topicId;
|
||||
if (Objects.isNull(comment.getParentId())) {
|
||||
emailDTO.setEmail(userInfo.getEmail());
|
||||
emailDTO.setSubject(COMMENT_REMIND);
|
||||
emailDTO.setTemplate("owner.html");
|
||||
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(comment.getCreateTime());
|
||||
map.put("time", createTime);
|
||||
map.put("url", url);
|
||||
map.put("title", title);
|
||||
map.put("nickname", fromNickname);
|
||||
map.put("content", comment.getCommentContent());
|
||||
} else {
|
||||
Comment parentComment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().select(Comment::getUserId, Comment::getCommentContent, Comment::getCreateTime).eq(Comment::getId, comment.getParentId()));
|
||||
if (!userInfo.getId().equals(parentComment.getUserId())) {
|
||||
userInfo = userInfoMapper.selectById(parentComment.getUserId());
|
||||
}
|
||||
emailDTO.setEmail(userInfo.getEmail());
|
||||
emailDTO.setSubject(COMMENT_REMIND);
|
||||
emailDTO.setTemplate("user.html");
|
||||
map.put("url", url);
|
||||
map.put("title", title);
|
||||
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(parentComment.getCreateTime());
|
||||
map.put("time", createTime);
|
||||
map.put("toUser", userInfo.getNickname());
|
||||
map.put("fromUser", fromNickname);
|
||||
map.put("parentComment", parentComment.getCommentContent());
|
||||
if (!comment.getReplyUserId().equals(parentComment.getUserId())) {
|
||||
UserInfo mentionUserInfo = userInfoMapper.selectById(comment.getReplyUserId());
|
||||
if (Objects.nonNull(mentionUserInfo.getWebsite())) {
|
||||
map.put("replyComment", "<a style=\"text-decoration:none;color:#12addb\" href=\""
|
||||
+ mentionUserInfo.getWebsite()
|
||||
+ "\">@" + mentionUserInfo.getNickname() + " " + "</a>" + parentComment.getCommentContent());
|
||||
} else {
|
||||
map.put("replyComment", "@" + mentionUserInfo.getNickname() + " " + parentComment.getCommentContent());
|
||||
}
|
||||
} else {
|
||||
map.put("replyComment", comment.getCommentContent());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String adminEmail = userInfoMapper.selectById(BLOGGER_ID).getEmail();
|
||||
emailDTO.setEmail(adminEmail);
|
||||
emailDTO.setSubject(CHECK_REMIND);
|
||||
emailDTO.setTemplate("common.html");
|
||||
map.put("content", "您收到了一条新的回复,请前往后台管理页面审核");
|
||||
}
|
||||
emailDTO.setCommentMap(map);
|
||||
return emailDTO;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.ExceptionLogDTO;
|
||||
import com.aurora.entity.ExceptionLog;
|
||||
import com.aurora.mapper.ExceptionLogMapper;
|
||||
import com.aurora.service.ExceptionLogService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ExceptionLogServiceImpl extends ServiceImpl<ExceptionLogMapper, ExceptionLog> implements ExceptionLogService {
|
||||
|
||||
@Override
|
||||
public PageResultDTO<ExceptionLogDTO> listExceptionLogs(ConditionVO conditionVO) {
|
||||
Page<ExceptionLog> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
Page<ExceptionLog> exceptionLogPage = this.page(page, new LambdaQueryWrapper<ExceptionLog>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), ExceptionLog::getOptDesc, conditionVO.getKeywords())
|
||||
.orderByDesc(ExceptionLog::getId));
|
||||
List<ExceptionLogDTO> exceptionLogDTOs = BeanCopyUtil.copyList(exceptionLogPage.getRecords(), ExceptionLogDTO.class);
|
||||
return new PageResultDTO<>(exceptionLogDTOs, (int) exceptionLogPage.getTotal());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.FriendLinkAdminDTO;
|
||||
import com.aurora.model.dto.FriendLinkDTO;
|
||||
import com.aurora.entity.FriendLink;
|
||||
import com.aurora.mapper.FriendLinkMapper;
|
||||
import com.aurora.service.FriendLinkService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.FriendLinkVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class FriendLinkServiceImpl extends ServiceImpl<FriendLinkMapper, FriendLink> implements FriendLinkService {
|
||||
|
||||
@Autowired
|
||||
private FriendLinkMapper friendLinkMapper;
|
||||
|
||||
@Override
|
||||
public List<FriendLinkDTO> listFriendLinks() {
|
||||
List<FriendLink> friendLinks = friendLinkMapper.selectList(null);
|
||||
return BeanCopyUtil.copyList(friendLinks, FriendLinkDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDTO<FriendLinkAdminDTO> listFriendLinksAdmin(ConditionVO conditionVO) {
|
||||
Page<FriendLink> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
Page<FriendLink> friendLinkPage = friendLinkMapper.selectPage(page, new LambdaQueryWrapper<FriendLink>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), FriendLink::getLinkName, conditionVO.getKeywords()));
|
||||
List<FriendLinkAdminDTO> friendLinkBackDTOs = BeanCopyUtil.copyList(friendLinkPage.getRecords(), FriendLinkAdminDTO.class);
|
||||
return new PageResultDTO<>(friendLinkBackDTOs, (int) friendLinkPage.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdateFriendLink(FriendLinkVO friendLinkVO) {
|
||||
FriendLink friendLink = BeanCopyUtil.copyObject(friendLinkVO, FriendLink.class);
|
||||
this.saveOrUpdate(friendLink);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.JobLogDTO;
|
||||
import com.aurora.entity.JobLog;
|
||||
import com.aurora.mapper.JobLogMapper;
|
||||
import com.aurora.service.JobLogService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.JobLogSearchVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class JobLogServiceImpl extends ServiceImpl<JobLogMapper, JobLog> implements JobLogService {
|
||||
|
||||
@Autowired
|
||||
private JobLogMapper jobLogMapper;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<JobLogDTO> listJobLogs(JobLogSearchVO jobLogSearchVO) {
|
||||
LambdaQueryWrapper<JobLog> queryWrapper = new LambdaQueryWrapper<JobLog>()
|
||||
.orderByDesc(JobLog::getCreateTime)
|
||||
.eq(Objects.nonNull(jobLogSearchVO.getJobId()), JobLog::getJobId, jobLogSearchVO.getJobId())
|
||||
.like(StringUtils.isNotBlank(jobLogSearchVO.getJobName()), JobLog::getJobName, jobLogSearchVO.getJobName())
|
||||
.like(StringUtils.isNotBlank(jobLogSearchVO.getJobGroup()), JobLog::getJobGroup, jobLogSearchVO.getJobGroup())
|
||||
.eq(Objects.nonNull(jobLogSearchVO.getStatus()), JobLog::getStatus, jobLogSearchVO.getStatus())
|
||||
.between(Objects.nonNull(jobLogSearchVO.getStartTime()) && Objects.nonNull(jobLogSearchVO.getEndTime()),
|
||||
JobLog::getCreateTime,
|
||||
jobLogSearchVO.getStartTime(),
|
||||
jobLogSearchVO.getEndTime());
|
||||
Page<JobLog> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
Page<JobLog> jobLogPage = jobLogMapper.selectPage(page, queryWrapper);
|
||||
List<JobLogDTO> jobLogDTOs = BeanCopyUtil.copyList(jobLogPage.getRecords(), JobLogDTO.class);
|
||||
return new PageResultDTO<>(jobLogDTOs, (int)jobLogPage.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteJobLogs(List<Integer> ids) {
|
||||
LambdaQueryWrapper<JobLog> queryWrapper = new LambdaQueryWrapper<JobLog>().in(JobLog::getId, ids);
|
||||
jobLogMapper.delete(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanJobLogs() {
|
||||
jobLogMapper.delete(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listJobLogGroups() {
|
||||
return jobLogMapper.listJobLogGroups();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.enums.JobStatusEnum;
|
||||
import com.aurora.model.dto.JobDTO;
|
||||
import com.aurora.entity.Job;
|
||||
import com.aurora.mapper.JobMapper;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.service.JobService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.CronUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.util.ScheduleUtil;
|
||||
import com.aurora.model.vo.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
public class JobServiceImpl extends ServiceImpl<JobMapper, Job> implements JobService {
|
||||
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
private JobMapper jobMapper;
|
||||
|
||||
@SneakyThrows
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
scheduler.clear();
|
||||
List<Job> jobs = jobMapper.selectList(null);
|
||||
for (Job job : jobs) {
|
||||
ScheduleUtil.createScheduleJob(scheduler, job);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveJob(JobVO jobVO) {
|
||||
checkCronIsValid(jobVO);
|
||||
Job job = BeanCopyUtil.copyObject(jobVO, Job.class);
|
||||
int row = jobMapper.insert(job);
|
||||
if (row > 0) ScheduleUtil.createScheduleJob(scheduler, job);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateJob(JobVO jobVO) {
|
||||
checkCronIsValid(jobVO);
|
||||
Job temp = jobMapper.selectById(jobVO.getId());
|
||||
Job job = BeanCopyUtil.copyObject(jobVO, Job.class);
|
||||
int row = jobMapper.updateById(job);
|
||||
if (row > 0) updateSchedulerJob(job, temp.getJobGroup());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteJobs(List<Integer> tagIds) {
|
||||
List<Job> jobs = jobMapper.selectList(new LambdaQueryWrapper<Job>().in(Job::getId, tagIds));
|
||||
int row = jobMapper.delete(new LambdaQueryWrapper<Job>().in(Job::getId, tagIds));
|
||||
if (row > 0) {
|
||||
jobs.forEach(item -> {
|
||||
try {
|
||||
scheduler.deleteJob(ScheduleUtil.getJobKey(item.getId(), item.getJobGroup()));
|
||||
} catch (SchedulerException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobDTO getJobById(Integer jobId) {
|
||||
Job job = jobMapper.selectById(jobId);
|
||||
JobDTO jobDTO = BeanCopyUtil.copyObject(job, JobDTO.class);
|
||||
Date nextExecution = CronUtil.getNextExecution(jobDTO.getCronExpression());
|
||||
jobDTO.setNextValidTime(nextExecution);
|
||||
return jobDTO;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<JobDTO> listJobs(JobSearchVO jobSearchVO) {
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> jobMapper.countJobs(jobSearchVO));
|
||||
List<JobDTO> jobDTOs = jobMapper.listJobs(PageUtil.getLimitCurrent(), PageUtil.getSize(), jobSearchVO);
|
||||
return new PageResultDTO<>(jobDTOs, asyncCount.get());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void updateJobStatus(JobStatusVO jobStatusVO) {
|
||||
Job job = jobMapper.selectById(jobStatusVO.getId());
|
||||
if (job.getStatus().equals(jobStatusVO.getStatus())) {
|
||||
return;
|
||||
}
|
||||
Integer status = jobStatusVO.getStatus();
|
||||
Integer jobId = job.getId();
|
||||
String jobGroup = job.getJobGroup();
|
||||
LambdaUpdateWrapper<Job> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(Job::getId, jobStatusVO.getId()).set(Job::getStatus, status);
|
||||
int row = jobMapper.update(null, updateWrapper);
|
||||
if (row > 0) {
|
||||
if (JobStatusEnum.NORMAL.getValue().equals(status)) {
|
||||
scheduler.resumeJob(ScheduleUtil.getJobKey(jobId, jobGroup));
|
||||
} else if (JobStatusEnum.PAUSE.getValue().equals(status)) {
|
||||
scheduler.pauseJob(ScheduleUtil.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void runJob(JobRunVO jobRunVO) {
|
||||
Integer jobId = jobRunVO.getId();
|
||||
String jobGroup = jobRunVO.getJobGroup();
|
||||
scheduler.triggerJob(ScheduleUtil.getJobKey(jobId, jobGroup));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listJobGroups() {
|
||||
return jobMapper.listJobGroups();
|
||||
}
|
||||
|
||||
private void checkCronIsValid(JobVO jobVO) {
|
||||
boolean valid = CronUtil.isValid(jobVO.getCronExpression());
|
||||
Assert.isTrue(valid, "Cron表达式无效!");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void updateSchedulerJob(Job job, String jobGroup) {
|
||||
Integer jobId = job.getId();
|
||||
JobKey jobKey = ScheduleUtil.getJobKey(jobId, jobGroup);
|
||||
if (scheduler.checkExists(jobKey)) {
|
||||
scheduler.deleteJob(jobKey);
|
||||
}
|
||||
ScheduleUtil.createScheduleJob(scheduler, job);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.LabelOptionDTO;
|
||||
import com.aurora.model.dto.MenuDTO;
|
||||
import com.aurora.model.dto.UserMenuDTO;
|
||||
import com.aurora.entity.Menu;
|
||||
import com.aurora.entity.RoleMenu;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.MenuMapper;
|
||||
import com.aurora.mapper.RoleMenuMapper;
|
||||
import com.aurora.service.MenuService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.UserUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.IsHiddenVO;
|
||||
import com.aurora.model.vo.MenuVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.COMPONENT;
|
||||
import static com.aurora.constant.CommonConstant.TRUE;
|
||||
|
||||
@Service
|
||||
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
|
||||
|
||||
@Autowired
|
||||
private MenuMapper menuMapper;
|
||||
|
||||
@Autowired
|
||||
private RoleMenuMapper roleMenuMapper;
|
||||
|
||||
@Override
|
||||
public List<MenuDTO> listMenus(ConditionVO conditionVO) {
|
||||
List<Menu> menus = menuMapper.selectList(new LambdaQueryWrapper<Menu>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Menu::getName, conditionVO.getKeywords()));
|
||||
List<Menu> catalogs = listCatalogs(menus);
|
||||
Map<Integer, List<Menu>> childrenMap = getMenuMap(menus);
|
||||
List<MenuDTO> menuDTOs = catalogs.stream().map(item -> {
|
||||
MenuDTO menuDTO = BeanCopyUtil.copyObject(item, MenuDTO.class);
|
||||
List<MenuDTO> list = BeanCopyUtil.copyList(childrenMap.get(item.getId()), MenuDTO.class).stream()
|
||||
.sorted(Comparator.comparing(MenuDTO::getOrderNum))
|
||||
.collect(Collectors.toList());
|
||||
menuDTO.setChildren(list);
|
||||
childrenMap.remove(item.getId());
|
||||
return menuDTO;
|
||||
}).sorted(Comparator.comparing(MenuDTO::getOrderNum)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(childrenMap)) {
|
||||
List<Menu> childrenList = new ArrayList<>();
|
||||
childrenMap.values().forEach(childrenList::addAll);
|
||||
List<MenuDTO> childrenDTOList = childrenList.stream()
|
||||
.map(item -> BeanCopyUtil.copyObject(item, MenuDTO.class))
|
||||
.sorted(Comparator.comparing(MenuDTO::getOrderNum))
|
||||
.collect(Collectors.toList());
|
||||
menuDTOs.addAll(childrenDTOList);
|
||||
}
|
||||
return menuDTOs;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveOrUpdateMenu(MenuVO menuVO) {
|
||||
Menu menu = BeanCopyUtil.copyObject(menuVO, Menu.class);
|
||||
this.saveOrUpdate(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMenuIsHidden(IsHiddenVO isHiddenVO) {
|
||||
Menu menu = BeanCopyUtil.copyObject(isHiddenVO, Menu.class);
|
||||
menuMapper.updateById(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMenu(Integer menuId) {
|
||||
Integer count = roleMenuMapper.selectCount(new LambdaQueryWrapper<RoleMenu>()
|
||||
.eq(RoleMenu::getMenuId, menuId));
|
||||
if (count > 0) {
|
||||
throw new BizException("菜单下有角色关联");
|
||||
}
|
||||
List<Integer> menuIds = menuMapper.selectList(new LambdaQueryWrapper<Menu>()
|
||||
.select(Menu::getId)
|
||||
.eq(Menu::getParentId, menuId))
|
||||
.stream()
|
||||
.map(Menu::getId)
|
||||
.collect(Collectors.toList());
|
||||
menuIds.add(menuId);
|
||||
menuMapper.deleteBatchIds(menuIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelOptionDTO> listMenuOptions() {
|
||||
List<Menu> menus = menuMapper.selectList(new LambdaQueryWrapper<Menu>()
|
||||
.select(Menu::getId, Menu::getName, Menu::getParentId, Menu::getOrderNum));
|
||||
List<Menu> catalogs = listCatalogs(menus);
|
||||
Map<Integer, List<Menu>> childrenMap = getMenuMap(menus);
|
||||
return catalogs.stream().map(item -> {
|
||||
List<LabelOptionDTO> list = new ArrayList<>();
|
||||
List<Menu> children = childrenMap.get(item.getId());
|
||||
if (CollectionUtils.isNotEmpty(children)) {
|
||||
list = children.stream()
|
||||
.sorted(Comparator.comparing(Menu::getOrderNum))
|
||||
.map(menu -> LabelOptionDTO.builder()
|
||||
.id(menu.getId())
|
||||
.label(menu.getName())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return LabelOptionDTO.builder()
|
||||
.id(item.getId())
|
||||
.label(item.getName())
|
||||
.children(list)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserMenuDTO> listUserMenus() {
|
||||
List<Menu> menus = menuMapper.listMenusByUserInfoId(UserUtil.getUserDetailsDTO().getUserInfoId());
|
||||
List<Menu> catalogs = listCatalogs(menus);
|
||||
Map<Integer, List<Menu>> childrenMap = getMenuMap(menus);
|
||||
return convertUserMenuList(catalogs, childrenMap);
|
||||
}
|
||||
|
||||
private List<Menu> listCatalogs(List<Menu> menus) {
|
||||
return menus.stream()
|
||||
.filter(item -> Objects.isNull(item.getParentId()))
|
||||
.sorted(Comparator.comparing(Menu::getOrderNum))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Map<Integer, List<Menu>> getMenuMap(List<Menu> menus) {
|
||||
return menus.stream()
|
||||
.filter(item -> Objects.nonNull(item.getParentId()))
|
||||
.collect(Collectors.groupingBy(Menu::getParentId));
|
||||
}
|
||||
|
||||
private List<UserMenuDTO> convertUserMenuList(List<Menu> catalogList, Map<Integer, List<Menu>> childrenMap) {
|
||||
return catalogList.stream().map(item -> {
|
||||
UserMenuDTO userMenuDTO = new UserMenuDTO();
|
||||
List<UserMenuDTO> list = new ArrayList<>();
|
||||
List<Menu> children = childrenMap.get(item.getId());
|
||||
if (CollectionUtils.isNotEmpty(children)) {
|
||||
userMenuDTO = BeanCopyUtil.copyObject(item, UserMenuDTO.class);
|
||||
list = children.stream()
|
||||
.sorted(Comparator.comparing(Menu::getOrderNum))
|
||||
.map(menu -> {
|
||||
UserMenuDTO dto = BeanCopyUtil.copyObject(menu, UserMenuDTO.class);
|
||||
dto.setHidden(menu.getIsHidden().equals(TRUE));
|
||||
return dto;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
userMenuDTO.setPath(item.getPath());
|
||||
userMenuDTO.setComponent(COMPONENT);
|
||||
list.add(UserMenuDTO.builder()
|
||||
.path("")
|
||||
.name(item.getName())
|
||||
.icon(item.getIcon())
|
||||
.component(item.getComponent())
|
||||
.build());
|
||||
}
|
||||
userMenuDTO.setHidden(item.getIsHidden().equals(TRUE));
|
||||
userMenuDTO.setChildren(list);
|
||||
return userMenuDTO;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.OperationLogDTO;
|
||||
import com.aurora.entity.OperationLog;
|
||||
import com.aurora.mapper.OperationLogMapper;
|
||||
import com.aurora.service.OperationLogService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog> implements OperationLogService {
|
||||
|
||||
@Override
|
||||
public PageResultDTO<OperationLogDTO> listOperationLogs(ConditionVO conditionVO) {
|
||||
Page<OperationLog> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
Page<OperationLog> operationLogPage = this.page(page, new LambdaQueryWrapper<OperationLog>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), OperationLog::getOptModule, conditionVO.getKeywords())
|
||||
.or()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), OperationLog::getOptDesc, conditionVO.getKeywords())
|
||||
.orderByDesc(OperationLog::getId));
|
||||
List<OperationLogDTO> operationLogDTOs = BeanCopyUtil.copyList(operationLogPage.getRecords(), OperationLogDTO.class);
|
||||
return new PageResultDTO<>(operationLogDTOs, (int) operationLogPage.getTotal());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,110 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.PhotoAlbumAdminDTO;
|
||||
import com.aurora.model.dto.PhotoAlbumDTO;
|
||||
import com.aurora.entity.Photo;
|
||||
import com.aurora.entity.PhotoAlbum;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.PhotoAlbumMapper;
|
||||
import com.aurora.mapper.PhotoMapper;
|
||||
import com.aurora.service.PhotoAlbumService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.PhotoAlbumVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.FALSE;
|
||||
import static com.aurora.constant.CommonConstant.TRUE;
|
||||
import static com.aurora.enums.PhotoAlbumStatusEnum.PUBLIC;
|
||||
|
||||
@Service
|
||||
public class PhotoAlbumServiceImpl extends ServiceImpl<PhotoAlbumMapper, PhotoAlbum> implements PhotoAlbumService {
|
||||
|
||||
@Autowired
|
||||
private PhotoAlbumMapper photoAlbumMapper;
|
||||
|
||||
@Autowired
|
||||
private PhotoMapper photoMapper;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveOrUpdatePhotoAlbum(PhotoAlbumVO photoAlbumVO) {
|
||||
PhotoAlbum album = photoAlbumMapper.selectOne(new LambdaQueryWrapper<PhotoAlbum>()
|
||||
.select(PhotoAlbum::getId)
|
||||
.eq(PhotoAlbum::getAlbumName, photoAlbumVO.getAlbumName()));
|
||||
if (Objects.nonNull(album) && !album.getId().equals(photoAlbumVO.getId())) {
|
||||
throw new BizException("相册名已存在");
|
||||
}
|
||||
PhotoAlbum photoAlbum = BeanCopyUtil.copyObject(photoAlbumVO, PhotoAlbum.class);
|
||||
this.saveOrUpdate(photoAlbum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDTO<PhotoAlbumAdminDTO> listPhotoAlbumsAdmin(ConditionVO conditionVO) {
|
||||
Integer count = photoAlbumMapper.selectCount(new LambdaQueryWrapper<PhotoAlbum>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), PhotoAlbum::getAlbumName, conditionVO.getKeywords())
|
||||
.eq(PhotoAlbum::getIsDelete, FALSE));
|
||||
if (count == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<PhotoAlbumAdminDTO> photoAlbumBacks = photoAlbumMapper.listPhotoAlbumsAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
return new PageResultDTO<>(photoAlbumBacks, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PhotoAlbumDTO> listPhotoAlbumInfosAdmin() {
|
||||
List<PhotoAlbum> photoAlbums = photoAlbumMapper.selectList(new LambdaQueryWrapper<PhotoAlbum>()
|
||||
.eq(PhotoAlbum::getIsDelete, FALSE));
|
||||
return BeanCopyUtil.copyList(photoAlbums, PhotoAlbumDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhotoAlbumAdminDTO getPhotoAlbumByIdAdmin(Integer albumId) {
|
||||
PhotoAlbum photoAlbum = photoAlbumMapper.selectById(albumId);
|
||||
Integer photoCount = photoMapper.selectCount(new LambdaQueryWrapper<Photo>()
|
||||
.eq(Photo::getAlbumId, albumId)
|
||||
.eq(Photo::getIsDelete, FALSE));
|
||||
PhotoAlbumAdminDTO album = BeanCopyUtil.copyObject(photoAlbum, PhotoAlbumAdminDTO.class);
|
||||
album.setPhotoCount(photoCount);
|
||||
return album;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deletePhotoAlbumById(Integer albumId) {
|
||||
Integer count = photoMapper.selectCount(new LambdaQueryWrapper<Photo>()
|
||||
.eq(Photo::getAlbumId, albumId));
|
||||
if (count > 0) {
|
||||
photoAlbumMapper.updateById(PhotoAlbum.builder()
|
||||
.id(albumId)
|
||||
.isDelete(TRUE)
|
||||
.build());
|
||||
photoMapper.update(new Photo(), new LambdaUpdateWrapper<Photo>()
|
||||
.set(Photo::getIsDelete, TRUE)
|
||||
.eq(Photo::getAlbumId, albumId));
|
||||
} else {
|
||||
photoAlbumMapper.deleteById(albumId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PhotoAlbumDTO> listPhotoAlbums() {
|
||||
List<PhotoAlbum> photoAlbumList = photoAlbumMapper.selectList(new LambdaQueryWrapper<PhotoAlbum>()
|
||||
.eq(PhotoAlbum::getStatus, PUBLIC.getStatus())
|
||||
.eq(PhotoAlbum::getIsDelete, FALSE)
|
||||
.orderByDesc(PhotoAlbum::getId));
|
||||
return BeanCopyUtil.copyList(photoAlbumList, PhotoAlbumDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.dto.PhotoAdminDTO;
|
||||
import com.aurora.model.dto.PhotoAlbumAdminDTO;
|
||||
import com.aurora.model.dto.PhotoDTO;
|
||||
import com.aurora.entity.Photo;
|
||||
import com.aurora.entity.PhotoAlbum;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.PhotoAlbumMapper;
|
||||
import com.aurora.mapper.PhotoMapper;
|
||||
import com.aurora.service.PhotoAlbumService;
|
||||
import com.aurora.service.PhotoService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.FALSE;
|
||||
import static com.aurora.enums.PhotoAlbumStatusEnum.PUBLIC;
|
||||
|
||||
@Service
|
||||
public class PhotoServiceImpl extends ServiceImpl<PhotoMapper, Photo> implements PhotoService {
|
||||
|
||||
@Autowired
|
||||
private PhotoMapper photoMapper;
|
||||
|
||||
@Autowired
|
||||
private PhotoAlbumService photoAlbumService;
|
||||
|
||||
@Override
|
||||
public PageResultDTO<PhotoAdminDTO> listPhotos(ConditionVO conditionVO) {
|
||||
Page<Photo> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
Page<Photo> photoPage = photoMapper.selectPage(page, new LambdaQueryWrapper<Photo>()
|
||||
.eq(Objects.nonNull(conditionVO.getAlbumId()), Photo::getAlbumId, conditionVO.getAlbumId())
|
||||
.eq(Photo::getIsDelete, conditionVO.getIsDelete())
|
||||
.orderByDesc(Photo::getId)
|
||||
.orderByDesc(Photo::getUpdateTime));
|
||||
List<PhotoAdminDTO> photos = BeanCopyUtil.copyList(photoPage.getRecords(), PhotoAdminDTO.class);
|
||||
return new PageResultDTO<>(photos, (int) photoPage.getTotal());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updatePhoto(PhotoInfoVO photoInfoVO) {
|
||||
Photo photo = BeanCopyUtil.copyObject(photoInfoVO, Photo.class);
|
||||
photoMapper.updateById(photo);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void savePhotos(PhotoVO photoVO) {
|
||||
List<Photo> photoList = photoVO.getPhotoUrls().stream().map(item -> Photo.builder()
|
||||
.albumId(photoVO.getAlbumId())
|
||||
.photoName(IdWorker.getIdStr())
|
||||
.photoSrc(item)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
this.saveBatch(photoList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updatePhotosAlbum(PhotoVO photoVO) {
|
||||
List<Photo> photoList = photoVO.getPhotoIds().stream().map(item -> Photo.builder()
|
||||
.id(item)
|
||||
.albumId(photoVO.getAlbumId())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
this.updateBatchById(photoList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updatePhotoDelete(DeleteVO deleteVO) {
|
||||
List<Photo> photoList = deleteVO.getIds().stream().map(item -> Photo.builder()
|
||||
.id(item)
|
||||
.isDelete(deleteVO.getIsDelete())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
this.updateBatchById(photoList);
|
||||
if (deleteVO.getIsDelete().equals(FALSE)) {
|
||||
List<PhotoAlbum> photoAlbumList = photoMapper.selectList(new LambdaQueryWrapper<Photo>()
|
||||
.select(Photo::getAlbumId)
|
||||
.in(Photo::getId, deleteVO.getIds())
|
||||
.groupBy(Photo::getAlbumId))
|
||||
.stream()
|
||||
.map(item -> PhotoAlbum.builder()
|
||||
.id(item.getAlbumId())
|
||||
.isDelete(FALSE)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
photoAlbumService.updateBatchById(photoAlbumList);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deletePhotos(List<Integer> photoIds) {
|
||||
photoMapper.deleteBatchIds(photoIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhotoDTO listPhotosByAlbumId(Integer albumId) {
|
||||
PhotoAlbum photoAlbum = photoAlbumService.getOne(new LambdaQueryWrapper<PhotoAlbum>()
|
||||
.eq(PhotoAlbum::getId, albumId)
|
||||
.eq(PhotoAlbum::getIsDelete, FALSE)
|
||||
.eq(PhotoAlbum::getStatus, PUBLIC.getStatus()));
|
||||
if (Objects.isNull(photoAlbum)) {
|
||||
throw new BizException("相册不存在");
|
||||
}
|
||||
Page<Photo> page = new Page<>(PageUtil.getCurrent(), PageUtil.getSize());
|
||||
List<String> photos = photoMapper.selectPage(page, new LambdaQueryWrapper<Photo>()
|
||||
.select(Photo::getPhotoSrc)
|
||||
.eq(Photo::getAlbumId, albumId)
|
||||
.eq(Photo::getIsDelete, FALSE)
|
||||
.orderByDesc(Photo::getId))
|
||||
.getRecords()
|
||||
.stream()
|
||||
.map(Photo::getPhotoSrc)
|
||||
.collect(Collectors.toList());
|
||||
return PhotoDTO.builder()
|
||||
.photoAlbumCover(photoAlbum.getAlbumCover())
|
||||
.photoAlbumName(photoAlbum.getAlbumName())
|
||||
.photos(photos)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,326 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
|
||||
import com.aurora.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.BitFieldSubCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@SuppressWarnings("all")
|
||||
public class RedisServiceImpl implements RedisService {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Override
|
||||
public void set(String key, Object value, long time) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String key, Object value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean del(String key) {
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long del(List<String> keys) {
|
||||
return redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean expire(String key, long time) {
|
||||
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasKey(String key) {
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long incr(String key, long delta) {
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long incrExpire(String key, long time) {
|
||||
Long count = redisTemplate.opsForValue().increment(key, 1);
|
||||
if (count != null && count == 1) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long decr(String key, long delta) {
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object hGet(String key, String hashKey) {
|
||||
return redisTemplate.opsForHash().get(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hSet(String key, String hashKey, Object value, long time) {
|
||||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
return expire(key, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hSet(String key, String hashKey, Object value) {
|
||||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map hGetAll(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hSetAll(String key, Map<String, Object> map, long time) {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return expire(key, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hSetAll(String key, Map<String, ?> map) {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hDel(String key, Object... hashKey) {
|
||||
redisTemplate.opsForHash().delete(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hHasKey(String key, String hashKey) {
|
||||
return redisTemplate.opsForHash().hasKey(key, hashKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hIncr(String key, String hashKey, Long delta) {
|
||||
return redisTemplate.opsForHash().increment(key, hashKey, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hDecr(String key, String hashKey, Long delta) {
|
||||
return redisTemplate.opsForHash().increment(key, hashKey, -delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double zIncr(String key, Object value, Double score) {
|
||||
return redisTemplate.opsForZSet().incrementScore(key, value, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double zDecr(String key, Object value, Double score) {
|
||||
return redisTemplate.opsForZSet().incrementScore(key, value, -score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {
|
||||
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double zScore(String key, Object value) {
|
||||
return redisTemplate.opsForZSet().score(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Double> zAllScore(String key) {
|
||||
return Objects.requireNonNull(redisTemplate.opsForZSet().rangeWithScores(key, 0, -1))
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> sMembers(String key) {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sAdd(String key, Object... values) {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sAddExpire(String key, long time, Object... values) {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
expire(key, time);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean sIsMember(String key, Object value) {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sSize(String key) {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long sRemove(String key, Object... values) {
|
||||
return redisTemplate.opsForSet().remove(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> lRange(String key, long start, long end) {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lSize(String key) {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lIndex(String key, long index) {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPush(String key, Object value) {
|
||||
return redisTemplate.opsForList().rightPush(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPush(String key, Object value, long time) {
|
||||
Long index = redisTemplate.opsForList().rightPush(key, value);
|
||||
expire(key, time);
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPushAll(String key, Object... values) {
|
||||
return redisTemplate.opsForList().rightPushAll(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lPushAll(String key, Long time, Object... values) {
|
||||
Long count = redisTemplate.opsForList().rightPushAll(key, values);
|
||||
expire(key, time);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lRemove(String key, long count, Object value) {
|
||||
return redisTemplate.opsForList().remove(key, count, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean bitAdd(String key, int offset, boolean b) {
|
||||
return redisTemplate.opsForValue().setBit(key, offset, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean bitGet(String key, int offset) {
|
||||
return redisTemplate.opsForValue().getBit(key, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long bitCount(String key) {
|
||||
return redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> bitField(String key, int limit, int offset) {
|
||||
return redisTemplate.execute((RedisCallback<List<Long>>) con ->
|
||||
con.bitField(key.getBytes(),
|
||||
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] bitGetAll(String key) {
|
||||
return redisTemplate.execute((RedisCallback<byte[]>) con -> con.get(key.getBytes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hyperAdd(String key, Object... value) {
|
||||
return redisTemplate.opsForHyperLogLog().add(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long hyperGet(String... key) {
|
||||
return redisTemplate.opsForHyperLogLog().size(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hyperDel(String key) {
|
||||
redisTemplate.opsForHyperLogLog().delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long geoAdd(String key, Double x, Double y, String name) {
|
||||
return redisTemplate.opsForGeo().add(key, new Point(x, y), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Point> geoGetPointList(String key, Object... place) {
|
||||
return redisTemplate.opsForGeo().position(key, place);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance geoCalculationDistance(String key, String placeOne, String placeTow) {
|
||||
return redisTemplate.opsForGeo()
|
||||
.distance(key, placeOne, placeTow, RedisGeoCommands.DistanceUnit.KILOMETERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoResults<RedisGeoCommands.GeoLocation<Object>> geoNearByPlace(String key, String place, Distance distance, long limit, Sort.Direction sort) {
|
||||
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates();
|
||||
// 判断排序方式
|
||||
if (Sort.Direction.ASC == sort) {
|
||||
args.sortAscending();
|
||||
} else {
|
||||
args.sortDescending();
|
||||
}
|
||||
args.limit(limit);
|
||||
return redisTemplate.opsForGeo()
|
||||
.radius(key, place, distance, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> geoGetHash(String key, String... place) {
|
||||
return redisTemplate.opsForGeo()
|
||||
.hash(key, place);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.LabelOptionDTO;
|
||||
import com.aurora.model.dto.ResourceDTO;
|
||||
import com.aurora.entity.Resource;
|
||||
import com.aurora.entity.RoleResource;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.handler.FilterInvocationSecurityMetadataSourceImpl;
|
||||
import com.aurora.mapper.ResourceMapper;
|
||||
import com.aurora.mapper.RoleResourceMapper;
|
||||
import com.aurora.service.ResourceService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.vo.ResourceVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.CommonConstant.FALSE;
|
||||
|
||||
@Service
|
||||
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private ResourceMapper resourceMapper;
|
||||
|
||||
@Autowired
|
||||
private RoleResourceMapper roleResourceMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private FilterInvocationSecurityMetadataSourceImpl filterInvocationSecurityMetadataSource;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void importSwagger() {
|
||||
this.remove(null);
|
||||
roleResourceMapper.delete(null);
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
Map<String, Object> data = restTemplate.getForObject("http://localhost:8080/v2/api-docs", Map.class);
|
||||
List<Map<String, String>> tagList = (List<Map<String, String>>) data.get("tags");
|
||||
tagList.forEach(item -> {
|
||||
Resource resource = Resource.builder()
|
||||
.resourceName(item.get("name"))
|
||||
.isAnonymous(FALSE)
|
||||
.createTime(LocalDateTime.now())
|
||||
.build();
|
||||
resources.add(resource);
|
||||
});
|
||||
this.saveBatch(resources);
|
||||
Map<String, Integer> permissionMap = resources.stream()
|
||||
.collect(Collectors.toMap(Resource::getResourceName, Resource::getId));
|
||||
resources.clear();
|
||||
Map<String, Map<String, Map<String, Object>>> path = (Map<String, Map<String, Map<String, Object>>>) data.get("paths");
|
||||
path.forEach((url, value) -> value.forEach((requestMethod, info) -> {
|
||||
String permissionName = info.get("summary").toString();
|
||||
List<String> tag = (List<String>) info.get("tags");
|
||||
Integer parentId = permissionMap.get(tag.get(0));
|
||||
Resource resource = Resource.builder()
|
||||
.resourceName(permissionName)
|
||||
.url(url.replaceAll("\\{[^}]*\\}", "*"))
|
||||
.parentId(parentId)
|
||||
.requestMethod(requestMethod.toUpperCase())
|
||||
.isAnonymous(FALSE)
|
||||
.createTime(LocalDateTime.now())
|
||||
.build();
|
||||
resources.add(resource);
|
||||
}));
|
||||
this.saveBatch(resources);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdateResource(ResourceVO resourceVO) {
|
||||
Resource resource = BeanCopyUtil.copyObject(resourceVO, Resource.class);
|
||||
this.saveOrUpdate(resource);
|
||||
filterInvocationSecurityMetadataSource.clearDataSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteResource(Integer resourceId) {
|
||||
Integer count = roleResourceMapper.selectCount(new LambdaQueryWrapper<RoleResource>()
|
||||
.eq(RoleResource::getResourceId, resourceId));
|
||||
if (count > 0) {
|
||||
throw new BizException("该资源下存在角色");
|
||||
}
|
||||
List<Integer> resourceIds = resourceMapper.selectList(new LambdaQueryWrapper<Resource>()
|
||||
.select(Resource::getId).
|
||||
eq(Resource::getParentId, resourceId))
|
||||
.stream()
|
||||
.map(Resource::getId)
|
||||
.collect(Collectors.toList());
|
||||
resourceIds.add(resourceId);
|
||||
resourceMapper.deleteBatchIds(resourceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceDTO> listResources(ConditionVO conditionVO) {
|
||||
List<Resource> resources = resourceMapper.selectList(new LambdaQueryWrapper<Resource>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Resource::getResourceName, conditionVO.getKeywords()));
|
||||
List<Resource> parents = listResourceModule(resources);
|
||||
Map<Integer, List<Resource>> childrenMap = listResourceChildren(resources);
|
||||
List<ResourceDTO> resourceDTOs = parents.stream().map(item -> {
|
||||
ResourceDTO resourceDTO = BeanCopyUtil.copyObject(item, ResourceDTO.class);
|
||||
List<ResourceDTO> child = BeanCopyUtil.copyList(childrenMap.get(item.getId()), ResourceDTO.class);
|
||||
resourceDTO.setChildren(child);
|
||||
childrenMap.remove(item.getId());
|
||||
return resourceDTO;
|
||||
}).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(childrenMap)) {
|
||||
List<Resource> childrenList = new ArrayList<>();
|
||||
childrenMap.values().forEach(childrenList::addAll);
|
||||
List<ResourceDTO> childrenDTOs = childrenList.stream()
|
||||
.map(item -> BeanCopyUtil.copyObject(item, ResourceDTO.class))
|
||||
.collect(Collectors.toList());
|
||||
resourceDTOs.addAll(childrenDTOs);
|
||||
}
|
||||
return resourceDTOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelOptionDTO> listResourceOption() {
|
||||
List<Resource> resources = resourceMapper.selectList(new LambdaQueryWrapper<Resource>()
|
||||
.select(Resource::getId, Resource::getResourceName, Resource::getParentId)
|
||||
.eq(Resource::getIsAnonymous, FALSE));
|
||||
List<Resource> parents = listResourceModule(resources);
|
||||
Map<Integer, List<Resource>> childrenMap = listResourceChildren(resources);
|
||||
return parents.stream().map(item -> {
|
||||
List<LabelOptionDTO> list = new ArrayList<>();
|
||||
List<Resource> children = childrenMap.get(item.getId());
|
||||
if (CollectionUtils.isNotEmpty(children)) {
|
||||
list = children.stream()
|
||||
.map(resource -> LabelOptionDTO.builder()
|
||||
.id(resource.getId())
|
||||
.label(resource.getResourceName())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return LabelOptionDTO.builder()
|
||||
.id(item.getId())
|
||||
.label(item.getResourceName())
|
||||
.children(list)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
private List<Resource> listResourceModule(List<Resource> resourceList) {
|
||||
return resourceList.stream()
|
||||
.filter(item -> Objects.isNull(item.getParentId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Map<Integer, List<Resource>> listResourceChildren(List<Resource> resourceList) {
|
||||
return resourceList.stream()
|
||||
.filter(item -> Objects.nonNull(item.getParentId()))
|
||||
.collect(Collectors.groupingBy(Resource::getParentId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.entity.RoleMenu;
|
||||
import com.aurora.mapper.RoleMenuMapper;
|
||||
import com.aurora.service.RoleMenuService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.entity.RoleResource;
|
||||
import com.aurora.mapper.RoleResourceMapper;
|
||||
import com.aurora.service.RoleResourceService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RoleResourceServiceImpl extends ServiceImpl<RoleResourceMapper, RoleResource> implements RoleResourceService {
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.constant.CommonConstant;
|
||||
import com.aurora.model.dto.RoleDTO;
|
||||
import com.aurora.model.dto.UserRoleDTO;
|
||||
import com.aurora.entity.Role;
|
||||
import com.aurora.entity.RoleMenu;
|
||||
import com.aurora.entity.RoleResource;
|
||||
import com.aurora.entity.UserRole;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.handler.FilterInvocationSecurityMetadataSourceImpl;
|
||||
import com.aurora.mapper.RoleMapper;
|
||||
import com.aurora.mapper.UserRoleMapper;
|
||||
import com.aurora.service.RoleMenuService;
|
||||
import com.aurora.service.RoleResourceService;
|
||||
import com.aurora.service.RoleService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.RoleVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
|
||||
|
||||
@Autowired
|
||||
private RoleMapper roleMapper;
|
||||
|
||||
@Autowired
|
||||
private UserRoleMapper userRoleMapper;
|
||||
|
||||
@Autowired
|
||||
private RoleResourceService roleResourceService;
|
||||
|
||||
@Autowired
|
||||
private RoleMenuService roleMenuService;
|
||||
|
||||
@Autowired
|
||||
private FilterInvocationSecurityMetadataSourceImpl filterInvocationSecurityMetadataSource;
|
||||
|
||||
@Override
|
||||
public List<UserRoleDTO> listUserRoles() {
|
||||
List<Role> roleList = roleMapper.selectList(new LambdaQueryWrapper<Role>()
|
||||
.select(Role::getId, Role::getRoleName));
|
||||
return BeanCopyUtil.copyList(roleList, UserRoleDTO.class);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<RoleDTO> listRoles(ConditionVO conditionVO) {
|
||||
LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<Role>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Role::getRoleName, conditionVO.getKeywords());
|
||||
CompletableFuture<Integer> asyncCount = CompletableFuture.supplyAsync(() -> roleMapper.selectCount(queryWrapper));
|
||||
List<RoleDTO> roleDTOs = roleMapper.listRoles(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
return new PageResultDTO<>(roleDTOs, asyncCount.get());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveOrUpdateRole(RoleVO roleVO) {
|
||||
Role roleCheck = roleMapper.selectOne(new LambdaQueryWrapper<Role>()
|
||||
.select(Role::getId)
|
||||
.eq(Role::getRoleName, roleVO.getRoleName()));
|
||||
if (Objects.nonNull(roleCheck) && !(roleCheck.getId().equals(roleVO.getId()))) {
|
||||
throw new BizException("该角色存在");
|
||||
}
|
||||
Role role = Role.builder()
|
||||
.id(roleVO.getId())
|
||||
.roleName(roleVO.getRoleName())
|
||||
.isDisable(CommonConstant.FALSE)
|
||||
.build();
|
||||
this.saveOrUpdate(role);
|
||||
if (Objects.nonNull(roleVO.getResourceIds())) {
|
||||
if (Objects.nonNull(roleVO.getId())) {
|
||||
roleResourceService.remove(new LambdaQueryWrapper<RoleResource>()
|
||||
.eq(RoleResource::getRoleId, roleVO.getId()));
|
||||
}
|
||||
List<RoleResource> roleResourceList = roleVO.getResourceIds().stream()
|
||||
.map(resourceId -> RoleResource.builder()
|
||||
.roleId(role.getId())
|
||||
.resourceId(resourceId)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
roleResourceService.saveBatch(roleResourceList);
|
||||
filterInvocationSecurityMetadataSource.clearDataSource();
|
||||
}
|
||||
if (Objects.nonNull(roleVO.getMenuIds())) {
|
||||
if (Objects.nonNull(roleVO.getId())) {
|
||||
roleMenuService.remove(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, roleVO.getId()));
|
||||
}
|
||||
List<RoleMenu> roleMenuList = roleVO.getMenuIds().stream()
|
||||
.map(menuId -> RoleMenu.builder()
|
||||
.roleId(role.getId())
|
||||
.menuId(menuId)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
roleMenuService.saveBatch(roleMenuList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRoles(List<Integer> roleIdList) {
|
||||
Integer count = userRoleMapper.selectCount(new LambdaQueryWrapper<UserRole>()
|
||||
.in(UserRole::getRoleId, roleIdList));
|
||||
if (count > 0) {
|
||||
throw new BizException("该角色下存在用户");
|
||||
}
|
||||
roleMapper.deleteBatchIds(roleIdList);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
|
||||
import com.aurora.model.dto.TagAdminDTO;
|
||||
import com.aurora.model.dto.TagDTO;
|
||||
import com.aurora.entity.ArticleTag;
|
||||
import com.aurora.entity.Tag;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.ArticleTagMapper;
|
||||
import com.aurora.mapper.TagMapper;
|
||||
import com.aurora.service.TagService;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.TagVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {
|
||||
|
||||
@Autowired
|
||||
private TagMapper tagMapper;
|
||||
|
||||
@Autowired
|
||||
private ArticleTagMapper articleTagMapper;
|
||||
|
||||
@Override
|
||||
public List<TagDTO> listTags() {
|
||||
return tagMapper.listTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagDTO> listTopTenTags() {
|
||||
return tagMapper.listTopTenTags();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public PageResultDTO<TagAdminDTO> listTagsAdmin(ConditionVO conditionVO) {
|
||||
Integer count = tagMapper.selectCount(new LambdaQueryWrapper<Tag>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Tag::getTagName, conditionVO.getKeywords()));
|
||||
if (count == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<TagAdminDTO> tags = tagMapper.listTagsAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
return new PageResultDTO<>(tags, count);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<TagAdminDTO> listTagsAdminBySearch(ConditionVO conditionVO) {
|
||||
List<Tag> tags = tagMapper.selectList(new LambdaQueryWrapper<Tag>()
|
||||
.like(StringUtils.isNotBlank(conditionVO.getKeywords()), Tag::getTagName, conditionVO.getKeywords())
|
||||
.orderByDesc(Tag::getId));
|
||||
return BeanCopyUtil.copyList(tags, TagAdminDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdateTag(TagVO tagVO) {
|
||||
Tag existTag = tagMapper.selectOne(new LambdaQueryWrapper<Tag>()
|
||||
.select(Tag::getId)
|
||||
.eq(Tag::getTagName, tagVO.getTagName()));
|
||||
if (Objects.nonNull(existTag) && !existTag.getId().equals(tagVO.getId())) {
|
||||
throw new BizException("标签名已存在");
|
||||
}
|
||||
Tag tag = BeanCopyUtil.copyObject(tagVO, Tag.class);
|
||||
this.saveOrUpdate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTag(List<Integer> tagIds) {
|
||||
Integer count = articleTagMapper.selectCount(new LambdaQueryWrapper<ArticleTag>()
|
||||
.in(ArticleTag::getTagId, tagIds));
|
||||
if (count > 0) {
|
||||
throw new BizException("删除失败,该标签下存在文章");
|
||||
}
|
||||
tagMapper.deleteBatchIds(tagIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.aurora.enums.CommentTypeEnum;
|
||||
import com.aurora.model.dto.CommentCountDTO;
|
||||
import com.aurora.model.dto.TalkAdminDTO;
|
||||
import com.aurora.model.dto.TalkDTO;
|
||||
import com.aurora.entity.Talk;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.CommentMapper;
|
||||
import com.aurora.mapper.TalkMapper;
|
||||
import com.aurora.service.TalkService;
|
||||
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.CommonUtil;
|
||||
import com.aurora.util.PageUtil;
|
||||
import com.aurora.util.UserUtil;
|
||||
import com.aurora.model.vo.ConditionVO;
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.vo.TalkVO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.enums.TalkStatusEnum.PUBLIC;
|
||||
|
||||
|
||||
@Service
|
||||
public class TalkServiceImpl extends ServiceImpl<TalkMapper, Talk> implements TalkService {
|
||||
|
||||
@Autowired
|
||||
private TalkMapper talkMapper;
|
||||
|
||||
@Autowired
|
||||
private CommentMapper commentMapper;
|
||||
|
||||
@Override
|
||||
public PageResultDTO<TalkDTO> listTalks() {
|
||||
Integer count = talkMapper.selectCount((new LambdaQueryWrapper<Talk>()
|
||||
.eq(Talk::getStatus, PUBLIC.getStatus())));
|
||||
if (count == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<TalkDTO> talkDTOs = talkMapper.listTalks(PageUtil.getLimitCurrent(), PageUtil.getSize());
|
||||
List<Integer> talkIds = talkDTOs.stream()
|
||||
.map(TalkDTO::getId)
|
||||
.collect(Collectors.toList());
|
||||
Map<Integer, Integer> commentCountMap = commentMapper.listCommentCountByTypeAndTopicIds(CommentTypeEnum.TALK.getType(), talkIds)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(CommentCountDTO::getId, CommentCountDTO::getCommentCount));
|
||||
talkDTOs.forEach(item -> {
|
||||
item.setCommentCount(commentCountMap.get(item.getId()));
|
||||
if (Objects.nonNull(item.getImages())) {
|
||||
item.setImgs(CommonUtil.castList(JSON.parseObject(item.getImages(), List.class), String.class));
|
||||
}
|
||||
});
|
||||
return new PageResultDTO<>(talkDTOs, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TalkDTO getTalkById(Integer talkId) {
|
||||
TalkDTO talkDTO = talkMapper.getTalkById(talkId);
|
||||
if (Objects.isNull(talkDTO)) {
|
||||
throw new BizException("说说不存在");
|
||||
}
|
||||
if (Objects.nonNull(talkDTO.getImages())) {
|
||||
talkDTO.setImgs(CommonUtil.castList(JSON.parseObject(talkDTO.getImages(), List.class), String.class));
|
||||
}
|
||||
CommentCountDTO commentCountDTO = commentMapper.listCommentCountByTypeAndTopicId(CommentTypeEnum.TALK.getType(), talkId);
|
||||
if (Objects.nonNull(commentCountDTO)) {
|
||||
talkDTO.setCommentCount(commentCountDTO.getCommentCount());
|
||||
}
|
||||
return talkDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveOrUpdateTalk(TalkVO talkVO) {
|
||||
Talk talk = BeanCopyUtil.copyObject(talkVO, Talk.class);
|
||||
talk.setUserId(UserUtil.getUserDetailsDTO().getUserInfoId());
|
||||
this.saveOrUpdate(talk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTalks(List<Integer> talkIds) {
|
||||
talkMapper.deleteBatchIds(talkIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDTO<TalkAdminDTO> listBackTalks(ConditionVO conditionVO) {
|
||||
Integer count = talkMapper.selectCount(new LambdaQueryWrapper<Talk>()
|
||||
.eq(Objects.nonNull(conditionVO.getStatus()), Talk::getStatus, conditionVO.getStatus()));
|
||||
if (count == 0) {
|
||||
return new PageResultDTO<>();
|
||||
}
|
||||
List<TalkAdminDTO> talkDTOs = talkMapper.listTalksAdmin(PageUtil.getLimitCurrent(), PageUtil.getSize(), conditionVO);
|
||||
talkDTOs.forEach(item -> {
|
||||
if (Objects.nonNull(item.getImages())) {
|
||||
item.setImgs(CommonUtil.castList(JSON.parseObject(item.getImages(), List.class), String.class));
|
||||
}
|
||||
});
|
||||
return new PageResultDTO<>(talkDTOs, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TalkAdminDTO getBackTalkById(Integer talkId) {
|
||||
TalkAdminDTO talkBackDTO = talkMapper.getTalkByIdAdmin(talkId);
|
||||
if (Objects.nonNull(talkBackDTO.getImages())) {
|
||||
talkBackDTO.setImgs(CommonUtil.castList(JSON.parseObject(talkBackDTO.getImages(), List.class), String.class));
|
||||
}
|
||||
return talkBackDTO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.UserDetailsDTO;
|
||||
import com.aurora.service.RedisService;
|
||||
import com.aurora.service.TokenService;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Base64;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.aurora.constant.AuthConstant.*;
|
||||
import static com.aurora.constant.RedisConstant.LOGIN_USER;
|
||||
|
||||
|
||||
@Service
|
||||
public class TokenServiceImpl implements TokenService {
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public String createToken(UserDetailsDTO userDetailsDTO) {
|
||||
refreshToken(userDetailsDTO);
|
||||
String userId = userDetailsDTO.getId().toString();
|
||||
return createToken(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createToken(String subject) {
|
||||
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
|
||||
SecretKey secretKey = generalKey();
|
||||
return Jwts.builder().setId(getUuid()).setSubject(subject)
|
||||
.setIssuer("huaweimian")
|
||||
.signWith(signatureAlgorithm, secretKey).compact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshToken(UserDetailsDTO userDetailsDTO) {
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
userDetailsDTO.setExpireTime(currentTime.plusSeconds(EXPIRE_TIME));
|
||||
String userId = userDetailsDTO.getId().toString();
|
||||
redisService.hSet(LOGIN_USER, userId, userDetailsDTO, EXPIRE_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renewToken(UserDetailsDTO userDetailsDTO) {
|
||||
LocalDateTime expireTime = userDetailsDTO.getExpireTime();
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
if (Duration.between(currentTime, expireTime).toMinutes() <= TWENTY_MINUTES) {
|
||||
refreshToken(userDetailsDTO);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Claims parseToken(String token) {
|
||||
SecretKey secretKey = generalKey();
|
||||
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetailsDTO getUserDetailDTO(HttpServletRequest request) {
|
||||
String token = Optional.ofNullable(request.getHeader(TOKEN_HEADER)).orElse("").replaceFirst(TOKEN_PREFIX, "");
|
||||
if (StringUtils.hasText(token) && !token.equals("null")) {
|
||||
Claims claims = parseToken(token);
|
||||
String userId = claims.getSubject();
|
||||
return (UserDetailsDTO) redisService.hGet(LOGIN_USER, userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delLoginUser(Integer userId) {
|
||||
redisService.hDel(LOGIN_USER, String.valueOf(userId));
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
public SecretKey generalKey() {
|
||||
byte[] encodedKey = Base64.getDecoder().decode(secret);
|
||||
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.aurora.model.dto.UniqueViewDTO;
|
||||
import com.aurora.entity.UniqueView;
|
||||
import com.aurora.mapper.UniqueViewMapper;
|
||||
import com.aurora.service.UniqueViewService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UniqueViewServiceImpl extends ServiceImpl<UniqueViewMapper, UniqueView> implements UniqueViewService {
|
||||
|
||||
@Autowired
|
||||
private UniqueViewMapper uniqueViewMapper;
|
||||
|
||||
@Override
|
||||
public List<UniqueViewDTO> listUniqueViews() {
|
||||
DateTime startTime = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -7));
|
||||
DateTime endTime = DateUtil.endOfDay(new Date());
|
||||
return uniqueViewMapper.listUniqueViews(startTime, endTime);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
|
||||
import com.aurora.model.dto.UserDetailsDTO;
|
||||
import com.aurora.entity.UserAuth;
|
||||
import com.aurora.entity.UserInfo;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.RoleMapper;
|
||||
import com.aurora.mapper.UserAuthMapper;
|
||||
import com.aurora.mapper.UserInfoMapper;
|
||||
import com.aurora.util.IpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import eu.bitwalker.useragentutils.UserAgent;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class UserDetailServiceImpl implements UserDetailsService {
|
||||
|
||||
@Autowired
|
||||
private UserAuthMapper userAuthMapper;
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private RoleMapper roleMapper;
|
||||
|
||||
@Resource
|
||||
private HttpServletRequest request;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
if (StringUtils.isBlank(username)) {
|
||||
throw new BizException("用户名不能为空!");
|
||||
}
|
||||
UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
|
||||
.select(UserAuth::getId, UserAuth::getUserInfoId, UserAuth::getUsername, UserAuth::getPassword, UserAuth::getLoginType)
|
||||
.eq(UserAuth::getUsername, username));
|
||||
if (Objects.isNull(userAuth)) {
|
||||
throw new BizException("用户不存在!");
|
||||
}
|
||||
return convertUserDetail(userAuth, request);
|
||||
}
|
||||
|
||||
public UserDetailsDTO convertUserDetail(UserAuth user, HttpServletRequest request) {
|
||||
UserInfo userInfo = userInfoMapper.selectById(user.getUserInfoId());
|
||||
List<String> roles = roleMapper.listRolesByUserInfoId(userInfo.getId());
|
||||
String ipAddress = IpUtil.getIpAddress(request);
|
||||
String ipSource = IpUtil.getIpSource(ipAddress);
|
||||
UserAgent userAgent = IpUtil.getUserAgent(request);
|
||||
return UserDetailsDTO.builder()
|
||||
.id(user.getId())
|
||||
.loginType(user.getLoginType())
|
||||
.userInfoId(userInfo.getId())
|
||||
.username(user.getUsername())
|
||||
.password(user.getPassword())
|
||||
.email(userInfo.getEmail())
|
||||
.roles(roles)
|
||||
.nickname(userInfo.getNickname())
|
||||
.avatar(userInfo.getAvatar())
|
||||
.intro(userInfo.getIntro())
|
||||
.website(userInfo.getWebsite())
|
||||
.isSubscribe(userInfo.getIsSubscribe())
|
||||
.ipAddress(ipAddress)
|
||||
.ipSource(ipSource)
|
||||
.isDisable(userInfo.getIsDisable())
|
||||
.browser(userAgent.getBrowser().getName())
|
||||
.os(userAgent.getOperatingSystem().getName())
|
||||
.lastLoginTime(LocalDateTime.now())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.model.dto.PageResultDTO;
|
||||
import com.aurora.model.dto.UserDetailsDTO;
|
||||
import com.aurora.model.dto.UserInfoDTO;
|
||||
import com.aurora.model.dto.UserOnlineDTO;
|
||||
import com.aurora.entity.UserAuth;
|
||||
import com.aurora.entity.UserInfo;
|
||||
import com.aurora.entity.UserRole;
|
||||
import com.aurora.enums.FilePathEnum;
|
||||
import com.aurora.exception.BizException;
|
||||
import com.aurora.mapper.UserAuthMapper;
|
||||
import com.aurora.mapper.UserInfoMapper;
|
||||
import com.aurora.service.RedisService;
|
||||
import com.aurora.service.TokenService;
|
||||
import com.aurora.service.UserInfoService;
|
||||
import com.aurora.service.UserRoleService;
|
||||
import com.aurora.strategy.context.UploadStrategyContext;
|
||||
import com.aurora.util.BeanCopyUtil;
|
||||
import com.aurora.util.UserUtil;
|
||||
import com.aurora.model.vo.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.aurora.constant.RedisConstant.USER_CODE_KEY;
|
||||
import static com.aurora.util.PageUtil.getLimitCurrent;
|
||||
import static com.aurora.util.PageUtil.getSize;
|
||||
|
||||
|
||||
@Service
|
||||
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private UserAuthMapper userAuthMapper;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private UserRoleService userRoleService;
|
||||
|
||||
@Autowired
|
||||
private UploadStrategyContext uploadStrategyContext;
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateUserInfo(UserInfoVO userInfoVO) {
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(UserUtil.getUserDetailsDTO().getUserInfoId())
|
||||
.nickname(userInfoVO.getNickname())
|
||||
.intro(userInfoVO.getIntro())
|
||||
.website(userInfoVO.getWebsite())
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String updateUserAvatar(MultipartFile file) {
|
||||
String avatar = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.AVATAR.getPath());
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(UserUtil.getUserDetailsDTO().getUserInfoId())
|
||||
.avatar(avatar)
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
return avatar;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveUserEmail(EmailVO emailVO) {
|
||||
if (Objects.isNull(redisService.get(USER_CODE_KEY + emailVO.getEmail()))) {
|
||||
throw new BizException("验证码错误");
|
||||
}
|
||||
if (!emailVO.getCode().equals(redisService.get(USER_CODE_KEY + emailVO.getEmail()).toString())) {
|
||||
throw new BizException("验证码错误!");
|
||||
}
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(UserUtil.getUserDetailsDTO().getUserInfoId())
|
||||
.email(emailVO.getEmail())
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateUserSubscribe(SubscribeVO subscribeVO) {
|
||||
UserInfo temp = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getId, subscribeVO.getUserId()));
|
||||
if (StringUtils.isEmpty(temp.getEmail())) {
|
||||
throw new BizException("邮箱未绑定!");
|
||||
}
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(subscribeVO.getUserId())
|
||||
.isSubscribe(subscribeVO.getIsSubscribe())
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateUserRole(UserRoleVO userRoleVO) {
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(userRoleVO.getUserInfoId())
|
||||
.nickname(userRoleVO.getNickname())
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
userRoleService.remove(new LambdaQueryWrapper<UserRole>()
|
||||
.eq(UserRole::getUserId, userRoleVO.getUserInfoId()));
|
||||
List<UserRole> userRoleList = userRoleVO.getRoleIds().stream()
|
||||
.map(roleId -> UserRole.builder()
|
||||
.roleId(roleId)
|
||||
.userId(userRoleVO.getUserInfoId())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
userRoleService.saveBatch(userRoleList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateUserDisable(UserDisableVO userDisableVO) {
|
||||
removeOnlineUser(userDisableVO.getId());
|
||||
UserInfo userInfo = UserInfo.builder()
|
||||
.id(userDisableVO.getId())
|
||||
.isDisable(userDisableVO.getIsDisable())
|
||||
.build();
|
||||
userInfoMapper.updateById(userInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDTO<UserOnlineDTO> listOnlineUsers(ConditionVO conditionVO) {
|
||||
Map<String, Object> userMaps = redisService.hGetAll("login_user");
|
||||
Collection<Object> values = userMaps.values();
|
||||
ArrayList<UserDetailsDTO> userDetailsDTOs = new ArrayList<>();
|
||||
for (Object value : values) {
|
||||
userDetailsDTOs.add((UserDetailsDTO) value);
|
||||
}
|
||||
List<UserOnlineDTO> userOnlineDTOs = BeanCopyUtil.copyList(userDetailsDTOs, UserOnlineDTO.class);
|
||||
List<UserOnlineDTO> onlineUsers = userOnlineDTOs.stream()
|
||||
.filter(item -> StringUtils.isBlank(conditionVO.getKeywords()) || item.getNickname().contains(conditionVO.getKeywords()))
|
||||
.sorted(Comparator.comparing(UserOnlineDTO::getLastLoginTime).reversed())
|
||||
.collect(Collectors.toList());
|
||||
int fromIndex = getLimitCurrent().intValue();
|
||||
int size = getSize().intValue();
|
||||
int toIndex = onlineUsers.size() - fromIndex > size ? fromIndex + size : onlineUsers.size();
|
||||
List<UserOnlineDTO> userOnlineList = onlineUsers.subList(fromIndex, toIndex);
|
||||
return new PageResultDTO<>(userOnlineList, onlineUsers.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeOnlineUser(Integer userInfoId) {
|
||||
Integer userId = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>().eq(UserAuth::getUserInfoId, userInfoId)).getId();
|
||||
tokenService.delLoginUser(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfoDTO getUserInfoById(Integer id) {
|
||||
UserInfo userInfo = userInfoMapper.selectById(id);
|
||||
return BeanCopyUtil.copyObject(userInfo, UserInfoDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.aurora.service.impl;
|
||||
|
||||
import com.aurora.entity.UserRole;
|
||||
import com.aurora.mapper.UserRoleMapper;
|
||||
import com.aurora.service.UserRoleService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {
|
||||
|
||||
}
|
||||
Loading…
Reference in new issue