Initial commit

This commit is contained in:
jade
2026-07-03 17:47:03 +09:00
commit 1bebb681fe
103 changed files with 5225 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
package io.shinhanlife;
import io.shinhanlife.glow.GlowMybatisMapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = "io.shinhanlife", annotationClass = GlowMybatisMapper.class) // @GlowMybatisMapper 어노테이션이 있는 인터페이스만 스캔
public class AxHubAdminApplication {
public static void main(String[] args) {
SpringApplication.run(AxHubAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,19 @@
package io.shinhanlife.axhub.biz.sm.mmg.converter;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RResponse;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public abstract class MenuConverter {
public abstract MenuInDto smMmg0000M01RRequestToMenuInDto(SmMmg0000M01RRequest req);
public abstract MenuListDto smMmg0000M01RResponseToMenuListDto(SmMmg0000M01RResponse res);
public abstract SmMmg0000M01RResponse menuListDtoeToSmMmg0000M01RResponse(MenuListDto res);
}

View File

@@ -0,0 +1,61 @@
package io.shinhanlife.axhub.biz.sm.mmg.domain.model;
import io.shinhanlife.glow.db.dto.AuditInfo;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* ZtMenu은 ZT_MENU 테이블을 매핑하는 Entity 클래스입니다.
* 이 클래스는 테이블의 컬럼을 Java 필드로 매핑합니다.
*
* @Data: Lombok을 통해 getter, setter 등을 자동 생성.
*/
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ZtMenu extends AuditInfo {
// 메뉴 ID (PK)
private Integer menuId;
// 부모 메뉴 ID (FK)
private Integer parentMenuId;
// 컴포넌트 이름
private String name;
// 라우트 경로
private String path;
// 메뉴 이름
private String title;
// 메뉴 아이콘
private String icon;
// 메뉴 숨김 여부 (Y/N)
private String isHide;
// 탭 숨김 여부 (Y/N)
private String isHideTab;
// 링크
private String link;
// iframe 여부 (Y/N)
private String isIframe;
// 캐시 여부 (Y/N)
private String keepAlive;
// 메뉴 표시 순서
private Integer orderSeq;
// 활성 여부 (Y/N)
private String isActive;
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.axhub.biz.sm.mmg.domain.repository;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuOutDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuSaveInDto;
import io.shinhanlife.glow.GlowMybatisMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@GlowMybatisMapper
public interface MenuRepository {
List<MenuOutDto> selectMenu(MenuInDto dto);
MenuOutDto selectMenuById(@Param("menuId") Integer menuId);
void insertMenu(MenuSaveInDto dto);
void updateMenu(MenuSaveInDto dto);
void deleteMenu(@Param("menuId") Integer menuId);
}

View File

@@ -0,0 +1,20 @@
package io.shinhanlife.axhub.biz.sm.mmg.domain.service.impl;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuOutDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuSaveInDto;
import java.util.List;
public interface MenuService {
List<MenuListDto> selectMenu(MenuInDto dto);
MenuOutDto findById(Integer menuId);
Integer save(MenuSaveInDto dto);
void delete(Integer menuId);
}

View File

@@ -0,0 +1,117 @@
package io.shinhanlife.axhub.biz.sm.mmg.domain.service.impl;
import io.shinhanlife.axhub.biz.sm.mmg.domain.repository.MenuRepository;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuOutDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuSaveInDto;
import io.shinhanlife.axhub.common.util.SessionUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class MenuServiceImpl implements MenuService {
private final MenuRepository menuRepository;
@Override
public List<MenuListDto> selectMenu(MenuInDto dto) {
List<MenuOutDto> allMenus = menuRepository.selectMenu(dto);
// 비루트 메뉴(부모 ID가 null이 아닌)만 그룹핑하여 맵 생성
Map<Integer, List<MenuOutDto>> menuMap = allMenus.stream()
.filter(menu -> menu.getParentMenuId() != null)
.collect(Collectors.groupingBy(MenuOutDto::getParentMenuId));
// 루트 메뉴 (parentMenuId == null)
List<MenuOutDto> roots = allMenus.stream()
.filter(menu -> menu.getParentMenuId() == null)
.collect(Collectors.toList());
// 트리 빌드
List<MenuListDto> menuList = buildTree(roots, menuMap);
return menuList;
}
private List<MenuListDto> buildTree(List<MenuOutDto> menus, Map<Integer, List<MenuOutDto>> menuMap) {
List<MenuListDto> dtos = new ArrayList<>();
for (MenuOutDto menu : menus) {
MenuListDto dto = convertToDto(menu);
List<MenuOutDto> children = menuMap.getOrDefault(menu.getMenuId(), new ArrayList<>());
if (!children.isEmpty()) {
dto.setChildren(buildTree(children, menuMap));
}
dtos.add(dto);
}
return dtos;
}
@Override
public MenuOutDto findById(Integer menuId) {
return menuRepository.selectMenuById(menuId);
}
@Override
@Transactional
public Integer save(MenuSaveInDto dto) {
Date now = new Date();
String prafNo = SessionUtil.getPrafNo();
String ognzNo = SessionUtil.getOgnzNo();
if (dto.getIsActive() == null) dto.setIsActive("Y");
if (dto.getIsHide() == null) dto.setIsHide("N");
if (dto.getIsHideTab() == null) dto.setIsHideTab("N");
if (dto.getIsIframe() == null) dto.setIsIframe("N");
if (dto.getKeepAlive() == null) dto.setKeepAlive("N");
if (dto.getOrderSeq() == null) dto.setOrderSeq(0);
dto.setSystChgDt(now);
dto.setSystChgPrafNo(prafNo);
dto.setSystChgOgnzNo(ognzNo);
dto.setSystChgSystCd("AXH");
dto.setSystChgPrgrId("SMNMG0100M");
if (dto.getMenuId() == null) {
dto.setSystRgiDt(now);
dto.setSystRgiPrafNo(prafNo);
dto.setSystRgiOgnzNo(ognzNo);
dto.setSystRgiSystCd("AXH");
dto.setSystRgiPrgrId("SMNMG0100M");
menuRepository.insertMenu(dto);
} else {
menuRepository.updateMenu(dto);
}
return dto.getMenuId();
}
@Override
@Transactional
public void delete(Integer menuId) {
menuRepository.deleteMenu(menuId);
}
private MenuListDto convertToDto(MenuOutDto menu) {
MenuListDto.Meta meta = new MenuListDto.Meta();
meta.setTitle(menu.getTitle());
meta.setIcon(menu.getIcon());
meta.setHide("Y".equals(menu.getIsHide()));
meta.setHideTab("Y".equals(menu.getIsHideTab()));
meta.setLink(menu.getLink());
meta.setIframe("Y".equals(menu.getIsIframe()));
meta.setKeepAlive("Y".equals(menu.getKeepAlive()));
meta.setOrderSeq(menu.getOrderSeq());
meta.setActive("Y".equals(menu.getIsActive()));
return MenuListDto.builder().id(menu.getMenuId()).name(menu.getName()).path(menu.getPath()).meta(meta).build();
}
}

View File

@@ -0,0 +1,22 @@
package io.shinhanlife.axhub.biz.sm.mmg.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
@AllArgsConstructor
public class MenuInDto {
public MenuInDto() {
setIsActive("Y");
}
private String isActive; // 기본 활성 메뉴만
private String path; // 라우트 경로
private String title; // 기본 활성 메뉴만
}

View File

@@ -0,0 +1,90 @@
package io.shinhanlife.axhub.biz.sm.mmg.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* MenuDto는 Vue의 MenuListType에 맞춘 DTO입니다.
* 트리 구조를 지원하며, meta 객체 포함.
* @Data: Lombok을 통해 getter, setter 등을 자동 생성.
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MenuListDto {
private Integer id;
private Integer parentMenuId;
private String name;
private String path;
private Meta meta;
private List<MenuListDto> children;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Meta {
private String title;
private String icon;
private boolean showBadge;
private String showTextBadge;
private boolean hide;
private boolean hideTab;
private String link;
private boolean iframe;
private boolean keepAlive;
// 메뉴 표시 순서
private Integer orderSeq;
// 활성 여부
private boolean isActive;
@JsonProperty("isHide")
public boolean isHide() {
return hide;
}
@JsonProperty("isHide")
public void setHide(boolean hide) {
this.hide = hide;
}
@JsonProperty("isHideTab")
public boolean isHideTab() {
return hideTab;
}
@JsonProperty("isHideTab")
public void setHideTab(boolean hideTab) {
this.hideTab = hideTab;
}
@JsonProperty("isIframe")
public boolean isIframe() {
return iframe;
}
@JsonProperty("isIframe")
public void setIframe(boolean iframe) {
this.iframe = iframe;
}
@JsonProperty("isActive")
public boolean isActive() {
return isActive;
}
@JsonProperty("isActive")
public void setActive(boolean isActive) {
this.isActive = isActive;
}
}
}

View File

@@ -0,0 +1,53 @@
package io.shinhanlife.axhub.biz.sm.mmg.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
@AllArgsConstructor
public class MenuOutDto {
// 메뉴 ID (PK)
private Integer menuId;
// 부모 메뉴 ID (FK)
private Integer parentMenuId;
// 컴포넌트 이름
private String name;
// 라우트 경로
private String path;
// 메뉴 이름
private String title;
// 메뉴 아이콘
private String icon;
// 메뉴 숨김 여부 (Y/N)
private String isHide;
// 탭 숨김 여부 (Y/N)
private String isHideTab;
// 링크
private String link;
// iframe 여부 (Y/N)
private String isIframe;
// 캐시 여부 (Y/N)
private String keepAlive;
// 메뉴 표시 순서
private Integer orderSeq;
// 활성 여부 (Y/N)
private String isActive;
}

View File

@@ -0,0 +1,39 @@
package io.shinhanlife.axhub.biz.sm.mmg.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
@NoArgsConstructor
public class MenuSaveInDto {
private Integer menuId;
private Integer parentMenuId;
private String name;
private String path;
private String title;
private String icon;
private String isHide;
private String isHideTab;
private String link;
private String isIframe;
private String keepAlive;
private Integer orderSeq;
private String isActive;
private Date systRgiDt;
private String systRgiPrafNo;
private String systRgiOgnzNo;
private String systRgiSystCd;
private String systRgiPrgrId;
private Date systChgDt;
private String systChgPrafNo;
private String systChgOgnzNo;
private String systChgSystCd;
private String systChgPrgrId;
}

View File

@@ -0,0 +1,30 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RResponse;
import io.shinhanlife.axhub.biz.sm.mmg.usecase.SmMmg0000MUseCase;
import io.shinhanlife.glow.BaseResponse;
import io.shinhanlife.glow.GlowControllerId;
import java.util.List;
import io.shinhanlife.glow.ResponseUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class SmMmg0000MController {
private final SmMmg0000MUseCase smMmg0000MUseCase;
@PostMapping("SMMMG0000M01R")
@GlowControllerId("SMMMG0000M01R")
public ResponseEntity<BaseResponse<List<SmMmg0000M01RResponse>>> SMMMG0000M01R(@RequestBody SmMmg0000M01RRequest req) {
return ResponseUtil.ok(smMmg0000MUseCase.selectMenu(req));
}
}

View File

@@ -0,0 +1,47 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01DRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RResponse;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SResponse;
import io.shinhanlife.axhub.biz.sm.mmg.usecase.SmNmg0100MUseCase;
import io.shinhanlife.glow.BaseResponse;
import io.shinhanlife.glow.GlowControllerId;
import io.shinhanlife.glow.ResponseUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequiredArgsConstructor
public class SmNmg0100MController {
private final SmNmg0100MUseCase useCase;
@PostMapping("SMNMG0100M01R")
@GlowControllerId("SMNMG0100M01R")
public ResponseEntity<BaseResponse<List<SmNmg0100M01RResponse>>> SMNMG0100M01R(
@RequestBody SmNmg0100M01RRequest req) {
return ResponseUtil.ok(useCase.selectMenu(req));
}
@PostMapping("SMNMG0100M01S")
@GlowControllerId("SMNMG0100M01S")
public ResponseEntity<BaseResponse<SmNmg0100M01SResponse>> SMNMG0100M01S(
@RequestBody SmNmg0100M01SRequest req) {
return ResponseUtil.ok(useCase.saveMenu(req));
}
@PostMapping("SMNMG0100M01D")
@GlowControllerId("SMNMG0100M01D")
public ResponseEntity<BaseResponse<Void>> SMNMG0100M01D(
@RequestBody SmNmg0100M01DRequest req) {
useCase.deleteMenu(req);
return ResponseUtil.ok(null);
}
}

View File

@@ -0,0 +1,19 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
@AllArgsConstructor
public class SmMmg0000M01RRequest {
public SmMmg0000M01RRequest() {
this.isActive = "Y";
}
private String isActive; // 기본 활성 메뉴만
private String path; // 라우트 경로
private String title; // 기본 활성 메뉴만
}

View File

@@ -0,0 +1,87 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class SmMmg0000M01RResponse {
private Integer id;
private Integer parentMenuId;
private String name;
private String path;
private MenuListDto.Meta meta;
private List<MenuListDto> children;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Meta {
private String title;
private String icon;
private boolean showBadge;
private String showTextBadge;
private boolean hide;
private boolean hideTab;
private String link;
private boolean iframe;
private boolean keepAlive;
// 메뉴 표시 순서
private Integer orderSeq;
// 활성 여부
private boolean isActive;
@JsonProperty("isHide")
public boolean isHide() {
return hide;
}
@JsonProperty("isHide")
public void setHide(boolean hide) {
this.hide = hide;
}
@JsonProperty("isHideTab")
public boolean isHideTab() {
return hideTab;
}
@JsonProperty("isHideTab")
public void setHideTab(boolean hideTab) {
this.hideTab = hideTab;
}
@JsonProperty("isIframe")
public boolean isIframe() {
return iframe;
}
@JsonProperty("isIframe")
public void setIframe(boolean iframe) {
this.iframe = iframe;
}
@JsonProperty("isActive")
public boolean isActive() {
return isActive;
}
@JsonProperty("isActive")
public void setActive(boolean isActive) {
this.isActive = isActive;
}
}
}

View File

@@ -0,0 +1,11 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SmNmg0100M01DRequest {
private Integer menuId;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SmNmg0100M01RRequest {
private String isActive;
private String path;
private String title;
}

View File

@@ -0,0 +1,70 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SmNmg0100M01RResponse {
private Integer id;
private Integer parentMenuId;
private String name;
private String path;
private Meta meta;
private List<SmNmg0100M01RResponse> children;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Meta {
private String title;
private String icon;
private String link;
private Integer orderSeq;
private boolean hide;
private boolean hideTab;
private boolean iframe;
private boolean keepAlive;
private boolean active;
@JsonProperty("isHide")
public boolean isHide() { return hide; }
@JsonProperty("isHide")
public void setHide(boolean hide) { this.hide = hide; }
@JsonProperty("isHideTab")
public boolean isHideTab() { return hideTab; }
@JsonProperty("isHideTab")
public void setHideTab(boolean hideTab) { this.hideTab = hideTab; }
@JsonProperty("isIframe")
public boolean isIframe() { return iframe; }
@JsonProperty("isIframe")
public void setIframe(boolean iframe) { this.iframe = iframe; }
@JsonProperty("keepAlive")
public boolean isKeepAlive() { return keepAlive; }
@JsonProperty("isActive")
public boolean isActive() { return active; }
@JsonProperty("isActive")
public void setActive(boolean active) { this.active = active; }
}
}

View File

@@ -0,0 +1,23 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SmNmg0100M01SRequest {
private Integer menuId;
private Integer parentMenuId;
private String name;
private String path;
private String title;
private String icon;
private String isHide;
private String isHideTab;
private String link;
private String isIframe;
private String keepAlive;
private Integer orderSeq;
private String isActive;
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.axhub.biz.sm.mmg.presentation.io;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SmNmg0100M01SResponse {
private Integer menuId;
}

View File

@@ -0,0 +1,12 @@
package io.shinhanlife.axhub.biz.sm.mmg.usecase;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RResponse;
import java.util.List;
public interface SmMmg0000MUseCase {
public List<SmMmg0000M01RResponse> selectMenu(SmMmg0000M01RRequest req);
}

View File

@@ -0,0 +1,18 @@
package io.shinhanlife.axhub.biz.sm.mmg.usecase;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01DRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RResponse;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SResponse;
import java.util.List;
public interface SmNmg0100MUseCase {
List<SmNmg0100M01RResponse> selectMenu(SmNmg0100M01RRequest req);
SmNmg0100M01SResponse saveMenu(SmNmg0100M01SRequest req);
void deleteMenu(SmNmg0100M01DRequest req);
}

View File

@@ -0,0 +1,38 @@
package io.shinhanlife.axhub.biz.sm.mmg.usecase.impl;
import java.util.ArrayList;
import java.util.List;
import io.shinhanlife.axhub.biz.sm.mmg.converter.MenuConverter;
import io.shinhanlife.axhub.biz.sm.mmg.domain.service.impl.MenuService;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmMmg0000M01RResponse;
import io.shinhanlife.axhub.biz.sm.mmg.usecase.SmMmg0000MUseCase;
import io.shinhanlife.glow.GlowServiceGroupId;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@GlowServiceGroupId(value = "SmMmgc", description="SmMmg")
public class SmMmg0000MUseCaseImpl implements SmMmg0000MUseCase {
private final MenuService menuService;
private final MenuConverter converter;
@Override
public List<SmMmg0000M01RResponse> selectMenu(SmMmg0000M01RRequest req) {
List<SmMmg0000M01RResponse> result = new ArrayList<>();
MenuInDto dto = converter.smMmg0000M01RRequestToMenuInDto(req);
List<MenuListDto> menuListDtos = menuService.selectMenu(dto);
for (MenuListDto menuListDto : menuListDtos) {
result.add(converter.menuListDtoeToSmMmg0000M01RResponse(menuListDto));
}
return result;
}
}

View File

@@ -0,0 +1,93 @@
package io.shinhanlife.axhub.biz.sm.mmg.usecase.impl;
import io.shinhanlife.axhub.biz.sm.mmg.domain.service.impl.MenuService;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuInDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuListDto;
import io.shinhanlife.axhub.biz.sm.mmg.dto.MenuSaveInDto;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01DRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01RResponse;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SRequest;
import io.shinhanlife.axhub.biz.sm.mmg.presentation.io.SmNmg0100M01SResponse;
import io.shinhanlife.axhub.biz.sm.mmg.usecase.SmNmg0100MUseCase;
import io.shinhanlife.glow.GlowServiceGroupId;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@GlowServiceGroupId(value = "SmNmgc", description = "SmNmg")
public class SmNmg0100MUseCaseImpl implements SmNmg0100MUseCase {
private final MenuService menuService;
@Override
public List<SmNmg0100M01RResponse> selectMenu(SmNmg0100M01RRequest req) {
MenuInDto inDto = new MenuInDto();
inDto.setIsActive(req.getIsActive());
inDto.setPath(req.getPath());
inDto.setTitle(req.getTitle());
List<MenuListDto> tree = menuService.selectMenu(inDto);
return tree.stream().map(this::toResponse).collect(Collectors.toList());
}
@Override
public SmNmg0100M01SResponse saveMenu(SmNmg0100M01SRequest req) {
MenuSaveInDto dto = new MenuSaveInDto();
dto.setMenuId(req.getMenuId());
dto.setParentMenuId(req.getParentMenuId());
dto.setName(req.getName());
dto.setPath(req.getPath());
dto.setTitle(req.getTitle());
dto.setIcon(req.getIcon());
dto.setIsHide(req.getIsHide());
dto.setIsHideTab(req.getIsHideTab());
dto.setLink(req.getLink());
dto.setIsIframe(req.getIsIframe());
dto.setKeepAlive(req.getKeepAlive());
dto.setOrderSeq(req.getOrderSeq());
dto.setIsActive(req.getIsActive());
Integer savedId = menuService.save(dto);
return SmNmg0100M01SResponse.builder().menuId(savedId).build();
}
@Override
public void deleteMenu(SmNmg0100M01DRequest req) {
menuService.delete(req.getMenuId());
}
private SmNmg0100M01RResponse toResponse(MenuListDto dto) {
MenuListDto.Meta m = dto.getMeta();
SmNmg0100M01RResponse.Meta meta = SmNmg0100M01RResponse.Meta.builder()
.title(m != null ? m.getTitle() : null)
.icon(m != null ? m.getIcon() : null)
.hide(m != null && m.isHide())
.hideTab(m != null && m.isHideTab())
.link(m != null ? m.getLink() : null)
.iframe(m != null && m.isIframe())
.keepAlive(m != null && m.isKeepAlive())
.orderSeq(m != null ? m.getOrderSeq() : 0)
.active(m != null && m.isActive())
.build();
List<SmNmg0100M01RResponse> children = (dto.getChildren() == null || dto.getChildren().isEmpty())
? Collections.emptyList()
: dto.getChildren().stream().map(this::toResponse).collect(Collectors.toList());
return SmNmg0100M01RResponse.builder()
.id(dto.getId())
.parentMenuId(dto.getParentMenuId())
.name(dto.getName())
.path(dto.getPath())
.meta(meta)
.children(children)
.build();
}
}

View File

@@ -0,0 +1,23 @@
package io.shinhanlife.axhub.biz.so.atm.converter;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSaveInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSearchInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListInDto;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSaveRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchResponse;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.RoleListRequest;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public abstract class AccessMgmtConverter {
public abstract RoleListInDto toInDto(RoleListRequest request);
public abstract AthrSearchInDto toInDto(AthrSearchRequest request);
public abstract AthrSaveInDto toInDto(AthrSaveRequest request);
public abstract AthrSearchResponse toResponse(AthrOutDto outDto);
}

View File

@@ -0,0 +1,34 @@
package io.shinhanlife.axhub.biz.so.atm.domain.repository;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrItemOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSearchInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleKnwlAthrInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleToolAthrInDto;
import io.shinhanlife.glow.GlowMybatisMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@GlowMybatisMapper
public interface AccessMgmtMapper {
List<RoleListOutDto> selectRoles(RoleListInDto inDto);
List<AthrItemOutDto> selectAllTools();
List<AthrItemOutDto> selectAllKnwls();
List<String> selectGrantedToolIds(AthrSearchInDto inDto);
List<String> selectGrantedKnwlIds(AthrSearchInDto inDto);
void deleteToolAthr(@Param("systId") String systId, @Param("roleNo") String roleNo);
void insertToolAthr(RoleToolAthrInDto inDto);
void deleteKnwlAthr(@Param("systId") String systId, @Param("roleNo") String roleNo);
void insertKnwlAthr(RoleKnwlAthrInDto inDto);
}

View File

@@ -0,0 +1,18 @@
package io.shinhanlife.axhub.biz.so.atm.domain.service;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSaveInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSearchInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import java.util.List;
public interface AccessMgmtService {
List<RoleListOutDto> getRoles(RoleListInDto inDto);
AthrOutDto getAthr(AthrSearchInDto inDto);
void saveAthr(AthrSaveInDto inDto);
}

View File

@@ -0,0 +1,128 @@
package io.shinhanlife.axhub.biz.so.atm.domain.service.impl;
import io.shinhanlife.axhub.biz.so.atm.domain.repository.AccessMgmtMapper;
import io.shinhanlife.axhub.biz.so.atm.domain.service.AccessMgmtService;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrItemOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSaveInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrSearchInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleKnwlAthrInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListInDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleToolAthrInDto;
import io.shinhanlife.axhub.common.util.SessionUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class AccessMgmtServiceImpl implements AccessMgmtService {
private final AccessMgmtMapper accessMgmtMapper;
private static final String SYSTEM_CD = "AXH";
private static final String SYSTEM_PRG = "SOATM0100";
@Override
public List<RoleListOutDto> getRoles(RoleListInDto inDto) {
return accessMgmtMapper.selectRoles(inDto);
}
@Override
public AthrOutDto getAthr(AthrSearchInDto inDto) {
Set<String> grantedToolIds = accessMgmtMapper.selectGrantedToolIds(inDto)
.stream().collect(Collectors.toSet());
Set<String> grantedKnwlIds = accessMgmtMapper.selectGrantedKnwlIds(inDto)
.stream().collect(Collectors.toSet());
List<AthrItemOutDto> tools = accessMgmtMapper.selectAllTools()
.stream()
.peek(item -> item.setGranted(grantedToolIds.contains(item.getResourceId())))
.collect(Collectors.toList());
List<AthrItemOutDto> knwls = accessMgmtMapper.selectAllKnwls()
.stream()
.peek(item -> item.setGranted(grantedKnwlIds.contains(item.getResourceId())))
.collect(Collectors.toList());
return new AthrOutDto(tools, knwls);
}
@Override
@Transactional
public void saveAthr(AthrSaveInDto inDto) {
Date now = new Date();
String systId = inDto.getSystId();
String roleNo = inDto.getRoleNo();
accessMgmtMapper.deleteToolAthr(systId, roleNo);
if (inDto.getGrantedToolIds() != null) {
for (String toolId : inDto.getGrantedToolIds()) {
accessMgmtMapper.insertToolAthr(buildToolAthrInDto(systId, roleNo, toolId, now));
}
}
accessMgmtMapper.deleteKnwlAthr(systId, roleNo);
if (inDto.getGrantedKnwlIds() != null) {
for (String knwlId : inDto.getGrantedKnwlIds()) {
accessMgmtMapper.insertKnwlAthr(buildKnwlAthrInDto(systId, roleNo, knwlId, now));
}
}
}
private RoleToolAthrInDto buildToolAthrInDto(String systId, String roleNo, String toolId, Date now) {
RoleToolAthrInDto dto = new RoleToolAthrInDto();
dto.setRoleToolAthrId("RTA-" + shortUuid());
dto.setSystId(systId);
dto.setRoleNo(roleNo);
dto.setToolId(toolId);
dto.setPuseYn("Y");
fillAudit(dto, now);
return dto;
}
private RoleKnwlAthrInDto buildKnwlAthrInDto(String systId, String roleNo, String knwlId, Date now) {
RoleKnwlAthrInDto dto = new RoleKnwlAthrInDto();
dto.setRoleKnwlAthrId("RKA-" + shortUuid());
dto.setSystId(systId);
dto.setRoleNo(roleNo);
dto.setKnwlId(knwlId);
dto.setPuseYn("Y");
fillAudit(dto, now);
return dto;
}
private void fillAudit(RoleToolAthrInDto dto, Date now) {
String prafNo = SessionUtil.getPrafNo();
String ognzNo = SessionUtil.getOgnzNo();
dto.setSystRgiDt(now); dto.setSystRgiPrafNo(prafNo);
dto.setSystRgiOgnzNo(ognzNo); dto.setSystRgiSystCd(SYSTEM_CD);
dto.setSystRgiPrgrId(SYSTEM_PRG);
dto.setSystChgDt(now); dto.setSystChgPrafNo(prafNo);
dto.setSystChgOgnzNo(ognzNo); dto.setSystChgSystCd(SYSTEM_CD);
dto.setSystChgPrgrId(SYSTEM_PRG);
}
private void fillAudit(RoleKnwlAthrInDto dto, Date now) {
String prafNo = SessionUtil.getPrafNo();
String ognzNo = SessionUtil.getOgnzNo();
dto.setSystRgiDt(now); dto.setSystRgiPrafNo(prafNo);
dto.setSystRgiOgnzNo(ognzNo); dto.setSystRgiSystCd(SYSTEM_CD);
dto.setSystRgiPrgrId(SYSTEM_PRG);
dto.setSystChgDt(now); dto.setSystChgPrafNo(prafNo);
dto.setSystChgOgnzNo(ognzNo); dto.setSystChgSystCd(SYSTEM_CD);
dto.setSystChgPrgrId(SYSTEM_PRG);
}
private String shortUuid() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 12).toUpperCase();
}
}

View File

@@ -0,0 +1,14 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AthrItemOutDto {
private String resourceId;
private String resourceNm;
private String resourceDs;
private String typeCode;
private boolean granted;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
@Getter
@AllArgsConstructor
public class AthrOutDto {
private List<AthrItemOutDto> tools;
private List<AthrItemOutDto> knwls;
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AthrSaveInDto {
private String systId;
private String roleNo;
private List<String> grantedToolIds;
private List<String> grantedKnwlIds;
}

View File

@@ -0,0 +1,11 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AthrSearchInDto {
private String systId;
private String roleNo;
}

View File

@@ -0,0 +1,27 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
public class RoleKnwlAthrInDto {
private String roleKnwlAthrId;
private String systId;
private String roleNo;
private String knwlId;
private String puseYn;
private Date systRgiDt;
private String systRgiPrafNo;
private String systRgiOgnzNo;
private String systRgiSystCd;
private String systRgiPrgrId;
private Date systChgDt;
private String systChgPrafNo;
private String systChgOgnzNo;
private String systChgSystCd;
private String systChgPrgrId;
}

View File

@@ -0,0 +1,12 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class RoleListInDto {
private String systId;
private String puseYn;
private String keyword;
}

View File

@@ -0,0 +1,14 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class RoleListOutDto {
private String systId;
private String roleNo;
private String roleNm;
private String roleDs;
private String puseYn;
}

View File

@@ -0,0 +1,27 @@
package io.shinhanlife.axhub.biz.so.atm.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
public class RoleToolAthrInDto {
private String roleToolAthrId;
private String systId;
private String roleNo;
private String toolId;
private String puseYn;
private Date systRgiDt;
private String systRgiPrafNo;
private String systRgiOgnzNo;
private String systRgiSystCd;
private String systRgiPrgrId;
private Date systChgDt;
private String systChgPrafNo;
private String systChgOgnzNo;
private String systChgSystCd;
private String systChgPrgrId;
}

View File

@@ -0,0 +1,45 @@
package io.shinhanlife.axhub.biz.so.atm.presentation;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSaveRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchResponse;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.RoleListRequest;
import io.shinhanlife.axhub.biz.so.atm.usecase.AccessMgmtUseCase;
import io.shinhanlife.glow.BaseResponse;
import io.shinhanlife.glow.ResponseUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/so/atm")
@RequiredArgsConstructor
public class SOATM0100Controller {
private final AccessMgmtUseCase accessMgmtUseCase;
@PostMapping("/SOATM0100R")
public ResponseEntity<BaseResponse<List<RoleListOutDto>>> getRoles(
@RequestBody RoleListRequest request) {
return ResponseUtil.ok(accessMgmtUseCase.getRoles(request));
}
@PostMapping("/SOATM0101R")
public ResponseEntity<BaseResponse<AthrSearchResponse>> getAthr(
@RequestBody AthrSearchRequest request) {
return ResponseUtil.ok(accessMgmtUseCase.getAthr(request));
}
@PostMapping("/SOATM0100U")
public ResponseEntity<BaseResponse<Void>> saveAthr(
@RequestBody AthrSaveRequest request) {
accessMgmtUseCase.saveAthr(request);
return ResponseUtil.ok();
}
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.axhub.biz.so.atm.presentation.io;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AthrSaveRequest {
private String systId;
private String roleNo;
private List<String> grantedToolIds;
private List<String> grantedKnwlIds;
}

View File

@@ -0,0 +1,11 @@
package io.shinhanlife.axhub.biz.so.atm.presentation.io;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AthrSearchRequest {
private String systId;
private String roleNo;
}

View File

@@ -0,0 +1,14 @@
package io.shinhanlife.axhub.biz.so.atm.presentation.io;
import io.shinhanlife.axhub.biz.so.atm.dto.AthrItemOutDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
@Getter
@AllArgsConstructor
public class AthrSearchResponse {
private List<AthrItemOutDto> tools;
private List<AthrItemOutDto> knwls;
}

View File

@@ -0,0 +1,12 @@
package io.shinhanlife.axhub.biz.so.atm.presentation.io;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class RoleListRequest {
private String systId;
private String puseYn;
private String keyword;
}

View File

@@ -0,0 +1,18 @@
package io.shinhanlife.axhub.biz.so.atm.usecase;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSaveRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchResponse;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.RoleListRequest;
import java.util.List;
public interface AccessMgmtUseCase {
List<RoleListOutDto> getRoles(RoleListRequest request);
AthrSearchResponse getAthr(AthrSearchRequest request);
void saveAthr(AthrSaveRequest request);
}

View File

@@ -0,0 +1,37 @@
package io.shinhanlife.axhub.biz.so.atm.usecase.impl;
import io.shinhanlife.axhub.biz.so.atm.converter.AccessMgmtConverter;
import io.shinhanlife.axhub.biz.so.atm.domain.service.AccessMgmtService;
import io.shinhanlife.axhub.biz.so.atm.dto.RoleListOutDto;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSaveRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchRequest;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.AthrSearchResponse;
import io.shinhanlife.axhub.biz.so.atm.presentation.io.RoleListRequest;
import io.shinhanlife.axhub.biz.so.atm.usecase.AccessMgmtUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class AccessMgmtUseCaseImpl implements AccessMgmtUseCase {
private final AccessMgmtService accessMgmtService;
private final AccessMgmtConverter converter;
@Override
public List<RoleListOutDto> getRoles(RoleListRequest request) {
return accessMgmtService.getRoles(converter.toInDto(request));
}
@Override
public AthrSearchResponse getAthr(AthrSearchRequest request) {
return converter.toResponse(accessMgmtService.getAthr(converter.toInDto(request)));
}
@Override
public void saveAthr(AthrSaveRequest request) {
accessMgmtService.saveAthr(converter.toInDto(request));
}
}

View File

@@ -0,0 +1,19 @@
package io.shinhanlife.axhub.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 모든 엔드포인트에 대해 CORS 허용
.allowedOrigins("http://localhost:3006") // Vue 앱의 오리진 허용 (필요 시 여러 오리진 추가: .allowedOrigins("http://localhost:3006", "https://example.com"))
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 허용할 HTTP 메서드
.allowedHeaders("*") // 모든 헤더 허용
.allowCredentials(true) // 쿠키/인증 정보 허용 (필요 시)
.maxAge(3600); // preflight 요청 캐시 시간 (초 단위)
}
}

View File

@@ -0,0 +1,40 @@
package io.shinhanlife.axhub.common.config;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
public class P6SpySqlFormatter implements MessageFormattingStrategy {
@Override
public String formatMessage(int connectionId, String now, long elapsed,
String category, String prepared, String sql, String url) {
if (sql == null || sql.isBlank()) return "";
if (Category.STATEMENT.getName().equals(category)) {
String prettySQL = sql
.replaceAll("(?i)\\bSELECT\\b", "\nSELECT")
.replaceAll("(?i)\\bFROM\\b", "\n FROM")
.replaceAll("(?i)\\bWHERE\\b", "\n WHERE")
.replaceAll("(?i)\\bAND\\b", "\n AND")
.replaceAll("(?i)\\bOR\\b", "\n OR")
.replaceAll("(?i)\\bINNER JOIN\\b", "\n INNER JOIN")
.replaceAll("(?i)\\bLEFT JOIN\\b", "\n LEFT JOIN")
.replaceAll("(?i)\\bORDER BY\\b", "\n ORDER BY")
.replaceAll("(?i)\\bGROUP BY\\b", "\n GROUP BY")
.replaceAll("(?i)\\bINSERT INTO\\b", "\nINSERT INTO")
.replaceAll("(?i)\\bVALUES\\b", "\n VALUES")
.replaceAll("(?i)\\bUPDATE\\b", "\nUPDATE")
.replaceAll("(?i)\\bSET\\b", "\n SET")
.replaceAll("(?i)\\bDELETE FROM\\b", "\nDELETE FROM");
return String.format("""
\n┌─────────────────────────────────────────
│ SQL [%dms]
│%s
└─────────────────────────────────────────
""", elapsed, prettySQL.indent(2).stripTrailing());
}
return "";
}
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.axhub.common.session.converter;
import io.shinhanlife.axhub.common.session.dto.SessionDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacOutDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring")
public abstract class ZtUsacConverter {
@Mapping(target = "loginDtm", ignore = true)
@Mapping(target = "isManager", ignore = true)
public abstract SessionDto toSessionDto(ZtUsacOutDto dto);
}

View File

@@ -0,0 +1,37 @@
package io.shinhanlife.axhub.common.session.domain.model;
import io.shinhanlife.glow.db.dto.AuditInfo;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ZtUsacModel extends AuditInfo {
/* 인사번호 */
private String prafNo;
/* 인사명 */
private String prafNm;
/* 조직번호 */
private String ognzNo;
/* 이메일주소 */
private String addre;
/* 인사직무코드 */
private String prafOfduCd;
/* 인사직무명 */
private String prafOfduNm;
/* 인사직급코드 */
private String prafOfleCd;
/* 인사직급명 */
private String prafOfleNm;
/* 인사직책코드 */
private String prafDutyCd;
/* 인사직책명 */
private String prafDutyNm;
}

View File

@@ -0,0 +1,19 @@
package io.shinhanlife.axhub.common.session.domain.repository;
import io.shinhanlife.glow.GlowMybatisMapper;
import io.shinhanlife.axhub.common.session.dto.ZtUsacInDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacOutDto;
@GlowMybatisMapper
public interface ZtUsacRepository {
/**
* 사용자 조회 (단건)
*
* @param dto 사번
* @return 인사정보
*/
ZtUsacOutDto selectZtUsac(ZtUsacInDto dto);
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.axhub.common.session.domain.service;
import io.shinhanlife.axhub.common.session.dto.ZtUsacInDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacOutDto;
public interface ZtUsacService {
/**
* 사용자 조회 (단건)
*
* @param dto 사번
* @return 인사정보
*/
ZtUsacOutDto selectZtUsac(ZtUsacInDto dto);
}

View File

@@ -0,0 +1,28 @@
package io.shinhanlife.axhub.common.session.domain.service.impl;
import io.shinhanlife.axhub.common.session.domain.repository.ZtUsacRepository;
import io.shinhanlife.axhub.common.session.domain.service.ZtUsacService;
import io.shinhanlife.axhub.common.session.dto.ZtUsacInDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacOutDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ZtUsacServiceImpl implements ZtUsacService {
private final ZtUsacRepository ztUsacRepository;
/**
* 사용자 조회 (단건)
*
* @param dto 사번
* @return 인사정보
*/
@Override
public ZtUsacOutDto selectZtUsac(ZtUsacInDto dto) {
ZtUsacOutDto result = ztUsacRepository.selectZtUsac(dto);
result.initLists();
return result;
}
}

View File

@@ -0,0 +1,62 @@
package io.shinhanlife.axhub.common.session.dto;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
@AllArgsConstructor
public class SessionDto {
/* 인사번호 */
private String prafNo;
/* 인사명 */
private String prafNm;
/* 조직번호 */
private String ognzNo;
/* 조직번호 */
private String ognzNm;
/* 이메일주소 */
private String addre;
/* 인사직무코드 */
private String prafOfduCd;
/* 인사직무명 */
private String prafOfduNm;
/* 인사직급코드 */
private String prafOfleCd;
/* 인사직급명 */
private String prafOfleNm;
/* 인사직책코드 */
private String prafDutyCd;
/* 인사직책명 */
private String prafDutyNm;
private List<String> roleNoList;
private List<String> roleNmList;
private List<String> tgtrPrafNoList;
private List<String> tgtrOgnzNoList;
// 유틸성
private String loginDtm; // 로그인일시
private String isManager; // 관리자여부
public void setLoginDtm() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
this.loginDtm = LocalDateTime.now().format(formatter);
}
public void setIsManager(String isManager) {
// TODO 역할 필터링 후 관리자 여부 체크
this.isManager = "Y";
}
}

View File

@@ -0,0 +1,24 @@
package io.shinhanlife.axhub.common.session.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
@AllArgsConstructor
public class ZtUsacInDto {
public ZtUsacInDto() {
setPuseYn("Y");
}
/* 인사번호 */
private String prafNo;
/* 사용여부 */
private String puseYn;
}

View File

@@ -0,0 +1,68 @@
package io.shinhanlife.axhub.common.session.dto;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ZtUsacOutDto {
/* 인사번호 */
private String prafNo;
/* 인사명 */
private String prafNm;
/* 조직번호 */
private String ognzNo;
/* 조직명 */
private String ognzNm;
/* 이메일주소 */
// @GlowSecureField(type = DataSecureType.DECRYPT_DB, direction = SafeDBType.COMM) TODO 방화벽 뚫리면 확인
private String addre;
/* 인사직무코드 */
private String prafOfduCd;
/* 인사직무명 */
private String prafOfduNm;
/* 인사직급코드 */
private String prafOfleCd;
/* 인사직급명 */
private String prafOfleNm;
/* 인사직책코드 */
private String prafDutyCd;
/* 인사직책명 */
private String prafDutyNm;
/* 사용여부 */
private String puseYn;
private String roleNoStrList;
private String roleNmStrList;
private String tgtrPrafNoStrList;
private String tgtrOgnzNoStrList;
private List<String> roleNoList;
private List<String> roleNmList;
private List<String> tgtrPrafNoList;
private List<String> tgtrOgnzNoList;
public void initLists() {
this.roleNoList = convertStrToList(roleNoStrList);
this.roleNmList = convertStrToList(roleNmStrList);
this.tgtrPrafNoList = convertStrToList(tgtrPrafNoStrList);
this.tgtrOgnzNoList = convertStrToList(tgtrOgnzNoStrList);
}
private List<String> convertStrToList(String str) {
if (str == null || str.isEmpty()) {
return new ArrayList<>();
}
return Arrays.asList(str.split(","));
}
}

View File

@@ -0,0 +1,77 @@
package io.shinhanlife.axhub.common.session.presentation;
import io.micrometer.common.util.StringUtils;
import io.shinhanlife.glow.BaseResponse;
import io.shinhanlife.glow.BizException;
import io.shinhanlife.glow.GlowControllerId;
import io.shinhanlife.glow.ResponseUtil;
import io.shinhanlife.axhub.common.session.converter.ZtUsacConverter;
import io.shinhanlife.axhub.common.session.domain.service.ZtUsacService;
import io.shinhanlife.axhub.common.session.dto.SessionDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacInDto;
import io.shinhanlife.axhub.common.session.dto.ZtUsacOutDto;
import io.shinhanlife.axhub.common.session.presentation.io.SsoResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/sso")
public class SsoRestController {
private static final String NLS_LOGIN_URL = "";
private final ZtUsacService ztUsacService;
private final ZtUsacConverter ztUsacConverter;
/**
* sso 연동 전 임시 로그인
*
* @param request
* @param response
* @param session
* @param <T>
* @return
*/
@GlowControllerId("tempLogin")
@PostMapping("/tempLogin")
public <T> ResponseEntity<BaseResponse<SsoResponse>> tempLogin(HttpServletRequest request, HttpServletResponse response,
HttpSession session, @RequestBody SessionDto requestDto) {
try {
if (StringUtils.isEmpty(requestDto.getPrafNo())) {
throw new NotFoundException("SSO >> not found sso id");
}
// DB 유저 가져오기
ZtUsacOutDto ztUsacOutDto = ztUsacService.selectZtUsac(ZtUsacInDto.builder().prafNo(requestDto.getPrafNo()).puseYn("Y")
.build());
if (Objects.isNull(ztUsacOutDto) || StringUtils.isEmpty(ztUsacOutDto.getPrafNo())) {
throw new BizException("SSO >> not found UserInfo >> retCode:");
}
SessionDto sessionDto = ztUsacConverter.toSessionDto(ztUsacOutDto);
sessionDto.setLoginDtm(); // 로그인 시점 세팅
session.setAttribute("userInfo", sessionDto);
return ResponseUtil.ok(SsoResponse.builder().retCode("0").userInfo(sessionDto).build());
} catch (Exception e) {
log.error("로그인 실패", e);
session.invalidate();
}
return ResponseUtil.ok(SsoResponse.builder().redirectUrl(NLS_LOGIN_URL).build());
}
}

View File

@@ -0,0 +1,21 @@
package io.shinhanlife.axhub.common.session.presentation.io;
import io.shinhanlife.axhub.common.session.dto.SessionDto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SsoResponse {
private String retCode;
private SessionDto userInfo;
private String redirectUrl;
}

View File

@@ -0,0 +1,31 @@
package io.shinhanlife.axhub.common.util;
import io.shinhanlife.axhub.common.session.dto.SessionDto;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class SessionUtil {
private static final String SESSION_KEY = "userInfo";
private SessionUtil() {}
public static SessionDto getSession() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) return null;
HttpSession session = attributes.getRequest().getSession(false);
if (session == null) return null;
return (SessionDto) session.getAttribute(SESSION_KEY);
}
public static String getPrafNo() {
SessionDto session = getSession();
return session != null ? session.getPrafNo() : null;
}
public static String getOgnzNo() {
SessionDto session = getSession();
return session != null ? session.getOgnzNo() : null;
}
}

View File

@@ -0,0 +1,23 @@
package io.shinhanlife.axhub.sample.converter;
import io.shinhanlife.axhub.sample.domain.model.AppliSystNtfyPatiModel;
import io.shinhanlife.axhub.sample.dto.AppliSystNtfyRgiInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListOutDTO;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiRequest;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermRequest;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermResponse;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public abstract class SampleConverter {
public abstract StrnTermListInDTO convertRequestToDto(StrnTermRequest req);
public abstract StrnTermResponse convertDtoToResponse(StrnTermListOutDTO outDto);
public abstract AppliSystNtfyPatiModel convertDtoToModel(AppliSystNtfyRgiInDTO inDto);
public abstract AppliSystNtfyRgiInDTO convertAppliRequestToDto(AppliSystNtfyPatiRequest request);
}

View File

@@ -0,0 +1,21 @@
package io.shinhanlife.axhub.sample.domain.model;
import io.shinhanlife.glow.db.dto.AuditInfo;
import lombok.*;
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class AppliSystNtfyPatiModel extends AuditInfo {
private String appliSystNtfyPatiId;
private String appliSystNtfyKdCd;
private String appliDutjCd;
private String appliDutjPrjcCd;
private String ntfyMsgCt;
private String ntfyOccDt;
private String ntfyCfmDt;
private String ntfyTrgtPrafNo;
private String shmsPmlYn;
private String ntfyCfmYn;
}

View File

@@ -0,0 +1,20 @@
package io.shinhanlife.axhub.sample.domain.repository;
import io.shinhanlife.axhub.sample.domain.model.AppliSystNtfyPatiModel;
import io.shinhanlife.axhub.sample.dto.StrnTermListInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListOutDTO;
import io.shinhanlife.glow.GlowIndexPaging;
import io.shinhanlife.glow.GlowMybatisMapper;
import io.shinhanlife.glow.PageInfo;
import java.util.List;
@GlowMybatisMapper
public interface GlowSampleRepository {
@GlowIndexPaging
List<StrnTermListOutDTO.StrnTerm> selectStrnTerm(StrnTermListInDTO inDto, PageInfo pageInfo);
int insertAppliSystNtfyPati(AppliSystNtfyPatiModel appliSystNtfyPatiModel);
}

View File

@@ -0,0 +1,11 @@
package io.shinhanlife.axhub.sample.domain.service;
import io.shinhanlife.axhub.sample.dto.AppliSystNtfyRgiInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListOutDTO;
import io.shinhanlife.glow.PageInfo;
public interface GlowSampleService {
StrnTermListOutDTO getStrnTerms(StrnTermListInDTO inDto, PageInfo pageInfo);
int insertAppliSystNtfyPati(AppliSystNtfyRgiInDTO inDto);
}

View File

@@ -0,0 +1,41 @@
package io.shinhanlife.axhub.sample.domain.service.impl;
import io.shinhanlife.axhub.sample.converter.SampleConverter;
import io.shinhanlife.axhub.sample.domain.model.AppliSystNtfyPatiModel;
import io.shinhanlife.axhub.sample.domain.repository.GlowSampleRepository;
import io.shinhanlife.axhub.sample.domain.service.GlowSampleService;
import io.shinhanlife.axhub.sample.dto.AppliSystNtfyRgiInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListInDTO;
import io.shinhanlife.axhub.sample.dto.StrnTermListOutDTO;
import io.shinhanlife.glow.GlowLogger;
import io.shinhanlife.glow.GlowLogTarget;
import io.shinhanlife.glow.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class GlowSampleServiceImpl implements GlowSampleService {
@GlowLogTarget(GlowLogTarget.Target.FILE)
private final GlowLogger log;
private final GlowSampleRepository glowSampleRepository;
private final SampleConverter sampleConverter;
@Override
public StrnTermListOutDTO getStrnTerms(StrnTermListInDTO inDto, PageInfo pageInfo) {
List<StrnTermListOutDTO.StrnTerm> out = glowSampleRepository.selectStrnTerm(inDto, pageInfo);
return StrnTermListOutDTO.builder()
.strnTerms(out)
.pageInfo(pageInfo)
.build();
}
@Override
public int insertAppliSystNtfyPati(AppliSystNtfyRgiInDTO inDto) {
AppliSystNtfyPatiModel appliSystNtfyPatiModel = sampleConverter.convertDtoToModel(inDto);
return glowSampleRepository.insertAppliSystNtfyPati(appliSystNtfyPatiModel);
}
}

View File

@@ -0,0 +1,21 @@
package io.shinhanlife.axhub.sample.dto;
import lombok.*;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AppliSystNtfyRgiInDTO {
private String appliSystNtfyPatiId;
private String appliSystNtfyKdCd;
private String appliDutjCd;
private String appliDutjPrjcCd;
private String ntfyMsgCt;
private String ntfyOccDt;
private String ntfyCfmDt;
private String ntfyTrgtPrafNo;
private String shmsPmlYn;
private String ntfyCfmYn;
}

View File

@@ -0,0 +1,12 @@
package io.shinhanlife.axhub.sample.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class StrnTermListInDTO {
private String strnTermHanNm;
}

View File

@@ -0,0 +1,27 @@
package io.shinhanlife.axhub.sample.dto;
import io.shinhanlife.glow.PageInfo;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Builder
@Getter
@Setter
public class StrnTermListOutDTO {
private List<StrnTerm> strnTerms;
private PageInfo pageInfo;
@Builder
@Getter
@Setter
public static class StrnTerm{
private String strnTermHanNm;
private String strnTermEngcAbrNm;
private String strnTermEngNm;
private String strnTermScrnTermNm;
}
}

View File

@@ -0,0 +1,40 @@
package io.shinhanlife.axhub.sample.presentation;
import io.shinhanlife.glow.BaseResponse;
import io.shinhanlife.glow.GlowControllerId;
import io.shinhanlife.glow.GlowLogTarget;
import io.shinhanlife.glow.GlowLogger;
import io.shinhanlife.glow.ResponseUtil;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiRequest;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiResponse;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermRequest;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermResponse;
import io.shinhanlife.axhub.sample.usecase.GlowSampleUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class GlowSampleController {
@GlowLogTarget({GlowLogTarget.Target.CONSOLE, GlowLogTarget.Target.FILE})
private final GlowLogger log;
private final GlowSampleUseCase glowSampleUseCase;
@GlowControllerId(value = "selectStrnTerm")
@PostMapping("/selectStrnTerm")
public ResponseEntity<BaseResponse<StrnTermResponse>> getStrnTerms(@RequestBody StrnTermRequest request) {
return ResponseUtil.ok(glowSampleUseCase.getStrnTerms(request));
}
@GlowControllerId(value = "insertAp")
@PostMapping("/insertAppliSystNtfyPati")
public ResponseEntity<BaseResponse<AppliSystNtfyPatiResponse>> insertAppliSystNtfyPati(@RequestBody AppliSystNtfyPatiRequest request) {
return ResponseUtil.ok(glowSampleUseCase.insertAppliSystNtfyPati(request));
}
}

View File

@@ -0,0 +1,20 @@
package io.shinhanlife.axhub.sample.presentation.io;
import lombok.*;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class AppliSystNtfyPatiRequest {
private String appliSystNtfyPatiId;
private String appliSystNtfyKdCd;
private String appliDutjCd;
private String appliDutjPrjcCd;
private String ntfyMsgCt;
private String ntfyOccDt;
private String ntfyCfmDt;
private String ntfyTrgtPrafNo;
private String shmsPmlYn;
private String ntfyCfmYn;
}

View File

@@ -0,0 +1,12 @@
package io.shinhanlife.axhub.sample.presentation.io;
import lombok.*;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class AppliSystNtfyPatiResponse {
private String successYn;
private String msg;
}

View File

@@ -0,0 +1,14 @@
package io.shinhanlife.axhub.sample.presentation.io;
import io.shinhanlife.glow.PageInfo;
import lombok.*;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class StrnTermRequest {
private PageInfo pageInfo;
private String strnTermHanNm;
}

View File

@@ -0,0 +1,27 @@
package io.shinhanlife.axhub.sample.presentation.io;
import io.shinhanlife.glow.PageInfo;
import lombok.*;
import java.util.List;
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class StrnTermResponse {
private List<StrnTerm> strnTerms;
private PageInfo pageInfo;
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class StrnTerm{
private String strnTermHanNm;
private String strnTermEngcAbrNm;
private String strnTermEngNm;
private String strnTermScrnTermNm;
}
}

View File

@@ -0,0 +1,11 @@
package io.shinhanlife.axhub.sample.usecase;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiRequest;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiResponse;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermRequest;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermResponse;
public interface GlowSampleUseCase {
StrnTermResponse getStrnTerms(StrnTermRequest req);
AppliSystNtfyPatiResponse insertAppliSystNtfyPati(AppliSystNtfyPatiRequest req);
}

View File

@@ -0,0 +1,43 @@
package io.shinhanlife.axhub.sample.usecase.impl;
import io.shinhanlife.axhub.sample.converter.SampleConverter;
import io.shinhanlife.axhub.sample.domain.service.GlowSampleService;
import io.shinhanlife.axhub.sample.dto.StrnTermListOutDTO;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiRequest;
import io.shinhanlife.axhub.sample.presentation.io.AppliSystNtfyPatiResponse;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermRequest;
import io.shinhanlife.axhub.sample.presentation.io.StrnTermResponse;
import io.shinhanlife.axhub.sample.usecase.GlowSampleUseCase;
import io.shinhanlife.glow.GlowAppServiceId;
import io.shinhanlife.glow.GlowLogTarget;
import io.shinhanlife.glow.GlowLogger;
import io.shinhanlife.glow.GlowServiceGroupId;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@GlowServiceGroupId(value = "GlowSample", description="GlowSampleUseCase")
public class GlowSampleUseCaseImpl implements GlowSampleUseCase {
@GlowLogTarget(GlowLogTarget.Target.FILE)
private final GlowLogger log;
private final GlowSampleService glowSampleService;
private final SampleConverter converter;
@GlowAppServiceId(value = "SAMPLE-DB-0001", description = "표준용어조회(DB)")
public StrnTermResponse getStrnTerms(StrnTermRequest req) {
StrnTermListOutDTO outDto = glowSampleService.getStrnTerms(converter.convertRequestToDto(req), req.getPageInfo());
return converter.convertDtoToResponse(outDto);
}
@GlowAppServiceId(value = "SAMPLE-DB-0002", description = "어플리케이션시스템알림내역등록")
public AppliSystNtfyPatiResponse insertAppliSystNtfyPati(AppliSystNtfyPatiRequest req) {
int rtn = glowSampleService.insertAppliSystNtfyPati(converter.convertAppliRequestToDto(req));
return AppliSystNtfyPatiResponse.builder()
.successYn(rtn > 0 ? "Y" : "N")
.msg(rtn > 0 ? "성공적으로 처리 되었습니다." : "처리중 오류발생!!")
.build();
}
}

View File

@@ -0,0 +1,29 @@
package io.shinhanlife.glow;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
//@Schema(description = "응답 에러 객체. 성공 케이스일 경우 null. 실제 에러가 발생할 경우에만 예외명, 예외 메시지 필드 세팅 예정.")
public class BaseException {
// @Schema(description = "Error 코드 Meta 참조 운영. (예) 20001, 50001 등", shinhanlife = "20001")
String code;
// @Schema(description = "메시지")
String message;
// @Schema(description = "예외명.", shinhanlife = "NullPointerException")
@Builder.Default
String exceptionName = "";
// @Schema(description = "예외상세", shinhanlife = "StackTrace")
@Builder.Default
String exceptionDetail = "";
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.glow;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
@ToString
@Getter
@Builder
@AllArgsConstructor
public class BaseResponse<T> {
// @Schema(description = "응답 코드 HTTP STATUS 오류 - 실제 Header 는 200 으로 내려감", shinhanlife = "200")
private int code;
// @Schema(description = "응답 메시지. 응답 코드와 매핑된 메시지.", shinhanlife = "데이터 생성 성공")
private String message;
// @Schema(description = "응답 본문 데이터. 실제 비즈니스 데이터.")
private T data;
private BaseException error;
}

View File

@@ -0,0 +1,6 @@
package io.shinhanlife.glow;
public class BizException extends RuntimeException {
public BizException(String s) {
}
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.glow;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GlowAppServiceId {
String value();
String description() default "";
}

View File

@@ -0,0 +1,5 @@
package io.shinhanlife.glow;
public @interface GlowControllerId {
String value();
}

View File

@@ -0,0 +1,9 @@
package io.shinhanlife.glow;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GlowIndexPaging {
}

View File

@@ -0,0 +1,15 @@
package io.shinhanlife.glow;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GlowLogTarget {
Target[] value() default {};
enum Target {
FILE, CONSOLE
}
}

View File

@@ -0,0 +1,19 @@
package io.shinhanlife.glow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class GlowLogger {
private Logger log = LoggerFactory.getLogger(GlowLogger.class);
public void debug(String message, Object... args) { log.debug(message, args); }
public void info(String message, Object... args) { log.info(message, args); }
public void warn(String message, Object... args) { log.warn(message, args); }
public void error(String message, Object... args) { log.error(message, args); }
public void error(String message, Throwable t) { log.error(message, t); }
}

View File

@@ -0,0 +1,18 @@
package io.shinhanlife.glow;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
* MyBatis Mapper 인터페이스를 나타내는 어노테이션
* MyBatis Mapper와 동일한 기능을 제공합니다.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapper
@Component
public @interface GlowMybatisMapper {
}

View File

@@ -0,0 +1,7 @@
package io.shinhanlife.glow;
public @interface GlowServiceGroupId {
String value();
String description();
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.glow;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GlowTrgmField {
/**
* 필드 순서
*/
int order();
/**
* 필드 길이
*/
int length();
/**
* 필드 설명
*/
String description() default "";
}

View File

@@ -0,0 +1,68 @@
package io.shinhanlife.glow;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.session.RowBounds;
import java.io.Serial;
import java.io.Serializable;
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@EqualsAndHashCode(callSuper = true)
public class PageInfo extends RowBounds implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 페이지번호 ( 입력값 )
*/
@GlowTrgmField(order = 1, length = 5, description = "페이지번호")
private int pageNo;
/**
* 페이지 데이터 건수 ( 열 건수, 입력값 )
*/
@GlowTrgmField(order = 2, length = 5, description = "페이지데이터건수")
private int pageDataCc;
/**
* 총페이지 수 ( 리턴값 )
*/
@GlowTrgmField(order = 3, length = 10, description = "총페이지수")
private int totaPageCn;
/**
* 총 페이지 데이터 건수 ( 리턴값 )
*/
@GlowTrgmField(order = 4, length = 10, description = "총페이지데이터건수")
private int totaPageDataCc;
public PageInfo(int pageNo, int pageDataCc) {
super(((pageNo <= 0 ? 1 : pageNo) - 1) * pageDataCc, pageDataCc);
this.pageNo = pageNo;
this.pageDataCc = pageDataCc;
}
public PageInfo() {
}
@JsonIgnore
@Override
public int getOffset() {
return super.getOffset();
}
@JsonIgnore
@Override
public int getLimit() {
return super.getLimit();
}
}

View File

@@ -0,0 +1,31 @@
package io.shinhanlife.glow;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
@Getter
@RequiredArgsConstructor
public enum ResponseCode {
/* ===================== 성공 ===================== */
SUCCESS(HttpStatus.OK, "정상 처리되었습니다."),
CREATED(HttpStatus.CREATED, "데이터 생성 성공"),
/* ===================== 클라이언트 오류 (4xx) ===================== */
BAD_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 요청입니다."),
INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "유효하지 않은 파라미터입니다."),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "인증이 필요합니다."),
FORBIDDEN(HttpStatus.FORBIDDEN, "접근 권한이 없습니다."),
NOT_FOUND(HttpStatus.NOT_FOUND, "요청한 리소스를 찾을 수 없습니다."),
METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "허용되지 않은 HTTP 메서드입니다."),
CONFLICT(HttpStatus.CONFLICT, "이미 존재하는 데이터입니다."),
/* ===================== 서버 오류 (5xx) ===================== */
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 오류가 발생했습니다."),
SERVICE_UNAVAILABLE(HttpStatus.SERVICE_UNAVAILABLE, "서비스를 사용할 수 없습니다.");
private final HttpStatus status;
private final String message;
}

View File

@@ -0,0 +1,111 @@
package io.shinhanlife.glow;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
public final class ResponseUtil {
private ResponseUtil() {
}
public static <T> ResponseEntity<BaseResponse<T>> ok() {
return ResponseEntity.ok(
BaseResponse.<T>builder()
.code(ResponseCode.SUCCESS.getStatus().value())
.message(ResponseCode.SUCCESS.getMessage())
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> ok(T data) {
return ResponseEntity.ok(
BaseResponse.<T>builder()
.code(ResponseCode.SUCCESS.getStatus().value())
.message(ResponseCode.SUCCESS.getMessage())
.data(data)
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> ok(T data, ResponseCode responseCode) {
return ResponseEntity.ok(
BaseResponse.<T>builder()
.code(responseCode.getStatus().value())
.message(responseCode.getMessage())
.data(data)
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> error(
HttpStatus status, String code, String message
) {
return ResponseEntity.status(status)
.body(
BaseResponse.<T>builder()
.code(status.value())
.error(
BaseException.builder()
.code(code)
.message(message)
.build()
)
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> error(
HttpStatus status, String code, String message, String exceptionName, String stackTrace
) {
return ResponseEntity.status(status)
.body(
BaseResponse.<T>builder()
.code(status.value())
.error(
BaseException.builder()
.code(code)
.message(message)
.exceptionName(exceptionName)
.exceptionDetail(stackTrace)
.build()
)
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> okError(
HttpStatus status, String code, String message
) {
return ResponseEntity.ok(
BaseResponse.<T>builder()
.code(status.value())
.error(
BaseException.builder()
.code(code)
.message(message)
.build()
)
.build()
);
}
public static <T> ResponseEntity<BaseResponse<T>> okError(
HttpStatus status, String code, String message, String exceptionName, String stackTrace
) {
return ResponseEntity.ok(
BaseResponse.<T>builder()
.code(status.value())
.error(
BaseException.builder()
.code(code)
.message(message)
.exceptionName(exceptionName)
.exceptionDetail(stackTrace)
.build()
)
.build()
);
}
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.glow.db.dto;
import java.util.Date;
public class AuditInfo {
private Date systRgiDt; // 시스템등록일시
private String systRgiPrafNo; // 시스템등록인사번호
private String systRgiOgnzNo; // 시스템등록조직번호
private String systRgiSystCd; // 시스템등록시스템코드
private String systRgiPrgrId; // 시스템등록프로그램ID
private Date systChgDt; // 시스템변경일시
private String systChgPrafNo; // 시스템변경인사번호
private String systChgOgnzNo; // 시스템변경조직번호
private String systChgSystCd; // 시스템변경시스템코드
private String systChgPrgrId; // 시스템변경프로그램ID
}