From af4279daa4f99869fc61345ba05898ef9cce6af2 Mon Sep 17 00:00:00 2001 From: yongsik Date: Thu, 30 Oct 2025 19:51:36 +0900 Subject: [PATCH 1/6] =?UTF-8?q?(fix)=20=ED=8F=B4=EB=8D=94=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B0=9C=EC=88=98=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cooperationcenter/domain/survey/dto/SurveyFolderDto.java | 2 ++ .../templates/homepage/user/survey/survey-folder-list.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/SurveyFolderDto.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/SurveyFolderDto.java index 0415f92..5e4919b 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/SurveyFolderDto.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/SurveyFolderDto.java @@ -10,6 +10,7 @@ public record SurveyFolderDto( String folderId, String displayName, String storedName, + int surveyCnt, LocalDateTime createdAt ) { public static SurveyFolderDto from(SurveyFolder surveyFolder) { @@ -17,6 +18,7 @@ public static SurveyFolderDto from(SurveyFolder surveyFolder) { surveyFolder.getFolderId(), surveyFolder.getDisplayName(), surveyFolder.getStoredName(), + surveyFolder.getSurveys().size(), surveyFolder.getCreatedAt() ); } diff --git a/src/main/resources/templates/homepage/user/survey/survey-folder-list.html b/src/main/resources/templates/homepage/user/survey/survey-folder-list.html index e71bc1c..cdabc33 100644 --- a/src/main/resources/templates/homepage/user/survey/survey-folder-list.html +++ b/src/main/resources/templates/homepage/user/survey/survey-folder-list.html @@ -140,7 +140,7 @@

- 설문 0개 + 설문 0개
From dd3108467e2204b775254bb238934753bcafa255 Mon Sep 17 00:00:00 2001 From: yongsik Date: Thu, 30 Oct 2025 22:42:48 +0900 Subject: [PATCH 2/6] =?UTF-8?q?(fix)=20admin:=20=ED=95=99=EC=83=9D=20?= =?UTF-8?q?=ED=8E=98=EC=97=90=EC=A7=80=20=EC=A0=95=EB=A0=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=82=AD=EC=A0=9C,=20=ED=9A=8D=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=ED=8F=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/SchoolPostRepository.java | 18 +- .../homepage/SurveyRestController.java | 7 + .../domain/survey/dto/AnswerResponse.java | 7 +- .../repository/SurveyLogRepository.java | 1 + .../service/homepage/SurveyFindService.java | 9 + .../service/homepage/SurveyLogService.java | 7 + .../templates/adminpage/user/index.html | 255 +++++++++--------- .../adminpage/user/school/manageSchool.html | 4 +- .../adminpage/user/student/studentList.html | 79 ------ .../templates/homepage/user/signup.html | 10 +- 10 files changed, 172 insertions(+), 225 deletions(-) diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/school/repository/SchoolPostRepository.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/school/repository/SchoolPostRepository.java index 57b3acc..6d7d77e 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/school/repository/SchoolPostRepository.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/school/repository/SchoolPostRepository.java @@ -25,13 +25,17 @@ public interface SchoolPostRepository extends JpaRepository { void incrementViewCount(@Param("postId") Long postId); @Query(""" - SELECT p FROM SchoolPost p - WHERE p.schoolBoard.id = :boardId - ORDER BY - CASE WHEN p.type = com.cooperation.project.cooperationcenter.domain.school.dto.PostType.NOTICE THEN 0 ELSE 2 END, - p.createdAt DESC - """) - Page findPostsByBoardOrderByNoticeFirst(@Param("boardId") Long boardId, Pageable pageable); + SELECT p FROM SchoolPost p + WHERE p.schoolBoard.id = :boardId + AND p.status = com.cooperation.project.cooperationcenter.domain.school.dto.PostStatus.PUBLISHED + ORDER BY + CASE WHEN p.type = com.cooperation.project.cooperationcenter.domain.school.dto.PostType.NOTICE THEN 0 ELSE 2 END, + p.createdAt DESC +""") + Page findPostsByBoardOrderByNoticeFirst( + @Param("boardId") Long boardId, + Pageable pageable + ); } diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/controller/homepage/SurveyRestController.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/controller/homepage/SurveyRestController.java index 4ba2c0b..27b4245 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/controller/homepage/SurveyRestController.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/controller/homepage/SurveyRestController.java @@ -106,6 +106,13 @@ public ResponseEntity receiveSurveyAnswer( return ResponseEntity.ok().build(); } + @GetMapping("/admin/answer") + public BaseResponse getAllAnswerLog(){ + List result = surveyLogService.getAllAnswerLog(); + log.info("result : {}",result.toString()); + return BaseResponse.onSuccess(result); + } + @GetMapping("/admin/answer/{surveyId}") public BaseResponse getAnswerLog(@PathVariable String surveyId){ AnswerResponse.AnswerDto result = surveyLogService.getAnswerLog(surveyId); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/AnswerResponse.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/AnswerResponse.java index 183f000..bc2b30d 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/AnswerResponse.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/dto/AnswerResponse.java @@ -110,8 +110,8 @@ public record LogDto( String submitTime, Long spendTime, String finishStatus, - String logId - + String logId, + String surveyName ){ public static LogDto from(SurveyLog surveyLog){ long diffInSeconds = Duration.between(surveyLog.getStartTime(), surveyLog.getCreatedAt()).getSeconds(); @@ -121,7 +121,8 @@ public static LogDto from(SurveyLog surveyLog){ surveyLog.getCreatedAt().toString(), diffInSeconds, "finish", - surveyLog.getSurveyLogId() + surveyLog.getSurveyLogId(), + surveyLog.getSurvey().getSurveyTitle() ); } diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/repository/SurveyLogRepository.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/repository/SurveyLogRepository.java index 257c73e..682c321 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/repository/SurveyLogRepository.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/repository/SurveyLogRepository.java @@ -16,4 +16,5 @@ public interface SurveyLogRepository extends JpaRepository { SurveyLog findSurveyLogBySurveyLogId(String logId); Page findSurveysLogByMember(Member member, Pageable pageable); + List findTop7ByOrderByCreatedAtDesc(); } diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyFindService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyFindService.java index 8ec046a..4dcbf04 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyFindService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyFindService.java @@ -198,6 +198,15 @@ public Page getSurveyFromCondition(Pageable pageable, SurveyRequest.LogF } } + public List findAllSurveyLog(){ + try{ + return surveyLogRepository.findTop7ByOrderByCreatedAtDesc(); + }catch (Exception e){ + log.warn(e.getMessage()); + return null; + } + } + public SurveyLog getSurveyLog(String logId){ try{ return surveyLogRepository.findSurveyLogBySurveyLogId(logId); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyLogService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyLogService.java index 2a952c4..3cf2119 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyLogService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyLogService.java @@ -51,6 +51,13 @@ public AnswerResponse.AnswerPagedDto getAnswerLog(String surveyId, Pageable page return AnswerResponse.AnswerPagedDto.from(survey,logs); } + public List getAllAnswerLog(){ + List surveyLog = surveyFindService.findAllSurveyLog(); + return AnswerResponse.LogDto.from(surveyLog); + + } + + public AnswerResponse.AnswerDto getAnswerLog(String surveyId){ Survey survey = surveyFindService.getSurveyFromId(surveyId); List surveyLog = surveyFindService.getSurveyLogs(survey); diff --git a/src/main/resources/templates/adminpage/user/index.html b/src/main/resources/templates/adminpage/user/index.html index d7a30eb..54c0fcd 100644 --- a/src/main/resources/templates/adminpage/user/index.html +++ b/src/main/resources/templates/adminpage/user/index.html @@ -71,14 +71,9 @@

관리자 대시보드

시스템 현황을 한눈에 확인하세요

-
-
- -
- 5개 대기 -
+ + +

김관리자

최고 관리자

@@ -150,7 +145,7 @@

>

- 최근 로그인 기록 - 수정 필요 + 최근 로그인 기록

+ + `; + wrap.appendChild(box); + wrap.addEventListener("click", (e) => { if (e.target === wrap) wrap.remove(); }); + box.querySelector("#__notifier_ok__").onclick = () => wrap.remove(); + document.body.appendChild(wrap); + }, + + toast(message, ms = 2000) { + const el = document.createElement("div"); + el.textContent = message; + el.style.position = "fixed"; + el.style.left = "50%"; + el.style.bottom = "22px"; + el.style.transform = "translateX(-50%)"; + el.style.background = "#111827"; + el.style.color = "#fff"; + el.style.padding = "10px 14px"; + el.style.borderRadius = "10px"; + el.style.zIndex = "9999"; + el.style.boxShadow = "0 6px 20px rgba(0,0,0,.25)"; + document.body.appendChild(el); + setTimeout(() => el.remove(), ms); + } +}; + +function escapeHtml(s) { + if (typeof s !== "string") return ""; + return s.replace(/[&<>"'`=\/]/g, c => ({ + "&":"&","<":"<",">":">","\"":""","'":"'","`":"`","=":"=","/":"/" + }[c])); +} + +// (선택) 모듈 사용이 어려운 레거시 페이지 지원 +// window.Notifier = Notifier; \ No newline at end of file diff --git a/src/main/resources/templates/adminpage/user/login.html b/src/main/resources/templates/adminpage/user/login.html index 330d8aa..4099383 100644 --- a/src/main/resources/templates/adminpage/user/login.html +++ b/src/main/resources/templates/adminpage/user/login.html @@ -333,6 +333,6 @@

