결재 건수 및 결재 상세 화면 아마란스 연동

This commit is contained in:
2026-02-10 17:01:35 +09:00
parent 741f3737d4
commit 97f6cd77be
6 changed files with 1118 additions and 146 deletions

View File

@@ -1228,6 +1228,406 @@ public class ApprovalService {
return count;
}
/**
* Amaranth10 전자결재 문서 목록 조회 - JSON 문자열 반환 (AJAX 전용)
* approvalList.jsp 전용 엔드포인트에서 호출
* @param request HttpServletRequest
* @param paramMap 검색 파라미터
* @return JSON 문자열
*/
public String getAmaranthApprovalDocListJson(HttpServletRequest request, Map paramMap){
Map<String, Object> resultMap = getAmaranthApprovalDocList(request, paramMap);
return buildApprovalDocListJson(resultMap);
}
/**
* Amaranth10 결재 문서 상세 조회
* @param request HttpServletRequest
* @param paramMap docId, deptSeq 필수
* @return API 응답 JSON 원본 (contents HTML 포함)
*/
public String getAmaranthApprovalDocDetail(HttpServletRequest request, Map paramMap){
try {
// 세션에서 사원 정보 가져오기
HttpSession session = request.getSession();
PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
String empSeq = CommonUtils.checkNull(person.getEmpseq());
String compSeq = "1000";
String docId = CommonUtils.checkNull(paramMap.get("docId"));
String deptSeq = CommonUtils.checkNull(paramMap.get("deptSeq"));
System.out.println("=== Amaranth 결재 문서 상세 조회 ===");
System.out.println("empSeq: " + empSeq + ", docId: " + docId + ", deptSeq: " + deptSeq);
if(empSeq == null || empSeq.isEmpty()){
System.err.println("empSeq가 비어있습니다.");
return "{\"resultCode\":-1,\"resultMsg\":\"empSeq가 비어있습니다.\"}";
}
if(docId == null || docId.isEmpty()){
System.err.println("docId가 비어있습니다.");
return "{\"resultCode\":-1,\"resultMsg\":\"docId가 비어있습니다.\"}";
}
// API 호출
com.pms.api.AmaranthApprovalApiClient apiClient = new com.pms.api.AmaranthApprovalApiClient();
String baseUrl = "https://erp.rps-korea.com";
String apiResponse = apiClient.getApprovalDocDetail(baseUrl, empSeq, compSeq, deptSeq, docId);
System.out.println("상세 조회 API 응답 길이: " + (apiResponse != null ? apiResponse.length() : 0) + " bytes");
return apiResponse;
} catch(Exception e){
System.err.println("Amaranth 결재 문서 상세 조회 오류: " + e.getMessage());
e.printStackTrace();
return "{\"resultCode\":-1,\"resultMsg\":\"" + escapeJsonValue(e.getMessage()) + "\"}";
}
}
/**
* 결재 문서 목록 결과를 JSON 문자열로 변환
*/
private String buildApprovalDocListJson(Map<String, Object> resultMap){
StringBuilder json = new StringBuilder();
json.append("{");
// 페이징 정보
json.append("\"totalCount\":").append(resultMap.get("TOTAL_COUNT")).append(",");
json.append("\"maxPage\":").append(resultMap.get("MAX_PAGE_SIZE")).append(",");
json.append("\"nextPage\":").append(resultMap.get("NEXT_PAGE")).append(",");
json.append("\"prevPage\":").append(resultMap.get("PREV_PAGE")).append(",");
// 문서 리스트
json.append("\"list\":[");
ArrayList<HashMap<String, Object>> list = (ArrayList<HashMap<String, Object>>) resultMap.get("LIST");
if(list != null){
for(int i = 0; i < list.size(); i++){
if(i > 0) json.append(",");
HashMap<String, Object> doc = list.get(i);
json.append("{");
json.append("\"RNUM\":\"").append(escapeJsonValue(String.valueOf(doc.get("RNUM")))).append("\",");
json.append("\"DOC_ID\":\"").append(escapeJsonValue(String.valueOf(doc.get("DOC_ID")))).append("\",");
json.append("\"DOC_TITLE\":\"").append(escapeJsonValue(String.valueOf(doc.get("DOC_TITLE")))).append("\",");
json.append("\"FORM_NAME\":\"").append(escapeJsonValue(String.valueOf(doc.get("FORM_NAME")))).append("\",");
json.append("\"EMP_NAME\":\"").append(escapeJsonValue(String.valueOf(doc.get("EMP_NAME")))).append("\",");
json.append("\"DEPT_NAME\":\"").append(escapeJsonValue(String.valueOf(doc.get("DEPT_NAME")))).append("\",");
json.append("\"DOC_STS_NAME\":\"").append(escapeJsonValue(String.valueOf(doc.get("DOC_STS_NAME")))).append("\",");
json.append("\"REP_DT\":\"").append(escapeJsonValue(String.valueOf(doc.get("REP_DT")))).append("\",");
json.append("\"DOC_STS\":\"").append(escapeJsonValue(String.valueOf(doc.get("DOC_STS")))).append("\",");
json.append("\"DEPT_SEQ\":\"").append(escapeJsonValue(String.valueOf(doc.get("DEPT_SEQ")))).append("\"");
json.append("}");
}
}
json.append("]");
json.append("}");
return json.toString();
}
/**
* JSON 값 이스케이프 (서비스 내부용)
*/
private String escapeJsonValue(String value){
if(value == null || "null".equals(value)) return "";
return value.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
}
/**
* Amaranth10 전자결재 문서 목록 조회 (서버 인증 방식)
* @param request HttpServletRequest
* @param paramMap 검색 파라미터 (search_approvalTitle, search_fromDate, search_toDate, page 등)
* @return 결재 문서 목록 및 페이징 정보
*/
public Map<String, Object> getAmaranthApprovalDocList(HttpServletRequest request, Map paramMap){
Map<String, Object> resultMap = new HashMap();
ArrayList<HashMap<String, Object>> resultList = new ArrayList();
try{
// 세션에서 사원 정보 가져오기
HttpSession session = request.getSession();
PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
String empSeq = CommonUtils.checkNull(person.getEmpseq());
String compSeq = "1000"; // 회사 시퀀스
System.out.println("=== Amaranth 결재 문서 목록 조회 ===");
System.out.println("empSeq: " + empSeq);
if(empSeq == null || empSeq.isEmpty()){
System.err.println("empSeq가 비어있습니다. LoginId 업데이트 배치를 먼저 실행하세요.");
resultMap.put("LIST", resultList);
resultMap.put("TOTAL_COUNT", 0);
return resultMap;
}
// 검색 조건 매핑
String keyWord = CommonUtils.checkNull(paramMap.get("search_approvalTitle"));
String fromDt = CommonUtils.checkNull(paramMap.get("search_fromDate"));
String toDt = CommonUtils.checkNull(paramMap.get("search_toDate"));
String page = CommonUtils.checkNull(paramMap.get("page"), "1");
String pageSize = "20";
// menuId: 기안함(1000400) - 결재 전체 목록 조회용
String menuId = CommonUtils.checkNull(paramMap.get("menuId"), "1000400");
// API 호출
com.pms.api.AmaranthApprovalApiClient apiClient = new com.pms.api.AmaranthApprovalApiClient();
String baseUrl = "https://erp.rps-korea.com";
String apiResponse = apiClient.getApprovalDocList(
baseUrl, empSeq, compSeq, menuId, fromDt, toDt, keyWord, page, pageSize);
System.out.println("API 응답 길이: " + (apiResponse != null ? apiResponse.length() : 0) + " bytes");
// JSON 파싱
resultList = parseApprovalDocList(apiResponse);
int totalCnt = extractTotalCnt(apiResponse);
// 번호 매기기 (RNUM)
int startNum = (Integer.parseInt(page) - 1) * Integer.parseInt(pageSize);
for(int i = 0; i < resultList.size(); i++){
resultList.get(i).put("RNUM", String.valueOf(startNum + i + 1));
}
// 페이징 정보 설정
int currentPage = Integer.parseInt(page);
int pageSizeInt = Integer.parseInt(pageSize);
int maxPage = (int) Math.ceil((double) totalCnt / pageSizeInt);
if(maxPage < 1) maxPage = 1;
resultMap.put("LIST", resultList);
resultMap.put("TOTAL_COUNT", totalCnt);
resultMap.put("MAX_PAGE_SIZE", maxPage);
resultMap.put("NEXT_PAGE", Math.min(currentPage + 1, maxPage));
resultMap.put("PREV_PAGE", Math.max(currentPage - 1, 1));
System.out.println("결재 문서 수: " + resultList.size() + ", 전체: " + totalCnt);
}catch(Exception e){
System.err.println("Amaranth 결재 문서 목록 조회 오류: " + e.getMessage());
e.printStackTrace();
resultMap.put("LIST", resultList);
resultMap.put("TOTAL_COUNT", 0);
resultMap.put("MAX_PAGE_SIZE", 1);
resultMap.put("NEXT_PAGE", 1);
resultMap.put("PREV_PAGE", 1);
}
return resultMap;
}
/**
* API 응답에서 eaDocList 배열 파싱
* 응답 구조: {"resultData":{"eaDocList":[{...},{...}],"totalCnt":94}}
*/
private ArrayList<HashMap<String, Object>> parseApprovalDocList(String jsonResponse){
ArrayList<HashMap<String, Object>> list = new ArrayList();
try {
// eaDocList 배열 찾기
int eaDocListIndex = jsonResponse.indexOf("\"eaDocList\"");
if(eaDocListIndex == -1){
System.err.println("eaDocList를 찾을 수 없습니다.");
return list;
}
// eaDocList 다음의 [ 찾기
int arrayStart = jsonResponse.indexOf("[", eaDocListIndex);
if(arrayStart == -1){
System.err.println("eaDocList 배열 시작을 찾을 수 없습니다.");
return list;
}
// 대응하는 ] 찾기
int bracketCount = 0;
int arrayEnd = -1;
for(int i = arrayStart; i < jsonResponse.length(); i++){
char c = jsonResponse.charAt(i);
if(c == '[') bracketCount++;
else if(c == ']') bracketCount--;
if(bracketCount == 0){
arrayEnd = i;
break;
}
}
if(arrayEnd == -1){
System.err.println("eaDocList 배열 끝을 찾을 수 없습니다.");
return list;
}
String arrayStr = jsonResponse.substring(arrayStart + 1, arrayEnd);
// 각 문서 객체 파싱
int searchFrom = 0;
while(searchFrom < arrayStr.length()){
int objStart = arrayStr.indexOf("{", searchFrom);
if(objStart == -1) break;
// 중첩 { } 처리
int braceCount = 0;
int objEnd = -1;
for(int i = objStart; i < arrayStr.length(); i++){
char c = arrayStr.charAt(i);
if(c == '{') braceCount++;
else if(c == '}') braceCount--;
if(braceCount == 0){
objEnd = i;
break;
}
}
if(objEnd == -1) break;
String objStr = arrayStr.substring(objStart, objEnd + 1);
HashMap<String, Object> doc = parseDocObject(objStr);
if(!doc.isEmpty()){
list.add(doc);
}
searchFrom = objEnd + 1;
}
System.out.println("파싱된 문서 수: " + list.size());
} catch (Exception e) {
System.err.println("eaDocList 파싱 오류: " + e.getMessage());
e.printStackTrace();
}
return list;
}
/**
* 개별 문서 JSON 객체 파싱
*/
private HashMap<String, Object> parseDocObject(String objStr){
HashMap<String, Object> doc = new HashMap();
try {
doc.put("DOC_ID", extractJsonStringValue(objStr, "docId"));
doc.put("DOC_TITLE", extractJsonStringValue(objStr, "docTitle"));
doc.put("FORM_NAME", extractJsonStringValue(objStr, "formName"));
doc.put("EMP_NAME", extractJsonStringValue(objStr, "empName"));
doc.put("DEPT_NAME", extractJsonStringValue(objStr, "deptName"));
doc.put("DOC_STS", extractJsonStringValue(objStr, "docSts"));
doc.put("DOC_STS_NAME", extractJsonStringValue(objStr, "docStsName"));
doc.put("POSITION_NAME", extractJsonStringValue(objStr, "positionName"));
doc.put("DUTY_NAME", extractJsonStringValue(objStr, "dutyName"));
doc.put("LINE_NAME", extractJsonStringValue(objStr, "lineName"));
doc.put("ATTACH_CNT", extractJsonStringValue(objStr, "attachCnt"));
doc.put("COMMENT_CNT", extractJsonStringValue(objStr, "commentCnt"));
doc.put("EMERGENCY_FLAG", extractJsonStringValue(objStr, "emergencyFlag"));
doc.put("DELAY_FLAG", extractJsonStringValue(objStr, "delayFlag"));
doc.put("READ_YN", extractJsonStringValue(objStr, "readYN"));
doc.put("APP_YN", extractJsonStringValue(objStr, "appYN"));
doc.put("COMP_SEQ", extractJsonStringValue(objStr, "compSeq"));
doc.put("EMP_SEQ", extractJsonStringValue(objStr, "empSeq"));
doc.put("DEPT_SEQ", extractJsonStringValue(objStr, "deptSeq"));
// 상신일(repDt) 포맷팅: YYYYMMDDHHMISS → YYYY-MM-DD
String repDt = extractJsonStringValue(objStr, "repDt");
if(repDt != null && repDt.length() >= 8){
doc.put("REP_DT", repDt.substring(0, 4) + "-" + repDt.substring(4, 6) + "-" + repDt.substring(6, 8));
} else {
doc.put("REP_DT", repDt);
}
// 생성일(createdDt) 포맷팅
String createdDt = extractJsonStringValue(objStr, "createdDt");
if(createdDt != null && createdDt.length() >= 8){
doc.put("CREATED_DT", createdDt.substring(0, 4) + "-" + createdDt.substring(4, 6) + "-" + createdDt.substring(6, 8));
} else {
doc.put("CREATED_DT", createdDt);
}
} catch (Exception e) {
System.err.println("문서 객체 파싱 오류: " + e.getMessage());
}
return doc;
}
/**
* JSON 문자열에서 특정 키의 문자열 값 추출
*/
private String extractJsonStringValue(String json, String key){
String searchKey = "\"" + key + "\"";
int keyIndex = json.indexOf(searchKey);
if(keyIndex == -1) return "";
int colonIndex = json.indexOf(":", keyIndex + searchKey.length());
if(colonIndex == -1) return "";
// 콜론 뒤의 공백 건너뛰기
int valueStart = colonIndex + 1;
while(valueStart < json.length() && json.charAt(valueStart) == ' '){
valueStart++;
}
if(valueStart >= json.length()) return "";
// null 값 체크
if(json.substring(valueStart).startsWith("null")){
return "";
}
// 숫자 값 체크 (따옴표 없는 경우)
char firstChar = json.charAt(valueStart);
if(firstChar != '"'){
// 숫자나 boolean 값
int valueEnd = valueStart;
while(valueEnd < json.length()){
char c = json.charAt(valueEnd);
if(c == ',' || c == '}' || c == ']') break;
valueEnd++;
}
return json.substring(valueStart, valueEnd).trim();
}
// 문자열 값 (따옴표 있는 경우)
int quoteStart = valueStart; // 이미 '"' 위치
int quoteEnd = json.indexOf("\"", quoteStart + 1);
if(quoteEnd == -1) return "";
return json.substring(quoteStart + 1, quoteEnd);
}
/**
* API 응답에서 totalCnt 추출
*/
private int extractTotalCnt(String jsonResponse){
try {
String searchKey = "\"totalCnt\"";
int keyIndex = jsonResponse.indexOf(searchKey);
if(keyIndex == -1) return 0;
int colonIndex = jsonResponse.indexOf(":", keyIndex + searchKey.length());
if(colonIndex == -1) return 0;
int valueStart = colonIndex + 1;
while(valueStart < jsonResponse.length() && jsonResponse.charAt(valueStart) == ' '){
valueStart++;
}
int valueEnd = valueStart;
while(valueEnd < jsonResponse.length()){
char c = jsonResponse.charAt(valueEnd);
if(c == ',' || c == '}' || c == ']') break;
valueEnd++;
}
String cntStr = jsonResponse.substring(valueStart, valueEnd).trim();
return Integer.parseInt(cntStr);
} catch (Exception e) {
System.err.println("totalCnt 추출 오류: " + e.getMessage());
return 0;
}
}
public ArrayList getApprovalLine(HttpServletRequest request, Map paramMap){
ArrayList<HashMap<String,Object>> resultList = new ArrayList();
SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession();