Merge pull request '메뉴 권한별 레디스저장, 조회 추가' (#82) from feat/dev_251201 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/82
This commit is contained in:
2025-12-19 15:29:28 +09:00
6 changed files with 107 additions and 64 deletions

View File

@@ -17,6 +17,7 @@ import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -70,11 +71,42 @@ public class MenuApiController {
return ApiResponseDto.ok(ApiLogFunction.getUriMenuInfo(result, apiUri));
}
@Operation(summary = "권한별 메뉴 조회", description = "권한별 메뉴 ")
@Operation(summary = "권한별 메뉴 레디스 저장", description = "권한별 메뉴 레디스 저장")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "등록 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MenuDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/auth")
public ApiResponseDto<Void> getFindByRoleRedis() {
menuService.getFindByRoleRedis();
return ApiResponseDto.createOK(null);
}
@Operation(summary = "권한별 메뉴 조회", description = "권한별 메뉴 조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MenuDto.Basic.class))),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/auth")
public ApiResponseDto<String> getFindAllByRole() {
public ApiResponseDto<List<MenuDto.Basic>> getFindAllByRole() {
UserUtil userUtil = new UserUtil();
String role = userUtil.getRole();
return null; // ApiResponseDto.ok(menuService.getFindByRole(role));
return ApiResponseDto.ok(menuService.getFindByRole(role));
}
}

View File

@@ -4,7 +4,6 @@ import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -62,23 +61,4 @@ public class MenuDto {
this.menuApiUrl = menuApiUrl;
}
}
@Getter
@AllArgsConstructor
public class RoleBasic {
private String menuUid;
private String parentMenuUid;
private String menuNm;
private String menuUrl;
private String description;
private Long menuOrder;
private Boolean isUse;
private Boolean deleted;
private Long createdUid;
private Long updatedUid;
private ZonedDateTime createdDttm;
private ZonedDateTime updatedDttm;
private String menuApiUrl;
}
}

View File

@@ -1,10 +1,17 @@
package com.kamco.cd.kamcoback.menu.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.postgres.core.MenuCoreService;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
@Service
@@ -12,6 +19,8 @@ import org.springframework.stereotype.Service;
public class MenuService {
private final MenuCoreService menuCoreService;
private final StringRedisTemplate redisTemplate;
private final ObjectMapper objectMapper;
@Cacheable(value = "menuFindAll")
public List<MenuDto.Basic> getFindAll() {
@@ -19,12 +28,47 @@ public class MenuService {
}
/**
* 권한별 메뉴 목록
* 권한별 메뉴 목록 redis 등록
*
* @return
*/
public void getFindByRoleRedis() {
for (RoleType role : RoleType.values()) {
List<MenuDto.Basic> menus = menuCoreService.getFindByRole(role.name());
try {
String key = "menu:role:" + role.name();
String value = objectMapper.writeValueAsString(menus);
redisTemplate.opsForValue().set(key, value, Duration.ofHours(6));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
/**
* 권한별 메뉴 목록 조회
*
* @param role
* @return
*/
// public List<MenuDto.MenuList> getFindByRole(String role) {
// return menuCoreService.getFindByRole(role);
// }
public List<MenuDto.Basic> getFindByRole(String role) {
String key = "menu:role:" + role;
String json = redisTemplate.opsForValue().get(key);
if (json == null) {
return new ArrayList<>();
}
JavaType type =
objectMapper.getTypeFactory().constructCollectionType(List.class, MenuDto.Basic.class);
List<MenuDto.Basic> cached;
try {
cached = objectMapper.readValue(json, type);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return cached;
}
}

View File

@@ -1,12 +1,9 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.menu.dto.MenuDto.RoleBasic;
import com.kamco.cd.kamcoback.postgres.entity.MenuEntity;
import com.kamco.cd.kamcoback.postgres.repository.menu.MenuRepository;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -26,11 +23,7 @@ public class MenuCoreService {
* @param role
* @return
*/
public List<MenuDto.RoleBasic> getFindByRole(String role) {
Map<String, RoleBasic> map = new LinkedHashMap<>();
List<MenuDto.RoleBasic> rows = menuRepository.getFindByRole(role);
return menuRepository.getFindByRole(role);
public List<MenuDto.Basic> getFindByRole(String role) {
return menuRepository.getFindByRole(role).stream().map(MenuEntity::toDto).toList();
}
}

View File

@@ -1,6 +1,5 @@
package com.kamco.cd.kamcoback.postgres.repository.menu;
import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.postgres.entity.MenuEntity;
import java.util.List;
@@ -14,5 +13,5 @@ public interface MenuRepositoryCustom {
* @param role
* @return
*/
List<MenuDto.RoleBasic> getFindByRole(String role);
List<MenuEntity> getFindByRole(String role);
}

View File

@@ -3,9 +3,8 @@ package com.kamco.cd.kamcoback.postgres.repository.menu;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuEntity.menuEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMenuMappEntity.menuMappEntity;
import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.postgres.entity.MenuEntity;
import com.querydsl.core.types.Projections;
import com.kamco.cd.kamcoback.postgres.entity.QMenuEntity;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
@@ -31,33 +30,29 @@ public class MenuRepositoryImpl implements MenuRepositoryCustom {
* @return
*/
@Override
public List<MenuDto.RoleBasic> getFindByRole(String role) {
List<MenuDto.RoleBasic> content =
public List<MenuEntity> getFindByRole(String role) {
QMenuEntity child = new QMenuEntity("child");
List<MenuEntity> content =
queryFactory
.select(
Projections.constructor(
MenuDto.RoleBasic.class,
menuEntity.menuUid,
menuEntity.parent.menuUid,
menuEntity.menuNm,
menuEntity.menuUrl,
menuEntity.description,
menuEntity.menuOrder,
menuEntity.isUse,
menuEntity.deleted,
menuEntity.createdUid,
menuEntity.updatedUid,
menuEntity.createdDate,
menuEntity.modifiedDate,
menuEntity.menuApiUri))
.from(menuMappEntity)
.join(menuMappEntity.menuUid, menuEntity)
.selectDistinct(menuEntity)
.from(menuEntity)
.leftJoin(menuEntity.children, child)
.fetchJoin()
.leftJoin(menuMappEntity)
.on(
menuMappEntity
.roleCode
.eq(role)
.and(menuMappEntity.deleted.isFalse())
.and(
menuMappEntity.menuUid.eq(menuEntity).or(menuMappEntity.menuUid.eq(child))))
.where(
menuMappEntity.roleCode.eq(role),
menuMappEntity.deleted.isFalse(),
menuEntity.parent.isNull(),
menuEntity.deleted.isFalse(),
menuEntity.isUse.isTrue())
.orderBy(menuEntity.menuOrder.asc().nullsLast(), menuEntity.menuNm.asc())
menuEntity.isUse.isTrue(),
menuMappEntity.id.isNotNull())
.orderBy(menuEntity.menuOrder.asc().nullsLast(), child.menuOrder.asc().nullsLast())
.fetch();
return content;