package com.pms.controller; import com.pms.service.AdminService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.List; import java.util.Map; import com.pms.service.MultiLangService; import com.pms.util.Constants; import com.pms.common.bean.PersonBean; import org.mybatis.spring.SqlSessionTemplate; @Slf4j @RestController @RequestMapping("/admin") @RequiredArgsConstructor public class AdminController { private final AdminService adminService; private final MultiLangService multiLangService; private final SqlSessionTemplate sqlSessionTemplate; /** * 관리자 메뉴 목록 조회 */ @GetMapping("/menus") public ResponseEntity> getAdminMenuList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { // 현재 로그인한 사용자의 회사 코드 가져오기 String userCompanyCode = getCurrentUserCompanyCode(request); log.info("현재 사용자 회사 코드: {}", userCompanyCode); // 사용자 로케일 가져오기 String userLang = getCurrentUserLocale(request); log.info("사용자 로케일: {}", userLang); // 회사 코드와 로케일을 파라미터에 추가 paramMap.put("userCompanyCode", userCompanyCode); paramMap.put("userLang", userLang); List> menuList = adminService.getAdminMenuList(request, paramMap); // 메뉴 관리 화면에서는 회사 코드가 *인 사용자(최고 관리자)가 모든 메뉴를 볼 수 있도록 예외 처리 List> filteredMenuList; // 요청 경로 확인 String requestURI = request.getRequestURI(); log.info("요청 URI: {}", requestURI); log.info("사용자 회사 코드: {}", userCompanyCode); // 임시 해결책: 관리자 메뉴 API에서는 최고 관리자가 모든 메뉴를 볼 수 있도록 설정 if ("*".equals(userCompanyCode)) { // 최고 관리자는 메뉴 관리에서 모든 메뉴를 볼 수 있음 log.info("최고 관리자 - 메뉴 관리에서 모든 메뉴 표시"); log.info("사용자 회사 코드: {}", userCompanyCode); log.info("필터링 없이 모든 메뉴 반환"); filteredMenuList = menuList; } else { // 일반 사용자는 회사 코드 기반 필터링 적용 log.info("일반 사용자 - 회사 코드 기반 필터링 적용"); log.info("사용자 회사 코드: {}", userCompanyCode); filteredMenuList = filterMenusByCompany(menuList, userCompanyCode); } log.info("필터링 전 메뉴 수: {}, 필터링 후 메뉴 수: {}", menuList.size(), filteredMenuList.size()); // SQL에서 이미 번역된 텍스트를 가져오므로 별도 처리 불필요 log.info("SQL에서 번역된 텍스트를 가져왔습니다. TRANSLATED_NAME, TRANSLATED_DESC 필드 확인"); // 디버깅: 실제 응답 데이터 확인 log.info("=== 수정 후 프론트엔드로 전송할 데이터 ==="); for (int i = 0; i < filteredMenuList.size(); i++) { Map menu = filteredMenuList.get(i); log.info("메뉴 {} 응답 데이터: {}", i + 1, menu); log.info("메뉴 {} 키들: {}", i + 1, menu.keySet()); log.info("메뉴 {} COMPANY_CODE 값: {}", i + 1, menu.get("COMPANY_CODE")); log.info("메뉴 {} COMPANY_NAME 값: {}", i + 1, menu.get("COMPANY_NAME")); log.info("메뉴 {} LANG_KEY 값: {}", i + 1, menu.get("LANG_KEY")); log.info("메뉴 {} LANG_KEY_DESC 값: {}", i + 1, menu.get("LANG_KEY_DESC")); log.info("메뉴 {} TRANSLATED_NAME 값: {}", i + 1, menu.get("TRANSLATED_NAME")); log.info("메뉴 {} TRANSLATED_DESC 값: {}", i + 1, menu.get("TRANSLATED_DESC")); } // null 값을 명시적으로 포함하여 프론트엔드에서 처리할 수 있도록 함 for (Map menu : filteredMenuList) { // COMPANY_CODE가 없거나 null이면 빈 문자열로 설정 if (!menu.containsKey("COMPANY_CODE") || menu.get("COMPANY_CODE") == null) { menu.put("COMPANY_CODE", ""); } // COMPANY_NAME이 없거나 null이면 "미지정"으로 설정 if (!menu.containsKey("COMPANY_NAME") || menu.get("COMPANY_NAME") == null) { menu.put("COMPANY_NAME", "미지정"); } } // 디버깅: 수정 후 데이터 확인 log.info("=== 수정 후 프론트엔드로 전송할 데이터 ==="); if (!filteredMenuList.isEmpty()) { Map firstMenu = filteredMenuList.get(0); log.info("첫 번째 메뉴 수정 후 데이터: {}", firstMenu); log.info("첫 번째 메뉴 수정 후 키들: {}", firstMenu.keySet()); log.info("COMPANY_CODE 값: {}", firstMenu.get("COMPANY_CODE")); log.info("COMPANY_NAME 값: {}", firstMenu.get("COMPANY_NAME")); } // 메뉴 2번 데이터도 확인 if (filteredMenuList.size() > 1) { Map secondMenu = filteredMenuList.get(1); log.info("메뉴 2번 수정 후 데이터: {}", secondMenu); log.info("메뉴 2번 COMPANY_CODE 값: {}", secondMenu.get("COMPANY_CODE")); log.info("메뉴 2번 COMPANY_NAME 값: {}", secondMenu.get("COMPANY_NAME")); } Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", filteredMenuList); responseMap.put("message", "관리자 메뉴 목록 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("관리자 메뉴 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "관리자 메뉴 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "ADMIN_MENU_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 메뉴 목록 조회 */ @GetMapping("/user-menus") public ResponseEntity> getUserMenuList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { // 현재 로그인한 사용자의 회사 코드 가져오기 String userCompanyCode = getCurrentUserCompanyCode(request); log.info("사용자 메뉴 API - 현재 사용자 회사 코드: {}", userCompanyCode); // 사용자 로케일 가져오기 String userLang = getCurrentUserLocale(request); log.info("사용자 메뉴 API - 사용자 로케일: {}", userLang); // 회사 코드와 로케일을 파라미터에 추가 paramMap.put("userCompanyCode", userCompanyCode); paramMap.put("userLang", userLang); log.info("사용자 메뉴 API - 파라미터: {}", paramMap); List> menuList = adminService.getUserMenuList(request, paramMap); log.info("사용자 메뉴 API - 원본 메뉴 리스트 개수: {}", menuList.size()); if (!menuList.isEmpty()) { log.info("사용자 메뉴 API - 첫 번째 메뉴: {}", menuList.get(0)); } // 회사 코드 기반 메뉴 필터링 List> filteredMenuList; // 최고 관리자(*인 경우)는 모든 메뉴를 볼 수 있음 if ("*".equals(userCompanyCode)) { log.info("사용자 메뉴 API - 최고 관리자에게 모든 메뉴 표시"); filteredMenuList = menuList; } else { // 일반 사용자는 회사 코드 기반 필터링 적용 log.info("사용자 메뉴 API - 일반 사용자에게 필터링 적용"); filteredMenuList = filterMenusByCompany(menuList, userCompanyCode); } log.info("사용자 메뉴 API - 필터링 후 메뉴 리스트 개수: {}", filteredMenuList.size()); // 디버깅용 로그 추가 log.info("사용자 메뉴 조회 결과 - 메뉴 개수: {}", filteredMenuList.size()); if (!filteredMenuList.isEmpty()) { log.info("첫 번째 메뉴 데이터: {}", filteredMenuList.get(0)); log.info("첫 번째 메뉴 키들: {}", filteredMenuList.get(0).keySet()); } Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", filteredMenuList); responseMap.put("message", "사용자 메뉴 목록 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 메뉴 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 메뉴 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "USER_MENU_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 View 메뉴 목록 조회 */ @GetMapping("/user-view-menus") public ResponseEntity> getUserViewMenuList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { List> menuList = adminService.getUserViewMenuList(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", menuList); responseMap.put("message", "사용자 View 메뉴 목록 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 View 메뉴 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 View 메뉴 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "USER_VIEW_MENU_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 정보 조회 */ @GetMapping("/menus/{menuId}") public ResponseEntity> getMenuInfo( HttpServletRequest request, HttpServletResponse response, @PathVariable String menuId) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("OBJID", menuId); log.info("메뉴 정보 조회 요청 - menuId: {}", menuId); Map menuInfo = adminService.getMenuInfo(request, paramMap); // 회사 코드가 *인 사용자(최고 관리자)는 모든 메뉴 정보를 볼 수 있음 String userCompanyCode = getCurrentUserCompanyCode(request); if (!"*".equals(userCompanyCode)) { // 일반 사용자는 회사 코드 기반 권한 체크 String menuCompanyCode = (String) menuInfo.get("COMPANY_CODE"); if (!"*".equals(menuCompanyCode) && !userCompanyCode.equals(menuCompanyCode)) { log.warn("권한 없음 - 사용자 회사코드: {}, 메뉴 회사코드: {}", userCompanyCode, menuCompanyCode); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "해당 메뉴에 대한 접근 권한이 없습니다."); responseMap.put("errorCode", "MENU_ACCESS_DENIED"); return ResponseEntity.status(403).body(responseMap); } } // 다국어 텍스트 추가 (선택적) String langKey = (String) menuInfo.get("LANG_KEY"); String langKeyDesc = (String) menuInfo.get("LANG_KEY_DESC"); String userLang = getCurrentUserLocale(request); log.info("메뉴 상세 - 사용자 로케일: {}", userLang); // 다국어 키가 있을 때만 번역 시도 if (langKey != null && !langKey.trim().isEmpty()) { try { // 다국어 서비스를 통해 텍스트 조회 String translatedName = multiLangService.getLangText( (String) menuInfo.get("COMPANY_CODE"), langKey, userLang ); if (translatedName != null && !translatedName.trim().isEmpty()) { menuInfo.put("TRANSLATED_NAME", translatedName); } } catch (Exception e) { log.debug("다국어 텍스트 조회 실패 (무시): {}", e.getMessage()); } } if (langKeyDesc != null && !langKeyDesc.trim().isEmpty()) { try { String translatedDesc = multiLangService.getLangText( (String) menuInfo.get("COMPANY_CODE"), langKeyDesc, userLang ); if (translatedDesc != null && !translatedDesc.trim().isEmpty()) { menuInfo.put("TRANSLATED_DESC", translatedDesc); } } catch (Exception e) { log.debug("다국어 설명 조회 실패 (무시): {}", e.getMessage()); } } Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", menuInfo); responseMap.put("message", "메뉴 정보 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 정보 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 정보 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "MENU_INFO_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 등록/수정 */ @PostMapping("/menus") public ResponseEntity> saveMenu( HttpServletRequest request, HttpServletResponse response, @RequestBody Map menuData) { setCorsHeaders(response, request); try { // 회사 코드가 *인 사용자(최고 관리자)는 모든 메뉴를 관리할 수 있음 String userCompanyCode = getCurrentUserCompanyCode(request); if (!"*".equals(userCompanyCode)) { // 일반 사용자는 회사 코드 기반 권한 체크 String menuCompanyCode = (String) menuData.get("companyCode"); if (!"*".equals(menuCompanyCode) && !userCompanyCode.equals(menuCompanyCode)) { log.warn("권한 없음 - 사용자 회사코드: {}, 메뉴 회사코드: {}", userCompanyCode, menuCompanyCode); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "해당 회사의 메뉴를 관리할 권한이 없습니다."); responseMap.put("errorCode", "MENU_MANAGEMENT_DENIED"); return ResponseEntity.status(403).body(responseMap); } } log.info("메뉴 저장 요청 - menuData: {}", menuData); // objid가 있으면 수정, 없으면 등록 Object objidObj = menuData.get("objid"); String objid = objidObj != null ? objidObj.toString() : null; Map result; if (objid != null && !objid.trim().isEmpty()) { log.info("메뉴 수정 모드 - objid: {}", objid); // 메뉴 수정 result = adminService.updateMenu(request, menuData); } else { log.info("메뉴 등록 모드"); // 메뉴 등록 result = adminService.insertMenu(request, menuData); } Map responseMap = new HashMap<>(); responseMap.put("success", result.get("success")); responseMap.put("message", result.get("message")); if (result.get("objid") != null) { responseMap.put("objid", result.get("objid")); } return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 저장 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 저장 중 오류가 발생했습니다."); responseMap.put("errorCode", "MENU_SAVE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 삭제 */ @DeleteMapping("/menus/{menuId}") public ResponseEntity> deleteMenu( HttpServletRequest request, HttpServletResponse response, @PathVariable String menuId) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("objid", menuId); Map result = adminService.deleteMenu(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", result.get("success")); responseMap.put("message", result.get("message")); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 삭제 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 삭제에 실패하였습니다."); responseMap.put("errorCode", "MENU_DELETE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 일괄 삭제 */ @DeleteMapping("/menus/batch") public ResponseEntity> deleteMenusBatch( HttpServletRequest request, HttpServletResponse response, @RequestBody List menuIds) { setCorsHeaders(response, request); try { log.info("메뉴 일괄 삭제 요청: {}개의 메뉴", menuIds.size()); Map result = adminService.deleteMenusBatch(request, menuIds); Map responseMap = new HashMap<>(); responseMap.put("success", result.get("success")); responseMap.put("message", result.get("message")); // data 필드에 삭제 결과 정보 포함 Map dataMap = new HashMap<>(); dataMap.put("deletedCount", result.get("deletedCount")); dataMap.put("failedCount", result.get("failedCount")); dataMap.put("failedMenuIds", result.get("failedMenuIds")); responseMap.put("data", dataMap); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 일괄 삭제 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 일괄 삭제에 실패하였습니다."); responseMap.put("errorCode", "MENU_BATCH_DELETE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 활성/비활성 토글 */ @PutMapping("/menus/{menuId}/toggle") public ResponseEntity> toggleMenuStatus( HttpServletRequest request, HttpServletResponse response, @PathVariable String menuId) { setCorsHeaders(response, request); try { String result = adminService.toggleMenuStatus(menuId); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("message", "메뉴가 " + result + "되었습니다."); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 상태 토글 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 상태 변경에 실패하였습니다."); responseMap.put("errorCode", "MENU_TOGGLE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 메뉴 권한 그룹 목록 조회 */ @GetMapping("/menus/{menuId}/auth-groups") public ResponseEntity> getMenuAuthGroups( HttpServletRequest request, HttpServletResponse response, @PathVariable String menuId) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("objid", menuId); List> authGroups = adminService.getMenuAuthGroupList(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", authGroups); responseMap.put("message", "메뉴 권한 그룹 목록 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 권한 그룹 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 권한 그룹 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "MENU_AUTH_GROUPS_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 메뉴 권한 체크 */ @PostMapping("/check-menu-auth") public ResponseEntity> checkUserMenuAuth( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { Map authResult = adminService.checkUserMenuAuth(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", authResult); responseMap.put("message", "메뉴 권한 체크 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("메뉴 권한 체크 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "메뉴 권한 체크 중 오류가 발생했습니다."); responseMap.put("errorCode", "MENU_AUTH_CHECK_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 권한 관리 목록 조회 */ @GetMapping("/auth-list") public ResponseEntity> getAuthMngList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { List> authList = adminService.getAuthMngList(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", authList); responseMap.put("message", "권한 관리 목록 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("권한 관리 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "권한 관리 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "AUTH_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 정보 저장 */ @PostMapping("/user/save") public ResponseEntity> saveUserInfo( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { @SuppressWarnings("unchecked") Map resultMap = adminService.saveEtcUserInfo(request, paramMap); Boolean result = (Boolean) resultMap.get("result"); if (result != null && result) { return ResponseEntity.ok(resultMap); } else { return ResponseEntity.status(400).body(resultMap); } } catch (Exception e) { log.error("사용자 정보 저장 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("result", false); responseMap.put("msg", "시스템 오류가 발생했습니다: " + e.getMessage()); return ResponseEntity.status(500).body(responseMap); } } // ========== 회사 관리 CRUD API 엔드포인트들 시작 ========== /** * 회사 등록 */ @PostMapping("/companies") public ResponseEntity> insertCompany( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { Map result = adminService.insertCompany(request, paramMap); return ResponseEntity.ok(result); } catch (Exception e) { log.error("회사 등록 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 등록 중 오류가 발생했습니다."); responseMap.put("errorCode", "COMPANY_INSERT_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 회사 목록 조회 */ @GetMapping("/companies") public ResponseEntity> getCompanyList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { List> companyList = adminService.getCompanyList(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", companyList); responseMap.put("total", companyList.size()); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("회사 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "COMPANY_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 회사 정보 단건 조회 */ @GetMapping("/companies/{companyCode}") public ResponseEntity> getCompanyInfo( HttpServletRequest request, HttpServletResponse response, @PathVariable String companyCode) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("company_code", companyCode); Map result = adminService.getCompanyInfo(request, paramMap); return ResponseEntity.ok(result); } catch (Exception e) { log.error("회사 정보 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 정보 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "COMPANY_INFO_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 회사 데이터 디버깅 */ @GetMapping("/debug/company-data") public ResponseEntity> debugCompanyData( HttpServletRequest request, HttpServletResponse response) { setCorsHeaders(response, request); try { adminService.debugCompanyData(); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("message", "회사 데이터 디버깅 완료. 로그를 확인하세요."); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("회사 데이터 디버깅 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 데이터 디버깅 중 오류가 발생했습니다."); return ResponseEntity.status(500).body(responseMap); } } /** * 회사 정보 수정 */ @PutMapping("/companies/{companyCode}") public ResponseEntity> updateCompany( HttpServletRequest request, HttpServletResponse response, @PathVariable String companyCode, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { paramMap.put("company_code", companyCode); Map result = adminService.updateCompany(request, paramMap); return ResponseEntity.ok(result); } catch (Exception e) { log.error("회사 정보 수정 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 정보 수정 중 오류가 발생했습니다."); responseMap.put("errorCode", "COMPANY_UPDATE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 회사 삭제 */ @DeleteMapping("/companies/{companyCode}") public ResponseEntity> deleteCompany( HttpServletRequest request, HttpServletResponse response, @PathVariable String companyCode) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("company_code", companyCode); Map result = adminService.deleteCompany(request, paramMap); return ResponseEntity.ok(result); } catch (Exception e) { log.error("회사 삭제 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "회사 삭제 중 오류가 발생했습니다."); responseMap.put("errorCode", "COMPANY_DELETE_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 부서 목록 조회 (회사별) */ @GetMapping("/departments") public ResponseEntity> getDepartmentList( HttpServletRequest request, HttpServletResponse response, @RequestParam(required = false) String companyCode) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); if (companyCode != null && !companyCode.isEmpty()) { paramMap.put("COMPANY_CODE", companyCode); } List> departmentList = adminService.getDepartmentList(request, paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", departmentList); responseMap.put("message", "부서 목록 조회 완료"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("부서 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "부서 목록 조회 중 오류가 발생했습니다."); return ResponseEntity.status(500).body(responseMap); } } // ========== 회사 관리 CRUD API 엔드포인트들 종료 ========== /** * 연결 테스트 */ @GetMapping("/test") public ResponseEntity test(HttpServletRequest request, HttpServletResponse response) { setCorsHeaders(response, request); return ResponseEntity.ok("Admin Controller Connected!"); } /** * 현재 사용자의 로케일 정보 조회 */ @GetMapping("/user-locale") public ResponseEntity> getUserLocale(HttpServletRequest request, HttpServletResponse response) { setCorsHeaders(response, request); try { String userLocale = getCurrentUserLocale(request); log.info("사용자 로케일 조회: {}", userLocale); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", userLocale); responseMap.put("message", "사용자 로케일 조회 성공"); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 로케일 조회 실패", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 로케일 조회 실패"); responseMap.put("error", e.getMessage()); return ResponseEntity.badRequest().body(responseMap); } } /** * CORS 헤더 설정 (동적 origin 지원) */ private void setCorsHeaders(HttpServletResponse response, HttpServletRequest request) { String origin = request.getHeader("Origin"); // 허용된 origin 목록 String[] allowedOrigins = { "http://localhost:9771", "http://localhost:3000", "http://192.168.0.70:5555", "http://127.0.0.1:9771", "http://127.0.0.1:3000" }; // origin이 허용된 목록에 있는지 확인 boolean isAllowed = false; if (origin != null) { for (String allowedOrigin : allowedOrigins) { if (allowedOrigin.equals(origin)) { isAllowed = true; break; } } } if (isAllowed) { response.setHeader("Access-Control-Allow-Origin", origin); } else { // 기본값 설정 response.setHeader("Access-Control-Allow-Origin", "http://localhost:9771"); } response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Max-Age", "3600"); } /** * 현재 로그인한 사용자의 회사 코드 가져오기 */ private String getCurrentUserCompanyCode(HttpServletRequest request) { try { PersonBean person = (PersonBean) request.getSession().getAttribute(Constants.PERSON_BEAN); if (person != null) { String companyCode = person.getCompanyCode(); if (companyCode != null && !companyCode.trim().isEmpty()) { return companyCode; } } // 세션에서 가져올 수 없는 경우 기본값 반환 log.warn("세션에서 회사 코드를 가져올 수 없어 최고 관리자 권한으로 설정: *"); return "*"; } catch (Exception e) { log.error("회사 코드 조회 중 오류 발생", e); return "*"; // 임시로 최고 관리자 권한 } } /** * 현재 로그인한 사용자의 로케일 가져오기 */ private String getCurrentUserLocale(HttpServletRequest request) { try { PersonBean person = (PersonBean) request.getSession().getAttribute(Constants.PERSON_BEAN); if (person != null) { // PersonBean에 locale 필드가 있는지 확인 // 만약 없다면 데이터베이스에서 직접 조회 String locale = getUserLocaleFromDB(person.getUserId()); if (locale != null && !locale.trim().isEmpty()) { return locale; } } // 기본값 반환 log.warn("사용자 로케일을 가져올 수 없어 기본값 사용: ko"); return "ko"; } catch (Exception e) { log.error("사용자 로케일 조회 중 오류 발생", e); return "ko"; // 기본값 } } /** * 데이터베이스에서 사용자 로케일 조회 */ private String getUserLocaleFromDB(String userId) { try { Map paramMap = new HashMap<>(); paramMap.put("userId", userId); // MyBatis 매퍼를 통해 사용자 로케일 조회 String locale = sqlSessionTemplate.selectOne("admin.selectUserLocale", paramMap); if (locale != null && !locale.trim().isEmpty()) { log.info("사용자 {} 로케일: {}", userId, locale); return locale; } } catch (Exception e) { log.error("데이터베이스에서 사용자 로케일 조회 실패", e); } return null; } /** * 회사 코드에 따라 메뉴를 필터링합니다. */ private List> filterMenusByCompany(List> menuList, String userCompanyCode) { final String finalUserCompanyCode; if (userCompanyCode == null || userCompanyCode.trim().isEmpty()) { finalUserCompanyCode = "ILSHIN"; // 기본값 } else { finalUserCompanyCode = userCompanyCode; } log.info("메뉴 필터링 시작 - 사용자 회사 코드: {}", finalUserCompanyCode); return menuList.stream() .filter(menu -> { String menuCompanyCode = (String) menu.get("COMPANY_CODE"); // 사용자 회사 코드가 *인 경우 공통 메뉴만 접근 가능 if ("*".equals(finalUserCompanyCode)) { boolean isCommonMenu = "*".equals(menuCompanyCode); log.debug("공통 사용자 - 메뉴: {}, 회사코드: {}, 공통메뉴여부: {}", menu.get("MENU_NAME_KOR"), menuCompanyCode, isCommonMenu); return isCommonMenu; } // 특정 회사 사용자는 해당 회사 메뉴와 공통 메뉴 접근 가능 boolean isAllowed = "*".equals(menuCompanyCode) || finalUserCompanyCode.equals(menuCompanyCode); log.debug("특정 회사 사용자 - 메뉴: {}, 메뉴회사코드: {}, 사용자회사코드: {}, 허용여부: {}", menu.get("MENU_NAME_KOR"), menuCompanyCode, finalUserCompanyCode, isAllowed); return isAllowed; }) .collect(java.util.stream.Collectors.toList()); } // ========== 사용자 관리 REST API들 ========== /** * 사용자 목록 조회 */ @GetMapping("/users") public ResponseEntity> getUserList( HttpServletRequest request, HttpServletResponse response, @RequestParam Map paramMap) { setCorsHeaders(response, request); try { // 원본 JSP 컨트롤러처럼 파라미터 그대로 전달 List> userList = adminService.getEtcUserList(request, paramMap); // 총 개수 조회를 위한 별도 호출 (페이징 파라미터 제외) Map countParam = new HashMap<>(paramMap); countParam.remove("page"); countParam.remove("countPerPage"); countParam.remove("PAGE_START"); countParam.remove("PAGE_END"); int totalCount = adminService.getEtcUserListCnt(countParam); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", userList); responseMap.put("total", totalCount); // 실제 총 개수 return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 목록 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 목록 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "USER_LIST_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 상세 조회 */ @GetMapping("/users/{userId}") public ResponseEntity> getUserInfo( HttpServletRequest request, HttpServletResponse response, @PathVariable String userId) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("userId", userId); Map userInfo = adminService.getEtcUserInfo(paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", userInfo); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 상세 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 상세 조회 중 오류가 발생했습니다."); responseMap.put("errorCode", "USER_INFO_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 등록/수정 */ @PostMapping("/users") public ResponseEntity> saveUser( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { // 프론트엔드 필드명을 백엔드 쿼리 파라미터명으로 변환 Map convertedParams = new HashMap<>(); convertedParams.put("userId", paramMap.get("user_id")); convertedParams.put("password", paramMap.get("user_password")); convertedParams.put("userName", paramMap.get("user_name")); convertedParams.put("email", paramMap.get("email")); convertedParams.put("tel", paramMap.get("tel")); convertedParams.put("cellPhone", paramMap.get("cell_phone")); convertedParams.put("positionName", paramMap.get("position_name")); convertedParams.put("companyCode", paramMap.get("company_code")); convertedParams.put("deptCode", paramMap.get("dept_code")); convertedParams.put("sabun", paramMap.get("sabun")); convertedParams.put("status", paramMap.get("status")); log.info("사용자 저장 요청 - userId: {}", convertedParams.get("userId")); @SuppressWarnings("unchecked") Map resultMap = adminService.saveEtcUserInfo(request, convertedParams); Boolean result = (Boolean) resultMap.get("result"); if (result != null && result) { return ResponseEntity.ok(resultMap); } else { return ResponseEntity.status(400).body(resultMap); } } catch (Exception e) { log.error("사용자 저장 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("result", false); responseMap.put("msg", "시스템 오류가 발생했습니다: " + e.getMessage()); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 ID 중복 체크 */ @PostMapping("/users/check-duplicate") public ResponseEntity> checkDuplicateUserId( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { String userId = String.valueOf(paramMap.get("userId")); log.info("사용자 ID 중복 체크 요청 - userId: {}", userId); // 원본 AdminService 메서드 사용 (request 파라미터 제거) Map result = adminService.checkDuplicateEtcUserId(paramMap); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", result); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 ID 중복 체크 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 ID 중복 체크 중 오류가 발생했습니다."); responseMap.put("errorCode", "DUPLICATE_CHECK_ERROR"); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 상태 변경 */ @PutMapping("/users/{userId}/status") public ResponseEntity> changeUserStatus( HttpServletRequest request, HttpServletResponse response, @PathVariable String userId, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { paramMap.put("user_id", userId); Map resultMap = adminService.changeUserStatus(paramMap); Boolean result = (Boolean) resultMap.get("result"); if (result != null && result) { return ResponseEntity.ok(resultMap); } else { return ResponseEntity.status(400).body(resultMap); } } catch (Exception e) { log.error("사용자 상태 변경 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("result", false); responseMap.put("msg", "시스템 오류가 발생했습니다: " + e.getMessage()); return ResponseEntity.status(500).body(responseMap); } } // 사용자 변경이력 조회 API (원본 JSP 로직 기반) @GetMapping("/users/{userId}/history") public ResponseEntity> getUserHistory( HttpServletRequest request, HttpServletResponse response, @PathVariable String userId, @RequestParam(defaultValue = "1") String page, @RequestParam(defaultValue = "10") String countPerPage) { setCorsHeaders(response, request); try { Map paramMap = new HashMap<>(); paramMap.put("user_id", userId); paramMap.put("page", page); paramMap.put("countPerPage", countPerPage); log.info("사용자 변경이력 조회 - userId: {}, page: {}, countPerPage: {}", userId, page, countPerPage); log.info("전체 요청 파라미터: {}", request.getParameterMap()); log.info("paramMap 내용: {}", paramMap); // 원본 방식대로 서비스 호출 (서비스에서 페이징 처리) List> historyList = adminService.getUserHistoryList(request, paramMap); int totalCount = adminService.getUserHistoryListCnt(request, paramMap); // request에서 MAX_PAGE_SIZE 가져오기 (서비스에서 설정) Object maxPageSizeObj = request.getAttribute("MAX_PAGE_SIZE"); int maxPageSize = 1; if (maxPageSizeObj != null) { maxPageSize = ((Number) maxPageSizeObj).intValue(); } log.info("조회된 이력 개수: {}, 전체 개수: {}, 최대 페이지: {}", historyList.size(), totalCount, maxPageSize); Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("data", historyList); responseMap.put("total", totalCount); responseMap.put("maxPageSize", maxPageSize); return ResponseEntity.ok(responseMap); } catch (Exception e) { log.error("사용자 변경이력 조회 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 변경이력 조회에 실패했습니다: " + e.getMessage()); return ResponseEntity.status(500).body(responseMap); } } /** * 사용자 비밀번호 초기화 API */ @PostMapping("/users/reset-password") public ResponseEntity> resetUserPassword( HttpServletRequest request, HttpServletResponse response, @RequestBody Map paramMap) { setCorsHeaders(response, request); try { String userId = String.valueOf(paramMap.get("userId")); String newPassword = String.valueOf(paramMap.get("newPassword")); log.info("비밀번호 초기화 요청 - userId: {}", userId); // 입력값 검증 if (userId == null || userId.trim().isEmpty()) { Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "사용자 ID가 필요합니다."); return ResponseEntity.badRequest().body(responseMap); } if (newPassword == null || newPassword.trim().isEmpty()) { Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "새 비밀번호가 필요합니다."); return ResponseEntity.badRequest().body(responseMap); } // 원본 로직과 동일하게 파라미터 설정 Map resetParamMap = new HashMap<>(); resetParamMap.put("USER_ID", userId); resetParamMap.put("NEW_PASSWORD", newPassword); Map result = adminService.resetUserPassword(request, resetParamMap); if (Boolean.TRUE.equals(result.get("result")) || "true".equals(result.get("result"))) { Map responseMap = new HashMap<>(); responseMap.put("success", true); responseMap.put("message", result.get("msg")); return ResponseEntity.ok(responseMap); } else { Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", result.get("msg")); return ResponseEntity.ok(responseMap); } } catch (Exception e) { log.error("비밀번호 초기화 중 오류 발생", e); Map responseMap = new HashMap<>(); responseMap.put("success", false); responseMap.put("message", "비밀번호 초기화 중 시스템 오류가 발생했습니다."); return ResponseEntity.status(500).body(responseMap); } } // ========== 사용자 관리 REST API들 끝 ========== }