박현정 박현정 5 days ago
250806 박현정 프로젝트 즐겨찾기 및 정렬 기능 추가
@562afff8bae24653c5e25cf21a30ac960a806409
src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectDTO.java
--- src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectDTO.java
+++ src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectDTO.java
@@ -25,6 +25,7 @@
     private String projectGroupId; // 프로젝트 그룹 아이디
     private String projectName; //	프로젝트 이름
     private String isMain; // 대표 프로젝트 여부 ( N: 대표 아님, Y: 대표)
+    private String isFavorite; // 즐겨찾기 설정 여부 (N: 즐겨찾기 아님, Y: 즐겨찾기)
 //    private List<ProjectMemberDTO> projectMembers; // 프로젝트 참여자 정보 목록
 //    private ProjectCommentDTO projectComment; // 프로젝트 주석 정보
 //    private ProjectImageDTO projectImage; // 이미지 정보
@@ -38,6 +39,7 @@
                 projectVO.getProjectGroupId(),
                 projectVO.getProjectName(),
                 projectVO.getIsMain(),
+                projectVO.getIsFavorite(),
                 projectVO.getCreatedAt(),
                 projectVO.getUpdatedAt()
         );
src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectSearchReqDTO.java
--- src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectSearchReqDTO.java
+++ src/main/java/kr/co/takensoft/ai/system/project/dto/ProjectSearchReqDTO.java
@@ -22,5 +22,6 @@
     private String projectGroupId; // 프로젝트 그룹 아이디
     private String projectName; // 프로젝트 이름
     private String isMain; // 대표 프로젝트 여부('N' : 대표 아님, 'Y' : 대표)
+    private String sortOption; // 정렬 옵션 ('LATEST' : 최근 수정 순, 'OLDEST' : 오래된 순(수정), 'NAME_ASC' : 이름순)
 
 }
 
src/main/java/kr/co/takensoft/ai/system/project/dto/UpdateProjectFavoriteDTO.java (added)
+++ src/main/java/kr/co/takensoft/ai/system/project/dto/UpdateProjectFavoriteDTO.java
@@ -0,0 +1,23 @@
+package kr.co.takensoft.ai.system.project.dto;
+
+import kr.co.takensoft.ai.system.common.dto.BaseParam;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author 박현정
+ * @since 2025.08.06
+ * @modification
+ *     since    |    author    | description
+ *  2025.08.06  |    박현정    | 최초 등록
+ *
+ * 프로젝트 즐겨찾기 수정 관련 DTO
+ */
+@Setter
+@Getter
+@NoArgsConstructor
+public class UpdateProjectFavoriteDTO extends BaseParam {
+
+    private String isFavorite; // 즐겨찾기 설정(N: 해제, Y: 설정)
+}
src/main/java/kr/co/takensoft/ai/system/project/service/ProjectService.java
--- src/main/java/kr/co/takensoft/ai/system/project/service/ProjectService.java
+++ src/main/java/kr/co/takensoft/ai/system/project/service/ProjectService.java
@@ -1,11 +1,7 @@
 package kr.co.takensoft.ai.system.project.service;
 
 import kr.co.takensoft.ai.system.common.dto.BaseParam;
-import kr.co.takensoft.ai.system.project.dto.InsertProjectDTO;
-import kr.co.takensoft.ai.system.project.dto.ProjectSearchReqDTO;
-import kr.co.takensoft.ai.system.project.dto.UpdateProjectDTO;
-import kr.co.takensoft.ai.system.project.dto.UpdateProjectNameDTO;
-import kr.co.takensoft.ai.system.projectLog.dto.ProjectLogDTO;
+import kr.co.takensoft.ai.system.project.dto.*;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.HashMap;
@@ -120,4 +116,13 @@
      * 프로젝트 로그 목록 조회
      */
     HashMap<String, Object> findAllLogs(BaseParam request);
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param request - 즐겨찾기 설정 정보를 담은 DTO 객체
+     * @return 즐겨찾기 설정 성공 여부
+     *
+     * 프로젝트 즐겨찾기 설정/해제
+     */
+    int updateProjectFavorite(String projectGroupId, UpdateProjectFavoriteDTO request);
 }
