Merge branch 'main' into yoon

This commit is contained in:
yoon 2025-02-27 13:27:20 +09:00
commit d6f205f332
11 changed files with 165 additions and 71 deletions

View File

@ -9,15 +9,18 @@
* =========================================================== * ===========================================================
* DATE AUTHOR NOTE * DATE AUTHOR NOTE
* ----------------------------------------------------------- * -----------------------------------------------------------
* 24.01.02 서지희 최초 생성 * 25.01.07 서지희 최초 생성
* *
*************************************************************/ *************************************************************/
package io.company.localhost.controller.api; package io.company.localhost.controller.api;
import java.io.File;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -104,9 +107,13 @@ public class BoardController {
if (board == null) { if (board == null) {
throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다."); throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다.");
} }
// 📌 첨부파일 목록 추가
List<MapDto> attachments = boardService.selectAttachments(boardId);
board.put("attachments", attachments != null ? attachments : new ArrayList<>());
return ApiResponse.ok(board); return ApiResponse.ok(board);
} }
/** /**
* 게시물 삭제 * 게시물 삭제
* @ReqMap map 수정 데이터 (LOCBRDSEQ) * @ReqMap map 수정 데이터 (LOCBRDSEQ)
@ -203,6 +210,7 @@ public class BoardController {
@ParameterCheck @ParameterCheck
@PostMapping("/{LOCBRDSEQ}/comment") @PostMapping("/{LOCBRDSEQ}/comment")
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) { public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
if (map.containsKey("LOCCMTPWD") && !map.getString("LOCCMTPWD").trim().isEmpty()) { // 체크 if (map.containsKey("LOCCMTPWD") && !map.getString("LOCCMTPWD").trim().isEmpty()) { // 체크
String rawPassword = map.getString("LOCCMTPWD"); String rawPassword = map.getString("LOCCMTPWD");
String hashedPassword = passwordEncoder.encode(rawPassword); String hashedPassword = passwordEncoder.encode(rawPassword);
@ -228,13 +236,16 @@ public class BoardController {
/** /**
* 댓글/대댓글 삭제 * 댓글/대댓글 삭제
* @ReqMap map 수정 데이터 (LOCCMTSEQ) * @param commentId 댓글 ID
* @return 삭제 결과 메시지 * @return 삭제 결과 메시지
*/ */
@Member @Member
@ParameterCheck @ParameterCheck
@DeleteMapping("/comment/{commentId}") @DeleteMapping("/comment/{commentId}")
public ApiResponse<String> deleteComment(@ReqMap MapDto map) { public ApiResponse<String> deleteComment(@PathVariable("commentId") Long commentId) {
MapDto map = new MapDto();
map.put("LOCCMTSEQ", commentId);
boardService.deleteComment(map); boardService.deleteComment(map);
return ApiResponse.ok("댓글이 삭제되었습니다."); return ApiResponse.ok("댓글이 삭제되었습니다.");
} }

View File

@ -1,6 +1,18 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.api
* @fileName : VacationController.java
* @author : 서지희
* @date : 25.02.06
* @description : 게시판
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.controller.api; package io.company.localhost.controller.api;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -89,7 +89,7 @@ public class worddictController {
} }
/** /**
* 용어 등록 - 카테고리 등록 * 용어 등록 - 카테고리 등록
* @param WRDDICCAT 카테고리 코드값 ,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크 ,CMNCODNAM 추가 등록 카테고리 이름 * @param WRDDICCAT 카테고리 코드값 ,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크 ,CMNCODNAM 추가 등록 카테고리 이름
* @return * @return
*/ */
@Member @Member

View File

