重构收藏模块.

This commit is contained in:
lijiahang
2023-09-13 17:49:56 +08:00
parent a64481582f
commit 2ff0d37f07
15 changed files with 249 additions and 120 deletions

View File

@@ -1,11 +1,13 @@
package com.orion.ops.framework.common.utils;
import com.orion.lang.utils.Arrays1;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.spring.SpringHolder;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
@@ -20,6 +22,58 @@ public class Valid extends com.orion.lang.utils.Valid {
private static final Validator VALIDATOR = SpringHolder.getBean(Validator.class);
public static <T> T notNull(T object) {
return notNull(object, ErrorMessage.PARAM_MISSING);
}
public static String notBlank(String s) {
return notBlank(s, ErrorMessage.PARAM_MISSING);
}
public static <T extends Collection<?>> T notEmpty(T object) {
return notEmpty(object, ErrorMessage.PARAM_MISSING);
}
public static void allNotNull(Object... objects) {
if (objects != null) {
for (Object t : objects) {
notNull(t, ErrorMessage.PARAM_MISSING);
}
}
}
public static void allNotBlank(String... ss) {
if (ss != null) {
for (String s : ss) {
notBlank(s, ErrorMessage.PARAM_MISSING);
}
}
}
public static void eq(Object o1, Object o2) {
eq(o1, o2, ErrorMessage.INVALID_PARAM);
}
public static boolean isTrue(boolean s) {
return isTrue(s, ErrorMessage.INVALID_PARAM);
}
public static boolean isFalse(boolean s) {
return isFalse(s, ErrorMessage.INVALID_PARAM);
}
public static <T extends Comparable<T>> T gte(T t1, T t2) {
return gte(t1, t2, ErrorMessage.INVALID_PARAM);
}
@SafeVarargs
public static <T> T in(T t, T... ts) {
notNull(t, ErrorMessage.INVALID_PARAM);
notEmpty(ts, ErrorMessage.INVALID_PARAM);
isTrue(Arrays1.contains(ts, t), ErrorMessage.INVALID_PARAM);
return t;
}
/**
* 验证枚举
*

View File

@@ -3,6 +3,7 @@ package com.orion.ops.module.asset.service;
import com.orion.ops.module.asset.entity.dto.host.HostConfigContent;
import com.orion.ops.module.asset.entity.request.host.HostConfigUpdateRequest;
import com.orion.ops.module.asset.entity.vo.HostConfigVO;
import com.orion.ops.module.asset.enums.HostConfigTypeEnum;
import java.util.List;
@@ -29,10 +30,9 @@ public interface HostConfigService {
*
* @param hostId hostId
* @param type type
* @param clazz class
* @return 配置
*/
<T extends HostConfigContent> T getHostConfig(Long hostId, String type, Class<T> clazz);
<T extends HostConfigContent> T getHostConfig(Long hostId, HostConfigTypeEnum type);
/**
* 获取配置

View File

@@ -15,6 +15,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.util.List;
import java.util.stream.Collectors;
@@ -34,6 +35,7 @@ public class HostConfigServiceImpl implements HostConfigService {
@Override
public HostConfigVO getHostConfig(Long hostId, String type) {
Valid.valid(HostConfigTypeEnum::of, type);
// 查询配置
HostConfigDO config = hostConfigDAO.getHostConfigByHostId(hostId, type);
Valid.notNull(config, ErrorMessage.CONFIG_ABSENT);
@@ -44,11 +46,11 @@ public class HostConfigServiceImpl implements HostConfigService {
}
@Override
public <T extends HostConfigContent> T getHostConfig(Long hostId, String type, Class<T> clazz) {
public <T extends HostConfigContent> T getHostConfig(Long hostId, HostConfigTypeEnum type) {
// 查询配置
HostConfigDO config = hostConfigDAO.getHostConfigByHostId(hostId, type);
HostConfigDO config = hostConfigDAO.getHostConfigByHostId(hostId, type.name());
Valid.notNull(config, ErrorMessage.CONFIG_ABSENT);
return JSON.parseObject(config.getConfig(), clazz);
return JSON.parseObject(config.getConfig(), (Type) type.getType());
}
@Override
@@ -64,7 +66,7 @@ public class HostConfigServiceImpl implements HostConfigService {
@Override
public void updateHostConfig(HostConfigUpdateRequest request) {
String typeValue = request.getType();
HostConfigTypeEnum type = HostConfigTypeEnum.of(typeValue);
HostConfigTypeEnum type = Valid.valid(HostConfigTypeEnum::of, typeValue);
HostConfigContent requestConfig = JSON.parseObject(request.getConfig(), type.getType());
// 查询原配置
HostConfigDO record = hostConfigDAO.getHostConfigByHostId(request.getHostId(), typeValue);

View File

@@ -14,15 +14,6 @@ import java.util.concurrent.Future;
*/
public interface FavoriteApi {
/**
* 添加收藏
*
* @param type type
* @param userId userId
* @param relId relId
*/
void addFavorite(FavoriteTypeEnum type, Long userId, Long relId);
/**
* 获取收藏 relId 列表 会有已删除的 id
*
@@ -32,20 +23,6 @@ public interface FavoriteApi {
*/
Future<List<Long>> getFavoriteRelIdList(FavoriteTypeEnum type, Long userId);
/**
* 通过 userId 删除收藏
*
* @param userId userId
*/
void deleteByUserId(Long userId);
/**
* 通过 userId 删除收藏
*
* @param userIdList userId
*/
void deleteByUserIdList(List<Long> userIdList);
/**
* 通过 relId 删除收藏
*

View File

@@ -16,4 +16,16 @@ public enum FavoriteTypeEnum {
;
public static FavoriteTypeEnum of(String type) {
if (type == null) {
return null;
}
for (FavoriteTypeEnum value : values()) {
if (value.name().equals(type)) {
return value;
}
}
return null;
}
}

View File

@@ -1,7 +1,8 @@
package com.orion.ops.module.infra.api.impl;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.module.infra.api.FavoriteApi;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteCreateRequest;
import com.orion.ops.module.infra.dao.FavoriteDAO;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteQueryRequest;
import com.orion.ops.module.infra.enums.FavoriteTypeEnum;
import com.orion.ops.module.infra.service.FavoriteService;
@@ -26,50 +27,34 @@ public class FavoriteApiImpl implements FavoriteApi {
@Resource
private FavoriteService favoriteService;
@Override
@Async("asyncExecutor")
public void addFavorite(FavoriteTypeEnum type, Long userId, Long relId) {
String typeName = type.name();
FavoriteCreateRequest request = new FavoriteCreateRequest();
request.setUserId(userId);
request.setRelId(relId);
request.setType(typeName);
favoriteService.addFavorite(request);
}
@Resource
private FavoriteDAO favoriteDAO;
@Override
@Async("asyncExecutor")
public Future<List<Long>> getFavoriteRelIdList(FavoriteTypeEnum type, Long userId) {
FavoriteQueryRequest request = new FavoriteQueryRequest();
request.setUserId(userId);
request.setType(type.name());
Valid.allNotNull(type, userId);
// 查询
FavoriteQueryRequest request = new FavoriteQueryRequest();
request.setType(type.name());
request.setUserId(userId);
List<Long> relIdList = favoriteService.getFavoriteRelIdList(request);
return CompletableFuture.completedFuture(relIdList);
}
@Override
@Async("asyncExecutor")
public void deleteByUserId(Long userId) {
favoriteService.deleteFavoriteByUserId(userId);
}
@Override
@Async("asyncExecutor")
public void deleteByUserIdList(List<Long> userIdList) {
favoriteService.deleteFavoriteByUserIdList(userIdList);
}
@Override
@Async("asyncExecutor")
public void deleteByRelId(FavoriteTypeEnum type, Long relId) {
favoriteService.deleteFavoriteByRelId(type.name(), relId);
Valid.allNotNull(type, relId);
favoriteDAO.deleteFavoriteByRelId(type.name(), relId);
}
@Override
@Async("asyncExecutor")
public void deleteByRelIdList(FavoriteTypeEnum type, List<Long> relIdList) {
favoriteService.deleteFavoriteByRelIdList(type.name(), relIdList);
Valid.notNull(type);
Valid.notEmpty(relIdList);
favoriteDAO.deleteFavoriteByRelIdList(type.name(), relIdList);
}
}

View File

@@ -0,0 +1,23 @@
### 添加收藏
POST {{baseUrl}}/infra/favorite/add
Content-Type: application/json
Authorization: {{token}}
{
"relId": "",
"type": "HOST"
}
### 取消收藏
GET {{baseUrl}}/infra/favorite/cancel
Content-Type: application/json
Authorization: {{token}}
{
"relId": "",
"type": "HOST"
}
###

View File

@@ -0,0 +1,49 @@
package com.orion.ops.module.infra.controller;
import com.orion.ops.framework.common.annotation.RestWrapper;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteOperatorRequest;
import com.orion.ops.module.infra.service.FavoriteService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 收藏 api
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-5 11:58
*/
@Tag(name = "infra - 收藏服务")
@Slf4j
@Validated
@RestWrapper
@RestController
@RequestMapping("/infra/favorite")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class FavoriteController {
@Resource
private FavoriteService favoriteService;
@PutMapping("/add")
@Operation(summary = "添加收藏")
public Long addFavorite(@Validated @RequestBody FavoriteOperatorRequest request) {
return favoriteService.addFavorite(request);
}
@PutMapping("/cancel")
@Operation(summary = "取消收藏")
public Integer cancelFavorite(@Validated @RequestBody FavoriteOperatorRequest request) {
return favoriteService.cancelFavorite(request);
}
}

View File

@@ -1,7 +1,7 @@
package com.orion.ops.module.infra.convert;
import com.orion.ops.module.infra.entity.domain.FavoriteDO;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteCreateRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteOperatorRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteQueryRequest;
import com.orion.ops.module.infra.entity.vo.FavoriteVO;
import org.mapstruct.Mapper;
@@ -19,7 +19,7 @@ public interface FavoriteConvert {
FavoriteConvert MAPPER = Mappers.getMapper(FavoriteConvert.class);
FavoriteDO to(FavoriteCreateRequest request);
FavoriteDO to(FavoriteOperatorRequest request);
FavoriteDO to(FavoriteQueryRequest request);

View File

@@ -1,9 +1,12 @@
package com.orion.ops.module.infra.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.ops.framework.mybatis.core.mapper.IMapper;
import com.orion.ops.module.infra.entity.domain.FavoriteDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 收藏 Mapper 接口
*
@@ -14,4 +17,48 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FavoriteDAO extends IMapper<FavoriteDO> {
/**
* 通过 relId 删除收藏
*
* @param type type
* @param userId userId
* @param relId relId
* @return effect
*/
default int deleteFavorite(String type, Long userId, Long relId) {
LambdaQueryWrapper<FavoriteDO> wrapper = this.lambda()
.eq(FavoriteDO::getType, type)
.eq(FavoriteDO::getUserId, userId)
.eq(FavoriteDO::getRelId, relId);
return this.delete(wrapper);
}
/**
* 通过 relId 删除收藏
*
* @param type type
* @param relId relId
* @return effect
*/
default int deleteFavoriteByRelId(String type, Long relId) {
LambdaQueryWrapper<FavoriteDO> wrapper = this.lambda()
.eq(FavoriteDO::getType, type)
.eq(FavoriteDO::getRelId, relId);
return this.delete(wrapper);
}
/**
* 通过 relId 删除收藏
*
* @param type type
* @param relIdList relIdList
* @return effect
*/
default int deleteFavoriteByRelIdList(String type, List<Long> relIdList) {
LambdaQueryWrapper<FavoriteDO> wrapper = this.lambda()
.eq(FavoriteDO::getType, type)
.in(FavoriteDO::getRelId, relIdList);
return this.delete(wrapper);
}
}

View File

@@ -12,7 +12,7 @@ import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* 收藏 创建请求对象
* 收藏 操作请求对象
*
* @author Jiahang Li
* @version 1.0.0
@@ -22,12 +22,8 @@ import java.io.Serializable;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "FavoriteCreateRequest", description = "收藏 创建请求对象")
public class FavoriteCreateRequest implements Serializable {
@NotNull
@Schema(description = "用户id")
private Long userId;
@Schema(name = "FavoriteOperatorRequest", description = "收藏 操作请求对象")
public class FavoriteOperatorRequest implements Serializable {
@NotNull
@Schema(description = "引用id")

View File

@@ -36,7 +36,4 @@ public class FavoriteQueryRequest extends PageRequest {
@Schema(description = "用户id")
private List<Long> userIdList;
@Schema(description = "引用id")
private List<Long> relIdList;
}

View File

@@ -1,6 +1,6 @@
package com.orion.ops.module.infra.service;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteCreateRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteOperatorRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteQueryRequest;
import com.orion.ops.module.infra.entity.vo.FavoriteVO;
@@ -21,7 +21,15 @@ public interface FavoriteService {
* @param request request
* @return id
*/
Long addFavorite(FavoriteCreateRequest request);
Long addFavorite(FavoriteOperatorRequest request);
/**
* 删除收藏
*
* @param request request
* @return effect
*/
Integer cancelFavorite(FavoriteOperatorRequest request);
/**
* 查询收藏列表
@@ -53,20 +61,4 @@ public interface FavoriteService {
*/
void deleteFavoriteByUserIdList(List<Long> userIdList);
/**
* 通过 relId 删除收藏
*
* @param type type
* @param relId relId
*/
void deleteFavoriteByRelId(String type, Long relId);
/**
* 通过 relId 删除收藏
*
* @param type type
* @param relIdList relIdList
*/
void deleteFavoriteByRelIdList(String type, List<Long> relIdList);
}

View File

@@ -1,15 +1,16 @@
package com.orion.ops.module.infra.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.framework.redis.core.utils.RedisUtils;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.convert.FavoriteConvert;
import com.orion.ops.module.infra.dao.FavoriteDAO;
import com.orion.ops.module.infra.define.FavoriteCacheKeyDefine;
import com.orion.ops.module.infra.entity.domain.FavoriteDO;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteCreateRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteOperatorRequest;
import com.orion.ops.module.infra.entity.request.favorite.FavoriteQueryRequest;
import com.orion.ops.module.infra.entity.vo.FavoriteVO;
import com.orion.ops.module.infra.enums.FavoriteTypeEnum;
@@ -42,20 +43,35 @@ public class FavoriteServiceImpl implements FavoriteService {
private RedisTemplate<String, String> redisTemplate;
@Override
public Long addFavorite(FavoriteCreateRequest request) {
public Long addFavorite(FavoriteOperatorRequest request) {
String type = Valid.valid(FavoriteTypeEnum::of, request.getType()).name();
Long userId = SecurityUtils.getLoginUserId();
// 转换
FavoriteDO record = FavoriteConvert.MAPPER.to(request);
record.setUserId(userId);
// 插入
int effect = favoriteDAO.insert(record);
log.info("FavoriteService-addFavorite effect: {}, record: {}", effect, JSON.toJSONString(record));
// 设置缓存
String key = FavoriteCacheKeyDefine.FAVORITE.format(request.getType(), request.getUserId());
String key = FavoriteCacheKeyDefine.FAVORITE.format(type, userId);
RedisUtils.listPush(key, request.getRelId(), String::valueOf);
// 设置过期时间
RedisUtils.setExpire(key, FavoriteCacheKeyDefine.FAVORITE);
return record.getId();
}
@Override
public Integer cancelFavorite(FavoriteOperatorRequest request) {
String type = Valid.valid(FavoriteTypeEnum::of, request.getType()).name();
Long userId = SecurityUtils.getLoginUserId();
Long relId = request.getRelId();
// 删除库
int effect = favoriteDAO.deleteFavorite(type, userId, relId);
// 删除缓存
String key = FavoriteCacheKeyDefine.FAVORITE.format(type, userId);
redisTemplate.opsForList().remove(key, 1, relId);
return effect;
}
@Override
public List<FavoriteVO> getFavoriteList(FavoriteQueryRequest request) {
// 条件
@@ -129,30 +145,6 @@ public class FavoriteServiceImpl implements FavoriteService {
favoriteDAO.delete(this.buildQueryWrapper(request));
}
@Override
public void deleteFavoriteByRelId(String type, Long relId) {
if (relId == null) {
return;
}
FavoriteQueryRequest request = new FavoriteQueryRequest();
request.setType(type);
request.setRelId(relId);
// 只删除数据库 redis 等自动失效
favoriteDAO.delete(this.buildQueryWrapper(request));
}
@Override
public void deleteFavoriteByRelIdList(String type, List<Long> relIdList) {
if (Lists.isEmpty(relIdList)) {
return;
}
FavoriteQueryRequest request = new FavoriteQueryRequest();
request.setType(type);
request.setRelIdList(relIdList);
// 只删除数据库 redis 等自动失效
favoriteDAO.delete(this.buildQueryWrapper(request));
}
/**
* 构建查询 wrapper
*
@@ -165,8 +157,7 @@ public class FavoriteServiceImpl implements FavoriteService {
.eq(FavoriteDO::getUserId, request.getUserId())
.eq(FavoriteDO::getRelId, request.getRelId())
.eq(FavoriteDO::getType, request.getType())
.in(FavoriteDO::getUserId, request.getUserIdList())
.in(FavoriteDO::getRelId, request.getRelIdList());
.in(FavoriteDO::getUserId, request.getUserIdList());
}
}

View File

@@ -20,6 +20,7 @@ import com.orion.ops.module.infra.entity.request.user.*;
import com.orion.ops.module.infra.entity.vo.SystemUserVO;
import com.orion.ops.module.infra.enums.UserStatusEnum;
import com.orion.ops.module.infra.service.AuthenticationService;
import com.orion.ops.module.infra.service.FavoriteService;
import com.orion.ops.module.infra.service.SystemUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
@@ -47,6 +48,9 @@ public class SystemUserServiceImpl implements SystemUserService {
@Resource
private SystemUserRoleDAO systemUserRoleDAO;
@Resource
private FavoriteService favoriteService;
@Resource
private RedisTemplate<String, String> redisTemplate;
@@ -162,6 +166,8 @@ public class SystemUserServiceImpl implements SystemUserService {
effect += systemUserRoleDAO.deleteByUserId(id);
// 删除用户缓存 其他的会自动过期
redisTemplate.delete(UserCacheKeyDefine.USER_INFO.format(id));
// 删除用户收藏
favoriteService.deleteFavoriteByUserId(id);
return effect;
}
@@ -203,7 +209,6 @@ public class SystemUserServiceImpl implements SystemUserService {
LambdaQueryWrapper<SystemUserDO> wrapper = systemUserDAO.wrapper()
// 更新时忽略当前记录
.ne(SystemUserDO::getId, domain.getId())
// 用其他字段做重复校验
.eq(SystemUserDO::getUsername, domain.getUsername());
// 检查是否存在
boolean present = systemUserDAO.of(wrapper).present();
@@ -220,7 +225,6 @@ public class SystemUserServiceImpl implements SystemUserService {
LambdaQueryWrapper<SystemUserDO> wrapper = systemUserDAO.wrapper()
// 更新时忽略当前记录
.ne(SystemUserDO::getId, domain.getId())
// 用其他字段做重复校验
.eq(SystemUserDO::getNickname, domain.getNickname());
// 检查是否存在
boolean present = systemUserDAO.of(wrapper).present();