Files
invyone/backend-spring/src/main/java/com/erp/controller/AdminController.java
T

458 lines
18 KiB
Java

package com.erp.controller;
import com.erp.dto.ApiResponse;
import com.erp.service.AdminService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
@Slf4j
public class AdminController {
private final AdminService adminService;
// ── 메뉴 관리 ──────────────────────────────────────────────────────────
/**
* GET /api/admin/menus
* 관리자 메뉴 목록 조회
*/
@GetMapping("/menus")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getAdminMenus(
@RequestAttribute("company_code") String companyCode,
@RequestAttribute("role") String role,
@RequestAttribute("user_id") String userId,
@RequestParam Map<String, Object> params) {
params.put("company_code", companyCode);
params.put("user_type", role);
params.put("user_id", userId);
params.putIfAbsent("user_lang", "ko");
params.put("is_management_screen",
params.get("menu_type") == null || "true".equals(params.get("include_inactive")));
return ResponseEntity.ok(ApiResponse.success(adminService.getAdminMenuList(params), "관리자 메뉴 목록 조회 성공"));
}
/**
* GET /api/admin/user-menus
* 사용자 메뉴 목록 조회 (사이드바)
*/
@GetMapping("/user-menus")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getUserMenus(
@RequestAttribute("company_code") String companyCode,
@RequestAttribute("role") String role,
@RequestAttribute("user_id") String userId,
@RequestParam Map<String, Object> params) {
params.put("company_code", companyCode);
params.put("user_type", role);
params.put("user_id", userId);
params.putIfAbsent("user_lang", "ko");
return ResponseEntity.ok(ApiResponse.success(adminService.getUserMenuList(params), "사용자 메뉴 목록 조회 성공"));
}
/**
* GET /api/admin/pop-menus
* POP 메뉴 목록 조회
*/
@GetMapping("/pop-menus")
public ResponseEntity<ApiResponse<Map<String, Object>>> getPopMenus(
@RequestAttribute("company_code") String companyCode,
@RequestAttribute("role") String role) {
Map<String, Object> params = new HashMap<>();
params.put("company_code", companyCode);
params.put("user_type", role);
return ResponseEntity.ok(ApiResponse.success(adminService.getPopMenuList(params), "POP 메뉴 목록 조회 성공"));
}
/**
* GET /api/admin/menus/{menuId}
* 메뉴 단건 조회
*/
@GetMapping("/menus/{menuId}")
public ResponseEntity<ApiResponse<Map<String, Object>>> getMenuInfo(@PathVariable String menuId) {
Map<String, Object> menu = adminService.getMenuInfo(menuId);
if (menu == null) {
return ResponseEntity.status(404).body(ApiResponse.error("메뉴를 찾을 수 없습니다."));
}
return ResponseEntity.ok(ApiResponse.success(menu, "메뉴 정보 조회 성공"));
}
/**
* POST /api/admin/menus
* 메뉴 등록
*/
@PostMapping("/menus")
public ResponseEntity<ApiResponse<Map<String, Object>>> saveMenu(
@RequestAttribute("company_code") String companyCode,
@RequestBody Map<String, Object> body) {
body.put("company_code", companyCode);
return ResponseEntity.ok(ApiResponse.success(adminService.saveMenu(body), "메뉴 등록 성공"));
}
/**
* PUT /api/admin/menus/{menuId}
* 메뉴 수정
*/
@PutMapping("/menus/{menuId}")
public ResponseEntity<ApiResponse<Map<String, Object>>> updateMenu(
@PathVariable String menuId,
@RequestBody Map<String, Object> body) {
return ResponseEntity.ok(ApiResponse.success(adminService.updateMenu(menuId, body), "메뉴 수정 성공"));
}
/**
* DELETE /api/admin/menus/{menuId}
* 메뉴 삭제
*/
@DeleteMapping("/menus/{menuId}")
public ResponseEntity<ApiResponse<Void>> deleteMenu(@PathVariable String menuId) {
adminService.deleteMenu(menuId);
return ResponseEntity.ok(ApiResponse.success(null, "메뉴 삭제 성공"));
}
/**
* PUT /api/admin/menus/{menuId}/toggle
* 메뉴 상태 토글
*/
@PutMapping("/menus/{menuId}/toggle")
public ResponseEntity<ApiResponse<Map<String, Object>>> toggleMenuStatus(@PathVariable String menuId) {
return ResponseEntity.ok(ApiResponse.success(adminService.toggleMenuStatus(menuId), "메뉴 상태 변경 성공"));
}
/**
* DELETE /api/admin/menus/batch
* 메뉴 일괄 삭제
*/
@DeleteMapping("/menus/batch")
public ResponseEntity<ApiResponse<Void>> deleteMenusBatch(@RequestBody Map<String, Object> body) {
@SuppressWarnings("unchecked")
List<String> menuIds = (List<String>) body.get("menu_ids");
if (menuIds != null) {
menuIds.forEach(adminService::deleteMenu);
}
return ResponseEntity.ok(ApiResponse.success(null, "메뉴 일괄 삭제 성공"));
}
// ── 사용자 관리 ────────────────────────────────────────────────────────
/**
* GET /api/admin/users
* 사용자 목록 조회
*/
@GetMapping("/users")
public ResponseEntity<?> getUserList(
@RequestAttribute("company_code") String companyCode,
@RequestAttribute("role") String role,
@RequestParam Map<String, Object> params) {
// SUPER_ADMIN이 아닌 경우 자사 필터 적용
if (!"SUPER_ADMIN".equals(role)) {
params.put("company_code", companyCode);
} else {
params.put("company_code", "*");
}
params.putIfAbsent("page", "1");
params.putIfAbsent("limit", "20");
Map<String, Object> result = adminService.getUserList(params);
// Node.js 응답 형식: success, data, total, searchType, pagination, message
Map<String, Object> response = new HashMap<>(result);
response.put("success", true);
response.put("message", "사용자 목록 조회 성공");
return ResponseEntity.ok(response);
}
/**
* GET /api/admin/users/{userId}
* 사용자 단건 조회
*/
@GetMapping("/users/{userId}")
public ResponseEntity<ApiResponse<Map<String, Object>>> getUserInfo(@PathVariable String userId) {
Map<String, Object> user = adminService.getUserInfo(userId);
if (user == null) {
return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
}
return ResponseEntity.ok(ApiResponse.success(user, "사용자 정보 조회 성공"));
}
/**
* GET /api/admin/users/{userId}/history
* 사용자 변경이력 조회
*/
@GetMapping("/users/{userId}/history")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getUserHistory(
@PathVariable String userId,
@RequestParam Map<String, Object> params) {
return ResponseEntity.ok(ApiResponse.success(adminService.getUserHistory(userId, params), "사용자 변경이력 조회 성공"));
}
/**
* GET /api/admin/users/{userId}/with-dept
* 사원 + 부서 정보 조회 (수정 모달용)
*/
@GetMapping("/users/{userId}/with-dept")
public ResponseEntity<ApiResponse<Map<String, Object>>> getUserWithDept(
@RequestAttribute("company_code") String companyCode,
@PathVariable String userId) {
Map<String, Object> params = new HashMap<>();
params.put("company_code", companyCode);
params.put("user_id", userId);
Map<String, Object> result = adminService.getUserWithDept(params);
if (result == null) {
return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
}
return ResponseEntity.ok(ApiResponse.success(result));
}
/**
* POST /api/admin/users/with-dept
* 사원 + 부서 통합 저장
*/
@PostMapping("/users/with-dept")
public ResponseEntity<ApiResponse<Map<String, Object>>> saveUserWithDept(
@RequestAttribute("company_code") String companyCode,
@RequestBody Map<String, Object> body) {
body.put("company_code", companyCode);
return ResponseEntity.ok(ApiResponse.success(adminService.saveUserWithDept(body)));
}
/**
* POST /api/admin/users
* 사용자 등록/수정
*/
@PostMapping("/users")
public ResponseEntity<ApiResponse<Map<String, Object>>> saveUser(
@RequestAttribute("company_code") String companyCode,
@RequestBody Map<String, Object> body) {
body.put("company_code", companyCode);
return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "사용자 저장 성공"));
}
/**
* PUT /api/admin/users/{userId}
* 사용자 수정 (REST)
*/
@PutMapping("/users/{userId}")
public ResponseEntity<ApiResponse<Map<String, Object>>> updateUser(
@PathVariable String userId,
@RequestAttribute("company_code") String companyCode,
@RequestBody Map<String, Object> body) {
body.put("user_id", userId);
body.put("company_code", companyCode);
return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "사용자 수정 성공"));
}
/**
* DELETE /api/admin/users/{userId}
* 사용자 삭제 (비활성화)
*/
@DeleteMapping("/users/{userId}")
public ResponseEntity<ApiResponse<Void>> deleteUser(
@PathVariable String userId) {
Map<String, Object> existing = adminService.getUserInfo(userId);
if (existing == null) {
return ResponseEntity.status(404).body(ApiResponse.error("사용자를 찾을 수 없습니다."));
}
adminService.changeUserStatus(userId, "inactive");
return ResponseEntity.ok(ApiResponse.success(null, "사용자 삭제 성공"));
}
/**
* PATCH /api/admin/users/{userId}/status
* 사용자 상태 변경
*/
@PatchMapping("/users/{userId}/status")
public ResponseEntity<ApiResponse<Void>> changeUserStatus(
@PathVariable String userId,
@RequestBody Map<String, Object> body) {
String status = (String) body.get("status");
adminService.changeUserStatus(userId, status);
return ResponseEntity.ok(ApiResponse.success(null, "사용자 상태 변경 성공"));
}
/**
* POST /api/admin/users/reset-password
* 비밀번호 초기화
*/
@PostMapping("/users/reset-password")
public ResponseEntity<ApiResponse<Void>> resetUserPassword(@RequestBody Map<String, Object> body) {
String userId = (String) body.get("user_id");
adminService.resetUserPassword(userId);
return ResponseEntity.ok(ApiResponse.success(null, "비밀번호 초기화 성공"));
}
/**
* POST /api/admin/users/check-duplicate
* 사용자 ID 중복 확인
*/
@PostMapping("/users/check-duplicate")
public ResponseEntity<ApiResponse<Map<String, Object>>> checkDuplicateUserId(
@RequestBody Map<String, Object> body) {
String userId = (String) body.get("user_id");
Map<String, Object> existing = adminService.getUserInfo(userId);
Map<String, Object> result = new HashMap<>();
result.put("is_duplicate", existing != null);
return ResponseEntity.ok(ApiResponse.success(result, "아이디 중복 확인 완료"));
}
// ── 프로필 수정 ────────────────────────────────────────────────────────
/**
* PUT /api/admin/profile
* 프로필 수정 (본인)
*/
@PutMapping("/profile")
public ResponseEntity<ApiResponse<Map<String, Object>>> updateProfile(
@RequestAttribute("user_id") String userId,
@RequestBody Map<String, Object> body) {
body.put("user_id", userId);
return ResponseEntity.ok(ApiResponse.success(adminService.saveUser(body), "프로필 수정 성공"));
}
// ── 부서 관리 ──────────────────────────────────────────────────────────
/**
* GET /api/admin/departments
* 부서 목록 조회
*/
@GetMapping("/departments")
public ResponseEntity<?> getDepartmentList(
@RequestAttribute("company_code") String companyCode,
@RequestParam Map<String, Object> params) {
params.put("company_code", companyCode);
Map<String, Object> serviceResult = adminService.getDepartmentList(params);
int total = ((Number) serviceResult.get("total")).intValue();
Map<String, Object> data = new HashMap<>();
data.put("departments", serviceResult.get("departments"));
data.put("flat_list", serviceResult.get("flat_list"));
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("data", data);
response.put("message", "부서 목록 조회 성공");
response.put("total", total);
response.put("total_count", total);
return ResponseEntity.ok(response);
}
// ── 회사 관리 ──────────────────────────────────────────────────────────
/**
* GET /api/admin/companies
* 회사 목록 조회
*/
@GetMapping("/companies")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCompanyList() {
return ResponseEntity.ok(ApiResponse.success(adminService.getCompanyList(), "회사 목록 조회 성공"));
}
/**
* GET /api/admin/companies/db
* 실제 DB에서 회사 목록 조회
*/
@GetMapping("/companies/db")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getCompanyListFromDB() {
return ResponseEntity.ok(ApiResponse.success(adminService.getCompanyList(), "회사 목록 조회 성공"));
}
/**
* GET /api/admin/companies/{companyCode}
* 회사 단건 조회
*/
@GetMapping("/companies/{companyCode}")
public ResponseEntity<ApiResponse<Map<String, Object>>> getCompanyByCode(
@PathVariable String companyCode) {
Map<String, Object> company = adminService.getCompanyByCode(companyCode);
if (company == null) {
return ResponseEntity.status(404).body(ApiResponse.error("회사를 찾을 수 없습니다."));
}
return ResponseEntity.ok(ApiResponse.success(company, "회사 조회 성공"));
}
/**
* POST /api/admin/companies
* 회사 등록
*/
@PostMapping("/companies")
public ResponseEntity<ApiResponse<Map<String, Object>>> createCompany(
@RequestBody Map<String, Object> body) {
return ResponseEntity.ok(ApiResponse.success(adminService.createCompany(body), "회사 등록 성공"));
}
/**
* PUT /api/admin/companies/{companyCode}
* 회사 수정
*/
@PutMapping("/companies/{companyCode}")
public ResponseEntity<ApiResponse<Map<String, Object>>> updateCompany(
@PathVariable String companyCode,
@RequestBody Map<String, Object> body) {
return ResponseEntity.ok(ApiResponse.success(adminService.updateCompanyInfo(companyCode, body), "회사 수정 성공"));
}
/**
* DELETE /api/admin/companies/{companyCode}
* 회사 삭제 (비활성화)
*/
@DeleteMapping("/companies/{companyCode}")
public ResponseEntity<ApiResponse<Void>> deleteCompany(@PathVariable String companyCode) {
adminService.deleteCompany(companyCode);
return ResponseEntity.ok(ApiResponse.success(null, "회사 삭제 성공"));
}
// ── 로케일 관리 ────────────────────────────────────────────────────────
/**
* GET /api/admin/user-locale
* 사용자 로케일 조회
*/
@GetMapping("/user-locale")
public ResponseEntity<ApiResponse<Object>> getUserLocale(
@RequestAttribute("user_id") String userId) {
Map<String, Object> row = adminService.getUserLocale(userId);
Object locale = row.getOrDefault("locale", "KR");
return ResponseEntity.ok(ApiResponse.success(locale, "사용자 로케일 조회 성공"));
}
/**
* POST /api/admin/user-locale
* 사용자 로케일 설정
*/
@PostMapping("/user-locale")
public ResponseEntity<ApiResponse<Object>> setUserLocale(
@RequestAttribute("user_id") String userId,
@RequestBody Map<String, Object> body) {
String locale = (String) body.get("locale");
if (locale == null || locale.isBlank()) {
return ResponseEntity.badRequest().body(ApiResponse.error("로케일이 필요합니다."));
}
try {
adminService.setUserLocale(userId, locale);
return ResponseEntity.ok(ApiResponse.success(locale, "사용자 로케일 설정 성공"));
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage()));
}
}
// ── 테이블 스키마 ──────────────────────────────────────────────────────
/**
* GET /api/admin/tables/{tableName}/schema
* 테이블 스키마 조회
*/
@GetMapping("/tables/{tableName}/schema")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTableSchema(
@PathVariable String tableName) {
return ResponseEntity.ok(ApiResponse.success(adminService.getTableSchema(tableName), "테이블 스키마 조회 성공"));
}
}