src/main/java/kr/co/takensoft/ai/system/project/service/impl/ProjectServiceImpl.java
--- src/main/java/kr/co/takensoft/ai/system/project/service/impl/ProjectServiceImpl.java
+++ src/main/java/kr/co/takensoft/ai/system/project/service/impl/ProjectServiceImpl.java
@@ -55,6 +55,7 @@
      * 프로젝트 등록
      */
     @Override
+    @Transactional
     public int saveProject(InsertProjectDTO request) {
 
         try {
@@ -340,4 +341,29 @@
         result.put("editLogs", logDTOS);
         return result; // 프로젝트 로그 목록 조회 결과 응답
     }
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param request - 즐겨찾기 설정 정보를 담은 DTO 객체
+     * @return 즐겨찾기 설정 성공 여부
+     *
+     * 프로젝트 즐겨찾기 설정/해제
+     */
+    @Override
+    @Transactional
+    public int updateProjectFavorite(String projectGroupId, UpdateProjectFavoriteDTO request) {
+
+        String memberId = request.getMemberId(); // 사용자 아이디 가져오기
+        projectGroupService.validateExistence(projectGroupId);  // 프로젝트 그룹 존재 여부 검증
+        projectMemberService.validateProjectMember(projectGroupId, memberId); // 프로젝트 참여자 존재 여부 검증
+
+        String isFavorite = request.getIsFavorite(); // 즐겨찾기 설정 정보 가져오기
+        if (isFavorite.equals("Y")) { // 즐겨찾기 설정한 경우
+            return projectMemberService.setProjectFavorite(projectGroupId, memberId);
+        } else if (isFavorite.equals("N")) { // 즐겨찾기 해제한 경우
+            return projectMemberService.unsetProjectFavorite(projectGroupId, memberId);
+        } else { // 잘못된 값 예외 처리
+            throw new IllegalArgumentException("isFavorite 값은 'Y' 또는 'N' 이어야 합니다. 현재 값: " + isFavorite);
+        }
+    }
 }
src/main/java/kr/co/takensoft/ai/system/project/vo/ProjectVO.java
--- src/main/java/kr/co/takensoft/ai/system/project/vo/ProjectVO.java
+++ src/main/java/kr/co/takensoft/ai/system/project/vo/ProjectVO.java
@@ -26,6 +26,7 @@
     private String projectGroupId; // 프로젝트 그룹 아이디
     private String projectName; //	프로젝트 이름
     private String isMain; // 대표 프로젝트 여부 ( N: 대표 아님, Y: 대표)
+    private String isFavorite; // 즐겨찾기 설정 여부 (N: 즐겨찾기 아님, Y: 즐겨찾기)
     private String useAt; // 프로젝트 사용 여부 (N : 사용 안함, Y : 사용)
     private String imageId; // 프로젝트 이미지 아이디
     private String commentId; // 프로젝트 주석 아이디
src/main/java/kr/co/takensoft/ai/system/project/web/ProjectController.java
--- src/main/java/kr/co/takensoft/ai/system/project/web/ProjectController.java
+++ src/main/java/kr/co/takensoft/ai/system/project/web/ProjectController.java
@@ -1,13 +1,8 @@
 package kr.co.takensoft.ai.system.project.web;
 
-import kr.co.takensoft.ai.system.auth.vo.MemberVO;
 import kr.co.takensoft.ai.system.common.dto.BaseParam;
-import kr.co.takensoft.ai.system.project.dto.InsertProjectDTO;
-import kr.co.takensoft.ai.system.project.dto.ProjectSearchReqDTO;
-import kr.co.takensoft.ai.system.project.dto.UpdateProjectDTO;
-import kr.co.takensoft.ai.system.project.dto.UpdateProjectNameDTO;
+import kr.co.takensoft.ai.system.project.dto.*;
 import kr.co.takensoft.ai.system.project.service.ProjectService;
-import kr.co.takensoft.ai.system.projectLog.service.ProjectLogService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -154,4 +149,19 @@
         result.put("result", projectService.findAllLogs(request));
         return new ResponseEntity<>(result, HttpStatus.OK);
     }
