From 593affe7253c5114c09119a24e88f7bfbf33f9bf Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Wed, 3 Dec 2025 12:58:13 +0900 Subject: (대표님) working-dujin 경로 작업사항 [김준회] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/tags-plant/queries.ts | 2 + lib/tags-plant/service.ts | 158 ++++++++++++++++-------------- lib/tags-plant/table/add-tag-dialog.tsx | 2 +- lib/tags-plant/table/tag-table-column.tsx | 19 +++- lib/tags-plant/table/tag-table.tsx | 3 + 5 files changed, 104 insertions(+), 80 deletions(-) (limited to 'lib/tags-plant') diff --git a/lib/tags-plant/queries.ts b/lib/tags-plant/queries.ts index a0d28b1e..c7ad43e0 100644 --- a/lib/tags-plant/queries.ts +++ b/lib/tags-plant/queries.ts @@ -5,6 +5,7 @@ import db from "@/db/db" import { tagsPlant } from "@/db/schema/vendorData" import { eq, and } from "drizzle-orm" +import { revalidateTag, unstable_noStore } from "next/cache"; /** * 모든 태그 가져오기 (클라이언트 렌더링용) @@ -13,6 +14,7 @@ export async function getAllTagsPlant( projectCode: string, packageCode: string ) { + unstable_noStore(); try { const tags = await db .select() diff --git a/lib/tags-plant/service.ts b/lib/tags-plant/service.ts index 9e9d9ebf..27cc207b 100644 --- a/lib/tags-plant/service.ts +++ b/lib/tags-plant/service.ts @@ -25,6 +25,14 @@ interface CreatedOrExistingForm { isNewlyCreated: boolean; } +interface FormInfo { + formCode: string; + formName: string; + im: boolean; + eng: boolean; +} + + /** * 16진수 24자리 고유 식별자 생성 * @returns 24자리 16진수 문자열 (예: "a1b2c3d4e5f6789012345678") @@ -280,6 +288,7 @@ export async function createTag( tagIdx: generatedTagIdx, // 🆕 생성된 16진수 24자리 추가 tagNo: validated.data.tagNo, class: validated.data.class, + subclass: validated.data.subclass, tagType: validated.data.tagType, description: validated.data.description ?? null, }) @@ -1790,13 +1799,11 @@ export async function getIMForms( return existingForms } - // 2. DB에 없으면 SEDP API에서 가져오기 + // 2. DB에 없으면 두 API 동시 호출 const apiKey = await getSEDPToken() - // 2-1. GetByToolID로 레지스터 매핑 정보 가져오기 - const mappingResponse = await fetch( - `${SEDP_API_BASE_URL}/AdapterDataMapping/GetByToolID`, - { + const [newRegistersResponse, registersResponse] = await Promise.all([ + fetch(`${SEDP_API_BASE_URL}/AdapterDataMapping/GetByToolID`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -1808,95 +1815,94 @@ export async function getIMForms( ProjectNo: projectCode, TOOL_ID: "eVCP" }) - } - ) + }), + fetch(`${SEDP_API_BASE_URL}/Register/Get`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'accept': '*/*', + 'ApiKey': apiKey, + 'ProjectNo': projectCode + }, + body: JSON.stringify({ + ProjectNo: projectCode, + ContainDeleted: false + }) + }) + ]) - if (!mappingResponse.ok) { - throw new Error( - `레지스터 매핑 요청 실패: ${mappingResponse.status} ${mappingResponse.statusText}` - ) + if (!newRegistersResponse.ok) { + throw new Error(`새 레지스터 요청 실패: ${newRegistersResponse.status}`) } - const mappingData = await mappingResponse.json() - const registers: NewRegister[] = Array.isArray(mappingData) - ? mappingData - : [mappingData] + if (!registersResponse.ok) { + throw new Error(`레지스터 요청 실패: ${registersResponse.status}`) + } - // 2-2. packageCode가 SCOPES에 포함된 레지스터 필터링 - const matchingRegisters = registers.filter(register => - register.SCOPES.includes(packageCode) - ) + const newRegistersData = await newRegistersResponse.json() + const registersData = await registersResponse.json() - if (matchingRegisters.length === 0) { - console.log(`패키지 ${packageCode}에 해당하는 레지스터가 없습니다.`) - return [] + const newRegisters: NewRegister[] = Array.isArray(newRegistersData) + ? newRegistersData + : [newRegistersData] + + const registers: RegisterDetail[] = Array.isArray(registersData) + ? registersData + : [registersData] + + // 3. Register를 Map으로 변환 (TYPE_ID로 빠른 조회) + const registerMap = new Map() + for (const reg of registers) { + registerMap.set(reg.TYPE_ID, reg) } - // 2-3. 각 레지스터의 상세 정보 가져오기 + // 4. packageCode가 SCOPES에 포함되고, EP_ID가 "IMEP"인 것만 필터링 const formInfos: FormInfo[] = [] const formsToInsert: typeof formsPlant.$inferInsert[] = [] - for (const register of matchingRegisters) { - try { - const detailResponse = await fetch( - `${SEDP_API_BASE_URL}/Register/GetByID`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'accept': '*/*', - 'ApiKey': apiKey, - 'ProjectNo': projectCode - }, - body: JSON.stringify({ - ProjectNo: projectCode, - TYPE_ID: register.REG_TYPE_ID, - ContainDeleted: false - }) - } - ) - - if (!detailResponse.ok) { - console.error( - `레지스터 상세 정보 요청 실패 (${register.REG_TYPE_ID}): ${detailResponse.status}` - ) - continue - } - - const detail: RegisterDetail = await detailResponse.json() + for (const newReg of newRegisters) { + // packageCode가 SCOPES에 없으면 스킵 + if (!newReg.SCOPES || !newReg.SCOPES.includes(packageCode)) { + continue + } - // DELETED가 true이거나 DESC가 없으면 스킵 - if (detail.DELETED || !detail.DESC) { - continue - } + const formCode = newReg.REG_TYPE_ID + const register = registerMap.get(formCode) - formInfos.push({ - formCode: detail.TYPE_ID, - formName: detail.DESC - }) + // Register에서 EP_ID가 "IMEP"가 아니면 스킵 (IM 폼만 처리) + if (!register || register.EP_ID !== "IMEP") { + continue + } - // DB 삽입용 데이터 준비 - formsToInsert.push({ - projectCode: projectCode, - packageCode: packageCode, - formCode: detail.TYPE_ID, - formName: detail.DESC, - eng: false, - im: true - }) - } catch (error) { - console.error( - `레지스터 ${register.REG_TYPE_ID} 상세 정보 가져오기 실패:`, - error - ) + // DELETED면 스킵 + if (register.DELETED) { continue } + + const formName = newReg.DESC || register.DESC || formCode + + formInfos.push({ + formCode, + formName + }) + + formsToInsert.push({ + projectCode, + packageCode, + formCode, + formName, + eng: false, + im: true + }) } - // 2-4. DB에 저장 + // 5. DB에 저장 if (formsToInsert.length > 0) { - await db.insert(formsPlant).values(formsToInsert).onConflictDoNothing() - console.log(`${formsToInsert.length}개의 IM 폼을 DB에 저장했습니다.`) + await db.insert(formsPlant) + .values(formsToInsert) + .onConflictDoNothing() + + console.log(`[getIMForms] ${formsToInsert.length}개의 IM 폼을 DB에 저장했습니다.`) } return formInfos diff --git a/lib/tags-plant/table/add-tag-dialog.tsx b/lib/tags-plant/table/add-tag-dialog.tsx index de5d2bf8..1bfb0703 100644 --- a/lib/tags-plant/table/add-tag-dialog.tsx +++ b/lib/tags-plant/table/add-tag-dialog.tsx @@ -329,7 +329,7 @@ export function AddTagDialog({ projectCode, packageCode }: AddTagDialogProps) { const tagData: CreateTagSchema = { tagType: data.tagType, class: data.class, - // subclass: data.subclass, // 서브클래스 정보 추가 + subclass: data.subclass, // 서브클래스 정보 추가 tagNo: row.tagNo, description: row.description, ...Object.fromEntries( diff --git a/lib/tags-plant/table/tag-table-column.tsx b/lib/tags-plant/table/tag-table-column.tsx index 80c25464..30bdacc3 100644 --- a/lib/tags-plant/table/tag-table-column.tsx +++ b/lib/tags-plant/table/tag-table-column.tsx @@ -82,14 +82,27 @@ export function getColumns({ minSize: 150, size: 240, }, - { + { accessorKey: "class", header: ({ column }) => ( - + ), cell: ({ row }) =>
{row.getValue("class")}
, meta: { - excelHeader: "Tag Class" + excelHeader: "Class" + }, + enableResizing: true, + minSize: 100, + size: 150, + }, + { + accessorKey: "subclass", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("subclass")}
, + meta: { + excelHeader: "Item Class" }, enableResizing: true, minSize: 100, diff --git a/lib/tags-plant/table/tag-table.tsx b/lib/tags-plant/table/tag-table.tsx index 2fdcd5fc..70bfc4e4 100644 --- a/lib/tags-plant/table/tag-table.tsx +++ b/lib/tags-plant/table/tag-table.tsx @@ -78,6 +78,9 @@ export function TagsTable({ const [isLoading, setIsLoading] = React.useState(true) const [rowAction, setRowAction] = React.useState | null>(null) + + console.log(tableData,"tableData") + // 선택된 행 관리 const [selectedRowsData, setSelectedRowsData] = React.useState([]) const [clearSelection, setClearSelection] = React.useState(false) -- cgit v1.2.3