feature: 收藏功能.

This commit is contained in:
lijiahang
2023-09-05 11:50:53 +08:00
parent fb42e31f6e
commit 8035396995
15 changed files with 206 additions and 46 deletions

View File

@@ -1,6 +1,7 @@
package com.orion.ops.framework.common.entity;
import com.orion.lang.define.wrapper.IPageRequest;
import com.orion.ops.framework.common.valid.group.Page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
@@ -15,11 +16,11 @@ import org.hibernate.validator.constraints.Range;
@Data
public class PageRequest implements IPageRequest {
@Range(min = 1, max = 10000, groups = IPageRequest.class)
@Range(min = 1, max = 10000, groups = Page.class)
@Schema(description = "页码")
private int page;
@Range(min = 1, max = 100, groups = IPageRequest.class)
@Range(min = 1, max = 100, groups = Page.class)
@Schema(description = "大小")
private int limit;

View File

@@ -0,0 +1,11 @@
package com.orion.ops.framework.common.valid.group;
/**
* 分页验证分组
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/9/1 19:13
*/
public interface Id {
}

View File

@@ -0,0 +1,11 @@
package com.orion.ops.framework.common.valid.group;
/**
* 分页验证分组
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/9/1 19:13
*/
public interface Page {
}

View File

@@ -3,6 +3,7 @@ package com.orion.ops.framework.redis.core.utils;
import com.alibaba.fastjson.JSON;
import com.orion.lang.define.cache.CacheKeyDefine;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.lang.utils.io.Streams;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
@@ -10,8 +11,10 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* redis 工具类
@@ -132,6 +135,50 @@ public class RedisUtils {
}
}
/**
* 查询 list 区间
*
* @param key key
* @return list
*/
public static List<String> listRange(String key) {
// 查询列表
List<String> elements = redisTemplate.opsForList().range(key, 0, -1);
if (elements == null) {
return Lists.newList();
}
return elements;
}
/**
* 查询 list 区间
*
* @param key key
* @param mapper mapper
* @param <T> T
* @return list
*/
public static <T> List<T> listRange(String key, Function<String, T> mapper) {
// 查询列表
List<String> elements = redisTemplate.opsForList().range(key, 0, -1);
if (elements == null) {
return Lists.newList();
}
return Lists.map(elements, mapper);
}
/**
* list 添加元素
*
* @param key key
* @param list list
* @param mapper mapper
* @param <T> T
*/
public static <T> void listPushAll(String key, List<T> list, Function<T, String> mapper) {
redisTemplate.opsForList().rightPushAll(key, Lists.map(list, mapper));
}
/**
* 设置过期时间
*

View File

@@ -241,13 +241,15 @@ public class VelocityTemplateEngine extends AbstractTemplateEngine {
objectMap.put("apiComment", map);
String comment = tableInfo.getComment();
map.put("create", "创建" + comment);
map.put("updateAll", "更新" + comment);
map.put("updateById", "通过 id 更新" + comment);
map.put("getById", "通过 id 查询" + comment);
map.put("listByIdList", "通过 id 批量查询" + comment);
map.put("listAll", "查询全部" + comment);
map.put("listAll", "查询" + comment);
map.put("queryCount", "查询" + comment + "数量");
map.put("queryPage", "分页查询" + comment);
map.put("deleteById", "通过 id 删除" + comment);
map.put("deleteAll", "删除" + comment);
map.put("batchDeleteByIdList", "通过 id 批量删除" + comment);
map.put("export", "导出" + comment);
}

View File

@@ -1,10 +1,11 @@
package ${package.Controller};
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.define.wrapper.IPageRequest;
import com.orion.ops.framework.common.annotation.IgnoreLog;
import com.orion.ops.framework.common.annotation.RestWrapper;
import com.orion.ops.framework.common.constant.IgnoreLogMode;
import com.orion.ops.framework.common.valid.group.Id;
import com.orion.ops.framework.common.valid.group.Page;
import ${package.Service}.*;
#foreach($pkg in ${customModuleFilePackages})
import ${pkg}.*;
@@ -21,6 +22,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
@@ -56,7 +59,7 @@ public class ${table.controllerName} {
@PutMapping("/update")
@Operation(summary = "${apiComment.updateById}")
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:update')")
public Integer update${type}(@Validated @RequestBody ${type}UpdateRequest request) {
public Integer update${type}(@Validated @RequestBody(Id.class) ${type}UpdateRequest request) {
return ${typeLower}Service.update${type}ById(request);
}
@@ -90,7 +93,7 @@ public class ${table.controllerName} {
@PostMapping("/query")
@Operation(summary = "${apiComment.queryPage}")
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:query')")
public DataGrid<${type}VO> get${type}Page(@Validated(IPageRequest.class) @RequestBody ${type}QueryRequest request) {
public DataGrid<${type}VO> get${type}Page(@Validated(Page.class) @RequestBody ${type}QueryRequest request) {
return ${typeLower}Service.get${type}Page(request);
}
@@ -114,7 +117,7 @@ public class ${table.controllerName} {
@Operation(summary = "${apiComment.export}")
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:export')")
public void export${type}(@Validated @RequestBody ${type}QueryRequest request,
HttpServletResponse response) throws IOException {
HttpServletResponse response) throws IOException {
${typeLower}Service.export${type}(request, response);
}

View File

@@ -29,6 +29,8 @@ public interface ${type}Convert {
${type}VO to(${type}DO domain);
${type}Export export(${type}DO domain);
List<${type}VO> to(List<${type}DO> list);
}

View File

@@ -3,6 +3,7 @@ package ${package.ServiceImpl};
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.utils.collect.Lists;
import com.orion.office.excel.writer.exporting.ExcelExport;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.ops.framework.common.utils.FileNames;
@@ -67,6 +68,19 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
return effect;
}
@Override
public Integer update${type}(${type}QueryRequest query, ${type}UpdateRequest update) {
log.info("${type}Service.update${type} query: {}, update: {}", JSON.toJSONString(query), JSON.toJSONString(update));
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(query);
// 转换
${type}DO updateRecord = ${type}Convert.MAPPER.to(update);
// 更新
int effect = ${typeLower}DAO.update(updateRecord, wrapper);
log.info("${type}Service.update${type} effect: {}", effect);
return effect;
}
@Override
public ${type}VO get${type}ById(Long id) {
// 查询
@@ -130,6 +144,17 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
return effect;
}
@Override
public Integer delete${type}(${type}QueryRequest request) {
log.info("${type}Service.delete${type} request: {}", JSON.toJSONString(request));
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
// 删除
int effect = ${typeLower}DAO.delete(wrapper);
log.info("${type}Service.delete${type} effect: {}", effect);
return effect;
}
@Override
public void export${type}(${type}QueryRequest request, HttpServletResponse response) throws IOException {
// 条件

View File

@@ -5,6 +5,8 @@ import com.orion.lang.define.wrapper.DataGrid;
import ${pkg}.*;
#end
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
@@ -32,6 +34,15 @@ public interface ${table.serviceName} {
*/
Integer update${type}ById(${type}UpdateRequest request);
/**
* ${apiComment.updateAll}
*
* @param query query
* @param update update
* @return effect
*/
Integer update${type}(${type}QueryRequest query, ${type}UpdateRequest update);
/**
* ${apiComment.getById}
*
@@ -88,6 +99,14 @@ public interface ${table.serviceName} {
*/
Integer batchDelete${type}ByIdList(List<Long> idList);
/**
* ${apiComment.deleteAll}
*
* @param request request
* @return effect
*/
Integer delete${type}(${type}QueryRequest request);
/**
* ${apiComment.export}
*

View File

@@ -41,24 +41,39 @@ public class ${type}ApiImpl implements ${type}Api {
@Override
public Long create${type}(${type}CreateDTO dto) {
log.info("${type}Api.create${type} request: {}", JSON.toJSONString(dto));
log.info("${type}Api.create${type} dto: {}", JSON.toJSONString(dto));
Valid.valid(dto);
// 转换
${type}CreateRequest request = ${type}ProviderConvert.MAPPER.to(dto);
${type}CreateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
// 创建
return ${typeLower}Service.create${type}(request);
}
@Override
public Integer update${type}ById(${type}UpdateDTO dto) {
log.info("${type}Api.update${type}ById request: {}", JSON.toJSONString(dto));
log.info("${type}Api.update${type}ById dto: {}", JSON.toJSONString(dto));
Valid.valid(dto);
// 转换
${type}UpdateRequest request = ${type}ProviderConvert.MAPPER.to(dto);
${type}UpdateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
// 修改
return ${typeLower}Service.update${type}ById(request);
}
@Override
public Integer update${type}(${type}QueryDTO query, ${type}UpdateDTO update) {
log.info("${type}Api.update${type} query: {}, update: {}", JSON.toJSONString(query), JSON.toJSONString(update));
Valid.valid(query);
Valid.valid(update);
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(query);
// 转换
${type}DO updateRecord = ${type}ProviderConvert.MAPPER.to(update);
// 更新
int effect = ${typeLower}DAO.update(updateRecord, wrapper);
log.info("${type}Api.update${type} effect: {}", effect);
return effect;
}
@Override
public ${type}DTO get${type}ById(Long id) {
log.info("${type}Api.get${type}ById id: {}", id);
@@ -122,6 +137,16 @@ public class ${type}ApiImpl implements ${type}Api {
return ${typeLower}DAO.deleteBatchIds(idList);
}
@Override
public Integer delete${type}(${type}QueryDTO dto) {
log.info("${type}Api.delete${type} dto: {}", JSON.toJSONString(dto));
Valid.valid(dto);
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(dto);
// 删除
return ${typeLower}DAO.delete(wrapper);
}
/**
* 构建查询 wrapper
*

View File

@@ -32,6 +32,15 @@ public interface ${type}Api {
*/
Integer update${type}ById(${type}UpdateDTO dto);
/**
* ${apiComment.updateAll}
*
* @param query query
* @param update update
* @return effect
*/
Integer update${type}(${type}QueryDTO query, ${type}UpdateDTO update);
/**
* ${apiComment.getById}
*
@@ -80,4 +89,12 @@ public interface ${type}Api {
*/
Integer batchDelete${type}ByIdList(Collection<Long> idList);
/**
* ${apiComment.deleteAll}
*
* @param dto dto
* @return effect
*/
Integer delete${type}(${type}QueryDTO dto);
}

