diff --git a/stockMate/src/main/java/com/stockm8/config/ApplicationContextProvider.java b/stockMate/src/main/java/com/stockm8/config/ApplicationContextProvider.java new file mode 100644 index 0000000..fd86ab2 --- /dev/null +++ b/stockMate/src/main/java/com/stockm8/config/ApplicationContextProvider.java @@ -0,0 +1,20 @@ +package com.stockm8.config; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class ApplicationContextProvider implements ApplicationContextAware { + + private static ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + context = applicationContext; + } + + public static T getBean(Class requiredType) { + return context.getBean(requiredType); + } +} diff --git a/stockMate/src/main/java/com/stockm8/config/WebConfig.java b/stockMate/src/main/java/com/stockm8/config/WebConfig.java index 38226fb..d7938b1 100644 --- a/stockMate/src/main/java/com/stockm8/config/WebConfig.java +++ b/stockMate/src/main/java/com/stockm8/config/WebConfig.java @@ -40,6 +40,7 @@ import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import com.stockm8.interceptor.AdminInterceptor; import com.stockm8.interceptor.AuthorizationInterceptor; import com.stockm8.interceptor.FlashMessageInterceptor; import com.zaxxer.hikari.HikariConfig; @@ -61,12 +62,25 @@ public class WebConfig implements WebMvcConfigurer { @Autowired private FlashMessageInterceptor flashMessageInterceptor; + @Autowired + private AdminInterceptor adminInterceptor; + /** * 인터셉터 설정 * 특정 URL 패턴에 대해 AuthorizationInterceptor를 적용하며, 일부 URL은 제외합니다. */ @Override public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(adminInterceptor) + .addPathPatterns("/admin/**") // /admin/** 경로에만 적용 + .excludePathPatterns( // 인터셉터를 제외할 경로 + "/", // HomeController 경로 + "/favicon.ico", // 브라우저 기본 요청 + "/resources/**", // 정적 리소스 + "/user/**", // 로그인 및 회원가입 관련 요청 + "/static/**", + "/api/**" // API 요청에 대해서는 세션 체크를 제외 + ); // Intercepter 적용 registry.addInterceptor(authorizationInterceptor) .addPathPatterns("/dashboard", "/business", "/category/**", "/product/**", "/warehouse/**", "/stock/**", "/order/**","/admin/**" ) // 인터셉터를 적용할 경로 diff --git a/stockMate/src/main/java/com/stockm8/controller/AdminController.java b/stockMate/src/main/java/com/stockm8/controller/AdminController.java index b8f4361..3bc50c9 100644 --- a/stockMate/src/main/java/com/stockm8/controller/AdminController.java +++ b/stockMate/src/main/java/com/stockm8/controller/AdminController.java @@ -1,31 +1,22 @@ package com.stockm8.controller; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.stockm8.domain.vo.Criteria; -import com.stockm8.domain.vo.OrderItemVO; -import com.stockm8.domain.vo.OrderVO; -import com.stockm8.domain.vo.PageVO; -import com.stockm8.domain.vo.OrderVO.OrderType; -import com.stockm8.domain.vo.StockVO; +import org.springframework.web.bind.annotation.SessionAttribute; + +import com.stockm8.domain.dto.PendingUserDTO; +import com.stockm8.domain.enums.UserRole; import com.stockm8.domain.vo.UserVO; import com.stockm8.service.OrderService; import com.stockm8.service.UserService; @@ -33,48 +24,65 @@ @Controller @RequestMapping(value = "/admin/*") public class AdminController { - + // 현재 로그인한 사용자 정보 가져오기(인터셉터에서 정의됨) private UserVO getCurrentUser(HttpServletRequest request) { - return (UserVO) request.getAttribute("currentUser"); - } - - private static final Logger logger = LoggerFactory.getLogger(AdminController.class); - - @Inject - private OrderService orderService; - @Inject - private UserService userService; - - /** - * 어드민 메인 페이지 표시(GET) - * http://localhost:8088/admin/adminMain - * - */ - @RequestMapping(value = "/adminMain", method = RequestMethod.GET) - public String adminMainGET(Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { - logger.info("adminMainGET() 호출"); - - UserVO currentUser = getCurrentUser(request); - int businessId = currentUser.getBusinessId(); - - return "admin/adminMain"; - } - /** - * 어드민 회원목록표시(GET) - * http://localhost:8088/admin/adminList - * - */ - @RequestMapping(value = "/adminList", method = RequestMethod.GET) - public String adminListGET(Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { - logger.info("adminListGET() 호출"); - - UserVO currentUser = getCurrentUser(request); - int businessId = currentUser.getBusinessId(); - - return "admin/adminList"; + return (UserVO) request.getAttribute("currentUser"); + } + + private static final Logger logger = LoggerFactory.getLogger(AdminController.class); + + @Inject + private OrderService orderService; + @Inject + private UserService userService; + + /** + * 관리자 메인 페이지 표시(GET) http://localhost:8088/admin/main + * + * @throws Exception + * + */ + @GetMapping("/main") + public String adminMainGET(@SessionAttribute("userId") Long userId, Model model) throws Exception { + logger.info("adminMainGET() 호출 - 페이지 접근 (userId: {})", userId); + + // userId로 사용자 정보 가져오기 + UserVO user = userService.getUserById(userId); + + if (user != null) { + // 관리자 여부 확인 (ADMIN인 경우) + boolean isAdmin = user.getUserRole() == UserRole.ADMIN; + model.addAttribute("isAdmin", isAdmin); // JSP에 전달할 데이터 + } + return "admin/main"; // 메인 페이지 반환 + } + + @GetMapping("/approve") + public String adminApproveGET(@SessionAttribute("userId") Long userId, Model model) throws Exception { + logger.info("adminApproveGET() 호출 - 페이지 접근 (userId: {})", userId); + + // 조건에 맞는 사용자와 사업자 정보 가져오기 + List pendingUsers = userService.getPendingUsersWithBusiness(); + + // JSP로 전달 + model.addAttribute("pendingUsers", pendingUsers); + + return "admin/main"; // JSP 페이지 반환 } + /** + * 관리자 회원목록표시(GET) http://localhost:8088/admin/userList + * + */ + @RequestMapping(value = "/adminList", method = RequestMethod.GET) + public String adminListGET(Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { + logger.info("adminListGET() 호출"); + + UserVO currentUser = getCurrentUser(request); + int businessId = currentUser.getBusinessId(); + + return "admin/userList"; + } - -} //AdminController \ No newline at end of file +} // AdminController \ No newline at end of file diff --git a/stockMate/src/main/java/com/stockm8/controller/UserController.java b/stockMate/src/main/java/com/stockm8/controller/UserController.java index 1f45ba3..fa2a6da 100644 --- a/stockMate/src/main/java/com/stockm8/controller/UserController.java +++ b/stockMate/src/main/java/com/stockm8/controller/UserController.java @@ -138,16 +138,6 @@ public String userLoginPOST(UserVO user, RedirectAttributes rttr, HttpSession se return "redirect:/user/signin"; // 로그인 페이지 이동 } - - // 대시보드 페이지 - GET - @RequestMapping(value = "/dashboard", method = RequestMethod.GET) - public void dashGET() { - - logger.info(" dashGET() 호출 "); - - logger.info(" /user/main -> /user/dash.jsp 연결 "); - } - // 로그아웃 - GET @RequestMapping(value = "/signout", method = RequestMethod.GET) public String userLogoutGET(HttpSession session) throws Exception { @@ -158,7 +148,7 @@ public String userLogoutGET(HttpSession session) throws Exception { // 로그아웃 처리 후 페이지 이동 - return "redirect:/user/main"; + return "redirect:/user/signin"; } diff --git a/stockMate/src/main/java/com/stockm8/domain/dto/PendingUserDTO.java b/stockMate/src/main/java/com/stockm8/domain/dto/PendingUserDTO.java new file mode 100644 index 0000000..63c5bee --- /dev/null +++ b/stockMate/src/main/java/com/stockm8/domain/dto/PendingUserDTO.java @@ -0,0 +1,23 @@ +package com.stockm8.domain.dto; + +import java.sql.Timestamp; + +import lombok.Data; + +@Data +public class PendingUserDTO { + + // 사용자 정보 + private Long userId; + private String email; + private String userName; + private String userRole; + private String telNumber; + private Timestamp createdAt; + + // 사업자 정보 + private Integer businessId; + private String businessNumber; + private String businessName; + +} diff --git a/stockMate/src/main/java/com/stockm8/domain/vo/UserVO.java b/stockMate/src/main/java/com/stockm8/domain/vo/UserVO.java index 8b9b686..2128934 100644 --- a/stockMate/src/main/java/com/stockm8/domain/vo/UserVO.java +++ b/stockMate/src/main/java/com/stockm8/domain/vo/UserVO.java @@ -16,7 +16,7 @@ public class UserVO { private String email; // 사용자 이메일(로그인 ID) private String password; // 사용자 비밀번호 private String userName; // 사용자 이름 - private UserRole userRole; // 사용자 역할 (admin, manager, staff) + private UserRole userRole; // 사용자 역할 (ADMIN, MANAGER, STAFF) private Integer businessId; // 사업자 고유 ID (NULL 가능) private String telNumber; // 사용자 전화번호 private Integer createdBy; // 계정을 승인한 사용자 ID @@ -24,7 +24,6 @@ public class UserVO { private Timestamp updatedAt; // 계정 수정 날짜 private UserStatus userStatus; // 계정 상태 (approved, pending, rejected) private Boolean isDeleted; // 삭제 여부 (true/false) - } diff --git a/stockMate/src/main/java/com/stockm8/interceptor/AdminInterceptor.java b/stockMate/src/main/java/com/stockm8/interceptor/AdminInterceptor.java new file mode 100644 index 0000000..d76101b --- /dev/null +++ b/stockMate/src/main/java/com/stockm8/interceptor/AdminInterceptor.java @@ -0,0 +1,100 @@ +package com.stockm8.interceptor; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import com.stockm8.domain.enums.UserRole; +import com.stockm8.domain.vo.UserVO; +import com.stockm8.service.UserService; + +@Component +public class AdminInterceptor implements HandlerInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(AdminInterceptor.class); + + @Autowired + private UserService userService; // 유저 정보를 가져오기 위한 서비스 클래스 + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + HttpSession session = request.getSession(false); + Long userId = (session != null) ? (Long) session.getAttribute("userId") : null; + + // 1. 세션에서 사용자 ID 확인 + if (userId == null) { + logger.warn("세션에 유저 ID가 없습니다. 로그인 페이지로 이동합니다."); + saveRequestedUrlToSession(request); + return sendErrorMessage(request, response, "세션이 만료되었습니다. 다시 로그인해주세요.", "/user/signin"); + } + + // 2. DB에서 사용자 정보 조회 + UserVO user = userService.getUserById(userId); + if (user == null) { + logger.warn("해당 유저({}) 정보를 찾을 수 없습니다. 회원가입 페이지로 이동합니다.", userId); + return sendErrorMessage(request, response, "유저 정보를 찾을 수 없습니다. 회원가입을 진행해주세요.", "/user/signup"); + } + + // 3. 삭제된 계정 확인 + if (Boolean.TRUE.equals(user.getIsDeleted())) { + logger.warn("삭제된 유저({})입니다. 로그인 페이지로 이동합니다.", userId); + return sendErrorMessage(request, response, "삭제된 계정입니다. 관리자에게 문의해주세요.", "/user/signin"); + } + + // 4. 관리자 권한 확인 + if (user.getUserRole() != UserRole.ADMIN) { + logger.warn("권한 없는 접근 시도 (유저 ID: {}, 역할: {}).", userId, user.getUserRole()); + return sendErrorMessage(request, response, "관리자 전용 페이지입니다. 접근 권한이 없습니다.", "/user/signin"); + } + + // 검증 성공: 사용자 정보 저장 + logger.info("관리자 확인 완료 (유저 ID: {}, 이름: {}).", userId, user.getUserName()); + request.setAttribute("currentUser", user); + return true; + } + + /** + * 에러 메시지와 함께 리다이렉트 처리 + */ + private boolean sendErrorMessage(HttpServletRequest request, HttpServletResponse response, String message, String redirectUrl) throws IOException { + request.getSession().setAttribute("errorMessage", message); + response.sendRedirect(request.getContextPath() + redirectUrl); + return false; // 요청 중단 + } + + /** + * 요청한 URL을 세션에 저장 (로그인 후 리다이렉트를 위해) + */ + private void saveRequestedUrlToSession(HttpServletRequest request) { + String requestedUrl = request.getRequestURI(); + String queryString = request.getQueryString(); + if (queryString != null) { + requestedUrl += "?" + queryString; + } + request.getSession().setAttribute("requestedUrl", requestedUrl); + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) + throws Exception { + // TODO Auto-generated method stub + + } + +} diff --git a/stockMate/src/main/java/com/stockm8/interceptor/AuthorizationInterceptor.java b/stockMate/src/main/java/com/stockm8/interceptor/AuthorizationInterceptor.java index 28a2a5f..9739ae3 100644 --- a/stockMate/src/main/java/com/stockm8/interceptor/AuthorizationInterceptor.java +++ b/stockMate/src/main/java/com/stockm8/interceptor/AuthorizationInterceptor.java @@ -83,7 +83,6 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons logger.info("유효한 사용자 확인 (유저 ID: {}, 회사 ID: {})", userId, user.getBusinessId()); return true; // 유효성 검사 통과 - } // 원래 요청 URL 저장 메서드 diff --git a/stockMate/src/main/java/com/stockm8/persistence/UserDAO.java b/stockMate/src/main/java/com/stockm8/persistence/UserDAO.java index 85d296d..fda445f 100644 --- a/stockMate/src/main/java/com/stockm8/persistence/UserDAO.java +++ b/stockMate/src/main/java/com/stockm8/persistence/UserDAO.java @@ -4,8 +4,8 @@ import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; +import com.stockm8.domain.dto.PendingUserDTO; import com.stockm8.domain.vo.UserVO; @@ -19,6 +19,9 @@ public interface UserDAO { // 회원정보 조회동작 public UserVO getUser(Long userId , String password); // + + // 조건에 맞는 pending 회원 리스트와 사업자 정보 가져오기 + public List selectPendingUsersWithBusiness(); // 회원정보 수정동작 public void updateUser (UserVO user); diff --git a/stockMate/src/main/java/com/stockm8/persistence/UserDAOImpl.java b/stockMate/src/main/java/com/stockm8/persistence/UserDAOImpl.java index c81d567..2bbbc04 100644 --- a/stockMate/src/main/java/com/stockm8/persistence/UserDAOImpl.java +++ b/stockMate/src/main/java/com/stockm8/persistence/UserDAOImpl.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; +import com.stockm8.domain.dto.PendingUserDTO; import com.stockm8.domain.vo.UserVO; @Repository @@ -50,6 +51,16 @@ public UserVO getUser(Long userId, String password) { // 비밀번호와 사용자 ID를 사용하여 조회 return sqlSession.selectOne(NAMESPACE + "getUser", params); } + + @Override + public UserVO getUserInfoById(Long userId) throws Exception { + return sqlSession.selectOne("UserMapper.getUserInfoById", userId); + } + + @Override + public List selectPendingUsersWithBusiness() { + return sqlSession.selectList(NAMESPACE + "selectPendingUsersWithBusiness"); + } @Override public void updateUser(UserVO user) { @@ -61,10 +72,7 @@ public void updateUser(UserVO user) { } - @Override - public UserVO getUserInfoById(Long userId) throws Exception { - return sqlSession.selectOne("UserMapper.getUserInfoById", userId); - } + @Override public void updatePassword(Long userId, String newPassword) { diff --git a/stockMate/src/main/java/com/stockm8/service/UserService.java b/stockMate/src/main/java/com/stockm8/service/UserService.java index f41df29..18d72ec 100644 --- a/stockMate/src/main/java/com/stockm8/service/UserService.java +++ b/stockMate/src/main/java/com/stockm8/service/UserService.java @@ -2,7 +2,7 @@ import java.util.List; -import com.stockm8.domain.vo.BusinessVO; +import com.stockm8.domain.dto.PendingUserDTO; import com.stockm8.domain.vo.UserVO; public interface UserService { @@ -18,6 +18,9 @@ public interface UserService { // 회원정보 조회 public UserVO getUser(Long userId,String password) throws Exception; + // 조건에 맞는 pending 회원 리스트와 사업자 정보 가져오기 + public List getPendingUsersWithBusiness() throws Exception; + // 회원정보 수정 public void updateUser(UserVO user) throws Exception; diff --git a/stockMate/src/main/java/com/stockm8/service/UserServiceImpl.java b/stockMate/src/main/java/com/stockm8/service/UserServiceImpl.java index bf9b4f9..1b28c8a 100644 --- a/stockMate/src/main/java/com/stockm8/service/UserServiceImpl.java +++ b/stockMate/src/main/java/com/stockm8/service/UserServiceImpl.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.stockm8.domain.dto.PendingUserDTO; import com.stockm8.domain.vo.BusinessVO; import com.stockm8.domain.vo.UserVO; import com.stockm8.persistence.BusinessDAO; @@ -47,6 +48,11 @@ public UserVO getUser(Long userId, String password) throws Exception { return userDAO.getUser(userId, password); } + @Override + public List getPendingUsersWithBusiness() throws Exception { // TODO Auto-generated method stub + return userDAO.selectPendingUsersWithBusiness(); + } + // 회원 정보 수정 @Override public void updateUser(UserVO user) throws Exception { diff --git a/stockMate/src/main/resources/log4j.xml b/stockMate/src/main/resources/log4j.xml index 5df8957..1e1d52e 100644 --- a/stockMate/src/main/resources/log4j.xml +++ b/stockMate/src/main/resources/log4j.xml @@ -11,6 +11,10 @@ + + + + @@ -23,6 +27,7 @@ + diff --git a/stockMate/src/main/resources/mappers/userMapper.xml b/stockMate/src/main/resources/mappers/userMapper.xml index 5d01627..ef5ae3b 100644 --- a/stockMate/src/main/resources/mappers/userMapper.xml +++ b/stockMate/src/main/resources/mappers/userMapper.xml @@ -71,6 +71,24 @@ FROM users WHERE user_id = #{userId} + + + diff --git a/stockMate/src/main/webapp/WEB-INF/views/admin/approve.jsp b/stockMate/src/main/webapp/WEB-INF/views/admin/approve.jsp new file mode 100644 index 0000000..2de5a16 --- /dev/null +++ b/stockMate/src/main/webapp/WEB-INF/views/admin/approve.jsp @@ -0,0 +1,38 @@ +<%@ page contentType="text/html; charset=UTF-8" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + 승인 대기 사용자 리스트 + + +

승인 대기 사용자 리스트

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
사용자 ID이메일이름역할전화번호사업자등록번호회사명가입 날짜
${user.userId}${user.email}${user.userName}${user.userRole}${user.telNumber}${user.businessNumber}${user.businessName}${user.createdAt}
+ + diff --git a/stockMate/src/main/webapp/WEB-INF/views/admin/adminMain.jsp b/stockMate/src/main/webapp/WEB-INF/views/admin/main.jsp similarity index 80% rename from stockMate/src/main/webapp/WEB-INF/views/admin/adminMain.jsp rename to stockMate/src/main/webapp/WEB-INF/views/admin/main.jsp index eed9545..9bc16cc 100644 --- a/stockMate/src/main/webapp/WEB-INF/views/admin/adminMain.jsp +++ b/stockMate/src/main/webapp/WEB-INF/views/admin/main.jsp @@ -47,14 +47,14 @@
-
- + +
-
- + +
-
- + +
diff --git a/stockMate/src/main/webapp/WEB-INF/views/admin/adminList.jsp b/stockMate/src/main/webapp/WEB-INF/views/admin/userList.jsp similarity index 100% rename from stockMate/src/main/webapp/WEB-INF/views/admin/adminList.jsp rename to stockMate/src/main/webapp/WEB-INF/views/admin/userList.jsp diff --git a/stockMate/src/main/webapp/WEB-INF/views/category/register.jsp b/stockMate/src/main/webapp/WEB-INF/views/category/register.jsp index dc12105..c24a202 100644 --- a/stockMate/src/main/webapp/WEB-INF/views/category/register.jsp +++ b/stockMate/src/main/webapp/WEB-INF/views/category/register.jsp @@ -1,39 +1,76 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> -<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + 카테고리 등록 - - + + + + + + - -
-

카테고리 등록 페이지

- - - - - - - - - - - - -
- 카테고리 리스트로 이동 -
- - + + +
+ + +

카테고리 등록 페이지

+ +
+ + + + + + + +
+ + + + + + +
+
+ +
- \ No newline at end of file + diff --git a/stockMate/src/main/webapp/WEB-INF/views/dashboard.jsp b/stockMate/src/main/webapp/WEB-INF/views/dashboard.jsp index 731b04a..b678aab 100644 --- a/stockMate/src/main/webapp/WEB-INF/views/dashboard.jsp +++ b/stockMate/src/main/webapp/WEB-INF/views/dashboard.jsp @@ -5,7 +5,7 @@ - + 대시보드 \ No newline at end of file +