Merge pull request 'dev' (#533) from dev into prd-deploy

Reviewed-on: #533
This commit is contained in:
ysCha 2026-06-18 18:00:55 +09:00
commit 891c2b0a38
12 changed files with 469 additions and 287 deletions

View File

@ -3199,10 +3199,6 @@ public class EstimateService {
SimulationEstimateListResponse response = new SimulationEstimateListResponse(); SimulationEstimateListResponse response = new SimulationEstimateListResponse();
if (!"T01".equals(objectRequest.getSaleStoreId())) {
objectRequest.setSchSelSaleStoreId("");
}
// 견적서 목록 조회 // 견적서 목록 조회
List<ObjectResponse> objectList = estimateMapper.selectSimulationEstimateList(objectRequest); List<ObjectResponse> objectList = estimateMapper.selectSimulationEstimateList(objectRequest);

View File

@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.interplug.qcast.biz.excelDown.dto.NtrCtsCmpRequest; import com.interplug.qcast.biz.excelDown.dto.NtrCtsCmpRequest;
import com.interplug.qcast.biz.excelDown.dto.NtrCtsCmpResponse; import com.interplug.qcast.biz.excelDown.dto.NtrCtsCmpResponse;
import com.interplug.qcast.biz.excelDown.dto.QuotItemResponse;
import com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse; import com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse;
import com.interplug.qcast.biz.excelDown.dto.QuotRequest; import com.interplug.qcast.biz.excelDown.dto.QuotRequest;
import com.interplug.qcast.biz.excelDown.dto.QuotResponse; import com.interplug.qcast.biz.excelDown.dto.QuotResponse;
@ -37,13 +36,8 @@ public class ExcelDownController {
QuotResponse quotRes = new QuotResponse(); QuotResponse quotRes = new QuotResponse();
if ("1".equals(quotRequest.getSch_selectType())) { if ("1".equals(quotRequest.getSch_selectType())) {
List<QuotPlanResponse> quotPlanExclDownData = quotRes.setQuotPlanList(excelDownService.selectQuotPlanExclDownData(quotRequest));
excelDownService.selectQuotPlanExclDownData(quotRequest); quotRes.setQuotItemList(excelDownService.selectQuotItemExclDownData(quotRequest));
List<QuotItemResponse> quotItemExclDownData =
excelDownService.selectQuotItemExclDownData(quotRequest);
quotRes.setQuotPlanList(quotPlanExclDownData);
quotRes.setQuotItemList(quotItemExclDownData);
} else { } else {
List<QuotPlanResponse> quotPlanExclDownData = List<QuotPlanResponse> quotPlanExclDownData =
excelDownService.selectQuotPlanExclDownData2(quotRequest); excelDownService.selectQuotPlanExclDownData2(quotRequest);

View File

@ -10,6 +10,7 @@ import com.interplug.qcast.biz.excelDown.dto.WrntIsncCmplRequest;
import com.interplug.qcast.biz.excelDown.dto.WrntIsncCmplResponse; import com.interplug.qcast.biz.excelDown.dto.WrntIsncCmplResponse;
import java.util.List; import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
interface ExcelDownMapper { interface ExcelDownMapper {
@ -41,6 +42,7 @@ interface ExcelDownMapper {
*/ */
List<QuotItemResponse> selectQuotItemExclDownData(QuotRequest quotRequest) throws Exception; List<QuotItemResponse> selectQuotItemExclDownData(QuotRequest quotRequest) throws Exception;
/** /**
* 과거데이터_자연재해보상입력 엑셀다운로드 조회 * 과거데이터_자연재해보상입력 엑셀다운로드 조회
* *

View File

@ -5,9 +5,12 @@ import com.interplug.qcast.config.message.Messages;
import com.interplug.qcast.util.ZipFileManager; import com.interplug.qcast.util.ZipFileManager;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;

View File

@ -21,4 +21,9 @@ public class QuotRequest {
private String sch_saleStoreId; private String sch_saleStoreId;
@Schema(description = "영업 담당자명") @Schema(description = "영업 담당자명")
private String sch_businessChargerCd; private String sch_businessChargerCd;
@Schema(description = "페이지 번호 (1부터 시작, null이면 전체 조회)")
private Integer pageNo;
@Schema(description = "페이지당 건수")
private Integer pageSize;
} }

View File

@ -1,9 +1,7 @@
package com.interplug.qcast.biz.pwrGnrSimulation; package com.interplug.qcast.biz.pwrGnrSimulation;
import com.interplug.qcast.biz.estimate.dto.EstimateRequest; import com.interplug.qcast.biz.estimate.dto.EstimateRequest;
import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimGuideResponse; import com.interplug.qcast.biz.pwrGnrSimulation.dto.*;
import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimRequest;
import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimResponse;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -47,4 +45,11 @@ public class PwrGnrSimController {
throws Exception { throws Exception {
pwrGnrSimService.excelDownload(request, response, estimateRequest); pwrGnrSimService.excelDownload(request, response, estimateRequest);
} }
@Operation(description = "발전시뮬레이션 판매점정보 암호화를 처리한다.")
@GetMapping("/encData")
@ResponseStatus(HttpStatus.OK)
public PwrGnrSimEncResponse selectPwrGnrSimulationEncData(PwrGnrSimEncRequest pwrGnrSimEncRequest) throws Exception {
return pwrGnrSimService.selectPwrGnrSimulationEncData(pwrGnrSimEncRequest);
}
} }

View File

@ -8,6 +8,7 @@ import com.interplug.qcast.biz.pwrGnrSimulation.dto.*;
import com.interplug.qcast.config.Exception.ErrorCode; import com.interplug.qcast.config.Exception.ErrorCode;
import com.interplug.qcast.config.Exception.QcastException; import com.interplug.qcast.config.Exception.QcastException;
import com.interplug.qcast.config.message.Messages; import com.interplug.qcast.config.message.Messages;
import com.interplug.qcast.util.EncryptUtil;
import com.interplug.qcast.util.ExcelUtil; import com.interplug.qcast.util.ExcelUtil;
import com.interplug.qcast.util.InterfaceQsp; import com.interplug.qcast.util.InterfaceQsp;
import com.interplug.qcast.util.PdfUtil; import com.interplug.qcast.util.PdfUtil;
@ -2614,4 +2615,12 @@ public class PwrGnrSimService {
} }
} }
public PwrGnrSimEncResponse selectPwrGnrSimulationEncData(PwrGnrSimEncRequest pwrGnrSimEncRequest) throws Exception {
PwrGnrSimEncResponse encDataResponse = new PwrGnrSimEncResponse();
encDataResponse.setEncSaleStoreId(EncryptUtil.encryptAes256(pwrGnrSimEncRequest.getSaleStoreId()));
encDataResponse.setEncUserId(EncryptUtil.encryptAes256(pwrGnrSimEncRequest.getUserId()));
return encDataResponse;
}
} }

View File

@ -0,0 +1,13 @@
package com.interplug.qcast.biz.pwrGnrSimulation.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class PwrGnrSimEncRequest {
@Schema(description = "판매점ID")
private String saleStoreId;
@Schema(description = "사용자아이디")
private String userId;
}

View File

@ -0,0 +1,13 @@
package com.interplug.qcast.biz.pwrGnrSimulation.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class PwrGnrSimEncResponse {
@Schema(description = "암호화 판매점 아이디")
private String encSaleStoreId;
@Schema(description = "암호화 로그인 아이디")
private String encUserId;
}

View File

@ -0,0 +1,127 @@
package com.interplug.qcast.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
@Component
@Slf4j
public class EncryptUtil {
/** 초기화 비밀번호 */
@Value("${qsp.aes256.key}")
static String loginPasswordAesKey;
@Value("${qsp.aes256.key}")
public void setLoginPasswordAesKey(String value) {
loginPasswordAesKey = value;
}
/**
* 비밀번호를 암호화하는 기능(복호화가 되면 안되므로 SHA-256 인코딩 방식 적용)
*
* @param password 암호화될 패스워드
* @param id salt로 사용될 사용자 ID 지정
* @return
* @throws Exception
*/
public static String encryptSha256(String password, String id) {
if (password == null) {
return "";
}
String enStr = null;
try {
byte[] hashValue = null; // 해쉬값
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.reset();
md.update(id.getBytes());
hashValue = md.digest(password.getBytes());
enStr = new String(Base64.getEncoder().encode(hashValue));
} catch (Exception e) {
log.error("Sha Util Encrypt Error", e);
}
return enStr;
}
/**
* AES-256 암호화
* @param keyword
* @return
*/
public static String encryptAes256(String keyword) {
return encryptAes256(keyword, loginPasswordAesKey);
}
/**
* AES-256 암호화
* @param keyword
* @return
*/
public static String encryptAes256(String keyword, String loginPasswordKey) {
if(StringUtils.isBlank(keyword)) {
return null;
}
String enStr = null;
try {
byte[] keyData = loginPasswordAesKey.getBytes();
SecretKey secureKey = new SecretKeySpec(keyData, "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, secureKey, new IvParameterSpec(loginPasswordKey.substring(0, 16).getBytes()));
byte[] encrypted = c.doFinal(keyword.getBytes("UTF-8"));
enStr = new String(Base64.getEncoder().encode(encrypted));
} catch (Exception e) {
log.error("AES Util Encrypt Error", e);
}
return enStr;
}
/**
* AES-256 복호화
* @param keyword
* @return
*/
public static String decryptAes256(String keyword) {
return decryptAes256(keyword, loginPasswordAesKey);
}
/**
* AES-256 복호화
* @param keyword
* @return
*/
public static String decryptAes256(String keyword, String loginPasswordKey) {
if(StringUtils.isBlank(keyword)) {
return null;
}
String deStr = null;
try {
byte[] keyData = loginPasswordAesKey.getBytes();
SecretKey secureKey = new SecretKeySpec(keyData, "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, secureKey, new IvParameterSpec(loginPasswordKey.substring(0, 16).getBytes("UTF-8")));
byte[] byteStr = Base64.getDecoder().decode(keyword.getBytes());
deStr = new String(c.doFinal(byteStr), "UTF-8");
} catch (Exception e) {
log.error("AES Util Decrypt Error", e);
}
return deStr;
}
}

View File

@ -1549,7 +1549,7 @@
<select id="selectSimulationEstimateList" parameterType="com.interplug.qcast.biz.object.dto.ObjectRequest" resultType="com.interplug.qcast.biz.object.dto.ObjectResponse"> <select id="selectSimulationEstimateList" parameterType="com.interplug.qcast.biz.object.dto.ObjectRequest" resultType="com.interplug.qcast.biz.object.dto.ObjectResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectSimulationEstimateList */ /* sqlid : com.interplug.qcast.biz.estimate.selectSimulationEstimateList */
<if test='(saleStoreId != null and saleStoreId != "T01") or (schSelSaleStoreId != null and schSelSaleStoreId != "")'> <if test='saleStoreId != null and saleStoreId != "T01"'>
/* 계층형 구조에 맞는 SALE_STORE_ID 축출 - 재귀함수 */ /* 계층형 구조에 맞는 SALE_STORE_ID 축출 - 재귀함수 */
WITH SALES_STORE_CTE AS ( WITH SALES_STORE_CTE AS (
SELECT SELECT
@ -1559,14 +1559,7 @@
FROM M_SALES_STORE WITH(NOLOCK) FROM M_SALES_STORE WITH(NOLOCK)
WHERE APPROVE_FLG = '2' WHERE APPROVE_FLG = '2'
AND DEL_FLG = '0' AND DEL_FLG = '0'
<choose>
<when test='schSelSaleStoreId != null and schSelSaleStoreId != ""'>
AND SALE_STORE_ID = #{schSelSaleStoreId}
</when>
<otherwise>
AND SALE_STORE_ID = #{saleStoreId} AND SALE_STORE_ID = #{saleStoreId}
</otherwise>
</choose>
UNION ALL UNION ALL
SELECT SELECT
@ -1602,7 +1595,10 @@
ON O.SALE_STORE_ID = S.SALE_STORE_ID ON O.SALE_STORE_ID = S.SALE_STORE_ID
INNER JOIN T_PLAN P WITH (NOLOCK) INNER JOIN T_PLAN P WITH (NOLOCK)
ON O.OBJECT_NO = P.OBJECT_NO ON O.OBJECT_NO = P.OBJECT_NO
<if test='(saleStoreId != null and saleStoreId != "T01") or (schSelSaleStoreId != null and schSelSaleStoreId != "")'> INNER JOIN T_PLAN_INFO PI WITH (NOLOCK)
ON P.OBJECT_NO = PI.OBJECT_NO
AND P.PLAN_NO = PI.PLAN_NO
<if test='saleStoreId != null and saleStoreId != "T01"'>
INNER JOIN SALES_STORE_CTE T INNER JOIN SALES_STORE_CTE T
ON S.SALE_STORE_ID = T.SALE_STORE_ID ON S.SALE_STORE_ID = T.SALE_STORE_ID
</if> </if>
@ -1611,12 +1607,13 @@
WHERE OI.SOURCE_ORIGIN = 'QCAST_III' WHERE OI.SOURCE_ORIGIN = 'QCAST_III'
AND (OI.ORG_DEL_FLG = '0' AND OI.TEMP_FLG = '0') AND (OI.ORG_DEL_FLG = '0' AND OI.TEMP_FLG = '0')
AND P.DEL_FLG = '0' AND P.DEL_FLG = '0'
AND PI.DOC_NO IS NOT NULL
<if test='schObjectNo != null and schObjectNo != ""'> <if test='schObjectNo != null and schObjectNo != ""'>
AND O.OBJECT_NO LIKE '%' + #{schObjectNo} + '%' AND O.OBJECT_NO LIKE '%' + #{schObjectNo} + '%'
</if> </if>
<if test='schOtherSelSaleStoreId != null and schOtherSelSaleStoreId != ""'> <if test='schSelSaleStoreId != null and schSelSaleStoreId != ""'>
/* 2차점까지 고름 */ /* 판매점 아이디 선택 */
AND O.SALE_STORE_ID = #{schOtherSelSaleStoreId} AND O.SALE_STORE_ID = #{schSelSaleStoreId}
</if> </if>
<if test='schObjectName != null and schObjectName != ""'> <if test='schObjectName != null and schObjectName != ""'>
AND O.OBJECT_NAME LIKE '%' + #{schObjectName} + '%' AND O.OBJECT_NAME LIKE '%' + #{schObjectName} + '%'

View File

@ -6,8 +6,10 @@
<select id="selectQuotPlanExclDownData" parameterType="com.interplug.qcast.biz.excelDown.dto.QuotRequest" <select id="selectQuotPlanExclDownData" parameterType="com.interplug.qcast.biz.excelDown.dto.QuotRequest"
resultType="com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse"> resultType="com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse">
/* sqlid : com.interplug.qcast.api.excelDown.selectQuotPlanExclDownData (견적엑셀다운로드 플랜정보 데이터 조회) */ /* sqlid : com.interplug.qcast.api.excelDown.selectQuotPlanExclDownData (견적엑셀다운로드 플랜정보 데이터 조회) */
SELECT * FROM (
SELECT SELECT
B.OBJECT_NO /* 물건번호 物件番号 */ ROW_NUMBER() OVER (ORDER BY B.OBJECT_NO, A.PLAN_NO) AS RN
, B.OBJECT_NO /* 물건번호 物件番号 */
, A.PLAN_NO /* 플랜 案件番号 */ , A.PLAN_NO /* 플랜 案件番号 */
, CONVERT(varchar, A.LAST_EDIT_DATETIME, 120) AS LAST_EDIT_DATETIME /* 플랜정보 최신 갱신일시 プラン情報最新更新日時 */ , CONVERT(varchar, A.LAST_EDIT_DATETIME, 120) AS LAST_EDIT_DATETIME /* 플랜정보 최신 갱신일시 プラン情報最新更新日時 */
, G.SALE_STORE_NAME /* 판매대리점 販売代理店 */ , G.SALE_STORE_NAME /* 판매대리점 販売代理店 */
@ -180,6 +182,14 @@
ON G.FIRST_AGENT_ID = Y.SALE_STORE_ID /*1차점정보*/ ON G.FIRST_AGENT_ID = Y.SALE_STORE_ID /*1차점정보*/
WHERE A.DEL_FLG = 0 WHERE A.DEL_FLG = 0
AND (B.DEL_FLG = 0 OR (OI.SOURCE_ORIGIN = 'QCAST_III' AND OI.ORG_DEL_FLG = '0')) AND (B.DEL_FLG = 0 OR (OI.SOURCE_ORIGIN = 'QCAST_III' AND OI.ORG_DEL_FLG = '0'))
<include refid="quotPlanSearchConditions"/>
) AS PAGED
<if test="pageNo != null and pageSize != null">
WHERE RN BETWEEN (#{pageNo} - 1) * #{pageSize} + 1 AND #{pageNo} * #{pageSize}
</if>
</select>
<sql id="quotPlanSearchConditions">
<if test="sch_startDt != null and sch_startDt != '' and sch_endDt != null and sch_endDt != ''"> <!-- 견적일 --> <if test="sch_startDt != null and sch_startDt != '' and sch_endDt != null and sch_endDt != ''"> <!-- 견적일 -->
AND B.ESTIMATE_DETAIL_CREATE_DATE <![CDATA[>=]]> #{sch_startDt} + ' 00:00:00' AND B.ESTIMATE_DETAIL_CREATE_DATE <![CDATA[>=]]> #{sch_startDt} + ' 00:00:00'
AND B.ESTIMATE_DETAIL_CREATE_DATE <![CDATA[<=]]> #{sch_endDt} + ' 23:59:59' AND B.ESTIMATE_DETAIL_CREATE_DATE <![CDATA[<=]]> #{sch_endDt} + ' 23:59:59'
@ -190,7 +200,7 @@
<if test="sch_businessChargerCd != null and sch_businessChargerCd != ''"> <!-- 영업담당자 --> <if test="sch_businessChargerCd != null and sch_businessChargerCd != ''"> <!-- 영업담당자 -->
AND G.BUSINESS_CHARGER_CD = #{sch_businessChargerCd} AND G.BUSINESS_CHARGER_CD = #{sch_businessChargerCd}
</if> </if>
</select> </sql>
<select id="selectQuotPlanExclDownData2" parameterType="com.interplug.qcast.biz.excelDown.dto.QuotRequest" <select id="selectQuotPlanExclDownData2" parameterType="com.interplug.qcast.biz.excelDown.dto.QuotRequest"
resultType="com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse"> resultType="com.interplug.qcast.biz.excelDown.dto.QuotPlanResponse">
@ -234,7 +244,11 @@
resultType="com.interplug.qcast.biz.excelDown.dto.QuotItemResponse"> resultType="com.interplug.qcast.biz.excelDown.dto.QuotItemResponse">
/* sqlid : com.interplug.qcast.api.excelDown.selectQuotItemExclDownData (견적엑셀다운로드 품목단위 데이터 조회) */ /* sqlid : com.interplug.qcast.api.excelDown.selectQuotItemExclDownData (견적엑셀다운로드 품목단위 데이터 조회) */
SELECT SELECT
C.OBJECT_NO /* 물건번호 物件番号 */ *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY C.OBJECT_NO, B.PLAN_NO, A.ITEM_NO) AS RN
, C.OBJECT_NO /* 물건번호 物件番号 */
, B.PLAN_NO /* 플랜 案件番号 */ , B.PLAN_NO /* 플랜 案件番号 */
, C.OBJECT_NAME /* 물건명 案件名 */ , C.OBJECT_NAME /* 물건명 案件名 */
, H.SALE_STORE_NAME AS SOLD_SALE_STORE_NAME /* 1차 판매점명 一次販売店名 */ , H.SALE_STORE_NAME AS SOLD_SALE_STORE_NAME /* 1차 판매점명 一次販売店名 */
@ -308,6 +322,10 @@
<if test="sch_businessChargerCd != null and sch_businessChargerCd != ''"> <!-- 영업담당자 --> <if test="sch_businessChargerCd != null and sch_businessChargerCd != ''"> <!-- 영업담당자 -->
AND C.BUSINESS_CHARGER_CD = #{sch_businessChargerCd} AND C.BUSINESS_CHARGER_CD = #{sch_businessChargerCd}
</if> </if>
) AS PAGED
<if test="pageNo != null and pageSize != null">
WHERE RN BETWEEN (#{pageNo} - 1) * #{pageSize} + 1 AND #{pageNo} * #{pageSize}
</if>
</select> </select>