From 6f00de61d9669cb9f23cdfe4b4110fe6a027096d Mon Sep 17 00:00:00 2001 From: Rinjae Date: Mon, 13 Jul 2026 11:32:34 +0900 Subject: [PATCH] =?UTF-8?q?Q&A=20=EB=AC=B8=EC=9D=98=20=EA=B3=B5=EA=B0=9C?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?-=20=EA=B3=B5=EA=B0=9C=EB=B2=94=EC=9C=84=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B0=9C=EB=B0=9C(ALL/ORG/PRIVATE)=20-?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC/=EB=8C=93=EA=B8=80=20=EC=A0=95?= =?UTF-8?q?=EA=B5=90=ED=99=94=20-=20=EC=9A=94=EC=B2=AD=20=EB=B0=8F=20DB=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=ED=99=95=EC=9E=A5=20-=20UI,=20DTO,=20Serv?= =?UTF-8?q?ice=20=EA=B3=84=EC=B8=B5=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= =?UTF-8?q?=20-=20=EA=B0=90=EC=82=AC=20=EB=A1=9C=EA=B7=B8=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=88=98=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apim/portal/qna/entity/Inquiry.java | 19 ++++++ .../portal/qna/entity/InquiryComment.java | 12 ++++ .../portal/qna/entity/VisibilityScope.java | 67 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 src/main/java/com/eactive/apim/portal/qna/entity/VisibilityScope.java diff --git a/src/main/java/com/eactive/apim/portal/qna/entity/Inquiry.java b/src/main/java/com/eactive/apim/portal/qna/entity/Inquiry.java index 527873e..2c59f2e 100644 --- a/src/main/java/com/eactive/apim/portal/qna/entity/Inquiry.java +++ b/src/main/java/com/eactive/apim/portal/qna/entity/Inquiry.java @@ -86,4 +86,23 @@ public class Inquiry extends Auditable { @Column(name = "ATTACH_FILE") private String attachFile; + + /** + * 공개범위 (전체공개/법인공개/비공개). 기본값 ORG. + * PTL_PROPERTY 기관 기본값이 상한(ceiling)이며 읽기/쓰기 시 clamp 된다. + */ + @Enumerated(EnumType.STRING) + @Column(name = "VISIBILITY", length = 16) + private VisibilityScope visibility = VisibilityScope.ORG; + + /** + * 조회수. sessionStorage 기반 dedup 후 POST 요청으로만 증가한다. + */ + @Column(name = "VIEW_COUNT") + private long viewCount = 0L; + + /** 조회수 1 증가. */ + public void increaseViewCount() { + this.viewCount++; + } } diff --git a/src/main/java/com/eactive/apim/portal/qna/entity/InquiryComment.java b/src/main/java/com/eactive/apim/portal/qna/entity/InquiryComment.java index d66f4a5..9ef7bbe 100644 --- a/src/main/java/com/eactive/apim/portal/qna/entity/InquiryComment.java +++ b/src/main/java/com/eactive/apim/portal/qna/entity/InquiryComment.java @@ -36,6 +36,18 @@ public class InquiryComment extends Auditable implements Serializable { @Column(name = "ADMIN_YN", length = 1) private String adminYn = "N"; + /** + * 댓글 공개범위. 개념상 공개(ALL)/비공개(PRIVATE) 2단계. + * 비공개 댓글은 작성자·같은 법인 corp-manager·관리자만 열람 가능. + */ + @Enumerated(EnumType.STRING) + @Column(name = "VISIBILITY", length = 16) + private VisibilityScope visibility = VisibilityScope.ALL; + + public boolean isPrivate() { + return this.visibility == VisibilityScope.PRIVATE; + } + public void markDeleted() { this.delYn = "Y"; } diff --git a/src/main/java/com/eactive/apim/portal/qna/entity/VisibilityScope.java b/src/main/java/com/eactive/apim/portal/qna/entity/VisibilityScope.java new file mode 100644 index 0000000..fa24673 --- /dev/null +++ b/src/main/java/com/eactive/apim/portal/qna/entity/VisibilityScope.java @@ -0,0 +1,67 @@ +package com.eactive.apim.portal.qna.entity; + +/** + * 문의(Q&A) 게시물/댓글의 공개범위. + * + *

{@code width}는 공개 범위의 넓이 랭크로, 값이 클수록 더 넓게 공개된다. + * {@code PTL_PROPERTY}에 설정된 기관 기본값이 상한(ceiling)이 되며, 게시물이 상한보다 + * 넓게 설정될 수 없다({@link #clampTo}). property가 항상 우선한다.

+ * + * + */ +public enum VisibilityScope { + + ALL(3, "전체공개"), + ORG(2, "법인공개"), + PRIVATE(1, "비공개"); + + private final int width; + private final String label; + + VisibilityScope(int width, String label) { + this.width = width; + this.label = label; + } + + /** 공개 범위 넓이 랭크. 클수록 넓게 공개. */ + public int width() { + return width; + } + + /** 화면 표기용 한글 라벨. */ + public String label() { + return label; + } + + /** + * 문자열을 enum으로 안전 변환. null/빈값/미해당은 defaultScope 반환. + */ + public static VisibilityScope fromString(String value, VisibilityScope defaultScope) { + if (value == null || value.trim().isEmpty()) { + return defaultScope; + } + try { + return VisibilityScope.valueOf(value.trim().toUpperCase()); + } catch (IllegalArgumentException e) { + return defaultScope; + } + } + + /** + * 요청 공개범위를 상한으로 clamp 한다. 요청이 상한보다 넓으면 상한으로 낮춘다. + * (property가 항상 우선하므로, 저장값이 옛 상한이라 더 넓더라도 읽기 시 재-clamp 한다.) + */ + public static VisibilityScope clampTo(VisibilityScope requested, VisibilityScope ceiling) { + if (requested == null) { + return ceiling; + } + if (ceiling == null) { + return requested; + } + return requested.width() > ceiling.width() ? ceiling : requested; + } +}