Browse Source

feat : content(faq, qna) 작업중

feature/renewal/contents
qkr7828 7 months ago
parent
commit
1f5ad17f5e
  1. 165
      data/cns/src/main/java/kr/co/palnet/kac/data/cns/repository/CnsFaqQueryRepository.java
  2. 42
      data/cns/src/main/java/kr/co/palnet/kac/data/cns/service/CnsFaqDomainService.java
  3. 392
      web/api-cns/src/main/java/kr/co/palnet/kac/api/v1/cns/qna/controller/CnsQnaController.java
  4. 219
      web/api-cns/src/main/java/kr/co/palnet/kac/api/v1/cns/qna/service/CnsQnaService.java

165
data/cns/src/main/java/kr/co/palnet/kac/data/cns/repository/CnsFaqQueryRepository.java

@ -0,0 +1,165 @@
package kr.co.palnet.kac.data.cns.repository;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import kr.co.palnet.kac.data.cns.model.CnsFaqBas;
import kr.co.palnet.kac.data.cns.model.QCnsFaqBas;
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;
/**
* 조건값으로 FaQ리스트를 조회하는 SQL기능.
* @param category
* @param word
* @return
*/
public List<CnsFaqBas> 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));
}
/**
* 삭제여부[delYn]값이 'N' 조건,
* 표출여부[expsrYn]값이 'Y' 조건,
* 카테고리값[category] 조건,
* 제목[title] 값이 word와의 조건 값으로 조회하는 SQL 입니다.
*
* SELECT
* CFB.FAQ_SNO ,
* CFB.CATEGORY ,
* CFB.TITLE ,
* CFB.CONTENT ,
* CFB.VIEW_CNT ,
* CFB.EXPSR_YN ,
* CFB.CREATE_USER_ID ,
* CFB.CREATE_DT ,
* CFB.UPDATE_USER_ID ,
* CFB.UPDATE_DT
* FROM CNS_FAQ_BAS CFB
* WHERE CFB.DEL_YN = 'N'
* AND CFB.EXPSR_YN = 'Y'
* AND CFB.CATEGORY = #{category}
* AND CFB.TITLE = #{word}
* ORDER BY CFB.CREATE_DT DESC
*/
List<CnsFaqBas> r = query
.select(Projections.bean(
CnsFaqBas.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;
}
/**
* 일련번호[sno] 상세정보를 조회하는 SQL 기능.
* @param sno
* @return
*/
public CnsFaqBas getFaqDetail(int sno) {
QCnsFaqBas bas = QCnsFaqBas.cnsFaqBas;
BooleanBuilder builder = new BooleanBuilder();
builder.and(bas.faqSno.eq((long) sno));
builder.and(bas.expsrYn.eq("Y"));
builder.and(bas.delYn.eq("N"));
/**
* 일련번호[faqSno] 조건,
* 표출여부[expsrYn] 'Y' 인지 조건,
* 삭제여부[delYn] 'N' 인지 조건으로 조회하는 SQL 입니다.
*
* SELECT
* CFB.FAQ_SNO ,
* CFB.CATEGORY ,
* CFB.TITLE ,
* CFB.CONTENT ,
* CFB.VIEW_CNT ,
* CFB.EXPSR_YN ,
* CFB.CREATE_USER_ID ,
* CFB.CREATE_DT ,
* CFB.UPDATE_USER_ID ,
* CFB.UPDATE_DT
* FROM CNS_FAQ_BAS CFB
* WHERE CFB.FAQ_SNO = #{sno}
* AND CFB.EXPSR_YN = 'Y'
* AND CFB.DEL_YN = 'N'
*/
CnsFaqBas r = query
.select(Projections.bean(
CnsFaqBas.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(CnsFaqBas 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();
}
}

42
data/cns/src/main/java/kr/co/palnet/kac/data/cns/service/CnsFaqDomainService.java

@ -0,0 +1,42 @@
package kr.co.palnet.kac.data.cns.service;
import kr.co.palnet.kac.data.cns.model.CnsFaqBas;
import kr.co.palnet.kac.data.cns.repository.CnsFaqBasRepository;
import kr.co.palnet.kac.data.cns.repository.CnsFaqQueryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class CnsFaqDomainService {
private final CnsFaqBasRepository cnsFaqBasRepository;
private final CnsFaqQueryRepository query;
public List<CnsFaqBas> getFaqList(String category, String word){
return query.getFaqList(category, word);
}
public void updateViewCnt(int sno){
cnsFaqBasRepository.updateViewCnt(sno);
}
public CnsFaqBas getFaqDetail(int sno){
return query.getFaqDetail(sno);
}
public CnsFaqBas saveFaqBas(CnsFaqBas cnsFaqBas){
return cnsFaqBasRepository.save(cnsFaqBas);
}
public Optional<CnsFaqBas> findById(int faqSno){
return cnsFaqBasRepository.findById(faqSno);
}
public int deleteFaq(int faqSno){
return cnsFaqBasRepository.deleteFaq(faqSno);
}
}

392
web/api-cns/src/main/java/kr/co/palnet/kac/api/v1/cns/qna/controller/CnsQnaController.java

@ -0,0 +1,392 @@
package kr.co.palnet.kac.api.v1.cns.qna.controller;
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.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RequiredArgsConstructor
@RestController
@Tag(name = "QNA", description = "QNA 관련 API")
@RequestMapping("/api/cns/qna")
public class CnsQnaController {
private final CnsQnaService cnsQnaService;
private final JwtTokenUtil jwtTokenUtil;
/**
* QnA 등록하는 기능,
* QnaInsertRQModel 모델에 요청값으로 QnA를 등록하는 기능.
* @param rq
* @return
*/
@PostMapping(consumes = "multipart/form-data")
@Operation(summary = "QNA 등록 (사용자)", description = "사용자 권한으로 QNA를 등록하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공",
content = {
@io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json",
array = @io.swagger.v3.oas.annotations.media.ArraySchema(
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = boolean.class)))
})
})
public ResponseEntity<? extends BasicResponse> insertQna(QnaInsertRQModel rq) {
boolean result = false;
try {
result = cnsQnaService.insertQna(rq); // Qna 추가 하는기능
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA리스트 조회하는 기능[관리자],
* QnaListAdminRQ 조건값에 따라 조회함.
* @param rq
* @return
*/
@GetMapping
@Operation(summary = "QNA 리스트 조회 (관리자)", description = "QNA 리스트를 관리자 권한으로 조회하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공",
content = {
@io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json",
array = @io.swagger.v3.oas.annotations.media.ArraySchema(
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = QnaBasModel.class)))
})
})
public ResponseEntity<? extends BasicResponse> selectQna(QnaListAdminRQ rq) {
List<QnaBasModel> result = new ArrayList<>();
try {
result = cnsQnaService.selectQnaList(rq); // Qna리스트 조회하는 기능
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA리스트 조회하는 기능[관리자],
* QnaSelectListRQ 값에 따라서 조회함.
* @param rq
* @return
*/
@GetMapping("/user")
@Operation(summary = "QNA 리스트 조회 (사용자)", description = "QNA 리스트를 사용자 권한으로 조회하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공",
content = {
@io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json",
array = @io.swagger.v3.oas.annotations.media.ArraySchema(
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = QnaBasModel.class)))
})
})
public ResponseEntity<? extends BasicResponse> selectQnaForUser(QnaSelectListRQ rq) {
List<QnaBasModel> result = new ArrayList<>();
try {
result = cnsQnaService.selectQnaForUser(rq);
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA 상세보기 기능,
* QnA일련번호[qnaSno]값으로 조회함.
* @param qnaSno
* @return
*/
@GetMapping("/{qnaSno}")
@Operation(summary = "QNA 리스트 상세 조회", description = "QNA 리스트를 상세하게 조회하는 API 입니다.")
public ResponseEntity<? extends BasicResponse> detailQna(@Parameter(name="qnaSno", description = "QnA일련번호", in = ParameterIn.PATH, example = "295") @PathVariable int qnaSno) {
QnaDetailRSModel result = null;
try {
result = cnsQnaService.getQnaDetail(qnaSno); // Qna 상세불러오기 기능
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA수정 하는 기능[사용자],
* QnaInsertRQModel 모델에 입력받은 사항들을 수정함.
* @param rq
* @return
*/
@PutMapping(consumes = "multipart/form-data")
@Operation(summary = "QNA 수정 (사용자)", description = "QNA를 사용자 권한으로 수정하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공",
content = {
@io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json",
array = @io.swagger.v3.oas.annotations.media.ArraySchema(
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = boolean.class)))
})
})
public ResponseEntity<? extends BasicResponse> updateQna(QnaInsertRQModel rq) {
boolean result = false;
try {
result = cnsQnaService.updateQna(rq); // Qna 업데이트하는 기능
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA삭제하는 기능,
* QnA일련번호[qnaSno] 삭제함.
* @param qnaSno
* @return
*/
@DeleteMapping("/{qnaSno}")
@Operation(summary = "QNA 삭제", description = "QNA를 삭제하는 API 입니다.")
public ResponseEntity<? extends BasicResponse> deleteQna(@Parameter(name="qnaSno", description = "QnA일련번호", in = ParameterIn.PATH, example = "17") @PathVariable int qnaSno) {
// TODO 관리자만 삭제 가능 여부인지 확인 필요
boolean result = false;
try {
result = cnsQnaService.deleteQna(qnaSno); // Qna 삭제하기, file들도 모두 논리삭제하는 기능.
} catch (CustomException e) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
/**
* QnA 답변등록하는 기능[관리자],
* QnaInsertAnserRQModel에 입력받은 값으로 답변을 등록함.
* @param rq
* @return
*/
@PutMapping("/answer")
@Operation(summary = "QNA 답변 등록(관리자)", description = "QNA에 대한 답변을 관리자 권한으로 등록하는 API 입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공",
content = {
@io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json",
array = @io.swagger.v3.oas.annotations.media.ArraySchema(
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = boolean.class)))
})
})
public ResponseEntity<? extends BasicResponse> insertAnswer(@RequestBody QnaInsertAnserRQModel rq) {
// TODO 추후 auth -> role 체크로 변경
boolean result = false;
try {
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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* CustomException은 개발자가 "의도적으로" 예외처리,
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
Map<String, Object> 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) {
/**
* try{
...
}
* try 영역 코드들중 문제가 생기면 오는 .
* log.error 로그로 원인 파악과 함께 API를 호출한 곳에 서버에러 내려줌
*/
log.error("IGNORE : ", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("Server Error", "-1"));
}
return ResponseEntity.ok().body(new SuccessResponse<>(result));
}
}

