From 75249e6fa46864f49d4eb91bd755171b6b65eaae Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 28 Jul 2025 12:10:39 +0000
Subject: (김준회) 공통모듈 - Knox 결재 모듈 구현, 유저 선택기 구현, 상신 결재
저장을 위한 DB 스키마 및 서비스 추가, spreadjs 라이센스 환경변수 통일, 유저
테이블에 epId 컬럼 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/[lng]/admin/approval-test/page.tsx | 10 +-
app/[lng]/admin/approval-test/page.tsx.bak | 32 ----
app/[lng]/admin/mdg/page.tsx.bak | 277 -----------------------------
app/api/auth/[...nextauth]/route.ts | 1 +
4 files changed, 4 insertions(+), 316 deletions(-)
delete mode 100644 app/[lng]/admin/approval-test/page.tsx.bak
delete mode 100644 app/[lng]/admin/mdg/page.tsx.bak
(limited to 'app')
diff --git a/app/[lng]/admin/approval-test/page.tsx b/app/[lng]/admin/approval-test/page.tsx
index f044d87d..ab5654f3 100644
--- a/app/[lng]/admin/approval-test/page.tsx
+++ b/app/[lng]/admin/approval-test/page.tsx
@@ -2,8 +2,8 @@ import { Metadata } from 'next';
import ApprovalManager from '@/components/knox/approval/ApprovalManager';
export const metadata: Metadata = {
- title: 'Knox 결재 시스템 테스트 | Admin',
- description: 'Knox API를 사용한 결재 시스템 기능 테스트용',
+ title: 'Knox 결재 시스템 | Admin',
+ description: 'Knox API를 사용한 결재 시스템',
};
export default function ApprovalTestPage() {
@@ -12,18 +12,14 @@ export default function ApprovalTestPage() {
{/* 페이지 헤더 */}
-
Knox 결재 시스템 테스트
+
Knox 결재 시스템
Knox API를 사용한 결재 시스템 컴포넌트입니다.
-
- 테스트 모드가 기본적으로 활성화되어 있으며, 테스트 모드에서는 실제 API 대신 모킹 데이터를 사용
{/* 결재 관리자 컴포넌트 */}
diff --git a/app/[lng]/admin/approval-test/page.tsx.bak b/app/[lng]/admin/approval-test/page.tsx.bak
deleted file mode 100644
index de0e2b5a..00000000
--- a/app/[lng]/admin/approval-test/page.tsx.bak
+++ /dev/null
@@ -1,32 +0,0 @@
-import { Metadata } from 'next';
-import ApprovalManager from '@/components/knox/approval/ApprovalManager';
-
-export const metadata: Metadata = {
- title: 'Knox 결재 시스템 테스트 | Admin',
- description: 'Knox API를 사용한 결재 시스템의 모든 기능을 테스트할 수 있는 페이지입니다.',
-};
-
-export default function ApprovalTestPage() {
- return (
-
-
- {/* 페이지 헤더 */}
-
-
Knox 결재 시스템 테스트
-
- Knox API를 사용한 결재 시스템의 모든 기능을 테스트할 수 있습니다.
-
- 테스트 모드가 기본적으로 활성화되어 있으며, 실제 API 대신 가짜 데이터를 사용합니다.
-
-
-
- {/* 결재 관리자 컴포넌트 */}
-
-
-
- );
-}
diff --git a/app/[lng]/admin/mdg/page.tsx.bak b/app/[lng]/admin/mdg/page.tsx.bak
deleted file mode 100644
index e2926deb..00000000
--- a/app/[lng]/admin/mdg/page.tsx.bak
+++ /dev/null
@@ -1,277 +0,0 @@
-'use client'
-
-import { useState, useEffect } from 'react'
-import { Button } from '@/components/ui/button'
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
-import { Input } from '@/components/ui/input'
-import { Label } from '@/components/ui/label'
-import { Badge } from '@/components/ui/badge'
-import { toast } from 'sonner'
-import { Loader2, Send, RefreshCw } from 'lucide-react'
-
-// CSV 필드를 정의할 타입
-interface VendorFieldDef {
- table: string;
- name: string;
- mandatory: boolean;
- description: string;
-}
-
-// CSV 파싱 함수 (간단 파서)
-const parseCSV = (csv: string): VendorFieldDef[] => {
- const lines = csv.trim().split('\n');
- // 첫 번째 라인은 헤더이므로 제거
- return lines.slice(1).map((line) => {
- const parts = line.split(',');
- const table = parts[1]?.trim();
- const name = parts[2]?.trim();
- const mandatory = parts[3]?.trim() === 'M';
- const description = parts.slice(6).join(',').trim();
- return { table, name, mandatory, description } as VendorFieldDef;
- });
-};
-
-// 기존 샘플 기본값 (필요 시 확장)
-const sampleDefaults: Record = {
- BP_HEADER: 'TEST001',
- ZZSRMCD: 'EVCP',
- TITLE: 'TEST',
- BU_SORT1: 'TEST VENDOR',
- NAME_ORG1: '테스트 벤더 회사',
- KTOKK: 'Z001',
- VEN_KFBUS: '제조업',
- VEN_KFIND: 'IT',
- MASTERFLAG: 'X',
- IBND_TYPE: 'U',
- ZZREQID: 'TESTUSER01',
- ADDRNO: '0001',
- AD_NATION: '1',
- COUNTRY: 'KR',
- LANGU_COM: 'K',
- POST_COD1: '06292',
- CITY1: '서울시',
- DISTRICT: '강남구',
- REGION: '11',
- MC_STREET: '테헤란로 123',
- T_COUNTRY: 'KR',
- T_NUMBER: '02-1234-5678',
- F_COUNTRY: 'KR',
- F_NUMBER: '02-1234-5679',
- U_ADDRESS: 'https://test.vendor.com',
- E_ADDRESS: 'contact@test.vendor.com',
- BP_TX_TYP: 'KR2',
- TAXNUM: '123-45-67890',
- AD_CONSNO: '1',
-};
-
-// XML escape helper
-const escapeXml = (unsafe: string) => unsafe.replace(/[<>&'"']/g, (c) => {
- switch (c) {
- case '<': return '<';
- case '>': return '>';
- case '&': return '&';
- case '"': return '"';
- case "'": return ''';
- default: return c;
- }
-});
-
-export default function MDGTestPage() {
- const [formData, setFormData] = useState>({});
- const [fieldDefs, setFieldDefs] = useState([]);
- const [resultXml, setResultXml] = useState('');
- const [isLoading, setIsLoading] = useState(false);
-
- // CSV 로딩 및 초기 데이터 셋업
- useEffect(() => {
- const load = async () => {
- const res = await fetch('/wsdl/P2MD3007_AO.csv');
- const csvText = await res.text();
- const defs = parseCSV(csvText);
- setFieldDefs(defs);
-
- const init: Record = {};
- defs.forEach((d) => {
- init[d.name] = sampleDefaults[d.name] ?? '';
- });
- setFormData(init);
- };
-
- load();
- }, []);
-
- // XML 생성 유틸리티 (폼 데이터 -> SOAP Envelope)
- const buildEnvelopeXml = (currentForm: Record, defs: VendorFieldDef[]) => {
- if (defs.length === 0) return '';
- const bodyContent = defs.map((f) => {
- const val = currentForm[f.name] ?? '';
- return `<${f.name}>${escapeXml(val)}${f.name}>`;
- }).join('\n ');
-
- const supplierXml = `\n ${bodyContent}\n `;
-
- return `\n\n \n \n \n \n ${supplierXml}\n \n \n \n`;
- };
-
- // 폼 데이터 변경 시 실시간 XML 생성
- useEffect(() => {
- const xml = buildEnvelopeXml(formData, fieldDefs);
- setResultXml(xml);
- }, [formData, fieldDefs]);
-
- // 폼 데이터 업데이트
- const updateField = (field: string, value: string) => {
- setFormData(prev => ({ ...prev, [field]: value }));
- };
-
- // 기본값으로 리셋
- const resetForm = () => {
- const reset: Record = {};
- fieldDefs.forEach((d) => {
- reset[d.name] = sampleDefaults[d.name] ?? '';
- });
- setFormData(reset);
- toast.success('폼이 기본값으로 리셋되었습니다.');
- };
-
- // 테스트 송신 실행 (실제 서버 호출)
- const handleTestSend = async () => {
- try {
- setIsLoading(true);
-
- // 필수 필드 검증
- const requiredFields = fieldDefs.filter(d => d.mandatory).map(d => d.name);
- const missingFields = requiredFields.filter(field => !formData[field]?.trim());
-
- if (missingFields.length > 0) {
- toast.error(`필수 필드가 누락되었습니다: ${missingFields.join(', ')}`);
- setIsLoading(false);
- return;
- }
-
- // 서버 API 호출해 송신
- const res = await fetch('/api/mdg/send-vendor-xml', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ envelope: resultXml }),
- });
-
- const json = await res.json();
-
- if (!res.ok || !json.success) {
- // 상세 오류 메시지 추출 (vendorCode 기반 또는 직접 오류 메시지)
- const detailMsg = json?.results?.[0]?.error ?? json?.message ?? json?.responseText ?? '송신 실패';
- toast.error(`송신 실패: ${detailMsg}`);
- setIsLoading(false);
- return;
- }
-
- toast.success('MDG 송신이 완료되었습니다.');
-
- } catch (error) {
- console.error('테스트 송신 실패:', error);
- toast.error('테스트 송신 중 오류가 발생했습니다.');
- } finally {
- setIsLoading(false);
- }
- };
-
- return (
-
-
-
-
MDG VENDOR 마스터 테스트
-
- VENDOR 마스터 데이터를 MDG 시스템으로 테스트 송신합니다
-
-
-
-
-
-
-
-
- {/* 동적 필드 렌더링 */}
- {fieldDefs.length === 0 ? (
-
CSV 로딩 중...
- ) : (
-
- {Object.entries(
- fieldDefs.reduce((acc: Record
, cur) => {
- acc[cur.table] = acc[cur.table] ? [...acc[cur.table], cur] : [cur];
- return acc;
- }, {})
- ).map(([table, fields]) => (
-
-
-
- {table}
- {fields.some(f => f.mandatory) && (
- 필수 포함
- )}
-
- {table} 테이블 입력
-
-
- {fields.filter((f, idx, arr) => arr.findIndex(x => x.name === f.name) === idx).map((field) => (
-
-
-
updateField(field.name, e.target.value)}
- />
- {field.description && (
-
{field.description}
- )}
-
- ))}
-
-
- ))}
-
- )}
-
- {/* 송신 결과 영역 */}
-
-
- 송신 결과
-
- MDG 시스템으로의 송신 결과가 여기에 표시됩니다
-
-
-
- {resultXml ? (
-
- {resultXml}
-
- ) : (
-
-
- 테스트 송신 버튼을 클릭하면 결과가 표시됩니다.
-
-
- )}
-
-
-
- );
-}
-
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
index fe93906d..5896fb90 100644
--- a/app/api/auth/[...nextauth]/route.ts
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -235,6 +235,7 @@ export const authOptions: NextAuthOptions = {
authMethod: tempAuth.authMethod as AuthMethod,
dbSessionId: dbSession.id,
roles: userRoles, // ✅ roles 배열 추가
+ epId: user.epId, // Knox 계정인 경우, epId 추가 (Knox API 사용하는 경우 필요)
}
} catch (error) {
--
cgit v1.2.3