From 2ee86cadcd4a1ea45a4c839b4790144e8be7287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Tue, 17 Oct 2023 15:12:37 +0900 Subject: [PATCH 1/6] =?UTF-8?q?qna=20=EC=84=A4=EA=B3=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JwtAuthenticationController.java | 36 +--- .../biz/api/acnt/jwt/model/JwtRsModel.java | 3 +- .../biz/api/acnt/jwt/model/JwtUserModel.java | 2 + .../biz/api/acnt/jwt/service/JwtService.java | 1 + .../biz/api/acnt/jwt/utils/JwtTokenUtil.java | 71 ++++--- .../biz/api/bas/dron/model/BasDronModel.java | 5 +- .../biz/api/bas/dron/model/BasIdntfModel.java | 5 +- .../biz/api/bas/dron/model/BasOwnerModel.java | 5 +- .../api/bas/group/model/BasGroupModel.java | 5 +- .../cns/qna/controller/CnsQnaController.java | 56 +++-- .../biz/api/cns/qna/model/QnaBasModel.java | 14 +- .../api/cns/qna/model/QnaDetailRSModel.java | 3 +- .../cns/qna/model/QnaInsertAnserRQModel.java | 17 ++ .../api/cns/qna/model/QnaInsertRQModel.java | 3 + .../api/cns/qna/model/QnaSelectListRQ.java | 3 +- .../biz/api/cns/qna/service/CnsQnaMapper.java | 34 +++ .../api/cns/qna/service/CnsQnaService.java | 199 +++++++----------- .../file/controller/ComnFileController.java | 11 + .../api/comn/file/model/ComnFileModel.java | 27 +++ .../api/comn/file/service/ComnFileMapper.java | 23 ++ .../comn/file/service/ComnFileService.java | 121 +++++++---- .../cntrl/model/CtrCntrlArcrftWarnModel.java | 1 - .../ctr/cntrl/model/CtrCntrlWarnLogModel.java | 4 - .../com/palnet/biz/jpa/entity/CnsQnaBas.java | 47 +++-- .../palnet/biz/jpa/entity/PtyCrtfyhpBas.java | 1 - .../repository/cns/CnsQnaQueryRepository.java | 88 ++++---- .../repository/com/ComFileBasRepository.java | 5 +- .../pty/PtyCstmrQueryRepository.java | 25 ++- .../com/palnet/comn/code/RSErrorCode.java | 1 + 29 files changed, 473 insertions(+), 343 deletions(-) create mode 100644 pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertAnserRQModel.java create mode 100644 pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaMapper.java create mode 100644 pav-server/src/main/java/com/palnet/biz/api/comn/file/model/ComnFileModel.java create mode 100644 pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileMapper.java diff --git a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/controller/JwtAuthenticationController.java b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/controller/JwtAuthenticationController.java index 8bb6518..0cb758b 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/controller/JwtAuthenticationController.java +++ b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/controller/JwtAuthenticationController.java @@ -1,32 +1,8 @@ package com.palnet.biz.api.acnt.jwt.controller; -import java.util.HashMap; -import java.util.Map; - -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestAttribute; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - import com.palnet.biz.api.acnt.jwt.model.JwtProfileRsModel; import com.palnet.biz.api.acnt.jwt.model.JwtRqModel; import com.palnet.biz.api.acnt.jwt.model.JwtRsModel; -import com.palnet.biz.api.acnt.jwt.model.JwtUserModel; import com.palnet.biz.api.acnt.jwt.service.JwtService; import com.palnet.biz.api.acnt.jwt.service.JwtUserDetailsService; import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil; @@ -35,10 +11,18 @@ import com.palnet.biz.api.comn.response.ErrorResponse; import com.palnet.biz.api.comn.response.SuccessResponse; import com.palnet.biz.jpa.entity.PtyCstmrBas; import com.palnet.comn.code.RSErrorCode; -import com.palnet.comn.utils.EncryptUtils; - +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; @RestController @RequiredArgsConstructor diff --git a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtRsModel.java b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtRsModel.java index cab0aa4..b7319b4 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtRsModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtRsModel.java @@ -13,7 +13,8 @@ public class JwtRsModel implements Serializable { private String refreshToken; private String userId; - + private String userNm; + private Integer cstmrSno; private String auth; diff --git a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtUserModel.java b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtUserModel.java index 570b4fd..03ca37f 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtUserModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/model/JwtUserModel.java @@ -36,6 +36,8 @@ public class JwtUserModel implements UserDetails { @Column(name = "CSTMR_STATUS_CD") private String cstmrStatusCd; + @Transient + private String userNm; @Transient private List group; diff --git a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/service/JwtService.java b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/service/JwtService.java index dbd6501..0349b1a 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/service/JwtService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/service/JwtService.java @@ -113,6 +113,7 @@ public class JwtService { result.setRefreshToken(refreshToken); result.setAuth(userDetails.getAuth()); result.setUserId(userDetails.getUserId()); + result.setUserNm(userDetails.getUserNm()); result.setCstmrSno(userDetails.getCstmrSno()); ptyCstmrDtlRepository.findById(userDetails.getCstmrSno()).ifPresent(ptyCstmrDtl -> { diff --git a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/utils/JwtTokenUtil.java b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/utils/JwtTokenUtil.java index 68cbba6..141fd07 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/utils/JwtTokenUtil.java +++ b/pav-server/src/main/java/com/palnet/biz/api/acnt/jwt/utils/JwtTokenUtil.java @@ -14,7 +14,6 @@ import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.io.Serializable; -import java.time.Instant; import java.util.*; import java.util.function.Function; @@ -25,9 +24,9 @@ public class JwtTokenUtil implements Serializable { private static final long serialVersionUID = -2550185165626007488L; public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60; // 5시간 -// public static final long JWT_TOKEN_VALIDITY = 10; // 10초 - public static final long JWT_REFRESH_TOKEN_VALIDTY = 21* 24 * 60 * 60; //21일 - + // public static final long JWT_TOKEN_VALIDITY = 10; // 10초 + public static final long JWT_REFRESH_TOKEN_VALIDTY = 21 * 24 * 60 * 60; //21일 + @Value("${spring.jwt.secret}") private String secret; @@ -50,6 +49,7 @@ public class JwtTokenUtil implements Serializable { final Claims claims = getAllClaimsFromToken(token); return claimsResolver.apply(claims); } + //for retrieveing any information from token we will need the secret key private Claims getAllClaimsFromToken(String token) { return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); @@ -71,17 +71,18 @@ public class JwtTokenUtil implements Serializable { claims.put("cstmrSno", userDetails.getCstmrSno()); claims.put("auth", userDetails.getAuth()); claims.put("group", userDetails.getGroup()); + claims.put("userNm", userDetails.getUserNm()); return doGenerateToken(claims, userDetails.getUsername()); } - - + + public String generateRefreshToken(JwtUserModel userDetails) { - Map claims = new HashMap<>(); - claims.put("userId", userDetails.getUserId()); - claims.put("cstmrSno", userDetails.getCstmrSno()); - return doGenerateRefreshToken(claims, userDetails.getUsername()); + Map claims = new HashMap<>(); + claims.put("userId", userDetails.getUserId()); + claims.put("cstmrSno", userDetails.getCstmrSno()); + return doGenerateRefreshToken(claims, userDetails.getUsername()); } - + //while creating the token - //1. Define claims of the token, like Issuer, Expiration, Subject, and the ID @@ -94,11 +95,11 @@ public class JwtTokenUtil implements Serializable { .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000)) .signWith(SignatureAlgorithm.HS512, secret).compact(); } - - private String doGenerateRefreshToken(Map claims , String subject) { - return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())) - .setExpiration(new Date(System.currentTimeMillis() + JWT_REFRESH_TOKEN_VALIDTY * 1000)) - .signWith(SignatureAlgorithm.HS512, secret).compact(); + + private String doGenerateRefreshToken(Map claims, String subject) { + return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + JWT_REFRESH_TOKEN_VALIDTY * 1000)) + .signWith(SignatureAlgorithm.HS512, secret).compact(); } //validate token @@ -111,22 +112,34 @@ public class JwtTokenUtil implements Serializable { HttpServletRequest rq = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = rq.getHeader("Authorization"); - if(token == null || "".equals(token)) return null; + if (token == null || "".equals(token)) return null; token = token.substring(JWT_PREFIX.length()).trim(); String userId = getUsernameFromToken(token); return userId; } + + public String getUserNmByToken() { + HttpServletRequest rq = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String token = rq.getHeader("Authorization"); + + if (token == null || "".equals(token)) return null; + + token = token.substring(JWT_PREFIX.length()).trim(); + Claims payload = getAllClaimsFromToken(token); + return payload.get("userNm", String.class); + } + public Integer getCstmrSnoByToken() { HttpServletRequest rq = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = rq.getHeader("Authorization"); - if(token == null || "".equals(token)) return null; + if (token == null || "".equals(token)) return null; token = token.substring(JWT_PREFIX.length()).trim(); Claims payload = getAllClaimsFromToken(token); - Integer cstmrSno = payload.get("cstmrSno",Integer.class); + Integer cstmrSno = payload.get("cstmrSno", Integer.class); return cstmrSno; } @@ -135,20 +148,20 @@ public class JwtTokenUtil implements Serializable { HttpServletRequest rq = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = rq.getHeader("Authorization"); - if(token == null || "".equals(token)) return null; + if (token == null || "".equals(token)) return null; token = token.substring(JWT_PREFIX.length()).trim(); Claims payload = getAllClaimsFromToken(token); List groupList = payload.get("group", ArrayList.class); List r = new ArrayList<>(); - - if(groupList!=null) { - for(LinkedHashMap map : groupList){ - JwtGroupModel model = new JwtGroupModel(); - model.setGroupId(map.get("groupId")); - model.setGroupAuthCd(map.get("groupAuthCd")); - r.add(model); - } + + if (groupList != null) { + for (LinkedHashMap map : groupList) { + JwtGroupModel model = new JwtGroupModel(); + model.setGroupId(map.get("groupId")); + model.setGroupAuthCd(map.get("groupAuthCd")); + r.add(model); + } } return r; } @@ -157,7 +170,7 @@ public class JwtTokenUtil implements Serializable { HttpServletRequest rq = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = rq.getHeader("Authorization"); - if(token == null || "".equals(token)) return null; + if (token == null || "".equals(token)) return null; token = token.substring(JWT_PREFIX.length()).trim(); Claims payload = getAllClaimsFromToken(token); diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasDronModel.java b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasDronModel.java index 29e4572..7a7df0a 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasDronModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasDronModel.java @@ -1,12 +1,11 @@ package com.palnet.biz.api.bas.dron.model; -import java.time.Instant; -import java.util.Date; - import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.palnet.biz.config.convert.InstantDateStrSerializer; import lombok.Data; +import java.time.Instant; + @Data public class BasDronModel { diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasIdntfModel.java b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasIdntfModel.java index dd0a8af..fa542f3 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasIdntfModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasIdntfModel.java @@ -1,10 +1,9 @@ package com.palnet.biz.api.bas.dron.model; -import java.time.Instant; -import java.util.Date; - import lombok.Data; +import java.time.Instant; + @Data public class BasIdntfModel { diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasOwnerModel.java b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasOwnerModel.java index c6a4a5c..4ed839b 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasOwnerModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/dron/model/BasOwnerModel.java @@ -1,10 +1,9 @@ package com.palnet.biz.api.bas.dron.model; -import java.time.Instant; -import java.util.Date; - import lombok.Data; +import java.time.Instant; + @Data public class BasOwnerModel { diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/group/model/BasGroupModel.java b/pav-server/src/main/java/com/palnet/biz/api/bas/group/model/BasGroupModel.java index 21acd19..0db22af 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/group/model/BasGroupModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/group/model/BasGroupModel.java @@ -1,10 +1,9 @@ package com.palnet.biz.api.bas.group.model; -import java.time.Instant; -import java.util.Date; - import lombok.Data; +import java.time.Instant; + @Data public class BasGroupModel { diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java index 0a89299..8f00c29 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java @@ -1,13 +1,12 @@ package com.palnet.biz.api.cns.qna.controller; -import com.palnet.biz.api.cns.qna.model.QnaBasModel; -import com.palnet.biz.api.cns.qna.model.QnaDetailRSModel; -import com.palnet.biz.api.cns.qna.model.QnaInsertRQModel; -import com.palnet.biz.api.cns.qna.model.QnaSelectListRQ; +import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil; +import com.palnet.biz.api.cns.qna.model.*; import com.palnet.biz.api.cns.qna.service.CnsQnaService; import com.palnet.biz.api.comn.response.BasicResponse; import com.palnet.biz.api.comn.response.ErrorResponse; import com.palnet.biz.api.comn.response.SuccessResponse; +import com.palnet.comn.code.RSErrorCode; import com.palnet.comn.exception.CustomException; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -17,6 +16,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.naming.AuthenticationException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -30,13 +30,13 @@ import java.util.Map; public class CnsQnaController { private final CnsQnaService cnsQnaService; - - - // TODO json 가능 여부 + private final JwtTokenUtil jwtTokenUtil; + + @PostMapping(consumes = "multipart/form-data") @Tag(name = "QNA", description = "QNA 관련 API") - @ApiOperation(value = "QnA 등록[답변추가]") - public ResponseEntity insertQna(QnaInsertRQModel rq){ + @ApiOperation(value = "QnA 등록 - 사용자") + public ResponseEntity insertQna(QnaInsertRQModel rq) { boolean result = false; try { result = cnsQnaService.insertQna(rq); @@ -59,7 +59,7 @@ public class CnsQnaController { @GetMapping @Tag(name = "QNA", description = "QNA 관련 API") @ApiOperation(value = "QnA 리스트 조회") - public ResponseEntity selectQna(QnaSelectListRQ rq){ + public ResponseEntity selectQna(QnaSelectListRQ rq) { List result = new ArrayList<>(); try { @@ -84,8 +84,8 @@ public class CnsQnaController { @GetMapping("/{qnaSno}") @Tag(name = "QNA", description = "QNA 관련 API") @ApiOperation(value = "QnA 상세보기") - public ResponseEntity detailQna(@PathVariable int qnaSno){ - List result = null; + public ResponseEntity detailQna(@PathVariable int qnaSno) { + QnaDetailRSModel result = null; try { result = cnsQnaService.getQnaDetail(qnaSno); } catch (CustomException e) { @@ -106,8 +106,8 @@ public class CnsQnaController { @PutMapping @Tag(name = "QNA", description = "QNA 관련 API") - @ApiOperation(value = "QnA 업데이트") - public ResponseEntity updateQna(QnaInsertRQModel rq){ + @ApiOperation(value = "QnA 수정 - 사용자") + public ResponseEntity updateQna(QnaInsertRQModel rq) { boolean result = false; try { result = cnsQnaService.updateQna(rq); @@ -130,8 +130,8 @@ public class CnsQnaController { @DeleteMapping("/{qnaSno}") @Tag(name = "QNA", description = "QNA 관련 API") @ApiOperation(value = "QnA 삭제하기") - public ResponseEntity deleteQna(@PathVariable int qnaSno){ - + public ResponseEntity deleteQna(@PathVariable int qnaSno) { + // TODO 관리자만 삭제 가능 여부인지 확인 필요 boolean result = false; try { result = cnsQnaService.deleteQna(qnaSno); @@ -151,21 +151,19 @@ public class CnsQnaController { return ResponseEntity.ok().body(new SuccessResponse<>(result)); } - /** - * Qna Files 개별삭제 TODO:: 파일 업데이트의 기획이 어떻게 되는지 모름 - * @param qnaSno - * @param fileSno - * @return - */ - @DeleteMapping("/file/{qnaSno}/{fileSno}") + @PutMapping("/answer") @Tag(name = "QNA", description = "QNA 관련 API") - @ApiOperation(value = "QnA 파일 개별삭제") - public ResponseEntity deleteQnaFile(@PathVariable int qnaSno, @PathVariable int fileSno){ - log.warn("CnsQnaController - deleteQnaFile()"); - + @ApiOperation(value = "QnA 답변 등록 - 관리자") + public ResponseEntity insertAnswer(@RequestBody QnaInsertAnserRQModel rq) { + // TODO 추후 auth -> role 체크로 변경 boolean result = false; try { - result = cnsQnaService.deleteQnaFile(fileSno); + String userAuthByToken = jwtTokenUtil.getUserAuthByToken(); + if (!"SUPER".equals(userAuthByToken)) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ErrorResponse(RSErrorCode.AUTH_ERROR)); + } + + result = cnsQnaService.insertAnswer(rq); } catch (CustomException e) { Map resultMap = new HashMap<>(); log.error("IGNORE : ", e); @@ -180,6 +178,6 @@ public class CnsQnaController { } return ResponseEntity.ok().body(new SuccessResponse<>(result)); - } + } diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaBasModel.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaBasModel.java index 945df59..1f180c6 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaBasModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaBasModel.java @@ -1,9 +1,9 @@ package com.palnet.biz.api.cns.qna.model; -import java.time.Instant; - import lombok.Data; +import java.time.Instant; + @Data public class QnaBasModel { @@ -15,7 +15,15 @@ public class QnaBasModel { private String title; - private String content; + private String content; + + private String anserContent; + + private String anserUserNm; + + private Instant anserProcDt; + + private String anserStatus; private int fileGroupNo; diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaDetailRSModel.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaDetailRSModel.java index c86bf5c..17a36ec 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaDetailRSModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaDetailRSModel.java @@ -3,6 +3,7 @@ package com.palnet.biz.api.cns.qna.model; import java.time.Instant; import java.util.List; +import com.palnet.biz.api.comn.file.model.ComnFileModel; import com.palnet.biz.jpa.entity.ComFileBas; import lombok.Data; @@ -30,5 +31,5 @@ public class QnaDetailRSModel { private Instant updateDt; - private List files; + private List files; } diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertAnserRQModel.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertAnserRQModel.java new file mode 100644 index 0000000..d7440d6 --- /dev/null +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertAnserRQModel.java @@ -0,0 +1,17 @@ +package com.palnet.biz.api.cns.qna.model; + +import lombok.Data; + +@Data +public class QnaInsertAnserRQModel { + + private Integer qnaSno; + + // private Integer targetSno; // 상위 Qna 번호 + + private String anserContent; +// private String anserUserNm; +// private Instant anserProcDt; + private String anserStatus; + +} diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertRQModel.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertRQModel.java index a07315d..813227b 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertRQModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaInsertRQModel.java @@ -2,6 +2,7 @@ package com.palnet.biz.api.cns.qna.model; import java.util.List; +import com.palnet.biz.api.comn.file.model.ComnFileModel; import org.springframework.web.multipart.MultipartFile; import lombok.Data; @@ -19,5 +20,7 @@ public class QnaInsertRQModel { private String content; + private List fileInfos; + private List files; } diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaSelectListRQ.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaSelectListRQ.java index ccd1b76..dd267b7 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaSelectListRQ.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/model/QnaSelectListRQ.java @@ -5,7 +5,8 @@ import lombok.Data; @Data public class QnaSelectListRQ { + private String searchType; private String word; - private String category; + } diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaMapper.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaMapper.java new file mode 100644 index 0000000..0926eb2 --- /dev/null +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaMapper.java @@ -0,0 +1,34 @@ +package com.palnet.biz.api.cns.qna.service; + +import com.palnet.biz.api.cns.qna.model.QnaDetailRSModel; +import com.palnet.biz.api.cns.qna.model.QnaInsertAnserRQModel; +import com.palnet.biz.api.cns.qna.model.QnaInsertRQModel; +import com.palnet.biz.jpa.entity.CnsQnaBas; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * packageName : com.palnet.biz.api.cns.qna.service + * fileName : CnsQnaMapper + * author : dhji + * date : 2023-10-17(017) + * description : + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2023-10-17(017) dhji 최초 생성 + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface CnsQnaMapper { + CnsQnaMapper MAPPER = Mappers.getMapper(CnsQnaMapper.class); + + CnsQnaBas toEntity(QnaInsertRQModel rq); + + QnaDetailRSModel toModel(CnsQnaBas qnaBasModel); + + void merge(@MappingTarget CnsQnaBas entity, QnaInsertRQModel rq); + void merge(@MappingTarget CnsQnaBas entity, QnaInsertAnserRQModel rq); +} diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java index 0d1de3c..9a668c8 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java @@ -1,115 +1,90 @@ package com.palnet.biz.api.cns.qna.service; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; - -import javax.transaction.Transactional; - -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil; -import com.palnet.biz.api.cns.qna.model.QnaBasModel; -import com.palnet.biz.api.cns.qna.model.QnaDetailRSModel; -import com.palnet.biz.api.cns.qna.model.QnaInsertRQModel; -import com.palnet.biz.api.cns.qna.model.QnaSelectListRQ; +import com.palnet.biz.api.cns.qna.model.*; +import com.palnet.biz.api.comn.file.model.ComnFileModel; import com.palnet.biz.api.comn.file.service.ComnFileService; import com.palnet.biz.jpa.entity.CnsQnaBas; -import com.palnet.biz.jpa.entity.ComFileBas; import com.palnet.biz.jpa.repository.cns.CnsQnaBasRepository; import com.palnet.biz.jpa.repository.cns.CnsQnaQueryRepository; -import com.palnet.biz.jpa.repository.com.ComFileBasRepository; import com.palnet.comn.code.ErrorCode; import com.palnet.comn.exception.CustomException; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.transaction.Transactional; +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor -public class CnsQnaService { - +public class CnsQnaService { + private final CnsQnaBasRepository cnsQnaBasRepository; private final CnsQnaQueryRepository cnsQnaQueryRepository; - private final ComFileBasRepository comFileBasRepository; - private final ComnFileService comnFileService; private final JwtTokenUtil jwtTokenUtil; - - public boolean deleteQnaFile(int fileSno){ - - comnFileService.deleteFile(fileSno); - - return true; - } - /** * Qna 삭제하기, file들도 모두 논리삭제함. + * * @param qnaSno * @return */ @Transactional - public boolean deleteQna(int qnaSno){ + public boolean deleteQna(int qnaSno) { CnsQnaBas entity = cnsQnaBasRepository.findByQnaSnoAndDelYnAndExpsrYn(qnaSno, "N", "Y"); - if(entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); - - if(entity.getFileGroupNo() != null) comnFileService.deleteFiles(entity.getFileGroupNo()); - - entity.setDelYn("Y"); - - List deleteList = new ArrayList<>(); - deleteList.add(entity); + if (entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); - int targetSno = qnaSno; + if (entity.getFileGroupNo() != null) comnFileService.deleteFilesByFileGroupNo(entity.getFileGroupNo()); - // 대댓글 불러오기 - while(true){ - - CnsQnaBas cnsQnaBas = cnsQnaBasRepository.findFirstByTargetSnoAndDelYnAndExpsrYn(targetSno, "N", "Y"); - if(cnsQnaBas == null) break; - - cnsQnaBas.setDelYn("Y"); - - deleteList.add(cnsQnaBas); - - targetSno = cnsQnaBas.getQnaSno(); - } + entity.setDelYn("Y"); - deleteList = cnsQnaBasRepository.saveAll(deleteList); + cnsQnaBasRepository.save(entity); return true; } /** * Qna 업데이트하기 TODO :: File 업데이트 기능 아직 구현안함 + * * @param rq * @return */ @Transactional - public boolean updateQna(QnaInsertRQModel rq){ + public boolean updateQna(QnaInsertRQModel rq) { CnsQnaBas entity = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(rq.getQnaSno(), 0, "N", "Y"); - if(entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); - + if (entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); + + // 파일 삭제(논리적 삭제) + List prevFileInfos = comnFileService.getNormalFileListByGroupNo(entity.getFileGroupNo()); + List prevFileSnoList = prevFileInfos.stream().map(ComnFileModel::getFileSno).collect(Collectors.toList()); + List currentFileSnoList = rq.getFileInfos().stream().map(ComnFileModel::getFileSno).collect(Collectors.toList()); + boolean isChange = prevFileSnoList.removeAll(currentFileSnoList); + if (isChange) comnFileService.deleteFilesByFileGroupNo(entity.getFileGroupNo()); // File 삭제 + List files = rq.getFiles(); - if(files != null && files.size() > 0) comnFileService.fileUpload(files, entity.getFileGroupNo()); // File 업로드 + if (files != null && !files.isEmpty()) comnFileService.fileUpload(files, entity.getFileGroupNo()); // File 업로드 - if(rq.getCategory() != null) entity.setCategory(rq.getCategory()); - if(rq.getContent() != null) entity.setContent(rq.getContent()); - if(rq.getTitle() != null) entity.setTitle(rq.getTitle()); +// if(rq.getCategory() != null) entity.setCategory(rq.getCategory()); +// if(rq.getContent() != null) entity.setContent(rq.getContent()); +// if(rq.getTitle() != null) entity.setTitle(rq.getTitle()); + + CnsQnaMapper.MAPPER.merge(entity, rq); String userId = jwtTokenUtil.getUserIdByToken(); - + if (userId == null) userId = "NONE"; - entity.setUpdateDt(Instant.now()); entity.setUpdateUserId(userId); cnsQnaBasRepository.save(entity); @@ -119,104 +94,82 @@ public class CnsQnaService { /** * Qna 상세불러오기 + * * @param qnaSno * @return */ @Transactional // 조회수 증가하기떄문 - public List getQnaDetail(int qnaSno){ + public QnaDetailRSModel getQnaDetail(int qnaSno) { cnsQnaBasRepository.pulsViewCount(qnaSno); CnsQnaBas qnaBasModel = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(qnaSno, 0, "N", "Y"); - List files = null; - if(qnaBasModel.getFileGroupNo() != 0) files = comFileBasRepository.findByFileGroupNoAndDelYn(qnaBasModel.getFileGroupNo(), "N"); - - QnaDetailRSModel node = new QnaDetailRSModel(); - node.setQnaSno(qnaSno); - node.setTargetSno(qnaBasModel.getTargetSno()); - node.setCategory(qnaBasModel.getCategory()); - node.setTitle(qnaBasModel.getTitle()); - node.setContent(qnaBasModel.getContent()); - node.setViewCnt(qnaBasModel.getViewCnt()); - node.setCreateUserId(qnaBasModel.getCreateUserId()); - node.setCreateDt(qnaBasModel.getCreateDt()); - node.setUpdateUserId(qnaBasModel.getUpdateUserId()); - node.setUpdateDt(qnaBasModel.getUpdateDt()); - node.setFiles(files); - - List result = new ArrayList<>(); - result.add(node); - - int targetSno = qnaSno; - - // 대댓글 불러오기 - while(true){ - - CnsQnaBas cnsQnaBas = cnsQnaBasRepository.findFirstByTargetSnoAndDelYnAndExpsrYn(targetSno, "N", "Y"); - if(cnsQnaBas == null) break; - - QnaDetailRSModel detailNode = new QnaDetailRSModel(); - detailNode.setQnaSno(cnsQnaBas.getQnaSno()); - detailNode.setTargetSno(cnsQnaBas.getTargetSno()); - detailNode.setCategory(cnsQnaBas.getCategory()); - detailNode.setTitle(cnsQnaBas.getTitle()); - detailNode.setContent(cnsQnaBas.getContent()); - detailNode.setCreateUserId(cnsQnaBas.getCreateUserId()); - detailNode.setCreateDt(cnsQnaBas.getCreateDt()); - detailNode.setUpdateUserId(cnsQnaBas.getUpdateUserId()); - detailNode.setUpdateDt(cnsQnaBas.getUpdateDt()); - - result.add(detailNode); - - targetSno = cnsQnaBas.getQnaSno(); - } - - return result; - } + List files = null; + if (qnaBasModel.getFileGroupNo() != null && qnaBasModel.getFileGroupNo() != 0) + files = comnFileService.getNormalFileListByGroupNo(qnaBasModel.getFileGroupNo()); + + QnaDetailRSModel model = CnsQnaMapper.MAPPER.toModel(qnaBasModel); + model.setFiles(files); + + + return model; + } /** * Qna리스트 조회 + * * @param rq * @return */ - public List selectQnaList(QnaSelectListRQ rq){ - - return cnsQnaQueryRepository.getQnaList(rq.getCategory(), rq.getCategory()); + public List selectQnaList(QnaSelectListRQ rq) { + return cnsQnaQueryRepository.getQnaList(rq); } /** * QnaInsert + * * @param rq * @return */ @Transactional - public boolean insertQna(QnaInsertRQModel rq){ + public boolean insertQna(QnaInsertRQModel rq) { List files = rq.getFiles(); Integer fileGroupNo = null; - if(files != null && files.size() > 0) fileGroupNo = comnFileService.fileUpload(files, null); // File 업로드 + if (files != null && files.size() > 0) fileGroupNo = comnFileService.fileUpload(files, null); // File 업로드 String userId = jwtTokenUtil.getUserIdByToken(); - + if (userId == null) userId = "NONE"; - - CnsQnaBas cnsQnaBas = new CnsQnaBas(); - cnsQnaBas.setCategory(rq.getCategory()); - cnsQnaBas.setTitle(rq.getTitle()); - cnsQnaBas.setContent(rq.getContent()); - cnsQnaBas.setCreateDt(Instant.now()); + + CnsQnaBas cnsQnaBas = CnsQnaMapper.MAPPER.toEntity(rq); cnsQnaBas.setCreateUserId(userId); - cnsQnaBas.setUpdateDt(Instant.now()); cnsQnaBas.setUpdateUserId(userId); cnsQnaBas.setExpsrYn("Y"); - - if(fileGroupNo != null) cnsQnaBas.setFileGroupNo(fileGroupNo); - if(rq.getTargetSno() != null) cnsQnaBas.setTargetSno(rq.getTargetSno()); + cnsQnaBas.setDelYn("N"); + cnsQnaBas.setViewCnt(0); + + if (fileGroupNo != null) cnsQnaBas.setFileGroupNo(fileGroupNo); cnsQnaBasRepository.save(cnsQnaBas); return true; } - + + public boolean insertAnswer(QnaInsertAnserRQModel rq) { + CnsQnaBas entity = cnsQnaBasRepository.findByQnaSnoAndDelYnAndExpsrYn(rq.getQnaSno(), "N", "Y"); + if (entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); + + String userId = jwtTokenUtil.getUserIdByToken(); + String userNm = jwtTokenUtil.getUserNmByToken(); + + CnsQnaMapper.MAPPER.merge(entity, rq); + entity.setCreateUserId(userId); + entity.setAnserUserNm(userNm); + entity.setAnserProcDt(Instant.now()); + + cnsQnaBasRepository.save(entity); + return true; + } } diff --git a/pav-server/src/main/java/com/palnet/biz/api/comn/file/controller/ComnFileController.java b/pav-server/src/main/java/com/palnet/biz/api/comn/file/controller/ComnFileController.java index 0407111..5bc204f 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/comn/file/controller/ComnFileController.java +++ b/pav-server/src/main/java/com/palnet/biz/api/comn/file/controller/ComnFileController.java @@ -4,6 +4,7 @@ import com.palnet.biz.api.comn.file.service.ComnFileService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -26,6 +27,7 @@ public class ComnFileController { private final ComnFileService comnFileService; + @Deprecated @GetMapping("/download") public void downloadPDF(int fileSno) { try { @@ -34,4 +36,13 @@ public class ComnFileController { log.error("ERROR: ", e); } } + + @GetMapping("/download/{fileSno}") + public void download(@PathVariable("fileSno") int fileSno) { + try { + comnFileService.fileDownload(fileSno); + } catch (Exception e) { + log.error("ERROR: ", e); + } + } } diff --git a/pav-server/src/main/java/com/palnet/biz/api/comn/file/model/ComnFileModel.java b/pav-server/src/main/java/com/palnet/biz/api/comn/file/model/ComnFileModel.java new file mode 100644 index 0000000..95c842b --- /dev/null +++ b/pav-server/src/main/java/com/palnet/biz/api/comn/file/model/ComnFileModel.java @@ -0,0 +1,27 @@ +package com.palnet.biz.api.comn.file.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * packageName : com.palnet.biz.api.comn.file.model + * fileName : ComnFileModel + * author : dhji + * date : 2023-10-17(017) + * description : + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2023-10-17(017) dhji 최초 생성 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ComnFileModel { + private Integer fileSno; + private String downloadUrl; + private String fileName; +} diff --git a/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileMapper.java b/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileMapper.java new file mode 100644 index 0000000..94a2f3c --- /dev/null +++ b/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileMapper.java @@ -0,0 +1,23 @@ +package com.palnet.biz.api.comn.file.service; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * packageName : com.palnet.biz.api.comn.file.service + * fileName : ComnFileMapper + * author : dhji + * date : 2023-10-17(017) + * description : + * =========================================================== + * DATE AUTHOR NOTE + * ----------------------------------------------------------- + * 2023-10-17(017) dhji 최초 생성 + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public class ComnFileMapper { + ComnFileMapper MAPPER = Mappers.getMapper(ComnFileMapper.class); + +} diff --git a/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileService.java b/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileService.java index 3184499..6136dcc 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/comn/file/service/ComnFileService.java @@ -19,6 +19,7 @@ import java.util.Objects; import javax.servlet.http.HttpServletResponse; import javax.transaction.Transactional; +import com.palnet.biz.api.comn.file.model.ComnFileModel; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; @@ -45,13 +46,13 @@ public class ComnFileService { private final PdfUtils pdfUtils; private final JwtTokenUtil jwtTokenUtil; - private final ComFileBasRepository comFileBasRepository; + private final ComFileBasRepository comFileBasRepository; private final HttpServletResponse response; @Value("${base-url}") private String BASE_PATH; - + private final String DOWNLOAD_URL = "/api/comn/file/download"; private final String NORMAL_FORDER_PATH = "normal/"; /** @@ -127,16 +128,17 @@ public class ComnFileService { comFileBas.setFileGroupNo(fileGroupNo); return comFileBasRepository.save(comFileBas); - } + } /** * 다건 DB 인서트, 최신데이터 가져온 후 Group NO 1추가함 + * * @param comFileBas * @return */ - public List saveAll(List comFileBas, Integer fileGroupNo){ + public List saveAll(List comFileBas, Integer fileGroupNo) { - for(ComFileBas fileBas : comFileBas){ + for (ComFileBas fileBas : comFileBas) { fileBas.setFileGroupNo(fileGroupNo); } @@ -200,32 +202,32 @@ public class ComnFileService { } - public Integer fileUpload(List files, Integer fileGroupNo){ + public Integer fileUpload(List files, Integer fileGroupNo) { - if(!this.validCheck(files)) throw new CustomException(ErrorCode.NON_VALID_PARAMETER); + if (!this.validCheck(files)) throw new CustomException(ErrorCode.NON_VALID_PARAMETER); - if(fileGroupNo == null || fileGroupNo == 0) fileGroupNo = lastFileGroupNo(); + if (fileGroupNo == null || fileGroupNo == 0) fileGroupNo = lastFileGroupNo(); // TODO : 절대경로 - String absPath = "/Users/igyeongdo/WokrSpace/"; +// String absPath = "/Users/igyeongdo/WokrSpace/"; String fileUrl = new StringBuilder() - .append(absPath) - .append(this.BASE_PATH) - .append(this.NORMAL_FORDER_PATH) - .append(InstantUtils.toDateStringByFormat(Instant.now(), "yyyyMMdd")) - .append("/") - .toString(); - +// .append(absPath) + .append(this.BASE_PATH) + .append(this.NORMAL_FORDER_PATH) + .append(InstantUtils.toDateStringByFormat(Instant.now(), "yyyyMMdd")) + .append("/") + .toString(); + List comFileBas = new ArrayList<>(); - for(MultipartFile file : files){ - String oriNm = file.getOriginalFilename(); - String extension = oriNm.substring(oriNm.lastIndexOf(".")); + for (MultipartFile file : files) { + String oriNm = file.getOriginalFilename(); + String extension = oriNm.substring(oriNm.lastIndexOf(".")); String etc = String.valueOf(System.currentTimeMillis()); // 동명이인 방지 String fileName = this.getLaancSaveName(ExtensionConstant.fromExtension(extension), fileGroupNo.toString(), "qna", etc); - try { + try { Path directoryPath = Paths.get(fileUrl); if (!Files.exists(directoryPath)) { Files.createDirectories(directoryPath); @@ -251,35 +253,36 @@ public class ComnFileService { node.setFileOriNm(oriNm); node.setFileSize(String.valueOf(fileSize)); - comFileBas.add(node); + comFileBas.add(node); } catch (IOException e) { e.printStackTrace(); - } + } } - - this.saveAll(comFileBas, fileGroupNo); + + this.saveAll(comFileBas, fileGroupNo); return fileGroupNo; } /** - * 정해진 확장자만 올 수 있도록 validation처리, + * 정해진 확장자만 올 수 있도록 validation처리, * TODO :: 혹시 mime 타입으로 확인하여 처리해야 할까요? + * * @param files * @return */ - private boolean validCheck(List files){ + private boolean validCheck(List files) { - for(MultipartFile file : files){ + for (MultipartFile file : files) { - try { + try { String oriNm = file.getOriginalFilename(); String extension = oriNm.substring(oriNm.lastIndexOf(".")); - + ExtensionConstant constants = ExtensionConstant.fromExtension(extension); // 허락된 확장자가 아닐 경우 return false - if(constants == null) return false; + if (constants == null) return false; } catch (Exception e) { @@ -303,7 +306,7 @@ public class ComnFileService { ext = path.substring(lastIndex + 1); } - try (InputStream is = resource.getInputStream();){ + try (InputStream is = resource.getInputStream();) { byte[] imageBytes = IOUtils.toByteArray(is); String encodedString = java.util.Base64.getEncoder().encodeToString(imageBytes); str @@ -316,12 +319,13 @@ public class ComnFileService { } return str.toString(); } - + /** * 마지막 fileGroupNo 가져와 +1 후 반환 + * * @return */ - private Integer lastFileGroupNo(){ + private Integer lastFileGroupNo() { ComFileBas lastComFileBas = comFileBasRepository.findFirstByOrderByFileGroupNoDesc(); int fileGroupNo = (lastComFileBas == null) ? 1 : lastComFileBas.getFileGroupNo() + 1; @@ -329,34 +333,53 @@ public class ComnFileService { } @Transactional - public boolean deleteFiles(int fileGroupNo){ + public boolean deleteFilesByFileGroupNo(int fileGroupNo) { List files = comFileBasRepository.findByFileGroupNoAndDelYn(fileGroupNo, "N"); String userId = jwtTokenUtil.getUserIdByToken(); - + + if (userId == null) userId = "NONE"; + + for (ComFileBas file : files) { + file.setDelYn("Y"); + file.setDelUserId(userId); + file.setDelDt(Instant.now()); + } + + comFileBasRepository.saveAll(files); + + return true; + } + @Transactional + public boolean deleteFiles(List fileSnoList){ + + List files = comFileBasRepository.findByFileSnoInAndDelYn(fileSnoList, "N"); + + String userId = jwtTokenUtil.getUserIdByToken(); + if (userId == null) userId = "NONE"; - - for(ComFileBas file : files){ + + for (ComFileBas file : files) { file.setDelYn("Y"); file.setDelUserId(userId); file.setDelDt(Instant.now()); } - + comFileBasRepository.saveAll(files); return true; } @Transactional - public boolean deleteFile(int fileSno){ + public boolean deleteFile(int fileSno) { ComFileBas file = comFileBasRepository.findByFileSnoAndDelYn(fileSno, "N"); String userId = jwtTokenUtil.getUserIdByToken(); - - if (userId == null) userId = "NONE"; - + + if (userId == null) userId = "NONE"; + file.setDelYn("Y"); file.setDelUserId(userId); file.setDelDt(Instant.now()); @@ -366,4 +389,18 @@ public class ComnFileService { return true; } + public List getNormalFileListByGroupNo(Integer fileGroupNo) { + List files = comFileBasRepository.findByFileGroupNoAndDelYn(fileGroupNo, "N"); + List result = new ArrayList<>(); + for (ComFileBas file : files) { + result.add(ComnFileModel.builder() + .fileSno(file.getFileSno()) + .fileName(file.getFileOriNm()) + .downloadUrl(DOWNLOAD_URL + "/" + file.getFileSno()) + .build()); + } + + return result; + + } } diff --git a/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlArcrftWarnModel.java b/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlArcrftWarnModel.java index 0e76183..6bf3603 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlArcrftWarnModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlArcrftWarnModel.java @@ -3,7 +3,6 @@ package com.palnet.biz.api.ctr.cntrl.model; import lombok.Data; import java.time.Instant; -import java.util.Date; @Data public class CtrCntrlArcrftWarnModel { diff --git a/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlWarnLogModel.java b/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlWarnLogModel.java index 01baa65..e0ae82f 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlWarnLogModel.java +++ b/pav-server/src/main/java/com/palnet/biz/api/ctr/cntrl/model/CtrCntrlWarnLogModel.java @@ -3,10 +3,6 @@ package com.palnet.biz.api.ctr.cntrl.model; import lombok.Data; import java.time.Instant; -import java.util.Date; -import java.util.List; - -import com.palnet.biz.jpa.entity.CtrCntrlWarnLog; @Data public class CtrCntrlWarnLogModel { diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/entity/CnsQnaBas.java b/pav-server/src/main/java/com/palnet/biz/jpa/entity/CnsQnaBas.java index 1bca204..3f88fe3 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/entity/CnsQnaBas.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/entity/CnsQnaBas.java @@ -10,53 +10,66 @@ import java.time.Instant; @Entity @Data -@Table(name="CNS_QNA_BAS") -@NamedQuery(name="CnsQnaBas.findAll", query="SELECT c FROM CnsQnaBas c") +@Table(name = "CNS_QNA_BAS") +@NamedQuery(name = "CnsQnaBas.findAll", query = "SELECT c FROM CnsQnaBas c") public class CnsQnaBas implements Serializable { private static final long serialVersionUID = 1L; - + @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="QNA_SNO") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "QNA_SNO") private int qnaSno; - @Column(name="TARGET_SNO") + // 안쓸거 같음 + @Column(name = "TARGET_SNO") private int targetSno; - @Column(name="CATEGORY") + @Column(name = "CATEGORY") private String category; - @Column(name="TITLE") + @Column(name = "TITLE") private String title; - @Column(name="CONTENT") + @Column(name = "CONTENT") private String content; - @Column(name="FILE_GROUP_NO") + @Column(name = "ANSER_CONTENT") + private String anserContent; + + @Column(name = "ANSER_USER_NM") + private String anserUserNm; + + @Column(name = "ANSER_PROC_DT", columnDefinition = "TIMESTAMP") + private Instant anserProcDt; + + @Column(name = "ANSER_STATUS") + private String anserStatus; + + @Column(name = "FILE_GROUP_NO") private Integer fileGroupNo; - @Column(name="EXPSR_YN") + @Column(name = "EXPSR_YN") private String expsrYn = "N"; - @Column(name="DEL_YN") + @Column(name = "DEL_YN") private String delYn = "N"; - @Column(name="VIEW_CNT") + @Column(name = "VIEW_CNT") private int viewCnt = 0; - @Column(name="CREATE_USER_ID") + @Column(name = "CREATE_USER_ID") private String createUserId; @CreationTimestamp - @Column(name="CREATE_DT", columnDefinition = "TIMESTAMP", updatable = false) + @Column(name = "CREATE_DT", columnDefinition = "TIMESTAMP", updatable = false) private Instant createDt; - @Column(name="UPDATE_USER_ID") + @Column(name = "UPDATE_USER_ID") private String updateUserId; @UpdateTimestamp - @Column(name="UPDATE_DT", columnDefinition = "TIMESTAMP") + @Column(name = "UPDATE_DT", columnDefinition = "TIMESTAMP") private Instant updateDt; } diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/entity/PtyCrtfyhpBas.java b/pav-server/src/main/java/com/palnet/biz/jpa/entity/PtyCrtfyhpBas.java index 1906497..a48476c 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/entity/PtyCrtfyhpBas.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/entity/PtyCrtfyhpBas.java @@ -6,7 +6,6 @@ import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*; import java.io.Serializable; import java.time.Instant; -import java.util.Date; /** diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java index 32c787b..81a6ecb 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java @@ -2,12 +2,11 @@ package com.palnet.biz.jpa.repository.cns; import java.util.List; +import com.palnet.biz.api.cns.qna.model.QnaSelectListRQ; import org.springframework.stereotype.Repository; import com.palnet.biz.api.cns.qna.model.QnaBasModel; import com.palnet.biz.jpa.entity.QCnsQnaBas; -import com.palnet.comn.code.ErrorCode; -import com.palnet.comn.exception.CustomException; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Projections; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -20,50 +19,55 @@ import lombok.extern.slf4j.Slf4j; @RequiredArgsConstructor public class CnsQnaQueryRepository { - private final JPAQueryFactory query; + private final JPAQueryFactory query; - /** - * 카테고리와 글로 게시글 검색, 만약 조건 없으면 전체검색 - * @param category - * @param word - * @return - */ - public List getQnaList(String category, String word) { - QCnsQnaBas bas = QCnsQnaBas.cnsQnaBas; + /** + * 카테고리와 글로 게시글 검색, 만약 조건 없으면 전체검색 + * + * @param rq + * @return + */ + public List getQnaList(QnaSelectListRQ rq) { + QCnsQnaBas bas = QCnsQnaBas.cnsQnaBas; - BooleanBuilder builder = new BooleanBuilder(); - builder.and(bas.delYn.eq("N")); - builder.and(bas.expsrYn.eq("Y")); + BooleanBuilder builder = new BooleanBuilder(); + builder.and(bas.delYn.eq("N")); + builder.and(bas.expsrYn.eq("Y")); - if(category != null) { - builder.and(bas.category.eq(category)); - } + if (rq != null) { - if(word != null) { - builder.and(bas.title.contains(word)); - } + if (rq.getCategory() != null) { + builder.and(bas.category.eq(rq.getCategory())); + } - List r = query - .select(Projections.bean( - QnaBasModel.class, - bas.qnaSno, - bas.category, - bas.title, - bas.content, - bas.fileGroupNo, - bas.viewCnt, - bas.expsrYn, - bas.delYn, - bas.createUserId, - bas.createDt, - bas.updateUserId, - bas.updateDt - )) - .from(bas) - .where(builder) - .fetch(); - - return r; - } + if (rq.getWord() != null) { + if ("TITLE".equals(rq.getSearchType())) builder.and(bas.title.contains(rq.getWord())); + else if ("CONTENT".equals(rq.getSearchType())) builder.and(bas.content.contains(rq.getWord())); + else builder.and(bas.title.contains(rq.getWord()).or(bas.content.contains(rq.getWord()))); + } + } + + List r = query + .select(Projections.bean( + QnaBasModel.class, + bas.qnaSno, + bas.category, + bas.title, + bas.content, + bas.fileGroupNo, + bas.viewCnt, + bas.expsrYn, + bas.delYn, + bas.createUserId, + bas.createDt, + bas.updateUserId, + bas.updateDt + )) + .from(bas) + .where(builder) + .fetch(); + + return r; + } } diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/com/ComFileBasRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/com/ComFileBasRepository.java index 3fb74f1..439f94b 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/com/ComFileBasRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/com/ComFileBasRepository.java @@ -1,13 +1,14 @@ package com.palnet.biz.jpa.repository.com; -import java.util.List; - import com.palnet.biz.jpa.entity.ComFileBas; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface ComFileBasRepository extends JpaRepository{ + List findByFileSnoInAndDelYn(List fileSnos, String delYn); ComFileBas findFirstByOrderByFileSnoDesc(); diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/pty/PtyCstmrQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/pty/PtyCstmrQueryRepository.java index 6d9e06a..18be4a6 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/pty/PtyCstmrQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/pty/PtyCstmrQueryRepository.java @@ -128,25 +128,31 @@ public class PtyCstmrQueryRepository { } public JwtUserModel findUserPassword(String userId) { - QPtyCstmrBas basEntity = QPtyCstmrBas.ptyCstmrBas; - QPtyCstmrGroup groupEntity = QPtyCstmrGroup.ptyCstmrGroup; + QPtyCstmrBas bas = QPtyCstmrBas.ptyCstmrBas; + QPtyCstmrDtl dtl = QPtyCstmrDtl.ptyCstmrDtl; + QPtyCstmrGroup group = QPtyCstmrGroup.ptyCstmrGroup; BooleanBuilder builder = new BooleanBuilder(); - builder.and(basEntity.userId.eq(userId)); + builder.and(bas.userId.eq(userId)); - PtyCstmrBas entity = query.select(basEntity) - .from(basEntity) + PtyCstmrBas entity = query.select(bas) + .from(bas) .where(builder) .fetchFirst(); + PtyCstmrDtl dtlEntity = query.select(dtl) + .from(dtl) + .where(dtl.cstmrSno.eq(entity.getCstmrSno())) + .fetchFirst(); + List pcgEntityList = null; if (entity != null) { BooleanBuilder groupBuilder = new BooleanBuilder(); - groupBuilder.and(groupEntity.cstmrSno.eq(entity.getCstmrSno()) - .and(groupEntity.joinYn.eq("Y"))); + groupBuilder.and(group.cstmrSno.eq(entity.getCstmrSno()) + .and(group.joinYn.eq("Y"))); - pcgEntityList = query.select(groupEntity) - .from(groupEntity) + pcgEntityList = query.select(group) + .from(group) .where(groupBuilder) .fetch(); } @@ -169,6 +175,7 @@ public class PtyCstmrQueryRepository { } model.setGroup(groupModelList); } + model.setUserNm(dtlEntity.getMemberName()); return model; diff --git a/pav-server/src/main/java/com/palnet/comn/code/RSErrorCode.java b/pav-server/src/main/java/com/palnet/comn/code/RSErrorCode.java index 2ef4d83..635d251 100644 --- a/pav-server/src/main/java/com/palnet/comn/code/RSErrorCode.java +++ b/pav-server/src/main/java/com/palnet/comn/code/RSErrorCode.java @@ -8,6 +8,7 @@ public enum RSErrorCode { PSWD_NOTMATCH("-102" , "Password does not match"), ACNT_UNAVAIL("-103","Account is unavailable"), + AUTH_ERROR("-401", "auth error"), INTERNAL_SERVER_ERROR("-500", "Internal system error"), DATA_DUPLICATE("-104","Duplicate data exists"); From b567f3941fa917779346c69dc692dc779e44b85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Tue, 17 Oct 2023 15:14:30 +0900 Subject: [PATCH 2/6] =?UTF-8?q?qna=20=EC=84=A4=EA=B3=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java index 9a668c8..93a4051 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java @@ -148,6 +148,7 @@ public class CnsQnaService { cnsQnaBas.setExpsrYn("Y"); cnsQnaBas.setDelYn("N"); cnsQnaBas.setViewCnt(0); + cnsQnaBas.setAnserStatus("N"); if (fileGroupNo != null) cnsQnaBas.setFileGroupNo(fileGroupNo); @@ -168,6 +169,7 @@ public class CnsQnaService { entity.setCreateUserId(userId); entity.setAnserUserNm(userNm); entity.setAnserProcDt(Instant.now()); + entity.setAnserStatus("Y".equals(rq.getAnserStatus()) ? "Y" : "N"); cnsQnaBasRepository.save(entity); return true; From 56ffa8fcc7952d5fe9f26e18d1dcf30ccb51c489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Wed, 18 Oct 2023 17:58:01 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=EC=8B=A0=EC=B2=AD=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD=EC=9D=BC=EC=9E=90=20=EA=B8=B0=EC=A4=80=20?= =?UTF-8?q?=EA=B2=80=EC=83=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../biz/api/bas/laanc/model/BasLaancAprvListRq.java | 12 ++++++------ .../biz/api/bas/laanc/model/BasLaancAprvRs.java | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvListRq.java b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvListRq.java index 74044c1..cd65f5b 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvListRq.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvListRq.java @@ -29,12 +29,12 @@ public class BasLaancAprvListRq { @ApiParam(name = "작성자 이름", example = "팔") private String memberName; -// @ApiParam(name = "등록시작일자", example = "2023-12-12") -// @JsonSerialize(using = InstantDateStrSerializer.class) -// private Instant createStDate; -// @ApiParam(name = "등록종료일자", example = "2023-12-12") -// @JsonSerialize(using = InstantDateStrSerializer.class) -// private Instant createEndDate; + @ApiParam(name = "신청(등록)시작일자", example = "2023-12-12") + @JsonSerialize(using = InstantDateStrSerializer.class) + private Instant createStDate; + @ApiParam(name = "신청(등록)종료일자", example = "2023-12-12") + @JsonSerialize(using = InstantDateStrSerializer.class) + private Instant createEndDate; @ApiParam(name = "비행시작일자", example = "2023-12-12") @JsonSerialize(using = InstantDateStrSerializer.class) private Instant schFltStDate; diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java index 4e4068c..86bd07a 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java @@ -66,6 +66,7 @@ public class BasLaancAprvRs { private String aprvlYn; @ApiParam(name = "승인일자") private Instant aprvlDt; +// @ApiParam(name = "삭제여부") // private String delYn; @ApiParam(name = "등록자ID") private String createUserId; From c978a9171ac5bdd19ecbbea4dff4ef4cdaac56c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Wed, 18 Oct 2023 18:08:11 +0900 Subject: [PATCH 4/6] =?UTF-8?q?FAQ,=20QnA=20=EC=83=9D=EC=84=B1=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=20=EC=B5=9C=EA=B7=BC=EC=9D=BC=20=EC=88=9C=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cns/qna/controller/CnsQnaController.java | 29 ++- .../api/cns/qna/service/CnsQnaService.java | 7 + .../repository/cns/CnsFaqQueryRepository.java | 191 +++++++++--------- .../repository/cns/CnsQnaQueryRepository.java | 46 +++++ 4 files changed, 176 insertions(+), 97 deletions(-) diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java index 8f00c29..5fcb6f6 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/controller/CnsQnaController.java @@ -58,7 +58,7 @@ public class CnsQnaController { @GetMapping @Tag(name = "QNA", description = "QNA 관련 API") - @ApiOperation(value = "QnA 리스트 조회") + @ApiOperation(value = "QnA 리스트 조회-관리자") public ResponseEntity selectQna(QnaSelectListRQ rq) { List result = new ArrayList<>(); @@ -81,6 +81,31 @@ public class CnsQnaController { } + @GetMapping("/user") + @Tag(name = "QNA", description = "QNA 관련 API") + @ApiOperation(value = "QnA 리스트 조회-사용자") + public ResponseEntity selectQnaForUser(QnaSelectListRQ rq) { + + List result = new ArrayList<>(); + try { + result = cnsQnaService.selectQnaForUser(rq); + } catch (CustomException e) { + Map resultMap = new HashMap<>(); + log.error("IGNORE : ", e); + resultMap.put("result", false); + resultMap.put("errorCode", e.getErrorCode()); + resultMap.put("errorMessage", e.getMessage()); + return ResponseEntity.ok().body(new SuccessResponse<>(resultMap)); + } catch (Exception e) { + log.error("IGNORE : ", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ErrorResponse("Server Error", "-1")); + + } + return ResponseEntity.ok().body(new SuccessResponse<>(result)); + } + + @GetMapping("/{qnaSno}") @Tag(name = "QNA", description = "QNA 관련 API") @ApiOperation(value = "QnA 상세보기") @@ -127,6 +152,8 @@ public class CnsQnaController { return ResponseEntity.ok().body(new SuccessResponse<>(result)); } + + @DeleteMapping("/{qnaSno}") @Tag(name = "QNA", description = "QNA 관련 API") @ApiOperation(value = "QnA 삭제하기") diff --git a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java index 93a4051..a717bd5 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/cns/qna/service/CnsQnaService.java @@ -125,6 +125,11 @@ public class CnsQnaService { return cnsQnaQueryRepository.getQnaList(rq); } + public List selectQnaForUser(QnaSelectListRQ rq) { + String userId = jwtTokenUtil.getUserIdByToken(); + return cnsQnaQueryRepository.getQnaListForUser(rq, userId); + } + /** * QnaInsert * @@ -174,4 +179,6 @@ public class CnsQnaService { cnsQnaBasRepository.save(entity); return true; } + + } diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsFaqQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsFaqQueryRepository.java index c947ca5..ead1ace 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsFaqQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsFaqQueryRepository.java @@ -1,111 +1,110 @@ package com.palnet.biz.jpa.repository.cns; -import java.util.List; - -import org.springframework.stereotype.Repository; - import com.palnet.biz.api.cns.faq.model.FaqListModel; import com.palnet.biz.jpa.entity.QCnsFaqBas; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Projections; import com.querydsl.jpa.impl.JPAQueryFactory; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +import java.util.List; @Slf4j @Repository @RequiredArgsConstructor public class CnsFaqQueryRepository { - - private final JPAQueryFactory query; - - public List getFaqList(String category, String word) { - - QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; - - BooleanBuilder builder = new BooleanBuilder(); - builder.and(bas.delYn.eq("N")); - builder.and(bas.expsrYn.eq("Y")); - - if(category != null) { - builder.and(bas.category.eq(category)); - } - - if(word != null) { - builder.and(bas.title.contains(word)); - } - - List r = query - .select(Projections.bean( - FaqListModel.class, - bas.faqSno, - bas.category, - bas.title, - bas.content, - bas.viewCnt, - bas.expsrYn, - bas.createUserId, - bas.createDt, - bas.updateUserId, - bas.updateDt - )) - .from(bas) - .where(builder) - .fetch(); - - - return r; - } - - public FaqListModel getFaqDetail(int sno) { - - QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; - - BooleanBuilder builder = new BooleanBuilder(); - builder.and(bas.faqSno.eq(sno)); - builder.and(bas.expsrYn.eq("Y")); - builder.and(bas.delYn.eq("N")); - - FaqListModel r = query - .select(Projections.bean( - FaqListModel.class, - bas.faqSno, - bas.category, - bas.title, - bas.content, - bas.viewCnt, - bas.expsrYn, - bas.createUserId, - bas.createDt, - bas.updateUserId, - bas.updateDt - )) - .from(bas) - .where(builder) - .fetchOne(); - - - return r; - } - - public void updateFaq(FaqListModel model) { - QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; - - BooleanBuilder builder = new BooleanBuilder(); - builder.and(bas.faqSno.eq(model.getFaqSno())); - - query.update(bas) - .set(bas.category, model.getCategory()) - .set(bas.title, model.getTitle()) - .set(bas.content, model.getContent()) - .set(bas.viewCnt, model.getViewCnt()) - .set(bas.expsrYn, model.getExpsrYn()) - .set(bas.updateUserId, model.getUpdateUserId()) - .set(bas.updateDt, model.getUpdateDt()) - .where(builder) - .execute(); - - } - + + private final JPAQueryFactory query; + + public List getFaqList(String category, String word) { + + QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(bas.delYn.eq("N")); + builder.and(bas.expsrYn.eq("Y")); + + if (category != null) { + builder.and(bas.category.eq(category)); + } + + if (word != null) { + builder.and(bas.title.contains(word)); + } + + List r = query + .select(Projections.bean( + FaqListModel.class, + bas.faqSno, + bas.category, + bas.title, + bas.content, + bas.viewCnt, + bas.expsrYn, + bas.createUserId, + bas.createDt, + bas.updateUserId, + bas.updateDt + )) + .from(bas) + .where(builder) + .orderBy(bas.createDt.desc()) + .fetch(); + + + return r; + } + + public FaqListModel getFaqDetail(int sno) { + + QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(bas.faqSno.eq(sno)); + builder.and(bas.expsrYn.eq("Y")); + builder.and(bas.delYn.eq("N")); + + FaqListModel r = query + .select(Projections.bean( + FaqListModel.class, + bas.faqSno, + bas.category, + bas.title, + bas.content, + bas.viewCnt, + bas.expsrYn, + bas.createUserId, + bas.createDt, + bas.updateUserId, + bas.updateDt + )) + .from(bas) + .where(builder) + .fetchOne(); + + + return r; + } + + public void updateFaq(FaqListModel model) { + QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas; + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(bas.faqSno.eq(model.getFaqSno())); + + query.update(bas) + .set(bas.category, model.getCategory()) + .set(bas.title, model.getTitle()) + .set(bas.content, model.getContent()) + .set(bas.viewCnt, model.getViewCnt()) + .set(bas.expsrYn, model.getExpsrYn()) + .set(bas.updateUserId, model.getUpdateUserId()) + .set(bas.updateDt, model.getUpdateDt()) + .where(builder) + .execute(); + + } + } \ No newline at end of file diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java index 81a6ecb..dd54123 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/cns/CnsQnaQueryRepository.java @@ -65,6 +65,52 @@ public class CnsQnaQueryRepository { )) .from(bas) .where(builder) + .orderBy(bas.createDt.desc()) + .fetch(); + + return r; + } + + public List getQnaListForUser(QnaSelectListRQ rq, String userId) { + QCnsQnaBas bas = QCnsQnaBas.cnsQnaBas; + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(bas.delYn.eq("N")); + builder.and(bas.expsrYn.eq("Y")); + builder.and(bas.createUserId.eq(userId)); + + if (rq != null) { + + if (rq.getCategory() != null) { + builder.and(bas.category.eq(rq.getCategory())); + } + + if (rq.getWord() != null) { + if ("TITLE".equals(rq.getSearchType())) builder.and(bas.title.contains(rq.getWord())); + else if ("CONTENT".equals(rq.getSearchType())) builder.and(bas.content.contains(rq.getWord())); + else builder.and(bas.title.contains(rq.getWord()).or(bas.content.contains(rq.getWord()))); + } + } + + List r = query + .select(Projections.bean( + QnaBasModel.class, + bas.qnaSno, + bas.category, + bas.title, + bas.content, + bas.fileGroupNo, + bas.viewCnt, + bas.expsrYn, + bas.delYn, + bas.createUserId, + bas.createDt, + bas.updateUserId, + bas.updateDt + )) + .from(bas) + .where(builder) + .orderBy(bas.createDt.desc()) .fetch(); return r; From d5ce02101a713da27d5230fe585ee9d384bb2240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Wed, 18 Oct 2023 19:05:14 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=EC=8A=B9=EC=9D=B8=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=97=86=EB=8A=94=20api=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BasLaancAprvController.java | 27 ++++ .../api/bas/laanc/model/BasLaancAprvRs.java | 1 - .../laanc/service/BasLaancAprvService.java | 8 ++ .../flt/FltPlanQueryRepository.java | 122 ++++++++++++++++++ 4 files changed, 157 insertions(+), 1 deletion(-) diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/controller/BasLaancAprvController.java b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/controller/BasLaancAprvController.java index a0bd47f..351abc7 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/controller/BasLaancAprvController.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/controller/BasLaancAprvController.java @@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -78,6 +79,32 @@ public class BasLaancAprvController { return ResponseEntity.ok().body(new SuccessResponse<>(rs)); } + @ApiOperation(value = "LAANC 승인 목록") + @Tag(name = "LAANC 승인", description = "LAANC 승인 관련 API") + @GetMapping("/list2") + public ResponseEntity getLaancAprvList2(BasLaancAprvListRq rq) { + List rs = null; + try { + log.debug(">>> rq : {}", rq); + rs = basLaancAprvService.getLaancAprvList2(rq); + + } catch (CustomException e) { + Map resultMap = new HashMap<>(); + log.error("IGNORE : ", e); + resultMap.put("result", false); + resultMap.put("errorCode", e.getErrorCode()); + resultMap.put("errorMessage", e.getMessage()); + return ResponseEntity.ok().body(new SuccessResponse<>(resultMap)); + } catch (Exception e) { + log.error("IGNORE : ", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new ErrorResponse("Server Error", "-1")); + + } + + return ResponseEntity.ok().body(new SuccessResponse<>(rs)); + } + /** * laanc 승인 상세 * @param planSno diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java index 86bd07a..e4505f4 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/model/BasLaancAprvRs.java @@ -86,7 +86,6 @@ public class BasLaancAprvRs { public String getArcrftWght() { if (arcrftList == null || arcrftList.isEmpty()) return null; List arcrftWghtCdList = arcrftList.stream().map(BasLaancArcrftModel::getArcrftWghtCd).distinct().filter(Objects::nonNull).collect(Collectors.toList()); - System.out.println(arcrftWghtCdList); String ArcrftWghtType = arcrftWghtCdList.stream().map(ArcrftWghtCd::getValue).collect(Collectors.joining(",")); return ArcrftWghtType; } diff --git a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/service/BasLaancAprvService.java b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/service/BasLaancAprvService.java index 95d5a62..603e2fa 100644 --- a/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/service/BasLaancAprvService.java +++ b/pav-server/src/main/java/com/palnet/biz/api/bas/laanc/service/BasLaancAprvService.java @@ -14,6 +14,8 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import java.util.List; + /** * packageName : com.palnet.biz.api.bas.laanc.service * fileName : BasLaancAprvService @@ -44,6 +46,12 @@ public class BasLaancAprvService { Page rs = PageUtils.convert(result, BasLaancAprvMapper.MAPPER.toRsList(result.getContent())); return rs; } + public List getLaancAprvList2(BasLaancAprvListRq rq) { + LaancAprvSearchDto searchDto = BasLaancAprvMapper.MAPPER.toDto(rq); + List result = fltPlanQueryRepository.findAllAprvListBySearch2(searchDto); + List rs = BasLaancAprvMapper.MAPPER.toRsList(result); + return rs; + } /** * laanc 승인 상세 diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java index a7df972..a5f9038 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java @@ -850,6 +850,128 @@ public class FltPlanQueryRepository { return laancPlanDtos; } + + public List findAllAprvListBySearch2(LaancAprvSearchDto search) { + + QFltPlanBas bas = QFltPlanBas.fltPlanBas; + QFltPlanArea area = QFltPlanArea.fltPlanArea; + QFltPlanArcrft arcrft = QFltPlanArcrft.fltPlanArcrft; + + // serach + BooleanBuilder builder = new BooleanBuilder(); + if(search != null){ + if(StringUtils.hasText(search.getMemberName())){ + builder.and(bas.memberName.contains(search.getMemberName())); + } + if(search.getCreateDate() != null){ + Instant createStDate = InstantUtils.toDate(search.getCreateDate()); + Instant createEndDate = createStDate.plus(Duration.ofDays(1)); + builder.and(bas.createDt.goe(createStDate).and(bas.createDt.lt(createEndDate))); + } + if(search.getCreateStDate() != null) { + Instant createStDate = InstantUtils.toDate(search.getCreateStDate()); + builder.and(bas.createDt.goe(createStDate)); + } + if(search.getCreateEndDate() != null){ + Instant createEndDate = InstantUtils.toDate(search.getCreateEndDate()).plus(Duration.ofDays(1)); + builder.and(bas.createDt.lt(createEndDate)); + } + if(search.getSchFltStDate() != null){ + Instant schFltStDate = InstantUtils.toDate(search.getSchFltStDate()); + builder.and(bas.schFltStDt.goe(schFltStDate)); + } + if(search.getSchFltEndDate() != null){ + Instant schFltEndDate = InstantUtils.toDate(search.getSchFltEndDate()).plus(Duration.ofDays(1)); + builder.and(bas.schFltEndDt.lt(schFltEndDate)); + } + } + + + JPAQuery jpaQuery = query.from(bas) + .leftJoin(area) + .on(bas.planSno.eq(area.planSno)) + .leftJoin(arcrft) + .on(bas.planSno.eq(arcrft.planSno)) + .where(builder); + + List list = jpaQuery.transform( + GroupBy.groupBy(bas.planSno) + .list(Projections.bean( + LaancPlanDto.class, + bas.planSno, + bas.groupId, + bas.cstmrSno, + bas.memberName, + bas.email, + bas.hpno, + bas.clncd, + bas.addr, + bas.addrDtlCn, + bas.zip, + bas.schFltStDt, + bas.schFltEndDt, + bas.fltPurpose, + bas.aprvlYn, + bas.delYn, + bas.createUserId, + bas.createDt, + bas.updateUserId, + bas.updateDt, + bas.corpRegYn, + bas.serviceType, + GroupBy.list(Projections.bean( + LaancPlanAreaDto.class, + area.planAreaSno, + area.planSno, + area.areaType, + area.fltMethod, + area.fltAreaAddr, + area.bufferZone, + area.fltElev, + area.createUserId, + area.createDt, + area.updateUserId, + area.updateDt, + area.fltMothoeRm + ).skipNulls()).as("areaList"), + GroupBy.list(Projections.bean( + LaancPlanArcrftDto.class, + arcrft.planArcrftSno, + arcrft.planSno, + arcrft.arcrftSno, + arcrft.idntfNum, + arcrft.groupNm, + arcrft.prdctNum, + arcrft.arcrftTypeCd, + arcrft.arcrftModelNm, + arcrft.prdctCmpnNm, + arcrft.prdctDate, + arcrft.arcrftLngth, + arcrft.arcrftWdth, + arcrft.arcrftHght, + arcrft.arcrftWght, + arcrft.arcrftWghtCd, + arcrft.wghtTypeCd, + arcrft.imageUrl, + arcrft.takeoffWght, + arcrft.useYn, + arcrft.cameraYn, + arcrft.insrncYn, + arcrft.ownerNm, + arcrft.createUserId, + arcrft.createDt, + arcrft.updateUserId, + arcrft.updateDt, + arcrft.acrftInsuranceYn, + arcrft.insuranceExperiod, + arcrft.corporationNm + ).skipNulls()).as("arcrftList") + ).skipNulls()) + ); + + return list; + } + // laanc 승인 상세 public LaancPlanDto findAprvById(Integer planSno) { QFltPlanBas bas = QFltPlanBas.fltPlanBas; From 665ffc5989b582b8977fb32500df0daaebfee834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dhji=28=EC=A7=80=EB=8C=80=ED=95=9C=29?= Date: Wed, 18 Oct 2023 23:17:39 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=EC=8A=B9=EC=9D=B8=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD=EC=9D=BC=20=EA=B8=B0=EC=A4=80=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../biz/jpa/repository/flt/FltPlanQueryRepository.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java b/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java index a5f9038..2ab24d4 100644 --- a/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java +++ b/pav-server/src/main/java/com/palnet/biz/jpa/repository/flt/FltPlanQueryRepository.java @@ -753,7 +753,8 @@ public class FltPlanQueryRepository { .on(bas.planSno.eq(area.planSno)) .leftJoin(arcrft) .on(bas.planSno.eq(arcrft.planSno)) - .where(builder); + .where(builder) + .orderBy(bas.createDt.desc()); JPAQuery countQuery = jpaQuery.clone(); @@ -892,7 +893,8 @@ public class FltPlanQueryRepository { .on(bas.planSno.eq(area.planSno)) .leftJoin(arcrft) .on(bas.planSno.eq(arcrft.planSno)) - .where(builder); + .where(builder) + .orderBy(bas.createDt.desc()); List list = jpaQuery.transform( GroupBy.groupBy(bas.planSno)