로그인 실패

}); }); - + diff --git a/src/main/resources/templates/homepage/common/nav-user.html b/src/main/resources/templates/homepage/common/nav-user.html index d10661a..fd7cbc1 100644 --- a/src/main/resources/templates/homepage/common/nav-user.html +++ b/src/main/resources/templates/homepage/common/nav-user.html @@ -103,8 +103,7 @@ - - - - + + + diff --git a/src/main/resources/templates/homepage/common/survey-make-nav.html b/src/main/resources/templates/homepage/common/survey-make-nav.html new file mode 100644 index 0000000..40235ec --- /dev/null +++ b/src/main/resources/templates/homepage/common/survey-make-nav.html @@ -0,0 +1,14 @@ +
+ +
\ No newline at end of file diff --git a/src/main/resources/templates/homepage/common/survey-nav.html b/src/main/resources/templates/homepage/common/survey-nav.html index db4e23b..ee1bf30 100644 --- a/src/main/resources/templates/homepage/common/survey-nav.html +++ b/src/main/resources/templates/homepage/common/survey-nav.html @@ -18,14 +18,14 @@ 설문조사 목록 - + + + + + + + +
diff --git a/src/main/resources/templates/homepage/user/agency/agency-introduction.html b/src/main/resources/templates/homepage/user/agency/agency-introduction.html index 1719858..1e6b64b 100644 --- a/src/main/resources/templates/homepage/user/agency/agency-introduction.html +++ b/src/main/resources/templates/homepage/user/agency/agency-introduction.html @@ -591,5 +591,9 @@

