From ac0f51b816eecc43cdc3f7a54766ea89a30a5c2a Mon Sep 17 00:00:00 2001 From: HYOJIN Date: Tue, 14 Apr 2026 13:57:32 +0900 Subject: [PATCH] =?UTF-8?q?feat(config):=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20=EC=83=98?= =?UTF-8?q?=ED=94=8C=20=EC=BD=94=EB=93=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SnpSystemConfig 엔티티/레포/서비스/컨트롤러 구현 - GET/PUT /api/config/{configKey} 엔드포인트 - 공통 샘플 코드 관리 admin 페이지 (SampleCodePage) - 프론트엔드 configService 추가 Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/pages/admin/SampleCodePage.tsx | 107 ++++++++++++++++++ frontend/src/services/configService.ts | 12 ++ .../controller/SystemConfigController.java | 46 ++++++++ .../common/dto/SystemConfigResponse.java | 26 +++++ .../common/dto/UpdateSystemConfigRequest.java | 6 + .../common/entity/SnpSystemConfig.java | 44 +++++++ .../repository/SnpSystemConfigRepository.java | 11 ++ .../common/service/SystemConfigService.java | 48 ++++++++ 8 files changed, 300 insertions(+) create mode 100644 frontend/src/pages/admin/SampleCodePage.tsx create mode 100644 frontend/src/services/configService.ts create mode 100644 src/main/java/com/gcsc/connection/common/controller/SystemConfigController.java create mode 100644 src/main/java/com/gcsc/connection/common/dto/SystemConfigResponse.java create mode 100644 src/main/java/com/gcsc/connection/common/dto/UpdateSystemConfigRequest.java create mode 100644 src/main/java/com/gcsc/connection/common/entity/SnpSystemConfig.java create mode 100644 src/main/java/com/gcsc/connection/common/repository/SnpSystemConfigRepository.java create mode 100644 src/main/java/com/gcsc/connection/common/service/SystemConfigService.java diff --git a/frontend/src/pages/admin/SampleCodePage.tsx b/frontend/src/pages/admin/SampleCodePage.tsx new file mode 100644 index 0000000..774b9b2 --- /dev/null +++ b/frontend/src/pages/admin/SampleCodePage.tsx @@ -0,0 +1,107 @@ +import { useState, useEffect } from 'react'; +import { getSystemConfig, updateSystemConfig } from '../../services/configService'; + +const COMMON_SAMPLE_CODE_KEY = 'COMMON_SAMPLE_CODE'; + +const INPUT_CLS = + 'w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none text-sm font-mono'; + +const SampleCodePage = () => { + const [sampleCode, setSampleCode] = useState(''); + const [loading, setLoading] = useState(true); + const [saving, setSaving] = useState(false); + const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); + + useEffect(() => { + const fetchConfig = async () => { + try { + const res = await getSystemConfig(COMMON_SAMPLE_CODE_KEY); + if (res.success && res.data?.configValue != null) { + setSampleCode(res.data.configValue); + } + } catch { + setMessage({ type: 'error', text: '샘플 코드를 불러오는데 실패했습니다.' }); + } finally { + setLoading(false); + } + }; + + fetchConfig(); + }, []); + + const handleSave = async () => { + setSaving(true); + setMessage(null); + try { + const res = await updateSystemConfig(COMMON_SAMPLE_CODE_KEY, sampleCode); + if (res.success) { + setMessage({ type: 'success', text: '저장되었습니다.' }); + } else { + setMessage({ type: 'error', text: res.message || '저장에 실패했습니다.' }); + } + } catch { + setMessage({ type: 'error', text: '저장 중 오류가 발생했습니다.' }); + } finally { + setSaving(false); + setTimeout(() => setMessage(null), 3000); + } + }; + + if (loading) { + return ( +
+
+
+ ); + } + + return ( +
+
+
+

공통 샘플 코드 관리

+

+ API HUB 상세 페이지에 공통으로 표시되는 샘플 코드를 관리합니다. +

+
+ +
+ + {message && ( +
+ {message.text} +
+ )} + +
+ +