+
+    /**
+     * @param request - 사용자 아이디를 담은 DTO 객체
+     * @return ResponseEntity - 프로젝트 즐겨찾기 설정 결과를 포함하는 응답
+     *
+     * 프로젝트 즐겨찾기 설정/해제
+     */
+    @PostMapping("/{projectGroupId}/updateProjectFavorite.json")
+    public ResponseEntity<?> updateProjectFavorite(
+            @PathVariable String projectGroupId,
+            @RequestBody UpdateProjectFavoriteDTO request) {
+        HashMap<String, Object> result = new HashMap<>();
+        result.put("result", projectService.updateProjectFavorite(projectGroupId, request));
+        return new ResponseEntity<>(result, HttpStatus.OK);
+    }
 }
src/main/java/kr/co/takensoft/ai/system/projectMember/dao/ProjectMemberDAO.java
--- src/main/java/kr/co/takensoft/ai/system/projectMember/dao/ProjectMemberDAO.java
+++ src/main/java/kr/co/takensoft/ai/system/projectMember/dao/ProjectMemberDAO.java
@@ -51,4 +51,22 @@
      * 프로젝트 대표자 여부 검증
      */
     boolean existsByProjectGroupIdAndMemberIdAndIsOwner(String projectGroupId, String memberId);
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     * @return int - 프로젝트 즐겨찾기 설정 성공 여부
+     *
+     * 프로젝트 즐겨찾기 설정
+     */
+    int setProjectFavorite(String projectGroupId, String memberId);
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     * @return int - 프로젝트 즐겨찾기 해제 성공 여부
+     *
+     * 프로젝트 즐겨찾기 해제
+     */
+    int unsetProjectFavorite(String projectGroupId, String memberId);
 }
src/main/java/kr/co/takensoft/ai/system/projectMember/service/ProjectMemberService.java
--- src/main/java/kr/co/takensoft/ai/system/projectMember/service/ProjectMemberService.java
+++ src/main/java/kr/co/takensoft/ai/system/projectMember/service/ProjectMemberService.java
@@ -48,4 +48,20 @@
      * 프로젝트 대표자 여부 검증
      */
     void validateProjectOwner(String projectGroupId, String memberId);
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     *
+     * 프로젝트 즐겨찾기 설정
+     */
+    int setProjectFavorite(String projectGroupId, String memberId);
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     *
+     * 프로젝트 즐겨찾기 해제
+     */
+    int unsetProjectFavorite(String projectGroupId, String memberId);
 }
src/main/java/kr/co/takensoft/ai/system/projectMember/service/impl/ProjectMemberServiceImpl.java
--- src/main/java/kr/co/takensoft/ai/system/projectMember/service/impl/ProjectMemberServiceImpl.java
+++ src/main/java/kr/co/takensoft/ai/system/projectMember/service/impl/ProjectMemberServiceImpl.java
@@ -7,6 +7,7 @@
 import lombok.RequiredArgsConstructor;
 import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
@@ -84,4 +85,26 @@
             throw new IllegalArgumentException("이 프로젝트의 대표자가 아닙니다.");
         }
     }
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     *
+     * 프로젝트 즐겨찾기 설정
+     */
+    @Override
+    public int setProjectFavorite(String projectGroupId, String memberId) {
+        return projectMemberDAO.setProjectFavorite(projectGroupId, memberId);
+    }
+
+    /**
+     * @param projectGroupId - 프로젝트 그룹 아이디
+     * @param memberId - 사용자 아이디
+     *
+     * 프로젝트 즐겨찾기 해제
+     */
+    @Override
+    public int unsetProjectFavorite(String projectGroupId, String memberId) {
+        return projectMemberDAO.unsetProjectFavorite(projectGroupId, memberId);
+    }
 }
src/main/java/kr/co/takensoft/ai/system/projectMember/vo/ProjectMemberVO.java
--- src/main/java/kr/co/takensoft/ai/system/projectMember/vo/ProjectMemberVO.java
+++ src/main/java/kr/co/takensoft/ai/system/projectMember/vo/ProjectMemberVO.java
@@ -22,6 +22,7 @@
     private String memberId; // 참여자 아이디
     private String memberName; // 참여자 이름
     private String isOwner; // 프로젝트 대표자 여부 ( N: 대표자 아님, Y: 대표자)