연락처

}); }); + diff --git a/src/main/resources/templates/homepage/user/forgetPassword.html b/src/main/resources/templates/homepage/user/forgetPassword.html index f15af3d..1c6f070 100644 --- a/src/main/resources/templates/homepage/user/forgetPassword.html +++ b/src/main/resources/templates/homepage/user/forgetPassword.html @@ -121,7 +121,7 @@

비밀번호 찾기

- + + - + diff --git a/src/main/resources/templates/homepage/user/member/profile.html b/src/main/resources/templates/homepage/user/member/profile.html index fd38e26..57cc1ba 100644 --- a/src/main/resources/templates/homepage/user/member/profile.html +++ b/src/main/resources/templates/homepage/user/member/profile.html @@ -745,6 +745,14 @@

logo

+ + + - diff --git a/src/main/resources/templates/homepage/user/resetPassword.html b/src/main/resources/templates/homepage/user/resetPassword.html index d9bbac9..3434687 100644 --- a/src/main/resources/templates/homepage/user/resetPassword.html +++ b/src/main/resources/templates/homepage/user/resetPassword.html @@ -122,7 +122,7 @@

비밀번호 재설정

- + - - + + diff --git a/src/main/resources/templates/homepage/user/signup.html b/src/main/resources/templates/homepage/user/signup.html index 42c13d8..ac2ad6b 100644 --- a/src/main/resources/templates/homepage/user/signup.html +++ b/src/main/resources/templates/homepage/user/signup.html @@ -1459,6 +1459,6 @@

중국 주소 검색

} }); - + diff --git a/src/main/resources/templates/homepage/user/survey/survey-answer-detail.html b/src/main/resources/templates/homepage/user/survey/survey-answer-detail.html index 263de15..afbc8d5 100644 --- a/src/main/resources/templates/homepage/user/survey/survey-answer-detail.html +++ b/src/main/resources/templates/homepage/user/survey/survey-answer-detail.html @@ -260,7 +260,7 @@