219
web/api-cns/src/main/java/kr/co/palnet/kac/api/v1/cns/qna/service/CnsQnaService.java

@ -0,0 +1,219 @@
package kr.co.palnet.kac.api.v1.cns.qna.service;
import com.palnet.biz.api.acnt.jwt.utils.JwtTokenUtil;
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.PtyCstmrBas;
import com.palnet.biz.jpa.entity.PtyCstmrDtl;
import com.palnet.biz.jpa.repository.cns.CnsQnaBasRepository;
import com.palnet.biz.jpa.repository.cns.CnsQnaQueryRepository;
import com.palnet.biz.jpa.repository.pty.PtyCstmrBasRepository;
import com.palnet.biz.jpa.repository.pty.PtyCstmrDtlRepository;
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.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
@RequiredArgsConstructor
public class CnsQnaService {
private final CnsQnaBasRepository cnsQnaBasRepository;
private final CnsQnaQueryRepository cnsQnaQueryRepository;
private final PtyCstmrBasRepository ptyCstmrBasRepository;
private final PtyCstmrDtlRepository ptyCstmrDtlRepository;
private final ComnFileService comnFileService;
private final JwtTokenUtil jwtTokenUtil;
/**
* Qna 삭제하기, file들도 모두 논리삭제하는 기능.
* @param qnaSno
* @return
*/
// @Transactional는 데이터베이스의 정합성을 위해 사용합니다, 추가 수정 삭제 등에서 사용합니다, 이 기능에서는 삭제컬럼은 수정했기 때문에 사용했습니다.
@Transactional
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.deleteFilesByFileGroupNo(entity.getFileGroupNo());
entity.setDelYn("Y");
cnsQnaBasRepository.save(entity);
return true;
}
/**
* Qna 업데이트하는 기능.
* @param rq
* @return
*/
// @Transactional는 데이터베이스의 정합성을 위해 사용합니다, 추가 수정 삭제 등에서 사용합니다, 이 기능에서는 수정하기 때문에 사용합니다.
@Transactional
public boolean updateQna(QnaInsertRQModel rq) {
CnsQnaBas entity = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(rq.getQnaSno(), 0, "N", "Y");
if (entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND);
// 파일 삭제(논리적 삭제)
List<Integer> prevFileSnoList = new ArrayList<>();
List<Integer> currentFileSnoList = new ArrayList<>();
if (entity.getFileGroupNo() != null) {
List<ComnFileModel> prevFileInfos = comnFileService.getNormalFileListByGroupNo(entity.getFileGroupNo()); // 파일그룹번호[fileGroupNo]에 해당하는 파일등 모두 가져오는 기능.
prevFileSnoList = prevFileInfos.stream().map(ComnFileModel::getFileSno).collect(Collectors.toList());
}
if (rq.getFileInfos() != null) {
currentFileSnoList = rq.getFileInfos().stream().map(ComnFileModel::getFileSno).collect(Collectors.toList());
}
boolean isChange = prevFileSnoList.removeAll(currentFileSnoList);
if (isChange) {
comnFileService.deleteFiles(prevFileSnoList); // File 삭제
}
List<MultipartFile> files = rq.getFiles();
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());
CnsQnaMapper.MAPPER.merge(entity, rq);
String userId = jwtTokenUtil.getUserIdByToken();
if (userId == null) userId = "NONE";
entity.setUpdateUserId(userId);
// 수정시 답변상태 미응답 상태로 변경
entity.setAnserStatus("N");
cnsQnaBasRepository.save(entity);
return true;
}
/**
* Qna 상세불러오기 기능.
* @param qnaSno
* @return
*/
// @Transactional는 데이터베이스의 정합성을 위해 사용합니다, 추가 수정 삭제 등에서 사용합니다, 이 기능에서는 조회수 증가하기 떄문에 사용했습니다.
@Transactional
public QnaDetailRSModel getQnaDetail(int qnaSno) {
cnsQnaBasRepository.pulsViewCount(qnaSno);
CnsQnaBas entity = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(qnaSno, 0, "N", "Y");
if(entity == null) throw new CustomException(ErrorCode.DATA_NO);
List<ComnFileModel> files = null;
if (entity.getFileGroupNo() != null && entity.getFileGroupNo() != 0)
files = comnFileService.getNormalFileListByGroupNo(entity.getFileGroupNo()); // 파일그룹번호[fileGroupNo]에 해당하는 파일등 모두 가져오는 기능.
QnaDetailRSModel model = CnsQnaMapper.MAPPER.toModel(entity);
PtyCstmrBas user = ptyCstmrBasRepository.findByUserId(entity.getCreateUserId()).orElse(null);
if (user != null) {
PtyCstmrDtl ptyCstmrDtl = ptyCstmrDtlRepository.findById(user.getCstmrSno()).orElse(null);
if (ptyCstmrDtl != null) model.setCreateUserNm(ptyCstmrDtl.getMemberName());
}
model.setFileInfos(files);
return model;
}
/**
* Qna리스트 조회하는 기능[관리자].
*
* @param rq
* @return
*/
public List<QnaBasModel> selectQnaList(QnaListAdminRQ rq) {
return cnsQnaQueryRepository.getQnaList(rq);
}
/**
* Qna리스트 조회하는 기능[유저]
* @param rq
* @return
*/
public List<QnaBasModel> selectQnaForUser(QnaSelectListRQ rq) {
String userId = jwtTokenUtil.getUserIdByToken();
return cnsQnaQueryRepository.getQnaListForUser(rq, userId);
}
/**
* Qna 추가 하는기능.
* @param rq
* @return
*/
@Transactional
public boolean insertQna(QnaInsertRQModel rq) {
List<MultipartFile> files = rq.getFiles();
Integer fileGroupNo = null;
if (files != null && files.size() > 0) fileGroupNo = comnFileService.fileUpload(files, null); // File 업로드
String userId = jwtTokenUtil.getUserIdByToken();
if (userId == null) userId = "NONE";
CnsQnaBas cnsQnaBas = CnsQnaMapper.MAPPER.toEntity(rq);
cnsQnaBas.setCreateUserId(userId);
cnsQnaBas.setUpdateUserId(userId);
cnsQnaBas.setExpsrYn("Y");
cnsQnaBas.setDelYn("N");
cnsQnaBas.setViewCnt(0);
cnsQnaBas.setAnserStatus("N");
if (fileGroupNo != null) cnsQnaBas.setFileGroupNo(fileGroupNo);
cnsQnaBasRepository.save(cnsQnaBas);
return true;
}
/**
* 답변추가하는 기능.
* @param rq
* @return
*/
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.setUpdateUserId(userId);
entity.setAnserUserNm(userNm);
entity.setAnserProcDt(Instant.now());
entity.setAnserStatus("Y".equals(rq.getAnserStatus()) ? "Y" : "N");
cnsQnaBasRepository.save(entity);
return true;
}
}
Loading…
Cancel
Save