diff options
| author | joonhoekim <26rote@gmail.com> | 2025-07-28 12:10:39 +0000 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-07-28 12:10:39 +0000 |
| commit | 75249e6fa46864f49d4eb91bd755171b6b65eaae (patch) | |
| tree | f2c021f0fe10b3513d29f05ca15b82e460d79d20 /lib/knox-api/approval/approval.ts | |
| parent | c228a89c2834ee63b209bad608837c39643f350e (diff) | |
(김준회) 공통모듈 - Knox 결재 모듈 구현, 유저 선택기 구현, 상신 결재 저장을 위한 DB 스키마 및 서비스 추가, spreadjs 라이센스 환경변수 통일, 유저 테이블에 epId 컬럼 추가
Diffstat (limited to 'lib/knox-api/approval/approval.ts')
| -rw-r--r-- | lib/knox-api/approval/approval.ts | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/lib/knox-api/approval/approval.ts b/lib/knox-api/approval/approval.ts index 75066478..5e62382d 100644 --- a/lib/knox-api/approval/approval.ts +++ b/lib/knox-api/approval/approval.ts @@ -1,6 +1,8 @@ "use server" import { getKnoxConfig, createJsonHeaders, createFormHeaders } from '../common'; +import { randomUUID } from 'crypto'; +import { saveApprovalToDatabase, deleteApprovalFromDatabase } from './service'; // Knox API Approval 서버 액션들 // 가이드: lib/knox-api/approval/guide.html @@ -15,7 +17,7 @@ export interface BaseResponse { // 결재 경로 타입 export interface ApprovalLine { epId?: string; - userId?: string; + userId?: string; // eVCP ID라서 사용하지 않음! emailAddress?: string; seq: string; role: string; // 기안(0), 결재(1), 합의(2), 후결(3), 병렬합의(4), 병렬결재(7), 통보(9) @@ -132,7 +134,8 @@ export interface ApprovalIdsResponse extends BaseResponse { * POST /approval/api/v2.0/approvals/submit */ export async function submitApproval( - request: SubmitApprovalRequest + request: SubmitApprovalRequest, + userInfo: { userId: string; epId: string; emailAddress: string } ): Promise<SubmitApprovalResponse> { try { const config = await getKnoxConfig(); @@ -149,8 +152,8 @@ export async function submitApproval( timeZone: request.timeZone, docMngSaveCode: request.docMngSaveCode, subject: request.subject, - sbmLang: request.sbmLang, - apInfId: request.apInfId, + sbmLang: request.sbmLang || 'ko', + apInfId: request.apInfId, // 고정값, 환경변수로 설정해 common 에서 가져오기 importantYn: request.importantYn, aplns: request.aplns }; @@ -174,7 +177,28 @@ export async function submitApproval( throw new Error(`결재 상신 실패: ${response.status}`); } - return await response.json(); + const result = await response.json(); + + // Knox API 성공 시 데이터베이스에 저장 + if (result.result === 'SUCCESS') { + try { + await saveApprovalToDatabase( + request.apInfId, + userInfo.userId, + userInfo.epId, + userInfo.emailAddress, + request.subject, + request.contents, + request.aplns + ); + } catch (dbError) { + console.error('데이터베이스 저장 실패:', dbError); + // 데이터베이스 저장 실패는 Knox API 성공을 무효화하지 않음 + // 필요시 별도 처리 로직 추가 + } + } + + return result; } catch (error) { console.error('결재 상신 오류:', error); throw error; @@ -426,7 +450,20 @@ export async function cancelApproval( throw new Error(`상신 취소 실패: ${response.status}`); } - return await response.json(); + const result = await response.json(); + + // Knox API 성공 시 데이터베이스에서 삭제 + if (result.result === 'SUCCESS') { + try { + await deleteApprovalFromDatabase(apInfId); + } catch (dbError) { + console.error('데이터베이스 삭제 실패:', dbError); + // 데이터베이스 삭제 실패는 Knox API 성공을 무효화하지 않음 + // 필요시 별도 처리 로직 추가 + } + } + + return result; } catch (error) { console.error('상신 취소 오류:', error); throw error; @@ -501,10 +538,29 @@ export async function createSubmitApprovalRequest( approvalLines: ApprovalLine[], options: Partial<SubmitApprovalRequest> = {} ): Promise<SubmitApprovalRequest> { - const config = await getKnoxConfig(); + + // 요구하는 날짜 형식으로 변환 (YYYYMMDDHHMMSS) - UTC 기준 (타임존 정보를 GTC+9 로 제공하고 있음) const now = new Date(); - const sbmDt = now.toISOString().replace(/[-:T]/g, '').slice(0, 14); - const apInfId = `${config.systemId}${sbmDt}${Math.random().toString(36).substr(2, 9)}`.padEnd(32, '0'); + const formatter = new Intl.DateTimeFormat('en-CA', { + timeZone: 'UTC', + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false, + }); + + const parts = formatter.formatToParts(now); + const sbmDt = parts + .filter((part) => part.type !== 'literal') + .map((part) => part.value) + .join(''); + + + // EVCP 접두어 뒤에 28자리 무작위 문자열을 붙여 32byte 고유 ID 생성 + const apInfId = `EVCP${randomUUID().replace(/-/g, '').slice(0, 28)}`; return { contents, |