+ + - + + + From 473906a2c41f09d3d1b8d2c5694ea57c1b290bb8 Mon Sep 17 00:00:00 2001 From: yongsik Date: Fri, 31 Oct 2025 23:45:27 +0900 Subject: [PATCH 4/6] =?UTF-8?q?(feat)=20swagger=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ .../global/config/SecurityConfig.java | 8 ++++-- .../global/config/SwaggerConfig.java | 22 ++++++++++++++++ .../filter/AuthenticationTokenFilter.java | 26 +++++++------------ 4 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/cooperation/project/cooperationcenter/global/config/SwaggerConfig.java diff --git a/build.gradle b/build.gradle index cb284ad..24e3c18 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,9 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:4.11.0' implementation "org.springframework.boot:spring-boot-starter-mail" + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13' + } tasks.named('test') { diff --git a/src/main/java/com/cooperation/project/cooperationcenter/global/config/SecurityConfig.java b/src/main/java/com/cooperation/project/cooperationcenter/global/config/SecurityConfig.java index 2c68b86..d3e3f3f 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/global/config/SecurityConfig.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/global/config/SecurityConfig.java @@ -45,8 +45,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ //note static 해제 .requestMatchers("/css/**","/plugins/**","/js/**").permitAll() - //fixme 임시용임 밑에는 + .requestMatchers("/v3/**", + "/swagger-ui.html", + "/swagger-ui/**", + "/swagger-resources/**", + "/api-test/**").permitAll() // .requestMatchers("/api/v1/**").permitAll() // .requestMatchers("/**").permitAll() //note 일반 사용자 페이지 @@ -61,7 +65,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ //note 로그인한 사용자 .requestMatchers("/survey/log/detail/**").authenticated() - //note admin 페이지 .requestMatchers("/admin/login").permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") @@ -100,6 +103,7 @@ public CorsConfigurationSource corsConfigurationSource() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); configuration.addAllowedOriginPattern("http://172.30.1.70:8081"); + configuration.addAllowedOriginPattern("http://localhost:8081"); configuration.addAllowedOriginPattern("https://11680c706486.ngrok-free.app"); configuration.addAllowedHeader("*"); configuration.addAllowedMethod("*"); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/global/config/SwaggerConfig.java b/src/main/java/com/cooperation/project/cooperationcenter/global/config/SwaggerConfig.java new file mode 100644 index 0000000..d37c26b --- /dev/null +++ b/src/main/java/com/cooperation/project/cooperationcenter/global/config/SwaggerConfig.java @@ -0,0 +1,22 @@ +package com.cooperation.project.cooperationcenter.global.config; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; + +public class SwaggerConfig { + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .components(new Components()) + .info(apiInfo()); + } + + private Info apiInfo() { + return new Info() + .title("CooperationCenter") // API의 제목 + .description("유학원 홍보 웹사이트") // API에 대한 설명 + .version("1.0.0"); // API의 버전 + } +} diff --git a/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java b/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java index 21bffa9..039e62c 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java @@ -36,6 +36,16 @@ protected void doFilterInternal(HttpServletRequest request, String path = request.getServletPath(); log.info("진입 path:{}",path); + if ("/v3/api-docs".equals(path) || + path.startsWith("/v3/api-docs/") || + path.equals("/swagger-ui.html") || + path.startsWith("/swagger-ui/") || + path.startsWith("/swagger-resources/") || + path.startsWith("/api-test/")) { + filterChain.doFilter(request, response); + return; + } + //note 무시하는 endpoint들 final String[] IGNORE_PATHS = { "/css", "/js", "/plugins","/member/logout","/member/signup","/api/v1/member","/api/v1/admin","/api/v1/file/img","/admin/login","/favicon.ico","/api/v1/tencent" @@ -80,20 +90,4 @@ protected void doFilterInternal(HttpServletRequest request, SecurityContextHolder.clearContext(); filterChain.doFilter(request, response); } - - - private void sendErrorResponse(HttpServletResponse response, ErrorCode errorCode) throws IOException { - // 1) HTTP 상태 및 인코딩/타입 설정 - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.setContentType("application/json; charset=UTF-8"); - response.setCharacterEncoding("UTF-8"); - - // 2) BaseResponse 형식으로 에러 객체 생성 - BaseResponse errorBody = BaseResponse.onFailure(errorCode.getCode(), errorCode.getMessage(), null); - - // 3) JSON 직렬화 후 쓰기 - ObjectMapper objectMapper = new ObjectMapper(); - String json = objectMapper.writeValueAsString(errorBody); - response.getWriter().write(json); - } } From 7dd0d8aa43fc2132d1ae6dacdbb7011d270dc057 Mon Sep 17 00:00:00 2001 From: yongsik Date: Wed, 5 Nov 2025 22:03:09 +0900 Subject: [PATCH 5/6] =?UTF-8?q?(fix)=20html=EC=97=90=EC=84=9C=20response?= =?UTF-8?q?=20=EB=B0=9B=EB=8A=94=20=ED=98=95=EC=8B=9D=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EB=B0=9B?= =?UTF-8?q?=EA=B3=A0=20=EB=AA=A8=EB=8B=AC=EC=B0=BD=EA=B9=8C=EC=A7=80=20?= =?UTF-8?q?=EB=9D=84=EC=96=B4=EC=A4=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homepage/MemberProfileRestController.java | 39 ++++- .../homepage/MemberRestController.java | 35 ++++- .../domain/member/service/MemberService.java | 5 - .../domain/member/service/ProfileService.java | 13 +- .../service/homepage/SurveyAnswerService.java | 2 +- .../service/homepage/SurveySaveService.java | 5 +- .../global/exception/codes/ErrorCode.java | 1 + .../filter/AuthenticationTokenFilter.java | 1 + .../static/js/homepage/lib/apiClient.js | 43 ++++-- .../homepage/user/forgetPassword.html | 24 ++-- .../templates/homepage/user/login.html | 80 ++++------- .../homepage/user/member/profile.html | 96 +++++-------- .../homepage/user/resetPassword.html | 22 ++- .../templates/homepage/user/signup.html | 92 +++++------- .../user/survey/copy-survey-list-admin.html | 134 ++++++++---------- .../user/survey/survey-answer-log.html | 52 +++---- .../homepage/user/survey/survey-answer.html | 48 ++----- .../user/survey/survey-folder-list.html | 7 + .../user/survey/survey-list-admin.html | 64 ++++----- .../homepage/user/survey/survey-make.html | 38 ++--- 20 files changed, 374 insertions(+), 427 deletions(-) diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberProfileRestController.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberProfileRestController.java index ce56ea8..6995be3 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberProfileRestController.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberProfileRestController.java @@ -32,14 +32,25 @@ public BaseResponse updateMemberInfo(@RequestBody Profile.MemberDto request, }catch (BaseException e){ log.warn(e.getCode().toString()); return BaseResponse.onFailure(e.getCode(),null); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); } } @PatchMapping("/agency") public BaseResponse updateAgencyInfo(@RequestBody Profile.MemberDto request, @AuthenticationPrincipal MemberDetails memberDetails){ log.info("request:{}",request.toString()); - profileService.updateAgency(request,memberDetails); - return BaseResponse.onSuccess("success"); + try{ + profileService.updateAgency(request,memberDetails); + return BaseResponse.onSuccess("success"); + }catch (BaseException e){ + log.warn(e.getCode().toString()); + return BaseResponse.onFailure(e.getCode(),null); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } } @PatchMapping("/businessCert") @@ -47,8 +58,16 @@ public BaseResponse updateBusinessCertificate( @RequestPart(name = "businessCertificate", required = false) MultipartFile file , @AuthenticationPrincipal MemberDetails memberDetails ){ - profileService.updateBussinessCert(file,memberDetails); - return BaseResponse.onSuccess("success"); + try{ + profileService.updateBussinessCert(file,memberDetails); + return BaseResponse.onSuccess("success"); + }catch (BaseException e){ + log.warn(e.getCode().toString()); + return BaseResponse.onFailure(e.getCode(),null); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } } @PatchMapping("/agencyPicture") @@ -56,7 +75,15 @@ public BaseResponse updateAgencyPicture( @RequestPart(name = "agencyPicture", required = false) MultipartFile file , @AuthenticationPrincipal MemberDetails memberDetails ){ - profileService.updateAgencyPicture(file,memberDetails); - return BaseResponse.onSuccess("success"); + try{ + profileService.updateAgencyPicture(file,memberDetails); + return BaseResponse.onSuccess("success"); + }catch (BaseException e){ + log.warn(e.getCode().toString()); + return BaseResponse.onFailure(e.getCode(),null); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } } } diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberRestController.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberRestController.java index d74f292..c69598a 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberRestController.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/controller/homepage/MemberRestController.java @@ -4,6 +4,7 @@ import com.cooperation.project.cooperationcenter.domain.member.dto.MemberRequest; import com.cooperation.project.cooperationcenter.domain.member.dto.UpdatePasswordDto; import com.cooperation.project.cooperationcenter.domain.member.service.MemberService; +import com.cooperation.project.cooperationcenter.global.exception.BaseException; import com.cooperation.project.cooperationcenter.global.exception.BaseResponse; import com.cooperation.project.cooperationcenter.global.exception.codes.ErrorCode; import com.fasterxml.jackson.core.JsonProcessingException; @@ -36,30 +37,52 @@ public BaseResponse signup( try{ memberService.signup(data,agencyPicture,businessCertificate); return BaseResponse.onSuccess("success"); + }catch (BaseException e){ + return BaseResponse.onFailure(e.getCode(),null); }catch (Exception e){ log.warn(e.getMessage()); - return BaseResponse.onFailure(ErrorCode.BAD_REQUEST,null); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); } } @GetMapping("/check-id") public BaseResponse checkDuplicateId(@RequestParam String username) { - boolean isDuplicate = memberService.isUsernameTaken(username); - log.info("response:{}",isDuplicate); - return BaseResponse.onSuccess(isDuplicate); + try{ + return BaseResponse.onSuccess(memberService.isUsernameTaken(username)); + }catch (BaseException e){ + return BaseResponse.onFailure(e.getCode(),false); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } } @PostMapping("/login") public BaseResponse login(@RequestBody MemberRequest.LoginDto requestDto, HttpServletResponse response,HttpServletRequest request){ + try{ memberService.login(requestDto,response,request); log.info("loginSuccess"); return BaseResponse.onSuccess("success"); + }catch (BaseException e){ + return BaseResponse.onFailure(e.getCode(),false); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } + } @PostMapping("/logout") public BaseResponse userLogout(HttpServletRequest request ,HttpServletResponse response){ - memberService.logout(request,response); - return BaseResponse.onSuccess("log out success"); + try { + memberService.logout(request, response); + return BaseResponse.onSuccess("log out success"); + }catch (BaseException e){ + return BaseResponse.onFailure(e.getCode(),false); + }catch (Exception e){ + log.warn(e.getMessage()); + return BaseResponse.onFailure("ERROR",e.getMessage().toString(),false); + } } @PostMapping("/refresh") diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/MemberService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/MemberService.java index 6e987a9..7847bae 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/MemberService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/MemberService.java @@ -183,13 +183,8 @@ public Member getMember(String email){ } public boolean isUsernameTaken(String username){ - try{ log.info("username:{}",username); return memberRepository.existsMemberByEmail(username); - }catch (Exception e){ - log.warn(e.getMessage()); - return false; - } } @Transactional diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/ProfileService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/ProfileService.java index ce3606b..5755987 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/ProfileService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/member/service/ProfileService.java @@ -40,16 +40,8 @@ public class ProfileService { private final FileService fileService; public Member getMember(String email){ - try { - return memberRepository.findMemberByEmail(email) - .orElseThrow(() -> new BaseException(ErrorCode.MEMBER_NOT_FOUND)); - } catch (BaseException e){ - log.warn("멤버 조회 실패: {}", e.getMessage()); - return null; - } catch (Exception e){ - log.error("알 수 없는 에러 발생: {}", e.getMessage(), e); - return null; - } + return memberRepository.findMemberByEmail(email) + .orElseThrow(() -> new BaseException(ErrorCode.MEMBER_NOT_FOUND)); } public Profile.ProfileDto getProfileDto(MemberDetails memberDetails, Pageable pageable){ @@ -73,7 +65,6 @@ public void updateMember(Profile.MemberDto request,MemberDetails memberDetails){ Member member = getMember(memberDetails.getUsername()); member.updateMember(request); memberRepository.save(member); - throw new BaseException(ErrorCode.MEMBER_NOT_FOUND); } @Transactional diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyAnswerService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyAnswerService.java index c846806..65d42f0 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyAnswerService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveyAnswerService.java @@ -61,7 +61,7 @@ public void answerSurvey(String data, HttpServletRequest request, MemberDetails } Survey survey = surveyFindService.getSurveyFromId(requestDto.surveyId()); -// if(checkDate(survey)) throw new BaseException(ErrorCode.SURVEY_DATE_NOT_VALID); + if(checkDate(survey)) throw new BaseException(ErrorCode.SURVEY_DATE_NOT_VALID); survey.setParticipantCount(); Member member = memberRepository.findMemberByEmail(memberDetails.getUsername()).get(); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveySaveService.java b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveySaveService.java index 3b7e95e..e24d857 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveySaveService.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/domain/survey/service/homepage/SurveySaveService.java @@ -189,7 +189,10 @@ public AnswerPageDto getSurveys(String surveyId){ List response = new ArrayList<>(); Survey survey = surveyFindService.getSurveyFromId(surveyId); - if(!survey.isShare()) return null; + boolean expired = (survey.getEndDate() != null) && LocalDate.now().isAfter(survey.getEndDate()); // today > endDate + + if(!survey.isShare()) throw new BaseException(ErrorCode.SURVEY_NOT_SHARE); + if(expired) throw new BaseException(ErrorCode.SURVEY_DATE_NOT_VALID); List questions = surveyFindService.getQuestions(survey); List options = surveyFindService.getOptions(survey); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/global/exception/codes/ErrorCode.java b/src/main/java/com/cooperation/project/cooperationcenter/global/exception/codes/ErrorCode.java index 39be67c..e51477a 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/global/exception/codes/ErrorCode.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/global/exception/codes/ErrorCode.java @@ -95,6 +95,7 @@ public enum ErrorCode implements BaseCode { MEMBER_NOT_ADMIN(HttpStatus.BAD_REQUEST,"MEMBER-0004","Meber is not ADMIN"), SURVEY_DATE_NOT_VALID(HttpStatus.BAD_REQUEST,"SURVEY-0000","지금 설문조사 입력 기간이 아닙니다."), + SURVEY_NOT_SHARE(HttpStatus.BAD_REQUEST,"SURVEY-0001","해당 설문조사는 공개 전입니다."), // 5xx : server error INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "SERVER-0000", "서버 에러"); diff --git a/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java b/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java index 039e62c..e6c1a99 100644 --- a/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java +++ b/src/main/java/com/cooperation/project/cooperationcenter/global/filter/AuthenticationTokenFilter.java @@ -84,6 +84,7 @@ protected void doFilterInternal(HttpServletRequest request, } catch (ExpiredJwtException e) { log.warn(e.getMessage()); log.warn("authentication에서 오류발생"); + response.sendRedirect("/member/login"); request.setAttribute("tokenExpired", true); // 포워드 시 전달용 } } diff --git a/src/main/resources/static/js/homepage/lib/apiClient.js b/src/main/resources/static/js/homepage/lib/apiClient.js index 5c7d628..bf0aba2 100644 --- a/src/main/resources/static/js/homepage/lib/apiClient.js +++ b/src/main/resources/static/js/homepage/lib/apiClient.js @@ -34,8 +34,8 @@ export const api = { postJson(url, json, opts={}) { return this._request("POST", url, JSON.stringify(json), { ...opts, headers: { "Content-Type": "application/json", ...(opts.headers||{}) } }); }, putJson(url, json, opts={}) { return this._request("PUT", url, JSON.stringify(json), { ...opts, headers: { "Content-Type": "application/json", ...(opts.headers||{}) } }); }, postMultipart(url, formData, opts={}) { return this._request("POST", url, formData, opts); }, - patchJson(url, json, opts = {}) { return this._request("PATCH",url,JSON.stringify(json),{ ...opts, headers: { "Content-Type": "application/json", ...(opts.headers || {}) } }); - }, + patchMultipart(url, formData, opts = {}) {return this._request("PATCH", url, formData, opts);}, + patchJson(url, json, opts = {}) { return this._request("PATCH",url,JSON.stringify(json),{ ...opts, headers: { "Content-Type": "application/json", ...(opts.headers || {}) } }); }, // ---------- core ---------- async _request(method, url, body, opts) { @@ -58,14 +58,19 @@ export const api = { signal: opts?.signal }); } catch (e) { + console.log("res 중에 오류"); Notifier.modal("네트워크 오류", "서버에 연결할 수 없습니다. 잠시 후 다시 시도해주세요."); throw e; } + console.debug("[api] <-", res.status, res.statusText, "for", method, url); + if (!res.ok) { + console.log("!res.ok 진입"); const err = await parseErrorResponse(res); handleError(err, res.status, this.config.errorMap); - const e = new Error(err.message || `HTTP ${res.status}`); + const serverMsg = typeof err.raw === "string" ? err.raw : (err.message || ""); + const e = new Error(serverMsg || `HTTP ${res.status}`); e.code = err.code || null; e.status = res.status; e.payload = err.raw; @@ -74,7 +79,27 @@ export const api = { // content-type 따라 자동 파싱 const ct = res.headers.get("Content-Type") || ""; - if (ct.includes("application/json")) return res.json(); + if (ct.includes("application/json")){ + const j = await res.json(); + if (j && typeof j === "object" && "isSuccess" in j) { + if (j.isSuccess === false) { + const err = { + code: j.code ?? null, + message: j.message ?? null, + httpStatus: j.httpStatus ?? 400, // 표시용 상태(서버가 200으로 줘도 OK) + raw: j + }; + console.error("[API ERROR LOGICAL]", err.httpStatus, err.code, err.message, err.raw); + handleError(err, err.httpStatus, this.config.errorMap); + + const e = new Error(err.message || "Logical failure"); + e.code = err.code; e.status = err.httpStatus; e.payload = err.raw; + throw e; + } + return ("result" in j ? j.result : j); + } + return res.json(); + } if (ct.startsWith("text/")) return res.text(); return res; // 파일/바이너리 응답 등 } @@ -82,11 +107,11 @@ export const api = { // ---------- helpers ---------- async function parseErrorResponse(res) { - const ct = res.headers.get("Content-Type") || ""; - // 기대 포맷: { isSuccess:false, code:"...", message:"...", httpStatus:400 } try { - if (ct.includes("application/json")) { - const j = await res.json(); + const r2 = res.clone(); + const ct = r2.headers.get("Content-Type") || ""; + if (ct.includes("application/json")) { + const j = await r2.json(); // 다양한 래핑 가능성 방어: {reason:{...}}, {error:{...}}, 최상위 ... const pick = (obj) => { @@ -108,7 +133,7 @@ async function parseErrorResponse(res) { raw: j }; } - const t = await res.text(); + const t = await r2.text(); return { code: null, message: t || null, httpStatus: res.status, isSuccess: false, raw: t }; } catch { return { code: null, message: null, httpStatus: res.status, isSuccess: false, raw: null }; diff --git a/src/main/resources/templates/homepage/user/forgetPassword.html b/src/main/resources/templates/homepage/user/forgetPassword.html index 1c6f070..a4c7ee1 100644 --- a/src/main/resources/templates/homepage/user/forgetPassword.html +++ b/src/main/resources/templates/homepage/user/forgetPassword.html @@ -122,6 +122,13 @@

비밀번호 찾기

+ + + + - + + + + + + + + + + +
-
+
-
-
2025년 7월 1일 화요일
+
+
2025년 7월 1일 화요일
@@ -111,25 +101,20 @@
+
+
-

고객 만족도 조사 2025

+

고객 만족도 조사 2025

2025.06.20 - 2025.07.01

- - +
@@ -154,18 +139,66 @@

+ +
-

응답 내용

+ +
-

- -
-
-

답변

+ +
+

+ 질문 내용 +

+
+ + SHORT + + + ESSAY + + + 객관식 + + + 체크박스 + + + 드롭다운 + + + 날짜 + + + 파일 + + + 이미지 + + + 계층형 + +
+
+ + +
+
+

답변

@@ -181,103 +214,117 @@

+
미응답

-
-
-

선택된 항목

+
+
+
선택
+
선택된 항목
+
-
-

날짜

+
+ + 날짜
- +
-
+
+
+ +
파일명.ext
+
+
+ +
+
-
+
+
미응답
+
- -
- - - - > - - + +
+ + +
미응답
+ + + +
-
+
- - - - - - - - - - - - - -
+ - \ No newline at end of file +