View File

@@ -30,9 +30,11 @@ public interface ${type}ProviderConvert {
${type}DO to(${type}QueryDTO domain);
${type}CreateRequest to(${type}CreateDTO domain);
${type}DO to(${type}UpdateDTO update);
${type}UpdateRequest to(${type}UpdateDTO domain);
${type}CreateRequest toRequest(${type}CreateDTO request);
${type}UpdateRequest toRequest(${type}UpdateDTO request);
List<${type}DTO> toList(List<${type}DO> list);

View File

@@ -1,6 +1,5 @@
package com.orion.ops.module.infra.api.impl;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.framework.redis.core.utils.RedisUtils;
@@ -52,43 +51,36 @@ public class FavoriteApiImpl implements FavoriteApi {
favoriteService.addFavorite(request);
// 获取缓存
String key = FavoriteCacheKeyDefine.FAVORITE.format(typeName, userId);
String cache = redisTemplate.opsForValue().get(key);
List<Long> relIdList;
if (Strings.isBlank(cache)) {
relIdList = Lists.newList();
} else {
relIdList = Arrays.stream(cache.split(Const.COMMA))
.map(Long::valueOf)
.collect(Collectors.toList());
}
// 插入缓存
relIdList.add(relId);
RedisUtils.set(key, FavoriteCacheKeyDefine.FAVORITE, Lists.join(relIdList));
RedisUtils.listPushAll(key, Lists.singleton(relId), String::valueOf);
// 设置过期时间
RedisUtils.setExpire(key, FavoriteCacheKeyDefine.FAVORITE);
}
@Override
@Async("asyncExecutor")
public Future<List<Long>> getFavoriteRelIdList(FavoriteTypeEnum type, Long userId) {
// 获取缓存
String typeName = type.name();
String key = FavoriteCacheKeyDefine.FAVORITE.format(typeName, userId);
String cache = redisTemplate.opsForValue().get(key);
List<Long> relIdList;
if (cache != null) {
// 不为 null 则获取缓存
relIdList = Arrays.stream(cache.split(Const.COMMA))
.map(Long::valueOf)
.collect(Collectors.toList());
} else {
// 为 null 从数据库获取
// 获取缓存
List<Long> cacheRelIdList = RedisUtils.listRange(key, Long::valueOf);
if (cacheRelIdList.isEmpty()) {
// 查询数据库
FavoriteQueryRequest request = new FavoriteQueryRequest();
request.setUserId(userId);
request.setType(typeName);
relIdList = favoriteService.getFavoriteRelIdList(request);
cacheRelIdList = favoriteService.getFavoriteRelIdList(request);
// 设置 -1 到缓存防止穿透
if (cacheRelIdList.isEmpty()) {
cacheRelIdList.add(Const.L_N_1);
}
// 设置缓存
redisTemplate.opsForValue().set(key, Lists.join(relIdList));
RedisUtils.listPushAll(key, cacheRelIdList, String::valueOf);
// 设置过期时间
RedisUtils.setExpire(key, FavoriteCacheKeyDefine.FAVORITE);
}
return CompletableFuture.completedFuture(relIdList);
// 尝试删除防止穿透的 key
cacheRelIdList.remove(Const.L_N_1);
return CompletableFuture.completedFuture(cacheRelIdList);
}
@Override
@@ -141,6 +133,7 @@ public class FavoriteApiImpl implements FavoriteApi {
}
@Override
@Async("asyncExecutor")
public void deleteFavoriteByRelIdList(List<Long> relIdList) {
if (Lists.isEmpty(relIdList)) {
return;

View File

@@ -1,10 +1,11 @@
package com.orion.ops.module.infra.controller;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.define.wrapper.IPageRequest;
import com.orion.ops.framework.common.annotation.IgnoreLog;
import com.orion.ops.framework.common.annotation.RestWrapper;
import com.orion.ops.framework.common.constant.IgnoreLogMode;
import com.orion.ops.framework.common.valid.group.Id;
import com.orion.ops.framework.common.valid.group.Page;
import com.orion.ops.module.infra.entity.request.menu.SystemRoleBindMenuRequest;
import com.orion.ops.module.infra.entity.request.role.SystemRoleCreateRequest;
import com.orion.ops.module.infra.entity.request.role.SystemRoleQueryRequest;
@@ -56,14 +57,14 @@ public class SystemRoleController {
@PutMapping("/update")
@Operation(summary = "通过 id 更新角色")
@PreAuthorize("@ss.hasPermission('infra:system-role:update')")
public Integer updateSystemRole(@Validated @RequestBody SystemRoleUpdateRequest request) {
public Integer updateSystemRole(@Validated(Id.class) @RequestBody SystemRoleUpdateRequest request) {
return systemRoleService.updateSystemRoleById(request);
}
@PutMapping("/update-status")
@Operation(summary = "通过 id 更新角色状态")
@PreAuthorize("@ss.hasPermission('infra:system-role:update-status')")
public Integer updateRoleStatus(@Validated @RequestBody SystemRoleStatusRequest request) {
public Integer updateRoleStatus(@Validated(Id.class) @RequestBody SystemRoleStatusRequest request) {
return systemRoleService.updateRoleStatus(request);
}
@@ -88,7 +89,7 @@ public class SystemRoleController {
@PostMapping("/query")
@Operation(summary = "分页查询角色")
@PreAuthorize("@ss.hasPermission('infra:system-role:query')")
public DataGrid<SystemRoleVO> getSystemRolePage(@Validated(IPageRequest.class) @RequestBody SystemRoleQueryRequest request) {
public DataGrid<SystemRoleVO> getSystemRolePage(@Validated(Page.class) @RequestBody SystemRoleQueryRequest request) {
return systemRoleService.getSystemRolePage(request);
}

View File

@@ -2,11 +2,12 @@ package com.orion.ops.module.infra.controller;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.define.wrapper.HttpWrapper;
import com.orion.lang.define.wrapper.IPageRequest;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.common.annotation.IgnoreLog;
import com.orion.ops.framework.common.annotation.RestWrapper;
import com.orion.ops.framework.common.constant.IgnoreLogMode;
import com.orion.ops.framework.common.valid.group.Id;
import com.orion.ops.framework.common.valid.group.Page;
import com.orion.ops.module.infra.entity.request.user.*;
import com.orion.ops.module.infra.entity.vo.SystemUserVO;
import com.orion.ops.module.infra.service.SystemUserRoleService;
@@ -54,7 +55,7 @@ public class SystemUserController {
@PutMapping("/update")
@Operation(summary = "通过 id 更新用户")
@PreAuthorize("@ss.hasPermission('infra:system-user:update')")
public Integer updateSystemUser(@Validated @RequestBody SystemUserUpdateRequest request) {
public Integer updateSystemUser(@Validated(Id.class) @RequestBody SystemUserUpdateRequest request) {
return systemUserService.updateSystemUserById(request);
}
@@ -117,7 +118,7 @@ public class SystemUserController {
@PostMapping("/query")
@Operation(summary = "分页查询用户")
@PreAuthorize("@ss.hasPermission('infra:system-user:query')")
public DataGrid<SystemUserVO> getSystemUserPage(@Validated(IPageRequest.class) @RequestBody SystemUserQueryRequest request) {
public DataGrid<SystemUserVO> getSystemUserPage(@Validated(Page.class) @RequestBody SystemUserQueryRequest request) {
return systemUserService.getSystemUserPage(request);
}