import { apiClient } from "./client"; import type { DigitalTwinLayout, DigitalTwinLayoutDetail, CreateLayoutRequest, UpdateLayoutRequest, Warehouse, Area, Location, MaterialData, MaterialCount, } from "@/types/digitalTwin"; // API 응답 타입 interface ApiResponse { success: boolean; data?: T; message?: string; error?: string; } // 매핑 템플릿 타입 export interface DigitalTwinMappingTemplate { id: string; company_code: string; name: string; description?: string; external_db_connection_id: number; layout_type: string; config: any; created_by: string; created_at: string; updated_by: string; updated_at: string; } // ========== 레이아웃 관리 API ========== // 레이아웃 목록 조회 export const getLayouts = async (params?: { externalDbConnectionId?: number; warehouseKey?: string; }): Promise> => { try { const response = await apiClient.get("/digital-twin/layouts", { params }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 레이아웃 상세 조회 export const getLayoutById = async (id: number): Promise> => { try { const response = await apiClient.get(`/digital-twin/layouts/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 레이아웃 생성 export const createLayout = async (data: CreateLayoutRequest): Promise> => { try { const response = await apiClient.post("/digital-twin/layouts", data); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 레이아웃 수정 export const updateLayout = async (id: number, data: UpdateLayoutRequest): Promise> => { try { const response = await apiClient.put(`/digital-twin/layouts/${id}`, data); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 레이아웃 삭제 export const deleteLayout = async (id: number): Promise> => { try { const response = await apiClient.delete(`/digital-twin/layouts/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // ========== 외부 DB 테이블 조회 API ========== export const getTables = async (connectionId: number): Promise>> => { try { const response = await apiClient.get(`/digital-twin/data/tables/${connectionId}`); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; export const getTablePreview = async (connectionId: number, tableName: string): Promise> => { try { const response = await apiClient.get(`/digital-twin/data/table-preview/${connectionId}/${tableName}`); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // ========== 외부 DB 데이터 조회 API ========== // 창고 목록 조회 export const getWarehouses = async ( externalDbConnectionId: number, tableName: string, ): Promise> => { try { const response = await apiClient.get("/digital-twin/data/warehouses", { params: { externalDbConnectionId, tableName }, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // Area 목록 조회 export const getAreas = async ( externalDbConnectionId: number, tableName: string, warehouseKey: string, ): Promise> => { try { const response = await apiClient.get("/digital-twin/data/areas", { params: { externalDbConnectionId, tableName, warehouseKey }, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // Location 목록 조회 export const getLocations = async ( externalDbConnectionId: number, tableName: string, areaKey: string, ): Promise> => { try { const response = await apiClient.get("/digital-twin/data/locations", { params: { externalDbConnectionId, tableName, areaKey }, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 자재 목록 조회 (특정 Location) export const getMaterials = async ( externalDbConnectionId: number, materialConfig: { tableName: string; keyColumn: string; locationKeyColumn: string; layerColumn?: string; locaKey: string; }, ): Promise> => { try { const response = await apiClient.get("/digital-twin/data/materials", { params: { externalDbConnectionId, tableName: materialConfig.tableName, keyColumn: materialConfig.keyColumn, locationKeyColumn: materialConfig.locationKeyColumn, layerColumn: materialConfig.layerColumn, locaKey: materialConfig.locaKey, }, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 자재 개수 조회 (여러 Location) export const getMaterialCounts = async ( externalDbConnectionId: number, tableName: string, locaKeys: string[], ): Promise> => { try { const response = await apiClient.post("/digital-twin/data/material-counts", { externalDbConnectionId, tableName, locationKeys: locaKeys, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // ========== 동적 계층 구조 API ========== export interface HierarchyData { warehouse: any[]; levels: Array<{ level: number; name: string; data: any[]; }>; materials: Array<{ location_key: string; count: number; }>; } // 전체 계층 데이터 조회 export const getHierarchyData = async ( externalDbConnectionId: number, hierarchyConfig: any, ): Promise> => { try { const response = await apiClient.post("/digital-twin/data/hierarchy", { externalDbConnectionId, hierarchyConfig: JSON.stringify(hierarchyConfig), }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 특정 부모의 하위 데이터 조회 export const getChildrenData = async ( externalDbConnectionId: number, hierarchyConfig: any, parentLevel: number, parentKey: string, ): Promise> => { try { const response = await apiClient.post("/digital-twin/data/children", { externalDbConnectionId, hierarchyConfig: JSON.stringify(hierarchyConfig), parentLevel, parentKey, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // ========== 매핑 템플릿 API ========== // 템플릿 목록 조회 (회사 단위, 현재 사용자 기준) export const getMappingTemplates = async (params?: { externalDbConnectionId?: number; layoutType?: string; }): Promise> => { try { const response = await apiClient.get("/digital-twin/mapping-templates", { params: { externalDbConnectionId: params?.externalDbConnectionId, layoutType: params?.layoutType, }, }); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 템플릿 생성 export const createMappingTemplate = async (data: { name: string; description?: string; externalDbConnectionId: number; layoutType?: string; config: any; }): Promise> => { try { const response = await apiClient.post("/digital-twin/mapping-templates", data); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } }; // 템플릿 단건 조회 export const getMappingTemplateById = async ( id: string, ): Promise> => { try { const response = await apiClient.get(`/digital-twin/mapping-templates/${id}`); return response.data; } catch (error: any) { return { success: false, error: error.response?.data?.message || error.message, }; } };