450 lines
21 KiB
Java
450 lines
21 KiB
Java
package com.erp.service;
|
|
|
|
import com.erp.common.BaseService;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service
|
|
@Slf4j
|
|
public class AdminService extends BaseService {
|
|
|
|
@Autowired
|
|
private CommonService commonService;
|
|
@Autowired
|
|
private PasswordEncoder passwordEncoder;
|
|
|
|
// ── 메뉴 관리 ──────────────────────────────────────────────────────────
|
|
|
|
public List<Map<String, Object>> getAdminMenuList(Map<String, Object> params) {
|
|
params.putIfAbsent("user_lang", "ko");
|
|
// String "false"/"true" → Boolean (OGNL !includeInactive 오작동 방지)
|
|
Object includeInactiveRaw = params.get("include_inactive");
|
|
params.put("include_inactive", Boolean.TRUE.equals(includeInactiveRaw) || "true".equals(includeInactiveRaw));
|
|
params.putIfAbsent("is_management_screen", false);
|
|
return sqlSession.selectList("admin.selectAdminMenuList", params);
|
|
}
|
|
|
|
public List<Map<String, Object>> getUserMenuList(Map<String, Object> params) {
|
|
params.putIfAbsent("user_lang", "ko");
|
|
return sqlSession.selectList("admin.selectUserMenuList", params);
|
|
}
|
|
|
|
public Map<String, Object> getPopMenuList(Map<String, Object> params) {
|
|
Map<String, Object> result = new HashMap<>();
|
|
List<Map<String, Object>> parents = sqlSession.selectList("admin.selectPopParentMenu", params);
|
|
if (parents.isEmpty()) {
|
|
result.put("parent_menu", null);
|
|
result.put("child_menus", List.of());
|
|
result.put("landing_menu", null);
|
|
return result;
|
|
}
|
|
Map<String, Object> parent = parents.get(0);
|
|
Object parentObjid = parent.get("objid");
|
|
Object parentCompanyCode = parent.get("company_code");
|
|
|
|
Map<String, Object> childParams = new HashMap<>();
|
|
childParams.put("parent_objid", parentObjid);
|
|
childParams.put("parent_company_code", parentCompanyCode);
|
|
List<Map<String, Object>> children = sqlSession.selectList("admin.selectPopChildMenus", childParams);
|
|
|
|
Map<String, Object> landingMenu = children.stream()
|
|
.filter(m -> {
|
|
Object desc = m.get("menu_desc");
|
|
return desc != null && desc.toString().contains("[POP_LANDING]");
|
|
})
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
result.put("parent_menu", parent);
|
|
result.put("child_menus", children);
|
|
result.put("landing_menu", landingMenu);
|
|
return result;
|
|
}
|
|
|
|
public Map<String, Object> getMenuInfo(String menuId) {
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("menu_id", menuId);
|
|
return sqlSession.selectOne("admin.selectMenuById", params);
|
|
}
|
|
|
|
public Map<String, Object> saveMenu(Map<String, Object> params) {
|
|
// Generate timestamp-based objid
|
|
long objid = System.currentTimeMillis();
|
|
params.put("objid", objid);
|
|
|
|
normalizeMenuParams(params);
|
|
|
|
// Map frontend field names to DB column names
|
|
if (params.get("menu_name_kor") == null && params.get("menu_name") != null) {
|
|
params.put("menu_name_kor", params.get("menu_name"));
|
|
}
|
|
|
|
sqlSession.insert("admin.insertMenu", params);
|
|
return params;
|
|
}
|
|
|
|
public Map<String, Object> updateMenu(String menuId, Map<String, Object> params) {
|
|
params.put("menu_id", menuId);
|
|
normalizeMenuParams(params);
|
|
sqlSession.update("admin.updateMenu", params);
|
|
return params;
|
|
}
|
|
|
|
// 프론트가 보내는 camelCase 키를 XML이 기대하는 snake_case 키로 복사한다.
|
|
// (XML #{menu_name_kor} 등 snake_case 파라미터로 바인딩하기 위함)
|
|
private void normalizeMenuParams(Map<String, Object> params) {
|
|
copyIfAbsent(params, "menuNameKor", "menu_name_kor");
|
|
copyIfAbsent(params, "menuUrl", "menu_url");
|
|
copyIfAbsent(params, "menuDesc", "menu_desc");
|
|
copyIfAbsent(params, "parentObjId", "parent_obj_id");
|
|
copyIfAbsent(params, "langKey", "lang_key");
|
|
copyIfAbsent(params, "langKeyDesc", "lang_key_desc");
|
|
copyIfAbsent(params, "menuIcon", "menu_icon");
|
|
copyIfAbsent(params, "screenCode", "screen_code");
|
|
copyIfAbsent(params, "menuType", "menu_type");
|
|
copyIfAbsent(params, "companyCode", "company_code");
|
|
}
|
|
|
|
private void copyIfAbsent(Map<String, Object> params, String camelKey, String snakeKey) {
|
|
if (params.get(snakeKey) == null && params.get(camelKey) != null) {
|
|
params.put(snakeKey, params.get(camelKey));
|
|
}
|
|
}
|
|
|
|
public void deleteMenu(String menuId) {
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("menu_id", menuId);
|
|
sqlSession.delete("admin.deleteMenu", params);
|
|
}
|
|
|
|
public Map<String, Object> toggleMenuStatus(String menuId) {
|
|
Map<String, Object> current = getMenuInfo(menuId);
|
|
if (current == null) throw new IllegalArgumentException("메뉴를 찾을 수 없습니다.");
|
|
String newStatus = "active".equalsIgnoreCase((String) current.get("status")) ? "inactive" : "active";
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("menu_id", menuId);
|
|
params.put("status", newStatus);
|
|
sqlSession.update("admin.updateMenuStatus", params);
|
|
return Map.of("status", newStatus);
|
|
}
|
|
|
|
// ── 사용자 관리 ────────────────────────────────────────────────────────
|
|
|
|
public Map<String, Object> getUserList(Map<String, Object> params) {
|
|
String rawSearch = (String) params.get("search");
|
|
if (rawSearch != null && !rawSearch.isBlank()) {
|
|
params.put("search", "%" + rawSearch.trim() + "%");
|
|
}
|
|
commonService.applyPagination(params);
|
|
|
|
List<Map<String, Object>> users = sqlSession.selectList("admin.selectUserList", params);
|
|
Number countNum = sqlSession.selectOne("admin.selectUserCount", params);
|
|
int total = countNum != null ? countNum.intValue() : 0;
|
|
|
|
int page = params.get("page") != null ? Integer.parseInt(params.get("page").toString()) : 1;
|
|
int limit = params.get("limit") != null ? Integer.parseInt(params.get("limit").toString()) : 20;
|
|
int totalPages = (int) Math.ceil((double) total / limit);
|
|
|
|
Map<String, Object> pagination = new HashMap<>();
|
|
pagination.put("page", page);
|
|
pagination.put("limit", limit);
|
|
pagination.put("total_pages", totalPages);
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
result.put("data", users);
|
|
result.put("total", total);
|
|
result.put("search_type", rawSearch != null ? "v2" : "none");
|
|
result.put("pagination", pagination);
|
|
return result;
|
|
}
|
|
|
|
public Map<String, Object> getUserInfo(String userId) {
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("user_id", userId);
|
|
return sqlSession.selectOne("admin.selectUserById", params);
|
|
}
|
|
|
|
public List<Map<String, Object>> getUserHistory(String userId, Map<String, Object> params) {
|
|
params.put("user_id", userId);
|
|
commonService.applyPagination(params);
|
|
return sqlSession.selectList("admin.selectUserHistory", params);
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> saveUser(Map<String, Object> params) {
|
|
String userId = (String) params.get("user_id");
|
|
Map<String, Object> existing = sqlSession.selectOne("admin.selectUserById", Map.of("user_id", userId));
|
|
if (existing != null) {
|
|
sqlSession.update("admin.updateUser", params);
|
|
} else {
|
|
String rawPw = (String) params.getOrDefault("user_password", "Welcome1!");
|
|
params.put("user_password", passwordEncoder.encode(rawPw));
|
|
sqlSession.insert("admin.insertUser", params);
|
|
}
|
|
return params;
|
|
}
|
|
|
|
public void changeUserStatus(String userId, String status) {
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("user_id", userId);
|
|
params.put("status", status);
|
|
sqlSession.update("admin.updateUserStatus", params);
|
|
}
|
|
|
|
public void resetUserPassword(String userId) {
|
|
String defaultPw = passwordEncoder.encode("Welcome1!");
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("user_id", userId);
|
|
params.put("user_password", defaultPw);
|
|
sqlSession.update("admin.updateUserPassword", params);
|
|
}
|
|
|
|
public Map<String, Object> getUserLocale(String userId) {
|
|
Map<String, Object> row = sqlSession.selectOne("admin.selectUserLocale", Map.of("user_id", userId));
|
|
Map<String, Object> result = new HashMap<>();
|
|
result.put("locale", row != null ? row.get("locale") : "KR");
|
|
return result;
|
|
}
|
|
|
|
@Transactional
|
|
public void setUserLocale(String userId, String locale) {
|
|
Map<String, Object> valid = sqlSession.selectOne("admin.selectValidLocale", Map.of("locale", locale));
|
|
if (valid == null) {
|
|
throw new IllegalArgumentException("유효하지 않은 로케일입니다: " + locale);
|
|
}
|
|
Map<String, Object> params = new HashMap<>();
|
|
params.put("user_id", userId);
|
|
params.put("locale", locale);
|
|
sqlSession.update("admin.updateUserLocale", params);
|
|
}
|
|
|
|
public Map<String, Object> getUserWithDept(Map<String, Object> params) {
|
|
Map<String, Object> userInfo = sqlSession.selectOne("admin.selectUserById", params);
|
|
if (userInfo == null) return null;
|
|
List<Map<String, Object>> depts = sqlSession.selectList("admin.selectUserDeptList", params);
|
|
Map<String, Object> mainDept = depts.stream()
|
|
.filter(d -> Boolean.TRUE.equals(d.get("is_primary")))
|
|
.findFirst().orElse(null);
|
|
List<Map<String, Object>> subDepts = depts.stream()
|
|
.filter(d -> !Boolean.TRUE.equals(d.get("is_primary")))
|
|
.collect(Collectors.toList());
|
|
Map<String, Object> result = new HashMap<>();
|
|
result.put("user_info", userInfo);
|
|
result.put("main_dept", mainDept);
|
|
result.put("sub_depts", subDepts);
|
|
return result;
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> saveUserWithDept(Map<String, Object> body) {
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> userInfoRaw = (Map<String, Object>) body.get("user_info");
|
|
@SuppressWarnings("unchecked")
|
|
Map<String, Object> mainDept = (Map<String, Object>) body.get("main_dept");
|
|
@SuppressWarnings("unchecked")
|
|
List<Map<String, Object>> subDepts = body.get("sub_depts") != null
|
|
? (List<Map<String, Object>>) body.get("sub_depts") : List.of();
|
|
String companyCode = (String) body.get("company_code");
|
|
|
|
if (userInfoRaw == null) throw new IllegalArgumentException("userInfo is required");
|
|
|
|
// snake_case / camelCase 양쪽 처리
|
|
String userId = getField(userInfoRaw, "user_id", "user_id");
|
|
if (userId == null) throw new IllegalArgumentException("userId is required");
|
|
|
|
// 메인 부서 코드/이름/직위 결정
|
|
String deptCode = mainDept != null ? getField(mainDept, "dept_code", "dept_code") : null;
|
|
if (deptCode == null) deptCode = getField(userInfoRaw, "dept_code", "dept_code");
|
|
String deptName = mainDept != null ? getField(mainDept, "dept_name", "dept_name") : null;
|
|
if (deptName == null) deptName = getField(userInfoRaw, "dept_name", "dept_name");
|
|
String positionName = mainDept != null ? getField(mainDept, "position_name", "position_name") : null;
|
|
if (positionName == null) positionName = getField(userInfoRaw, "position_name", "position_name");
|
|
|
|
// camelCase params 빌드
|
|
Map<String, Object> saveParams = new HashMap<>();
|
|
saveParams.put("user_id", userId);
|
|
saveParams.put("user_name", getField(userInfoRaw, "user_name", "user_name"));
|
|
saveParams.put("user_name_eng", getField(userInfoRaw, "user_name_eng", "user_name_eng"));
|
|
saveParams.put("email", userInfoRaw.getOrDefault("email", null));
|
|
saveParams.put("tel", userInfoRaw.getOrDefault("tel", null));
|
|
saveParams.put("cell_phone", getField(userInfoRaw, "cell_phone", "cell_phone"));
|
|
saveParams.put("sabun", userInfoRaw.getOrDefault("sabun", null));
|
|
saveParams.put("user_type", getField(userInfoRaw, "user_type", "user_type"));
|
|
saveParams.put("user_type_name", getField(userInfoRaw, "user_type_name", "user_type_name"));
|
|
saveParams.put("status", userInfoRaw.getOrDefault("status", "active"));
|
|
saveParams.put("locale", userInfoRaw.getOrDefault("locale", null));
|
|
saveParams.put("position_code", getField(userInfoRaw, "position_code", "position_code"));
|
|
saveParams.put("dept_code", deptCode);
|
|
saveParams.put("dept_name", deptName);
|
|
saveParams.put("position_name", positionName);
|
|
String effectiveCompany = !"*".equals(companyCode) ? companyCode : null;
|
|
saveParams.put("company_code", effectiveCompany);
|
|
|
|
// 기존 사용자 확인
|
|
Map<String, Object> existing = sqlSession.selectOne("admin.selectUserById", Map.of("user_id", userId));
|
|
boolean isUpdate = existing != null;
|
|
|
|
if (isUpdate) {
|
|
// 비밀번호가 제공된 경우만 업데이트
|
|
String rawPw = getField(userInfoRaw, "user_password", "user_password");
|
|
if (rawPw != null && !rawPw.isBlank()) {
|
|
saveParams.put("user_password", passwordEncoder.encode(rawPw));
|
|
}
|
|
sqlSession.update("admin.updateUserForDept", saveParams);
|
|
} else {
|
|
String rawPw = getField(userInfoRaw, "user_password", "user_password");
|
|
if (rawPw == null || rawPw.isBlank()) rawPw = "Welcome1!";
|
|
saveParams.put("user_password", passwordEncoder.encode(rawPw));
|
|
sqlSession.insert("admin.insertUser", saveParams);
|
|
}
|
|
|
|
// user_dept 처리
|
|
if (mainDept != null || !subDepts.isEmpty()) {
|
|
// 1. 기존 부서 목록 조회
|
|
List<Map<String, Object>> existingDepts = sqlSession.selectList("admin.selectUserDeptList", Map.of("user_id", userId));
|
|
Map<String, Object> existingMain = existingDepts.stream()
|
|
.filter(d -> Boolean.TRUE.equals(d.get("is_primary")))
|
|
.findFirst().orElse(null);
|
|
|
|
// 2. 메인 부서 변경 시 기존 메인을 겸직으로 전환
|
|
if (mainDept != null && deptCode != null && existingMain != null) {
|
|
String existingMainCode = (String) existingMain.get("dept_code");
|
|
if (existingMainCode != null && !existingMainCode.equals(deptCode)) {
|
|
sqlSession.update("admin.updateUserDeptNotPrimary", Map.of("user_id", userId, "dept_code", existingMainCode));
|
|
}
|
|
}
|
|
|
|
// 3. 겸직 부서 전체 삭제 (새로 입력받은 것으로 교체)
|
|
sqlSession.delete("admin.deleteUserDeptSub", Map.of("user_id", userId));
|
|
|
|
// 4. 메인 부서 UPSERT
|
|
if (mainDept != null && deptCode != null) {
|
|
String userName = (String) saveParams.get("user_name");
|
|
Map<String, Object> dp = new HashMap<>();
|
|
dp.put("user_id", userId);
|
|
dp.put("dept_code", deptCode);
|
|
dp.put("is_primary", true);
|
|
dp.put("dept_name", deptName);
|
|
dp.put("user_name", userName);
|
|
dp.put("position_name", positionName);
|
|
dp.put("company_code", effectiveCompany);
|
|
sqlSession.insert("admin.upsertUserDept", dp);
|
|
}
|
|
|
|
// 5. 겸직 부서 저장
|
|
String userName = (String) saveParams.get("user_name");
|
|
for (Map<String, Object> sub : subDepts) {
|
|
String subCode = getField(sub, "dept_code", "dept_code");
|
|
if (subCode == null || subCode.equals(deptCode)) continue;
|
|
Map<String, Object> dp = new HashMap<>();
|
|
dp.put("user_id", userId);
|
|
dp.put("dept_code", subCode);
|
|
dp.put("is_primary", false);
|
|
dp.put("dept_name", getField(sub, "dept_name", "dept_name"));
|
|
dp.put("user_name", userName);
|
|
dp.put("position_name", getField(sub, "position_name", "position_name"));
|
|
dp.put("company_code", effectiveCompany);
|
|
sqlSession.insert("admin.upsertUserDept", dp);
|
|
}
|
|
}
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
result.put("user_id", userId);
|
|
result.put("is_update", isUpdate);
|
|
return result;
|
|
}
|
|
|
|
/** snake_case / camelCase 양쪽에서 값 추출 헬퍼 */
|
|
private String getField(Map<String, Object> map, String camelKey, String snakeKey) {
|
|
Object val = map.get(camelKey);
|
|
if (val == null) val = map.get(snakeKey);
|
|
return val != null ? val.toString() : null;
|
|
}
|
|
|
|
// ── 부서 관리 ──────────────────────────────────────────────────────────
|
|
|
|
public Map<String, Object> getDepartmentList(Map<String, Object> params) {
|
|
commonService.applyCompanyCodeFilter(params);
|
|
List<Map<String, Object>> rawList = sqlSession.selectList("admin.selectDepartmentList", params);
|
|
|
|
// 평탄 목록
|
|
List<Map<String, Object>> flatList = new java.util.ArrayList<>(rawList);
|
|
|
|
// 트리 구조 빌드
|
|
java.util.LinkedHashMap<String, Map<String, Object>> deptTreeMap = new java.util.LinkedHashMap<>();
|
|
List<Map<String, Object>> rootDepts = new java.util.ArrayList<>();
|
|
|
|
for (Map<String, Object> raw : rawList) {
|
|
Map<String, Object> node = new java.util.LinkedHashMap<>(raw);
|
|
node.put("children", new java.util.ArrayList<>());
|
|
deptTreeMap.put((String) raw.get("dept_code"), node);
|
|
}
|
|
|
|
// 2차: parent_dept_code 기준 트리 연결
|
|
for (Map<String, Object> raw : rawList) {
|
|
String deptCode = (String) raw.get("dept_code");
|
|
String parentDeptCode = (String) raw.get("parent_dept_code");
|
|
Map<String, Object> node = deptTreeMap.get(deptCode);
|
|
|
|
if (parentDeptCode != null && deptTreeMap.containsKey(parentDeptCode)) {
|
|
@SuppressWarnings("unchecked")
|
|
List<Map<String, Object>> children = (List<Map<String, Object>>) deptTreeMap.get(parentDeptCode).get("children");
|
|
children.add(node);
|
|
} else {
|
|
rootDepts.add(node);
|
|
}
|
|
}
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
result.put("departments", rootDepts);
|
|
result.put("flat_list", flatList);
|
|
result.put("total", rawList.size());
|
|
result.put("total_count", rawList.size());
|
|
return result;
|
|
}
|
|
|
|
// ── 회사 관리 ──────────────────────────────────────────────────────────
|
|
|
|
public List<Map<String, Object>> getCompanyList() {
|
|
List<Map<String, Object>> list = sqlSession.selectList("admin.selectCompanyList", new HashMap<>());
|
|
list.forEach(row -> row.put("data_type", "company"));
|
|
return list;
|
|
}
|
|
|
|
public Map<String, Object> getCompanyByCode(String companyCode) {
|
|
return sqlSession.selectOne("admin.selectCompanyByCode", Map.of("company_code", companyCode));
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> createCompany(Map<String, Object> params) {
|
|
sqlSession.insert("admin.insertCompany", params);
|
|
return params;
|
|
}
|
|
|
|
@Transactional
|
|
public Map<String, Object> updateCompanyInfo(String companyCode, Map<String, Object> params) {
|
|
params.put("company_code", companyCode);
|
|
sqlSession.update("admin.updateCompany", params);
|
|
return params;
|
|
}
|
|
|
|
@Transactional
|
|
public void deleteCompany(String companyCode) {
|
|
sqlSession.delete("admin.deleteCompany", Map.of("company_code", companyCode));
|
|
}
|
|
|
|
// ── 테이블 스키마 ──────────────────────────────────────────────────────
|
|
|
|
public List<Map<String, Object>> getTableSchema(String tableName) {
|
|
return sqlSession.selectList("admin.selectTableSchema", Map.of("table_name", tableName));
|
|
}
|
|
}
|