Q&A 7일후 자동 종료 배치
This commit is contained in:
@@ -20,15 +20,22 @@
|
|||||||
var select_orgId = "";
|
var select_orgId = "";
|
||||||
|
|
||||||
function formatInquiryStatus(cellvalue, options, rowObject) {
|
function formatInquiryStatus(cellvalue, options, rowObject) {
|
||||||
return cellvalue === 'PENDING'
|
if (cellvalue == 'PENDING') {
|
||||||
? '<span style="color: red;">문의중</span>'
|
return '<span style="color: red;">문의중</span>';
|
||||||
: '<span>답변완료</span>';
|
} else if (cellvalue == 'RESPONDED') {
|
||||||
|
return '<span >답변완료</span>'
|
||||||
|
} else if (cellvalue == 'CLOSED') {
|
||||||
|
return '<span >답변종료</span>'
|
||||||
|
} else {
|
||||||
|
return cellvalue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatFile(cellvalue, options, rowObject) {
|
function formatFile(cellvalue, options, rowObject) {
|
||||||
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
|
var iconPath = '${pageContext.request.contextPath}/images/icon_file.png';
|
||||||
var icon = rowObject.hasAttachment ? '<img src="' + iconPath + '" alt="File Attached" style="vertical-align: middle; margin-left: 5px; width: 16px; height: 16px;">' : '';
|
var icon = rowObject.hasAttachment ? '<img src="' + iconPath + '" alt="File Attached" style="vertical-align: middle; margin-left: 5px; width: 16px; height: 16px;">' : '';
|
||||||
return cellvalue + icon;
|
var commentCount = rowObject.commentCount > 0 ? ' <span style="color: #337ab7;">[' + rowObject.commentCount + ']</span>' : '';
|
||||||
|
return cellvalue + icon + commentCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSelectedRows() {
|
function deleteSelectedRows() {
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
var url = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.json" />';
|
var url = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.json" />';
|
||||||
var url_view = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.view" />';
|
var url_view = '<c:url value="/onl/apim/portalinquiry/portalInquiryMan.view" />';
|
||||||
var file_download = '<c:url value="/file/download.do" />';
|
var file_download = '<c:url value="/file/download.do" />';
|
||||||
|
var inquiryStatus = 'PENDING';
|
||||||
|
|
||||||
function decodeHTMLEntities(text) {
|
function decodeHTMLEntities(text) {
|
||||||
var textArea = document.createElement('textarea');
|
var textArea = document.createElement('textarea');
|
||||||
@@ -98,10 +99,21 @@
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: {cmd: 'DETAIL', id: key},
|
data: {cmd: 'DETAIL', id: key},
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
|
||||||
|
|
||||||
$("#id").val(key);
|
$("#id").val(key);
|
||||||
|
|
||||||
$("#inquirySubject").text(data.inquirySubject);
|
$("#inquirySubject").text(data.inquirySubject);
|
||||||
$("#inquiryDetail").html(data.inquiryDetail);
|
$("#inquiryDetail").html(data.inquiryDetail);
|
||||||
$("#inquiryStatus").text(data.inquiryStatus === 'PENDING' ? '문의중' : '답변완료');
|
|
||||||
|
inquiryStatus = data.inquiryStatus;
|
||||||
|
if (data.inquiryStatus == 'PENDING') {
|
||||||
|
$("#inquiryStatus").text('문의중');
|
||||||
|
} else if (data.inquiryStatus == 'RESPONDED') {
|
||||||
|
$("#inquiryStatus").text('답변완료');
|
||||||
|
} else if (data.inquiryStatus == 'CLOSED') {
|
||||||
|
$("#inquiryStatus").text('답변종료');
|
||||||
|
}
|
||||||
$("#inquirer").text(data.inquirer.userName);
|
$("#inquirer").text(data.inquirer.userName);
|
||||||
$("#createdDate").text(timeStampFormat(data.createdDate));
|
$("#createdDate").text(timeStampFormat(data.createdDate));
|
||||||
$("#responder").text(data.responderName || '');
|
$("#responder").text(data.responderName || '');
|
||||||
@@ -158,6 +170,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteComment(commentId, inquiryId) {
|
function deleteComment(commentId, inquiryId) {
|
||||||
|
if (inquiryStatus == 'CLOSED') {
|
||||||
|
alert('답변이 종료되어 삭제할 수 없습니다');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!confirm("댓글을 삭제하시겠습니까?")) return;
|
if (!confirm("댓글을 삭제하시겠습니까?")) return;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@@ -188,6 +204,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$("#btn_modify").click(function () {
|
$("#btn_modify").click(function () {
|
||||||
|
if (inquiryStatus == 'CLOSED') {
|
||||||
|
alert('답변이 종료되어 수정할 수 없습니다');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!checkRequired("ajaxForm")) return;
|
if (!checkRequired("ajaxForm")) return;
|
||||||
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
|
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
|
||||||
|
|
||||||
@@ -209,7 +229,10 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$("#btn_comment").click(function () {
|
$("#btn_comment").click(function () {
|
||||||
|
if (inquiryStatus == 'CLOSED') {
|
||||||
|
alert('답변이 종료되어 댓글을 등록할 수 없습니다');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
|
if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -297,6 +320,10 @@
|
|||||||
|
|
||||||
<!-- 답변 작성 부분 -->
|
<!-- 답변 작성 부분 -->
|
||||||
<div class="response-section">
|
<div class="response-section">
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-label">상태</div>
|
||||||
|
<div id="inquiryStatus" class="info-content"></div>
|
||||||
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-label">답변자</div>
|
<div class="info-label">답변자</div>
|
||||||
<div id="responder" class="info-content"></div>
|
<div id="responder" class="info-content"></div>
|
||||||
|
|||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
package com.eactive.eai.rms.data.entity.onl.apim.portalinquiry;
|
|
||||||
|
|
||||||
import com.eactive.apim.portal.qna.entity.InquiryComment;
|
|
||||||
import com.eactive.eai.data.jpa.BaseRepository;
|
|
||||||
import com.eactive.eai.rms.data.EMSDataSource;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@EMSDataSource
|
|
||||||
public interface InquiryCommentRepository extends BaseRepository<InquiryComment, String> {
|
|
||||||
|
|
||||||
long countByInquiry_Id(String inquiryId);
|
|
||||||
|
|
||||||
List<InquiryComment> findByInquiry_IdAndDelYnOrderBySeqAsc(String inquiryId, String delYn);
|
|
||||||
}
|
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package com.eactive.eai.rms.data.entity.onl.apim.portalinquiry;
|
||||||
|
|
||||||
|
import com.eactive.apim.portal.qna.entity.InquiryComment;
|
||||||
|
import com.eactive.eai.data.jpa.BaseRepository;
|
||||||
|
import com.eactive.eai.rms.data.EMSDataSource;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@EMSDataSource
|
||||||
|
public interface PortalInquiryCommentRepository extends BaseRepository<InquiryComment, String> {
|
||||||
|
|
||||||
|
long countByInquiry_Id(String inquiryId);
|
||||||
|
|
||||||
|
long countByInquiry_IdAndDelYn(String inquiryId, String delYn);
|
||||||
|
|
||||||
|
List<InquiryComment> findByInquiry_IdAndDelYnOrderByCreatedDateAsc(String inquiryId, String delYn);
|
||||||
|
|
||||||
|
Optional<InquiryComment> findTopByInquiry_IdAndDelYnOrderByCreatedDateDesc(
|
||||||
|
String inquiryId, String delYn);
|
||||||
|
|
||||||
|
Optional<InquiryComment> findTopByInquiry_IdAndAdminYnAndDelYnOrderByCreatedDateDesc(
|
||||||
|
String inquiryId, String adminYn, String delYn);
|
||||||
|
|
||||||
|
boolean existsByInquiry_IdAndAdminYnAndDelYnAndCreatedDateAfter(
|
||||||
|
String inquiryId, String adminYn, String delYn, LocalDateTime after);
|
||||||
|
}
|
||||||
+7
-3
@@ -10,18 +10,22 @@ import java.util.List;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(transactionManager = "transactionManagerForEMS")
|
@Transactional(transactionManager = "transactionManagerForEMS")
|
||||||
public class PortalInquiryCommentService extends AbstractEMSDataSerivce<InquiryComment, String, InquiryCommentRepository> {
|
public class PortalInquiryCommentService extends AbstractEMSDataSerivce<InquiryComment, String, PortalInquiryCommentRepository> {
|
||||||
|
|
||||||
// AbstractEMSDataSerivce의 repository 필드가 BaseRepository<T,I>로 고정되어
|
// AbstractEMSDataSerivce의 repository 필드가 BaseRepository<T,I>로 고정되어
|
||||||
// 커스텀 메서드를 호출할 수 없으므로 별도 필드로 직접 주입
|
// 커스텀 메서드를 호출할 수 없으므로 별도 필드로 직접 주입
|
||||||
@Autowired
|
@Autowired
|
||||||
private InquiryCommentRepository inquiryCommentRepository;
|
private PortalInquiryCommentRepository inquiryCommentRepository;
|
||||||
|
|
||||||
public long countByInquiryId(String inquiryId) {
|
public long countByInquiryId(String inquiryId) {
|
||||||
return inquiryCommentRepository.countByInquiry_Id(inquiryId);
|
return inquiryCommentRepository.countByInquiry_Id(inquiryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long countActiveByInquiryId(String inquiryId) {
|
||||||
|
return inquiryCommentRepository.countByInquiry_IdAndDelYn(inquiryId, "N");
|
||||||
|
}
|
||||||
|
|
||||||
public List<InquiryComment> findByInquiryId(String inquiryId) {
|
public List<InquiryComment> findByInquiryId(String inquiryId) {
|
||||||
return inquiryCommentRepository.findByInquiry_IdAndDelYnOrderBySeqAsc(inquiryId, "N");
|
return inquiryCommentRepository.findByInquiry_IdAndDelYnOrderByCreatedDateAsc(inquiryId, "N");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -4,7 +4,10 @@ import com.eactive.apim.portal.qna.entity.Inquiry;
|
|||||||
import com.eactive.eai.data.jpa.BaseRepository;
|
import com.eactive.eai.data.jpa.BaseRepository;
|
||||||
import com.eactive.eai.rms.data.EMSDataSource;
|
import com.eactive.eai.rms.data.EMSDataSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@EMSDataSource
|
@EMSDataSource
|
||||||
public interface PortalInquiryRepository extends BaseRepository<Inquiry, String> {
|
public interface PortalInquiryRepository extends BaseRepository<Inquiry, String> {
|
||||||
|
|
||||||
|
List<Inquiry> findByInquiryStatus(String inquiryStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-6
@@ -1,20 +1,28 @@
|
|||||||
package com.eactive.eai.rms.data.entity.onl.apim.portalinquiry;
|
package com.eactive.eai.rms.data.entity.onl.apim.portalinquiry;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.eactive.apim.portal.qna.entity.Inquiry;
|
import com.eactive.apim.portal.qna.entity.Inquiry;
|
||||||
import com.eactive.apim.portal.qna.entity.QInquiry;
|
import com.eactive.apim.portal.qna.entity.QInquiry;
|
||||||
import com.eactive.eai.rms.data.jpa.AbstractEMSDataSerivce;
|
import com.eactive.eai.rms.data.jpa.AbstractEMSDataSerivce;
|
||||||
import com.querydsl.core.BooleanBuilder;
|
import com.querydsl.core.BooleanBuilder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(transactionManager = "transactionManagerForEMS")
|
@Transactional(transactionManager = "transactionManagerForEMS")
|
||||||
public class PortalInquiryService extends AbstractEMSDataSerivce<Inquiry, String, PortalInquiryRepository> {
|
public class PortalInquiryService extends AbstractEMSDataSerivce<Inquiry, String, PortalInquiryRepository> {
|
||||||
|
|
||||||
|
// AbstractEMSDataSerivce의 repository 필드가 BaseRepository<T,I>로 고정되어
|
||||||
|
// 커스텀 메서드를 호출할 수 없으므로 별도 필드로 직접 주입
|
||||||
|
@Autowired
|
||||||
|
private PortalInquiryRepository portalInquiryRepository;
|
||||||
|
|
||||||
public Page<Inquiry> findAll(Pageable pageable, PortalInquirySearch portalInquirySearch) {
|
public Page<Inquiry> findAll(Pageable pageable, PortalInquirySearch portalInquirySearch) {
|
||||||
QInquiry qInquiry = QInquiry.inquiry;
|
QInquiry qInquiry = QInquiry.inquiry;
|
||||||
|
|
||||||
@@ -58,4 +66,8 @@ public class PortalInquiryService extends AbstractEMSDataSerivce<Inquiry, String
|
|||||||
repository.deleteAll(inquiries);
|
repository.deleteAll(inquiries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Inquiry> findByInquiryStatus(String inquiryStatus) {
|
||||||
|
return portalInquiryRepository.findByInquiryStatus(inquiryStatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.eactive.eai.rms.ext.djb.job;
|
||||||
|
|
||||||
|
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
|
||||||
|
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
|
||||||
|
import com.eactive.eai.rms.common.util.CommonUtil;
|
||||||
|
import com.eactive.eai.rms.onl.apim.portalInquiry.PortalInquiryClosingService;
|
||||||
|
import com.eactive.eai.rms.onl.common.util.DateUtil;
|
||||||
|
import org.quartz.DisallowConcurrentExecution;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 매일 00:05 실행 - RESPONDED 상태 문의글 자동 종료 배치
|
||||||
|
*
|
||||||
|
* <p>종료 조건 (기본 7일):</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>답변완료 후 댓글이 7일간 없는 경우</li>
|
||||||
|
* <li>관리자 댓글 등록 후 7일간 포탈사용자 댓글이 없는 경우</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>Cron: 0 5 0 * * ?</p>
|
||||||
|
*
|
||||||
|
* <p>Job 파라미터 (JobDataMap):</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>{@value #KEY_INQUIRY_COMMENT_CLOSING_DAY}: 종료 기준 일수 (기본값: 7)</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@DisallowConcurrentExecution
|
||||||
|
public class PortalInquiryClosingJob implements Job {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(PortalInquiryClosingJob.class);
|
||||||
|
|
||||||
|
/** Job 파라미터 키: 댓글종료 기간(일) */
|
||||||
|
public static final String KEY_INQUIRY_COMMENT_CLOSING_DAY = "inquiry.comment.closing_day";
|
||||||
|
|
||||||
|
private static final int DEFAULT_CLOSING_DAYS = 7;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PortalInquiryClosingService inquiryCommentClosingService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
log.info("*** START PortalInquiryCommentClosingService run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm"));
|
||||||
|
|
||||||
|
int closingDays = DEFAULT_CLOSING_DAYS;
|
||||||
|
String closingDayParam = context.getMergedJobDataMap().getString(KEY_INQUIRY_COMMENT_CLOSING_DAY);
|
||||||
|
if (closingDayParam != null) {
|
||||||
|
try {
|
||||||
|
closingDays = Integer.parseInt(closingDayParam);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("잘못된 {} 파라미터 값: '{}', 기본값 {}일 사용", KEY_INQUIRY_COMMENT_CLOSING_DAY, closingDayParam, DEFAULT_CLOSING_DAYS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSourceContextHolder.setDataSourceType(
|
||||||
|
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
|
||||||
|
try {
|
||||||
|
int closedCount = inquiryCommentClosingService.closeExpiredInquiries(closingDays);
|
||||||
|
log.info("PortalInquiryCommentClosingService 완료: {}건 CLOSED 처리", closedCount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("PortalInquiryCommentClosingService execution failed", e);
|
||||||
|
throw new JobExecutionException(e);
|
||||||
|
} finally {
|
||||||
|
DataSourceContextHolder.clearDataSourceType();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("*** END PortalInquiryCommentClosingService run({})", DateUtil.getDateTime("yyyy-MM-dd HH:mm"));
|
||||||
|
}
|
||||||
|
}
|
||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
package com.eactive.eai.rms.onl.apim.portalInquiry;
|
||||||
|
|
||||||
|
import com.eactive.apim.portal.qna.entity.Inquiry;
|
||||||
|
import com.eactive.apim.portal.qna.entity.InquiryComment;
|
||||||
|
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryCommentRepository;
|
||||||
|
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryCommentService;
|
||||||
|
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RESPONDED 상태 문의글 중 아래 조건에 해당하는 경우 CLOSED로 변경한다.
|
||||||
|
* - 조건 A: 활성 댓글이 없고 답변완료일(responseDate)로부터 N일 경과
|
||||||
|
* - 조건 B: 마지막 관리자 댓글(adminYn=Y) 이후 N일간 포탈사용자(adminYn=N) 댓글 없음
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Transactional(transactionManager = "transactionManagerForEMS")
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PortalInquiryClosingService {
|
||||||
|
|
||||||
|
private static final String RESPONDED = "RESPONDED";
|
||||||
|
private static final String CLOSED = "CLOSED";
|
||||||
|
|
||||||
|
private final PortalInquiryService portalInquiryService;
|
||||||
|
private final PortalInquiryCommentService portalInquiryCommentService;
|
||||||
|
private final PortalInquiryCommentRepository inquiryCommentRepository;
|
||||||
|
|
||||||
|
public int closeExpiredInquiries(int closingDays) {
|
||||||
|
LocalDateTime threshold = LocalDateTime.now().minusDays(closingDays);
|
||||||
|
List<Inquiry> respondedInquiries = portalInquiryService.findByInquiryStatus(RESPONDED);
|
||||||
|
|
||||||
|
int closedCount = 0;
|
||||||
|
for (Inquiry inquiry : respondedInquiries) {
|
||||||
|
if (shouldClose(inquiry, threshold)) {
|
||||||
|
inquiry.setInquiryStatus(CLOSED);
|
||||||
|
portalInquiryService.save(inquiry);
|
||||||
|
closedCount++;
|
||||||
|
log.info("문의글 CLOSED 처리: id={}", inquiry.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("InquiryCommentClosingService: 총 {}건 CLOSED 처리 (기준={}일)", closedCount, closingDays);
|
||||||
|
return closedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldClose(Inquiry inquiry, LocalDateTime threshold) {
|
||||||
|
long activeCommentCount = portalInquiryCommentService.countActiveByInquiryId(inquiry.getId());
|
||||||
|
|
||||||
|
// 댓글 없음 → 답변완료일 기준 N일 경과 여부만 확인
|
||||||
|
if (activeCommentCount == 0) {
|
||||||
|
LocalDateTime responseDate = inquiry.getResponseDate();
|
||||||
|
return responseDate != null && !responseDate.isAfter(threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가장 최근 활성 댓글 확인
|
||||||
|
Optional<InquiryComment> lastComment = inquiryCommentRepository
|
||||||
|
.findTopByInquiry_IdAndDelYnOrderByCreatedDateDesc(inquiry.getId(), "N");
|
||||||
|
|
||||||
|
if (!lastComment.isPresent()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 포탈사용자(adminYn != 'Y')가 마지막 댓글 작성자 → CLOSED 불가
|
||||||
|
if (!"Y".equals(lastComment.get().getAdminYn())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 관리자가 마지막 댓글 작성자 → N일 경과 여부 확인
|
||||||
|
LocalDateTime lastAdminDate = lastComment.get().getCreatedDate();
|
||||||
|
return lastAdminDate != null && !lastAdminDate.isAfter(threshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-3
@@ -20,9 +20,7 @@ public class PortalInquiryCommentUI {
|
|||||||
private String inquiryId;
|
private String inquiryId;
|
||||||
|
|
||||||
private String commentDetail;
|
private String commentDetail;
|
||||||
|
|
||||||
private int seq;
|
|
||||||
|
|
||||||
private String delYn;
|
private String delYn;
|
||||||
|
|
||||||
private String createdBy;
|
private String createdBy;
|
||||||
|
|||||||
+13
-2
@@ -9,6 +9,7 @@ import com.eactive.apim.portal.qna.entity.Inquiry;
|
|||||||
import com.eactive.apim.portal.qna.entity.InquiryComment;
|
import com.eactive.apim.portal.qna.entity.InquiryComment;
|
||||||
import com.eactive.apim.portal.user.entity.UserInfo;
|
import com.eactive.apim.portal.user.entity.UserInfo;
|
||||||
import com.eactive.eai.rms.common.base.BaseService;
|
import com.eactive.eai.rms.common.base.BaseService;
|
||||||
|
import com.eactive.eai.rms.common.exception.IntegrationException;
|
||||||
import com.eactive.eai.rms.data.entity.man.user.UserInfoService;
|
import com.eactive.eai.rms.data.entity.man.user.UserInfoService;
|
||||||
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryCommentService;
|
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryCommentService;
|
||||||
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquirySearch;
|
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquirySearch;
|
||||||
@@ -41,6 +42,7 @@ public class PortalInquiryManService extends BaseService {
|
|||||||
|
|
||||||
public static final String PENDING = "PENDING";
|
public static final String PENDING = "PENDING";
|
||||||
public static final String RESPONDED = "RESPONDED";
|
public static final String RESPONDED = "RESPONDED";
|
||||||
|
public static final String CLOSED = "CLOSED";
|
||||||
|
|
||||||
|
|
||||||
public PortalInquiryManService(PortalInquiryService portalInquiryService,
|
public PortalInquiryManService(PortalInquiryService portalInquiryService,
|
||||||
@@ -68,6 +70,7 @@ public class PortalInquiryManService extends BaseService {
|
|||||||
if (ui.getInquirer() != null) {
|
if (ui.getInquirer() != null) {
|
||||||
maskPortalInquiryUI(ui);
|
maskPortalInquiryUI(ui);
|
||||||
}
|
}
|
||||||
|
ui.setCommentCount((int) portalInquiryCommentService.countActiveByInquiryId(inquiry.getId()));
|
||||||
return setInquiryAttachmentStatus(ui);
|
return setInquiryAttachmentStatus(ui);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -154,6 +157,7 @@ public class PortalInquiryManService extends BaseService {
|
|||||||
UserInfo userinfo = userInfoService.getById(userId);
|
UserInfo userinfo = userInfoService.getById(userId);
|
||||||
|
|
||||||
Inquiry inquiry = portalInquiryService.getById(portalInquiryUI.getId());
|
Inquiry inquiry = portalInquiryService.getById(portalInquiryUI.getId());
|
||||||
|
validateNotClosed(inquiry);
|
||||||
// 답변 대기중 상태일 경우만 답변완료로 상태 변경
|
// 답변 대기중 상태일 경우만 답변완료로 상태 변경
|
||||||
if(inquiry.getInquiryStatus().equals(PENDING)) {
|
if(inquiry.getInquiryStatus().equals(PENDING)) {
|
||||||
inquiry.setInquiryStatus(RESPONDED);
|
inquiry.setInquiryStatus(RESPONDED);
|
||||||
@@ -199,21 +203,28 @@ public class PortalInquiryManService extends BaseService {
|
|||||||
|
|
||||||
public void insertComment(PortalInquiryCommentUI commentUI, String userId) {
|
public void insertComment(PortalInquiryCommentUI commentUI, String userId) {
|
||||||
Inquiry inquiry = portalInquiryService.getById(commentUI.getInquiryId());
|
Inquiry inquiry = portalInquiryService.getById(commentUI.getInquiryId());
|
||||||
|
validateNotClosed(inquiry);
|
||||||
|
|
||||||
InquiryComment comment = new InquiryComment();
|
InquiryComment comment = new InquiryComment();
|
||||||
comment.setInquiry(inquiry);
|
comment.setInquiry(inquiry);
|
||||||
comment.setCommentDetail(commentUI.getCommentDetail());
|
comment.setCommentDetail(commentUI.getCommentDetail());
|
||||||
comment.setDelYn("N");
|
comment.setDelYn("N");
|
||||||
int nextSeq = (int) portalInquiryCommentService.countByInquiryId(commentUI.getInquiryId()) + 1;
|
comment.setAdminYn("Y");
|
||||||
comment.setSeq(nextSeq);
|
|
||||||
|
|
||||||
portalInquiryCommentService.save(comment);
|
portalInquiryCommentService.save(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteComment(String commentId) {
|
public void deleteComment(String commentId) {
|
||||||
InquiryComment comment = portalInquiryCommentService.getById(commentId);
|
InquiryComment comment = portalInquiryCommentService.getById(commentId);
|
||||||
|
validateNotClosed(comment.getInquiry());
|
||||||
comment.setDelYn("Y");
|
comment.setDelYn("Y");
|
||||||
portalInquiryCommentService.save(comment);
|
portalInquiryCommentService.save(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateNotClosed(Inquiry inquiry) {
|
||||||
|
if (CLOSED.equals(inquiry.getInquiryStatus())) {
|
||||||
|
throw new IntegrationException("답변종료되어 수정할 수 없습니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,4 +55,6 @@ public class PortalInquiryUI {
|
|||||||
private LocalDateTime lastModifiedDate;
|
private LocalDateTime lastModifiedDate;
|
||||||
|
|
||||||
private String orgName;
|
private String orgName;
|
||||||
|
|
||||||
|
private int commentCount;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user