@ -1,12 +1,21 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : localbordMapper.java
* @author : 서지희
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.01.07 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
@Mapper @Mapper
@ -57,10 +66,10 @@ public interface localbordMapper {
void updateComment(MapDto map); void updateComment(MapDto map);
// 대댓글인지 확인 // 대댓글인지 확인
boolean selectIsReply(MapDto map); int selectIsReply(MapDto map);
// 댓글에 대댓글이 있는지 확인 // 댓글에 대댓글이 있는지 확인
boolean selectHasReplies(MapDto map); int selectHasReplies(MapDto map);
// 댓글 내용만 삭제 처리 (대댓글 유지) // 댓글 내용만 삭제 처리 (대댓글 유지)
void updateSoftDeleteComment(MapDto map); void updateSoftDeleteComment(MapDto map);

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : localvacaMapper.java
* @author : 서지희
* @date : 25.02.06
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;

View File

@ -1,11 +1,23 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : localbordService.java
* @author : 서지희
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.01.07 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.io.ByteArrayInputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import io.company.localhost.utils.BlobUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -134,6 +146,7 @@ public class localbordService {
} }
public void insertCommentOrReply(MapDto map) { public void insertCommentOrReply(MapDto map) {
// 익명게시판이면 회원 정보를 null로 설정 // 익명게시판이면 회원 정보를 null로 설정
if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) { if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) {
map.put("MEMBERSEQ", null); map.put("MEMBERSEQ", null);
@ -143,30 +156,42 @@ public class localbordService {
} }
if (map.get("LOCCMTPNT") == null) { if (map.get("LOCCMTPNT") == null) {
map.put("LOCCMTPNT", null); map.put("LOCCMTPNT", null);
if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) {
map.put("MEMBERSEQ", null);
}else {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
} }
boardMapper.insertCommentOrReply(map); boardMapper.insertCommentOrReply(map);
} }
}
public void updateComment(MapDto map) { public void updateComment(MapDto map) {
boardMapper.updateComment(map); boardMapper.updateComment(map);
} }
public void deleteComment(MapDto map) { public void deleteComment(MapDto map) {
boolean isReply = boardMapper.selectIsReply(map); // 댓글이 대댓글인지 확인
boolean isReply = boardMapper.selectIsReply(map) > 0;
if (isReply) { if (isReply) {
// 대댓글이면 바로 삭제
boardMapper.deleteReply(map); boardMapper.deleteReply(map);
} else { } else {
boolean hasReplies = boardMapper.selectHasReplies(map); // 댓글에 대댓글이 있는지 확인
boolean hasReplies = boardMapper.selectHasReplies(map) > 0;
if (hasReplies) { if (hasReplies) {
// 대댓글이 있는 경우, '삭제된 댓글입니다.' 변경 (소프트 삭제)
boardMapper.updateSoftDeleteComment(map); boardMapper.updateSoftDeleteComment(map);
} else { } else {
// 대댓글이 없는 경우, 완전 삭제
boardMapper.deleteComment(map); boardMapper.deleteComment(map);
} }
} }
} }
public String selectCommentPassword(int commentId) { public String selectCommentPassword(int commentId) {
return boardMapper.selectCommentPassword(commentId); return boardMapper.selectCommentPassword(commentId);
} }
@ -196,24 +221,6 @@ public class localbordService {
return boardMapper.selectCountCommentReactions(boardId); return boardMapper.selectCountCommentReactions(boardId);
} }
private String procBlobToString(Object blob) {
try {
if (blob instanceof String) {
return (String) blob; // 이미 문자열이면 그대로 반환
} else if (blob instanceof java.sql.Blob) {
java.sql.Blob sqlBlob = (java.sql.Blob) blob;
long blobLength = sqlBlob.length();
byte[] blobBytes = sqlBlob.getBytes(1, (int) blobLength);
return new String(blobBytes, StandardCharsets.UTF_8); // SQL BLOB 바이트 배열 문자열 변환
} else {
throw new UnsupportedOperationException("Unsupported blob type: " + blob.getClass()); // 지원되지 않는 타입이면 예외 발생
}
} catch (Exception e) {
throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e); // 변환 실패 예외 처리
}
}
private String procFirstImageUrl(String jsonContent) { private String procFirstImageUrl(String jsonContent) {
try { try {
// JSON 유효성 검사 // JSON 유효성 검사
@ -292,7 +299,7 @@ public class localbordService {
// Blob 데이터를 문자열로 변환 // Blob 데이터를 문자열로 변환
Object content = boardDetail.get("content"); Object content = boardDetail.get("content");
if (content != null) { if (content != null) {
String contentString = procBlobToString(content); // Blob을 문자열로 변환 String contentString = BlobUtil.procBlobToString(content); // Blob을 문자열로 변환
boardDetail.put("content", contentString); // JSON 변환 가능 boardDetail.put("content", contentString); // JSON 변환 가능
} }
} }
@ -309,7 +316,7 @@ public class localbordService {
post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0)); post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
Object content = post.get("content"); Object content = post.get("content");
String contentString = procBlobToString(content); String contentString = BlobUtil.procBlobToString(content);
post.put("content", contentString); post.put("content", contentString);
String firstImageUrl = procFirstImageUrl(contentString); String firstImageUrl = procFirstImageUrl(contentString);

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : localvacaService.java
* @author : 서지희
* @date : 25.02.06
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.net.URLDecoder; import java.net.URLDecoder;
@ -47,9 +61,7 @@ public class localvacaService {
return localvacaMapper.selectVacations(year, month); return localvacaMapper.selectVacations(year, month);
} }
/**
* 🔹 특정 연월에 대한 공휴일 데이터 조회
*/
public List<MapDto> selectHolidays(int year, int month) { public List<MapDto> selectHolidays(int year, int month) {
// ServiceKey를 디코딩해서 사용 // ServiceKey를 디코딩해서 사용
String decodedServiceKey = URLDecoder.decode(serviceKey, StandardCharsets.UTF_8); String decodedServiceKey = URLDecoder.decode(serviceKey, StandardCharsets.UTF_8);
@ -155,9 +167,7 @@ public class localvacaService {
return dto; return dto;
} }
/**
* 연차 사용 내역 조회 (사용한 연차 & 받은 연차)
*/
public Map<String, List<MapDto>> selectUserVacationHistory(Long userId, int year) { public Map<String, List<MapDto>> selectUserVacationHistory(Long userId, int year) {
List<MapDto> usedVacations = localvacaMapper.selectUsedVacations(userId,year); List<MapDto> usedVacations = localvacaMapper.selectUsedVacations(userId,year);
List<MapDto> receivedVacations = localvacaMapper.selectReceivedVacations(userId,year); List<MapDto> receivedVacations = localvacaMapper.selectReceivedVacations(userId,year);
@ -169,9 +179,6 @@ public class localvacaService {
return history; return history;
} }
/**
* 사원별 남은 연차 개수 조회
*/
public List<MapDto> selectEmployeeRemainingVacation() { public List<MapDto> selectEmployeeRemainingVacation() {
List<MapDto> employeeVacations = localvacaMapper.selectEmployeeRemainingVacation(); List<MapDto> employeeVacations = localvacaMapper.selectEmployeeRemainingVacation();

View File

@ -23,6 +23,7 @@ import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.commoncodMapper; import io.company.localhost.mapper.commoncodMapper;
import io.company.localhost.mapper.worddictyMapper; import io.company.localhost.mapper.worddictyMapper;
import io.company.localhost.utils.BlobUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -32,9 +33,14 @@ public class worddictyService {
private final worddictyMapper worddictymapper; private final worddictyMapper worddictymapper;
private final commoncodMapper commoncodmapper; private final commoncodMapper commoncodmapper;
public List<MapDto> getWordList(MapDto map) { public List<MapDto> getWordList(MapDto map) {
List<MapDto> wordList = worddictymapper.getWordList(map); List<MapDto> wordList = worddictymapper.getWordList(map);
for (MapDto word : wordList) {
Object content = word.get("WRDDICCON");
// BlobUtil.procBlobToString으로 content 변환
String contentString = BlobUtil.procBlobToString(content);
word.put("WRDDICCON", contentString);
}
List<MapDto> processedList = new ArrayList<>(); List<MapDto> processedList = new ArrayList<>();
// 데이터 가공 // 데이터 가공
@ -60,7 +66,6 @@ public class worddictyService {
} }
return processedList; return processedList;
} }
public Long insertWord(MapDto map) { public Long insertWord(MapDto map) {
if (map.containsKey("CMNCODNAM") && map.get("CMNCODNAM") != null) { if (map.containsKey("CMNCODNAM") && map.get("CMNCODNAM") != null) {
@ -68,28 +73,16 @@ public class worddictyService {
} }
return worddictymapper.insertWord(map); return worddictymapper.insertWord(map);
} }
public Long updateWord(MapDto map) { public Long updateWord(MapDto map) {
return worddictymapper.updateWord(map); return worddictymapper.updateWord(map);
} }
public MapDto getWordDetail(MapDto map) { public MapDto getWordDetail(MapDto map) {
return worddictymapper.getWordDetail(map); return worddictymapper.getWordDetail(map);
} }
public int getTotal(MapDto map) { public int getTotal(MapDto map) {
return worddictymapper.getTotal(map); return worddictymapper.getTotal(map);
} }
public Long updateword(MapDto map) { public Long updateword(MapDto map) {
return worddictymapper.updateword(map); return worddictymapper.updateword(map);
} }
} }

View File

@ -0,0 +1,42 @@
/************************************************************
*
* @packageName : io.company.localhost.utils
* @fileName : BlobUtil.java
* @author : 서지희
* @date : 25.02.25
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.25 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.utils;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
public class BlobUtil {
private BlobUtil() {
// 객체 생성 방지 (유틸리티 클래스는 인스턴스를 만들 필요가 없음)
}
public static String procBlobToString(Object blob) {
try {
if (blob instanceof String) {
return (String) blob; // 이미 문자열이면 그대로 반환
} else if (blob instanceof Blob) {
Blob sqlBlob = (Blob) blob;
long blobLength = sqlBlob.length();
byte[] blobBytes = sqlBlob.getBytes(1, (int) blobLength);
return new String(blobBytes, StandardCharsets.UTF_8); // SQL BLOB 바이트 배열 문자열 변환
} else {
throw new UnsupportedOperationException("Unsupported blob type: " + blob.getClass()); // 지원되지 않는 타입이면 예외 발생
}
} catch (Exception e) {
throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e); // 변환 실패 예외 처리
}
}
}

View File

@ -145,5 +145,4 @@
m.MEMBERLEA ="N" m.MEMBERLEA ="N"
</select> </select>
</mapper> </mapper>

View File

@ -199,16 +199,16 @@
</delete> </delete>
<!-- 대댓글인지 확인 --> <!-- 대댓글인지 확인 -->
<select id="selectIsReply" resultType="boolean"> <select id="selectIsReply" resultType="int">
SELECT COUNT(1) > 0 FROM localcomt SELECT COUNT(1) FROM localcomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPNT IS NOT NULL WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPNT IS NOT NULL
</select> </select>
<!-- 댓글에 대댓글이 있는지 확인 --> <!-- 댓글에 대댓글이 있는지 확인 -->
<select id="selectHasReplies" resultType="boolean"> <select id="selectHasReplies" resultType="int">
SELECT COUNT(1) > 0 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ} SELECT COUNT(1) FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
</select> </select>
<!-- 댓글 비밀번호 조회 --> <!-- 댓글 비밀번호 조회 -->
<select id="selectCommentPassword" resultType="String"> <select id="selectCommentPassword" resultType="String">
SELECT LOCCMTPWD SELECT LOCCMTPWD