+    private String isFavorite; // 즐겨찾기 여부 (N: 즐겨찾기 아님, Y: 즐겨찾기)
     private String useAt; // 사용 여부 (N : 사용 안함, Y : 사용)
     private String createdAt; // 생성일자
     private String updatedAt; // 수정일자
@@ -31,6 +32,7 @@
         this.projectMemberId = projectMemberId;
         this.projectGroupId = projectGroupId;
         this.memberId = memberId;
+        this.isFavorite = "N";
         this.isOwner = isOwner;
         this.useAt = "Y";
     }
src/main/resources/mybatis/mapper/project/project-SQL.xml
--- src/main/resources/mybatis/mapper/project/project-SQL.xml
+++ src/main/resources/mybatis/mapper/project/project-SQL.xml
@@ -12,6 +12,7 @@
         <result property="projectGroupId" column="project_group_id" />
         <result property="projectName" column="project_name" />
         <result property="isMain" column="is_main" />
+        <result property="isFavorite" column="is_favorite"/>
         <result property="useAt" column="use_at" />
         <result property="imageId" column="project_image_id"/>
         <result property="commentId" column="project_comment_id"/>
@@ -209,6 +210,7 @@
             p.project_group_id,
             p.project_name,
             p.is_main,
+            pm.is_favorite,
             p.created_at,
             p.updated_at
         FROM project p
@@ -226,6 +228,22 @@
             </if>
                 AND p.use_at = 'Y'
         </where>
+        ORDER BY
+            pm.is_favorite DESC,
+            <choose>
+                <when test='"LATEST".equals(sortOption)'>
+                    p.updated_at DESC
+                </when>
+                <when test='"OLDEST".equals(sortOption)'>
+                    p.updated_at ASC
+                </when>
+                <when test='"NAME_ASC".equals(sortOption)'>
+                    p.project_name ASC
+                </when>
+                <otherwise>
+                    p.updated_at DESC
+                </otherwise>
+            </choose>
     </select>
 
 
src/main/resources/mybatis/mapper/projectMember/projectMember-SQL.xml
--- src/main/resources/mybatis/mapper/projectMember/projectMember-SQL.xml
+++ src/main/resources/mybatis/mapper/projectMember/projectMember-SQL.xml
@@ -13,6 +13,7 @@
         <result property="memberId" column="member_id"/>
         <result property="memberName" column="member_name"/>
         <result property="isOwner" column="is_owner"/>
+        <result property="isFavorite" column="is_favorite"/>
         <result property="useAt" column="use_at"/>
         <result property="createdAt" column="created_at"/>
         <result property="updatedAt" column="updated_at"/>
@@ -38,6 +39,7 @@
             project_group_id,
             member_id,
             is_owner,
+            is_favorite,
             use_at,
             created_at,
             updated_at
@@ -47,6 +49,7 @@
             #{projectGroupId},
             #{memberId},
             #{isOwner},
+            #{isFavorite},
             #{useAt},
             CURRENT_TIMESTAMP,
             CURRENT_TIMESTAMP
@@ -108,4 +111,38 @@
         AND m.use_at = 'Y'
     </select>
 
+    <!--
+    작 성 자 : 박현정
+    작 성 일 : 2025.08.06
+    내    용 : 프로젝트 즐겨찾기 설정
+    -->
+    <update id="setProjectFavorite" parameterType="String">
+        UPDATE
+            project_member
+        <set>
+            is_favorite = 'Y',
+            updated_at = CURRENT_TIMESTAMP
+        </set>
+        WHERE project_group_id = #{projectGroupId}
+        AND member_id = #{memberId}
+        AND use_at = 'Y'
+    </update>
+
+    <!--
+    작 성 자 : 박현정
+    작 성 일 : 2025.08.06
+    내    용 : 프로젝트 즐겨찾기 해제
+    -->
+    <update id="unsetProjectFavorite" parameterType="String">
+        UPDATE
+            project_member
+        <set>
+            is_favorite = 'N',
+            updated_at = CURRENT_TIMESTAMP
+        </set>
+        WHERE project_group_id = #{projectGroupId}
+        AND member_id = #{memberId}
+        AND use_at = 'Y'
+    </update>
+
 </mapper>
(파일 끝에 줄바꿈 문자 없음)
Add a comment
List