diff --git a/WebContent/jsp/onl/apim/portalinquiry/portalInquiryManDetail.jsp b/WebContent/jsp/onl/apim/portalinquiry/portalInquiryManDetail.jsp index 7711d66..a302d4e 100644 --- a/WebContent/jsp/onl/apim/portalinquiry/portalInquiryManDetail.jsp +++ b/WebContent/jsp/onl/apim/portalinquiry/portalInquiryManDetail.jsp @@ -36,6 +36,13 @@ padding-bottom: 10px; border-bottom: 2px solid #e0e0e0; /* 제목 아래 줄 긋기 */ } + + .comment-section { + margin-bottom: 30px; + border: 1px solid #e0e0e0; /* 동일한 박스 스타일 */ + padding: 20px; + border-radius: 5px; + } .info-row { margin-bottom: 10px; @@ -57,6 +64,15 @@ width: 100%; min-height: 200px; } + + #commentDetail { + min-height: 100px; + border: 1px solid #00000032; + border-radius: 4px; + padding: 10px; + flex: 1; + font-family: '맑은고딕' + } .required-mark { color: red; @@ -94,6 +110,8 @@ var decodedContent = decodeHTMLEntities(data.responseDetail); $("#responseDetail").summernote('code', decodedContent || ''); + // 댓글 표시 + listComment(key); // 첨부 파일 표시 displayAttachFiles(data.fileInfo); @@ -104,6 +122,55 @@ } }); } + + function listComment(inquiryId) { + $.ajax({ + type: "POST", + url: url, + dataType: "json", + data: {cmd: 'LIST_COMMENT', id: inquiryId}, + success: function (data) { + var $commentList = $('#commentList'); + $commentList.empty(); + if (!data || data.length === 0) return; + $.each(data, function (i, comment) { + var date = comment.createdDate ? timeStampFormat(comment.createdDate) : ''; + var row = $('
').addClass('info-row'); + $('
').addClass('info-label').css('color', '#555').text(comment.writerName || '').appendTo(row); + var content = $('
').addClass('info-content'); + $('
').css('white-space', 'pre-wrap').text(comment.commentDetail).appendTo(content); + var meta = $('
').css({'font-size': '0.9em', 'color': '#999', 'margin-top': '2px'}); + $('').text(date).appendTo(meta); + $('
+ + +
+
+
+
${sessionScope.login.userName}
+
+ + +
+
+
+
diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/InquiryCommentRepository.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/InquiryCommentRepository.java new file mode 100644 index 0000000..caf0618 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/InquiryCommentRepository.java @@ -0,0 +1,15 @@ +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 { + + long countByInquiry_Id(String inquiryId); + + List findByInquiry_IdAndDelYnOrderBySeqAsc(String inquiryId, String delYn); +} diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/PortalInquiryCommentService.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/PortalInquiryCommentService.java new file mode 100644 index 0000000..b13b422 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/portalinquiry/PortalInquiryCommentService.java @@ -0,0 +1,27 @@ +package com.eactive.eai.rms.data.entity.onl.apim.portalinquiry; + +import com.eactive.apim.portal.qna.entity.InquiryComment; +import com.eactive.eai.rms.data.jpa.AbstractEMSDataSerivce; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(transactionManager = "transactionManagerForEMS") +public class PortalInquiryCommentService extends AbstractEMSDataSerivce { + + // AbstractEMSDataSerivce의 repository 필드가 BaseRepository로 고정되어 + // 커스텀 메서드를 호출할 수 없으므로 별도 필드로 직접 주입 + @Autowired + private InquiryCommentRepository inquiryCommentRepository; + + public long countByInquiryId(String inquiryId) { + return inquiryCommentRepository.countByInquiry_Id(inquiryId); + } + + public List findByInquiryId(String inquiryId) { + return inquiryCommentRepository.findByInquiry_IdAndDelYnOrderBySeqAsc(inquiryId, "N"); + } +} diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUI.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUI.java new file mode 100644 index 0000000..b5eddea --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUI.java @@ -0,0 +1,42 @@ +package com.eactive.eai.rms.onl.apim.portalInquiry; + +import com.eactive.apim.portal.file.entity.FileInfo; +import com.eactive.eai.data.converter.LocalDateTimeFormatters; +import com.eactive.eai.rms.onl.apim.portaluser.PortalUserUI; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.List; + + +@Data +public class PortalInquiryCommentUI { + + private String id; + + private String inquiryId; + + private String commentDetail; + + private int seq; + + private String delYn; + + private String createdBy; + + private String writerName; + + private String lastModifiedBy; + + @JsonFormat(pattern = LocalDateTimeFormatters.FORMAT_YYYYMMDDHHMMSS_14) + @DateTimeFormat(pattern = "yyyyMMddHHmmss") + private LocalDateTime createdDate; + + @JsonFormat(pattern = LocalDateTimeFormatters.FORMAT_YYYYMMDDHHMMSS_14) + @DateTimeFormat(pattern = "yyyyMMddHHmmss") + private LocalDateTime lastModifiedDate; + +} diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUIMapper.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUIMapper.java new file mode 100644 index 0000000..8a5e3dd --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryCommentUIMapper.java @@ -0,0 +1,17 @@ +package com.eactive.eai.rms.onl.apim.portalInquiry; + +import com.eactive.apim.portal.qna.entity.InquiryComment; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import java.util.List; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface PortalInquiryCommentUIMapper { + + @Mapping(target = "inquiryId", source = "inquiry.id") + PortalInquiryCommentUI toVo(InquiryComment entity); + + List toVoList(List entities); +} diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManController.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManController.java index a87c6ee..5fe6a76 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManController.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManController.java @@ -73,5 +73,23 @@ public class PortalInquiryManController extends BaseAnnotationController { portalInquiryManService.deleteBulk(ids); return ResponseEntity.ok().build(); } + + @PostMapping(value = "/onl/apim/portalinquiry/portalInquiryMan.json", params = "cmd=LIST_COMMENT") + public ResponseEntity> selectCommentList(String id) { + return ResponseEntity.ok(portalInquiryManService.selectCommentList(id)); + } + + @PostMapping(value = "/onl/apim/portalinquiry/portalInquiryMan.json", params = "cmd=INSERT_COMMENT") + public ResponseEntity insertComment(HttpServletRequest request, PortalInquiryCommentUI portalInquiryCommentUI) { + String userid = SessionManager.getUserId(request); + portalInquiryManService.insertComment(portalInquiryCommentUI, userid); + return ResponseEntity.ok().build(); + } + + @PostMapping(value = "/onl/apim/portalinquiry/portalInquiryMan.json", params = "cmd=DELETE_COMMENT") + public ResponseEntity deleteComment(String id) { + portalInquiryManService.deleteComment(id); + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManService.java index f8549d1..e9895ff 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalInquiry/PortalInquiryManService.java @@ -4,10 +4,13 @@ import com.eactive.apim.portal.file.entity.FileInfo; import com.eactive.apim.portal.file.service.FileService; import com.eactive.apim.portal.portaluser.entity.PortalUser; import com.eactive.apim.portal.portaluser.entity.PortalUserEnums; +import com.eactive.apim.portal.portaluser.repository.PortalUserRepository; import com.eactive.apim.portal.qna.entity.Inquiry; +import com.eactive.apim.portal.qna.entity.InquiryComment; import com.eactive.apim.portal.user.entity.UserInfo; import com.eactive.eai.rms.common.base.BaseService; 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.PortalInquirySearch; import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryService; import com.eactive.eai.rms.onl.apim.masking.MaskingUtils; @@ -22,14 +25,18 @@ import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; +import java.util.Optional; @Service @Transactional(transactionManager = "transactionManagerForEMS") @Slf4j public class PortalInquiryManService extends BaseService { private final PortalInquiryService portalInquiryService; + private final PortalInquiryCommentService portalInquiryCommentService; private final PortalInquiryUIMapper portalInquiryUIMapper; + private final PortalInquiryCommentUIMapper portalInquiryCommentUIMapper; private final UserInfoService userInfoService; + private final PortalUserRepository portalUserRepository; private final FileService fileService; public static final String PENDING = "PENDING"; @@ -37,12 +44,18 @@ public class PortalInquiryManService extends BaseService { public PortalInquiryManService(PortalInquiryService portalInquiryService, + PortalInquiryCommentService portalInquiryCommentService, PortalInquiryUIMapper portalInquiryUIMapper, + PortalInquiryCommentUIMapper portalInquiryCommentUIMapper, UserInfoService userInfoService, + PortalUserRepository portalUserRepository, FileService fileService){ this.portalInquiryService = portalInquiryService; + this.portalInquiryCommentService = portalInquiryCommentService; this.portalInquiryUIMapper = portalInquiryUIMapper; + this.portalInquiryCommentUIMapper = portalInquiryCommentUIMapper; this.userInfoService = userInfoService; + this.portalUserRepository = portalUserRepository; this.fileService = fileService; } @@ -161,5 +174,46 @@ public class PortalInquiryManService extends BaseService { List idList = Arrays.asList(ids.split(",")); portalInquiryService.deleteByIds(idList); } + + public List selectCommentList(String inquiryId) { + List comments = portalInquiryCommentService.findByInquiryId(inquiryId); + List result = portalInquiryCommentUIMapper.toVoList(comments); + result.forEach(ui -> ui.setWriterName(resolveWriterName(ui.getCreatedBy()))); + return result; + } + + private String resolveWriterName(String userId) { + if (StringUtils.isBlank(userId)) return ""; + // 직원(내부 사용자) 여부 먼저 확인 → 이름 그대로 반환 + Optional staff = userInfoService.findById(userId); + if (staff.isPresent()) { + return staff.get().getUsername(); + } + // 포털 회원이면 이름 마스킹 처리 (김수민 → 김수*) + Optional portalUser = portalUserRepository.findById(userId); + if (portalUser.isPresent()) { + return MaskingUtils.maskName(portalUser.get().getUserName()); + } + return userId; + } + + public void insertComment(PortalInquiryCommentUI commentUI, String userId) { + Inquiry inquiry = portalInquiryService.getById(commentUI.getInquiryId()); + + InquiryComment comment = new InquiryComment(); + comment.setInquiry(inquiry); + comment.setCommentDetail(commentUI.getCommentDetail()); + comment.setDelYn("N"); + int nextSeq = (int) portalInquiryCommentService.countByInquiryId(commentUI.getInquiryId()) + 1; + comment.setSeq(nextSeq); + + portalInquiryCommentService.save(comment); + } + + public void deleteComment(String commentId) { + InquiryComment comment = portalInquiryCommentService.getById(commentId); + comment.setDelYn("Y"); + portalInquiryCommentService.save(comment); + } }