feature/cns/faq-qna #9
Merged
lkd9125
merged 23 commits from feature/cns/faq-qna
into develop
11 months ago
21 changed files with 1333 additions and 96 deletions
@ -0,0 +1,74 @@
|
||||
package com.palnet.biz.api.cns.faq.controller; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import com.palnet.biz.api.cns.faq.model.FaqListRQModel; |
||||
import com.palnet.biz.api.cns.faq.model.FaqListModel; |
||||
import com.palnet.biz.api.cns.faq.service.CnsFaqService; |
||||
import com.palnet.biz.api.comn.response.BasicResponse; |
||||
import com.palnet.biz.api.comn.response.SuccessResponse; |
||||
|
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@RestController |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RequestMapping(value = "/api/bas/cns/faq") |
||||
public class CnsFaqController { |
||||
|
||||
private final CnsFaqService service; |
||||
|
||||
/*FAQ 목록 조회*/ |
||||
@PostMapping("/list") |
||||
public ResponseEntity<? extends BasicResponse> getFaqList(@RequestBody FaqListRQModel model) { |
||||
|
||||
List<FaqListModel> result = null; |
||||
|
||||
result = service.getFaqList(model); |
||||
|
||||
return ResponseEntity.ok().body(new SuccessResponse<>(result)); |
||||
} |
||||
|
||||
/*FAQ 상세 조회*/ |
||||
@GetMapping("/detail") |
||||
public ResponseEntity<FaqListModel> getFaqDetail(int sno) { |
||||
|
||||
FaqListModel result = null; |
||||
|
||||
result = service.getFaqDetail(sno); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
|
||||
/*FAQ 작성*/ |
||||
@PostMapping("/insert") |
||||
public void insertFaq(@RequestBody FaqListModel model) { |
||||
|
||||
service.insertFaq(model); |
||||
|
||||
} |
||||
|
||||
/*FAQ 업데이트*/ |
||||
@PostMapping("/update") |
||||
public void updateFaq(@RequestBody FaqListModel model) { |
||||
|
||||
service.updateFaq(model); |
||||
|
||||
} |
||||
|
||||
/*FAQ 논리 삭제*/ |
||||
@PostMapping("/delete") |
||||
public void deleteFaq(int sno) { |
||||
|
||||
service.deleteFaq(sno); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.palnet.biz.api.cns.faq.model; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class FaqListModel { |
||||
|
||||
private int faqSno; |
||||
|
||||
private String category; |
||||
|
||||
private String title; |
||||
|
||||
private String content; |
||||
|
||||
private int viewCnt; |
||||
|
||||
private String expsrYn; |
||||
|
||||
private String delYn; |
||||
|
||||
private String createUserId; |
||||
|
||||
private Instant createDt; |
||||
|
||||
private String updateUserId; |
||||
|
||||
private Instant updateDt; |
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.palnet.biz.api.cns.faq.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class FaqListRQModel { |
||||
|
||||
private String category; |
||||
|
||||
private String word; |
||||
|
||||
} |
@ -0,0 +1,105 @@
|
||||
package com.palnet.biz.api.cns.faq.service; |
||||
|
||||
import java.time.Instant; |
||||
import java.util.List; |
||||
|
||||
import javax.transaction.Transactional; |
||||
|
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import com.palnet.biz.api.cns.faq.model.FaqListModel; |
||||
import com.palnet.biz.api.cns.faq.model.FaqListRQModel; |
||||
import com.palnet.biz.jpa.entity.CnsFaqBas; |
||||
import com.palnet.biz.jpa.repository.cns.CnsFaqBasRepository; |
||||
import com.palnet.biz.jpa.repository.cns.CnsFaqQueryRepository; |
||||
import com.palnet.comn.code.ErrorCode; |
||||
import com.palnet.comn.exception.CustomException; |
||||
|
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@Slf4j |
||||
@Service |
||||
@RequiredArgsConstructor |
||||
public class CnsFaqService { |
||||
|
||||
private final CnsFaqQueryRepository query; |
||||
|
||||
private final CnsFaqBasRepository cnsFaqBasRepository; |
||||
|
||||
public List<FaqListModel> getFaqList(FaqListRQModel model){ |
||||
|
||||
List<FaqListModel> result = query.getFaqList(model.getCategory(), model.getWord()); |
||||
|
||||
if(result == null || result.size() < 1) throw new CustomException(ErrorCode.DATA_NO); |
||||
|
||||
return result; |
||||
|
||||
} |
||||
|
||||
public FaqListModel getFaqDetail(int sno){ |
||||
|
||||
cnsFaqBasRepository.updateViewCnt(sno); |
||||
|
||||
FaqListModel result = query.getFaqDetail(sno); |
||||
|
||||
if(result == null) throw new CustomException(ErrorCode.DATA_NO); |
||||
|
||||
return result; |
||||
|
||||
} |
||||
|
||||
@Transactional |
||||
public void insertFaq(FaqListModel model){ |
||||
|
||||
CnsFaqBas bas = new CnsFaqBas(); |
||||
|
||||
bas.setCreateDt(Instant.now()); |
||||
bas.setUpdateDt(Instant.now()); |
||||
|
||||
bas.setCategory(model.getCategory()); |
||||
bas.setContent(model.getContent()); |
||||
bas.setCreateUserId(model.getCreateUserId()); |
||||
bas.setDelYn(model.getDelYn()); |
||||
bas.setExpsrYn(model.getExpsrYn()); |
||||
bas.setTitle(model.getTitle()); |
||||
bas.setUpdateUserId(model.getUpdateUserId()); |
||||
bas.setViewCnt(0); |
||||
|
||||
try { |
||||
cnsFaqBasRepository.save(bas); |
||||
} catch(Exception e) { |
||||
throw new CustomException(ErrorCode.NON_VALID_PARAMETER); |
||||
} |
||||
} |
||||
|
||||
@Transactional |
||||
public void updateFaq(FaqListModel model) { |
||||
|
||||
FaqListModel prevData = query.getFaqDetail(model.getFaqSno()); |
||||
|
||||
if(prevData == null) throw new CustomException(ErrorCode.DATA_NO); |
||||
|
||||
if(model.getCategory() != null) prevData.setCategory(model.getCategory()); |
||||
if(model.getTitle() != null) prevData.setTitle(model.getTitle()); |
||||
if(model.getContent() != null) prevData.setContent(model.getContent()); |
||||
if(model.getExpsrYn() != null) prevData.setExpsrYn(model.getExpsrYn()); |
||||
if(model.getUpdateUserId() != null) prevData.setUpdateUserId(model.getUpdateUserId()); |
||||
|
||||
prevData.setUpdateDt(Instant.now()); |
||||
|
||||
try { |
||||
query.updateFaq(prevData); |
||||
} catch(Exception e) { |
||||
throw new CustomException(ErrorCode.NON_VALID_PARAMETER); |
||||
} |
||||
} |
||||
|
||||
public void deleteFaq(int sno) { |
||||
|
||||
int delCnt = cnsFaqBasRepository.deleteFaq(sno); |
||||
|
||||
if(delCnt == 0) throw new CustomException(ErrorCode.DATA_NO); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
package com.palnet.biz.api.cns.qna.controller; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.http.ResponseEntity; |
||||
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.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
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.QnaRSModel; |
||||
import com.palnet.biz.api.cns.qna.model.QnaSelectListRQ; |
||||
import com.palnet.biz.api.cns.qna.service.CnsQnaService; |
||||
|
||||
import io.swagger.annotations.ApiOperation; |
||||
import io.swagger.v3.oas.annotations.tags.Tag; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@RestController |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
@RequestMapping("/api/cns/qna") |
||||
public class CnsQnaController { |
||||
|
||||
private final CnsQnaService cnsQnaService; |
||||
|
||||
|
||||
@PostMapping(value = "/insert", consumes = "multipart/form-data") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 등록[답변추가]") |
||||
public ResponseEntity<Boolean> insertQna(QnaInsertRQModel rq){ |
||||
|
||||
boolean result = cnsQnaService.insertQna(rq); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
|
||||
@GetMapping("/select") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 리스트 조회") |
||||
public ResponseEntity<List<QnaBasModel>> selectQna(QnaSelectListRQ rq){ |
||||
|
||||
List<QnaBasModel> result = cnsQnaService.selectQnaList(rq); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
|
||||
|
||||
@GetMapping("/{qnaSno}/detail") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 상세보기") |
||||
public ResponseEntity<List<QnaDetailRSModel>> detailQna(@PathVariable int qnaSno){ |
||||
|
||||
List<QnaDetailRSModel> reulst = cnsQnaService.getQnaDetail(qnaSno); |
||||
|
||||
return ResponseEntity.ok().body(reulst); |
||||
} |
||||
|
||||
@PostMapping("/{qnaSno}/update") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 업데이트") |
||||
public ResponseEntity<Boolean> updateQna(@PathVariable int qnaSno, QnaInsertRQModel rq){ |
||||
|
||||
boolean result = cnsQnaService.updateQna(qnaSno, rq); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
|
||||
@GetMapping("/{qnaSno}/delete") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 삭제하기") |
||||
public ResponseEntity<Boolean> deleteQna(@PathVariable int qnaSno){ |
||||
|
||||
boolean result = cnsQnaService.deleteQna(qnaSno); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
|
||||
/** |
||||
* Qna Files 개별삭제 TODO:: 파일 업데이트의 기획이 어떻게 되는지 모름 |
||||
* @param qnaSno |
||||
* @param fileSno |
||||
* @return |
||||
*/ |
||||
@GetMapping("/{qnaSno}/{fileSno}/delete") |
||||
@Tag(name = "QNA", description = "QNA 관련 API") |
||||
@ApiOperation(value = "QnA 파일 개별삭제") |
||||
public ResponseEntity<Boolean> deleteQnaFile(@PathVariable int qnaSno, @PathVariable int fileSno){ |
||||
log.warn("CnsQnaController - deleteQnaFile()"); |
||||
|
||||
boolean result = cnsQnaService.deleteQnaFile(fileSno); |
||||
|
||||
return ResponseEntity.ok().body(result); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.palnet.biz.api.cns.qna.model; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class QnaBasModel { |
||||
|
||||
private int qnaSno; |
||||
|
||||
private int targetSno; |
||||
|
||||
private String category; |
||||
|
||||
private String title; |
||||
|
||||
private String content; |
||||
|
||||
private int fileGroupNo; |
||||
|
||||
private String expsrYn; |
||||
|
||||
private String delYn; |
||||
|
||||
private int viewCnt; |
||||
|
||||
private String createUserId; |
||||
|
||||
private Instant createDt; |
||||
|
||||
private String updateUserId; |
||||
|
||||
private Instant updateDt; |
||||
|
||||
} |
@ -0,0 +1,34 @@
|
||||
package com.palnet.biz.api.cns.qna.model; |
||||
|
||||
import java.time.Instant; |
||||
import java.util.List; |
||||
|
||||
import com.palnet.biz.jpa.entity.ComFileBas; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class QnaDetailRSModel { |
||||
|
||||
private int qnaSno; |
||||
|
||||
private int targetSno; |
||||
|
||||
private String category; |
||||
|
||||
private String title; |
||||
|
||||
private String content; |
||||
|
||||
private Integer viewCnt; |
||||
|
||||
private String createUserId; |
||||
|
||||
private Instant createDt; |
||||
|
||||
private String updateUserId; |
||||
|
||||
private Instant updateDt; |
||||
|
||||
private List<ComFileBas> files; |
||||
} |
@ -0,0 +1,23 @@
|
||||
package com.palnet.biz.api.cns.qna.model; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.web.multipart.MultipartFile; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class QnaInsertRQModel { |
||||
|
||||
private Integer qnaSno; |
||||
|
||||
private Integer targetSno; // 상위 Qna 번호
|
||||
|
||||
private String category; |
||||
|
||||
private String title; |
||||
|
||||
private String content; |
||||
|
||||
private List<MultipartFile> files; |
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.palnet.biz.api.cns.qna.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class QnaRSModel{ |
||||
|
||||
private int code; |
||||
|
||||
private String desc; |
||||
|
||||
private Object body; |
||||
|
||||
public QnaRSModel() { |
||||
this.code = 200; |
||||
} |
||||
|
||||
public QnaRSModel(Object body){ |
||||
this.code = 200; |
||||
this.body = body; |
||||
} |
||||
|
||||
public QnaRSModel(int code, Object body){ |
||||
this.code = code; |
||||
this.body = body; |
||||
} |
||||
|
||||
public QnaRSModel(int code, String desc, Object body){ |
||||
this.code = code; |
||||
this.desc = desc; |
||||
this.body = body; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
package com.palnet.biz.api.cns.qna.model; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class QnaSelectListRQ { |
||||
|
||||
private String word; |
||||
|
||||
private String category; |
||||
} |
@ -0,0 +1,216 @@
|
||||
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.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; |
||||
|
||||
@Service |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
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){ |
||||
|
||||
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<CnsQnaBas> deleteList = new ArrayList<>(); |
||||
deleteList.add(entity); |
||||
|
||||
int targetSno = qnaSno; |
||||
|
||||
// 대댓글 불러오기
|
||||
while(true){ |
||||
|
||||
CnsQnaBas cnsQnaBas = cnsQnaBasRepository.findFirstByTargetSnoAndDelYnAndExpsrYn(targetSno, "N", "Y"); |
||||
if(cnsQnaBas == null) break; |
||||
|
||||
cnsQnaBas.setDelYn("Y"); |
||||
|
||||
deleteList.add(cnsQnaBas); |
||||
|
||||
targetSno = cnsQnaBas.getQnaSno(); |
||||
} |
||||
|
||||
deleteList = cnsQnaBasRepository.saveAll(deleteList); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Qna 업데이트하기 TODO :: File 업데이트 기능 아직 구현안함 |
||||
* @param qnaSno |
||||
* @param rq |
||||
* @return |
||||
*/ |
||||
@Transactional |
||||
public boolean updateQna(int qnaSno, QnaInsertRQModel rq){ |
||||
|
||||
CnsQnaBas entity = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(qnaSno, 0, "N", "Y"); |
||||
if(entity == null) throw new CustomException(ErrorCode.DATA_NOTFIND); |
||||
|
||||
List<MultipartFile> files = rq.getFiles(); |
||||
if(files != null && files.size() > 0) 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()); |
||||
|
||||
cnsQnaBasRepository.save(entity); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Qna 상세불러오기 |
||||
* @param qnaSno |
||||
* @return |
||||
*/ |
||||
@Transactional // 조회수 증가하기떄문
|
||||
public List<QnaDetailRSModel> getQnaDetail(int qnaSno){ |
||||
|
||||
cnsQnaBasRepository.pulsViewCount(qnaSno); |
||||
|
||||
CnsQnaBas qnaBasModel = cnsQnaBasRepository.findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(qnaSno, 0, "N", "Y"); |
||||
List<ComFileBas> 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<QnaDetailRSModel> 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; |
||||
} |
||||
|
||||
/** |
||||
* Qna리스트 조회 |
||||
* @param rq |
||||
* @return |
||||
*/ |
||||
public List<QnaBasModel> selectQnaList(QnaSelectListRQ rq){ |
||||
|
||||
return cnsQnaQueryRepository.getQnaList(rq.getCategory(), rq.getCategory()); |
||||
} |
||||
|
||||
/** |
||||
* QnaInsert |
||||
* @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 = new CnsQnaBas(); |
||||
cnsQnaBas.setCategory(rq.getCategory()); |
||||
cnsQnaBas.setTitle(rq.getTitle()); |
||||
cnsQnaBas.setContent(rq.getContent()); |
||||
cnsQnaBas.setCreateDt(Instant.now()); |
||||
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()); |
||||
|
||||
cnsQnaBasRepository.save(cnsQnaBas); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,39 @@
|
||||
package com.palnet.biz.api.comn.file.constant; |
||||
|
||||
import java.util.HashSet; |
||||
|
||||
public enum ExtensionConstant { |
||||
JPG(".jpg"), |
||||
PNG(".png"), |
||||
JPEG(".jpeg"), |
||||
PDF(".pdf"), |
||||
XLSX(".xlsx"), |
||||
XLS(".xls"), |
||||
HWPX(".hwpx"), |
||||
HWP(".hwp"), |
||||
|
||||
; |
||||
|
||||
public final String extension; |
||||
|
||||
public HashSet<ExtensionConstant> hashExtension; |
||||
|
||||
private ExtensionConstant(String extension) { |
||||
this.extension = extension; |
||||
} |
||||
|
||||
public static ExtensionConstant fromExtension(String extension) { |
||||
try { |
||||
for (ExtensionConstant constant : ExtensionConstant.values()) { |
||||
if (constant.extension.equals(extension)) { |
||||
|
||||
return constant; |
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
package com.palnet.biz.jpa.entity; |
||||
|
||||
import java.io.Serializable; |
||||
import java.time.Instant; |
||||
|
||||
import javax.persistence.*; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Entity |
||||
@Data |
||||
@Table(name="CNS_FAQ_BAS") |
||||
@NamedQuery(name="CnsFaqBas.findAll", query="SELECT c FROM CnsFaqBas c") |
||||
public class CnsFaqBas implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
@Column(name="FAQ_SNO") |
||||
private int faqSno; |
||||
|
||||
@Column(name="CATEGORY") |
||||
private String category; |
||||
|
||||
@Column(name="TITLE") |
||||
private String title; |
||||
|
||||
@Column(name="CONTENT") |
||||
private String content; |
||||
|
||||
@Column(name="VIEW_CNT") |
||||
private int viewCnt = 0; |
||||
|
||||
@Column(name="EXPSR_YN") |
||||
private String expsrYn = "N"; |
||||
|
||||
@Column(name="DEL_YN") |
||||
private String delYn = "N"; |
||||
|
||||
@Column(name="CREATE_USER_ID") |
||||
private String createUserId; |
||||
|
||||
@Column(name="CREATE_DT") |
||||
private Instant createDt; |
||||
|
||||
@Column(name="UPDATE_USER_ID") |
||||
private String updateUserId; |
||||
|
||||
@Column(name="UPDATE_DT") |
||||
private Instant updateDt; |
||||
|
||||
} |
@ -0,0 +1,60 @@
|
||||
package com.palnet.biz.jpa.entity; |
||||
|
||||
import java.io.Serializable; |
||||
import java.time.Instant; |
||||
|
||||
import javax.persistence.*; |
||||
|
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
|
||||
@Entity |
||||
@Data |
||||
@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") |
||||
private int qnaSno; |
||||
|
||||
@Column(name="TARGET_SNO") |
||||
private int targetSno; |
||||
|
||||
@Column(name="CATEGORY") |
||||
private String category; |
||||
|
||||
@Column(name="TITLE") |
||||
private String title; |
||||
|
||||
@Column(name="CONTENT") |
||||
private String content; |
||||
|
||||
@Column(name="FILE_GROUP_NO") |
||||
private Integer fileGroupNo; |
||||
|
||||
@Column(name="EXPSR_YN") |
||||
private String expsrYn = "N"; |
||||
|
||||
@Column(name="DEL_YN") |
||||
private String delYn = "N"; |
||||
|
||||
@Column(name="VIEW_CNT") |
||||
private int viewCnt = 0; |
||||
|
||||
@Column(name="CREATE_USER_ID") |
||||
private String createUserId; |
||||
|
||||
@Column(name="CREATE_DT") |
||||
private Instant createDt; |
||||
|
||||
@Column(name="UPDATE_USER_ID") |
||||
private String updateUserId; |
||||
|
||||
@Column(name="UPDATE_DT") |
||||
private Instant updateDt; |
||||
|
||||
} |
@ -0,0 +1,27 @@
|
||||
package com.palnet.biz.jpa.repository.cns; |
||||
|
||||
import javax.transaction.Transactional; |
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository; |
||||
import org.springframework.data.jpa.repository.Modifying; |
||||
import org.springframework.data.jpa.repository.Query; |
||||
import org.springframework.data.repository.query.Param; |
||||
import org.springframework.stereotype.Repository; |
||||
|
||||
import com.palnet.biz.jpa.entity.CnsFaqBas; |
||||
|
||||
@Repository |
||||
public interface CnsFaqBasRepository extends JpaRepository<CnsFaqBas, Integer>{ |
||||
|
||||
@Modifying |
||||
@Transactional |
||||
@Query("update CnsFaqBas c set c.viewCnt = c.viewCnt + 1" + |
||||
"where c.faqSno = :sno") |
||||
int updateViewCnt(@Param("sno") int sno); |
||||
|
||||
@Modifying |
||||
@Transactional |
||||
@Query("update CnsFaqBas c set c.delYn = 'Y' " + |
||||
"where c.faqSno = :sno") |
||||
int deleteFaq(@Param("sno") int sno); |
||||
} |
@ -0,0 +1,111 @@
|
||||
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; |
||||
|
||||
@Slf4j |
||||
@Repository |
||||
@RequiredArgsConstructor |
||||
public class CnsFaqQueryRepository { |
||||
|
||||
private final JPAQueryFactory query; |
||||
|
||||
public List<FaqListModel> 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<FaqListModel> r = query |
||||
.select(Projections.bean( |
||||
FaqListModel.class, |
||||
bas.faqSno, |
||||
bas.category, |
||||
bas.title, |
||||
bas.content, |
||||
bas.viewCnt, |
||||
bas.expsrYn, |
||||
bas.delYn, |
||||
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)); |
||||
|
||||
FaqListModel r = query |
||||
.select(Projections.bean( |
||||
FaqListModel.class, |
||||
bas.faqSno, |
||||
bas.category, |
||||
bas.title, |
||||
bas.content, |
||||
bas.viewCnt, |
||||
bas.expsrYn, |
||||
bas.delYn, |
||||
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(); |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,23 @@
|
||||
package com.palnet.biz.jpa.repository.cns; |
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository; |
||||
import org.springframework.data.jpa.repository.Modifying; |
||||
import org.springframework.data.jpa.repository.Query; |
||||
import org.springframework.data.repository.query.Param; |
||||
import org.springframework.stereotype.Repository; |
||||
|
||||
import com.palnet.biz.jpa.entity.CnsQnaBas; |
||||
|
||||
@Repository |
||||
public interface CnsQnaBasRepository extends JpaRepository<CnsQnaBas, Integer>{ |
||||
|
||||
CnsQnaBas findFirstByTargetSnoAndDelYnAndExpsrYn(int targetSno, String delYn, String expsrYn); |
||||
|
||||
CnsQnaBas findByQnaSnoAndDelYnAndExpsrYn(int qnaSno, String delYn, String expsrYn); |
||||
|
||||
CnsQnaBas findFirstByQnaSnoAndTargetSnoAndDelYnAndExpsrYn(int qnaSno, int targetSno, String delYn, String expsrYn); |
||||
|
||||
@Modifying |
||||
@Query("UPDATE CnsQnaBas q SET q.viewCnt = q.viewCnt + 1 WHERE q.qnaSno = :qnaSno") |
||||
void pulsViewCount(@Param("qnaSno")int qnaSno); |
||||
} |
@ -0,0 +1,69 @@
|
||||
package com.palnet.biz.jpa.repository.cns; |
||||
|
||||
import java.util.List; |
||||
|
||||
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; |
||||
|
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
@Slf4j |
||||
@Repository |
||||
@RequiredArgsConstructor |
||||
public class CnsQnaQueryRepository { |
||||
|
||||
private final JPAQueryFactory query; |
||||
|
||||
/** |
||||
* 카테고리와 글로 게시글 검색, 만약 조건 없으면 전체검색 |
||||
* @param category |
||||
* @param word |
||||
* @return |
||||
*/ |
||||
public List<QnaBasModel> getQnaList(String category, String word) { |
||||
QCnsQnaBas bas = QCnsQnaBas.cnsQnaBas; |
||||
|
||||
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<QnaBasModel> 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; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue