174 lines
4.2 KiB
TypeScript
174 lines
4.2 KiB
TypeScript
import { pool } from "../database/db";
|
|
import logger from "../utils/logger";
|
|
|
|
export interface DigitalTwinLayoutTemplate {
|
|
id: string;
|
|
company_code: string;
|
|
name: string;
|
|
description?: string | null;
|
|
external_db_connection_id: number;
|
|
layout_type: string;
|
|
config: any;
|
|
created_by: string;
|
|
created_at: Date;
|
|
updated_by: string;
|
|
updated_at: Date;
|
|
}
|
|
|
|
interface ServiceResponse<T> {
|
|
success: boolean;
|
|
data?: T;
|
|
message?: string;
|
|
error?: string;
|
|
}
|
|
|
|
export class DigitalTwinTemplateService {
|
|
static async listTemplates(
|
|
companyCode: string,
|
|
options: { externalDbConnectionId?: number; layoutType?: string } = {},
|
|
): Promise<ServiceResponse<DigitalTwinLayoutTemplate[]>> {
|
|
try {
|
|
const params: any[] = [companyCode];
|
|
let paramIndex = 2;
|
|
|
|
let query = `
|
|
SELECT *
|
|
FROM digital_twin_layout_template
|
|
WHERE company_code = $1
|
|
`;
|
|
|
|
if (options.layoutType) {
|
|
query += ` AND layout_type = $${paramIndex++}`;
|
|
params.push(options.layoutType);
|
|
}
|
|
|
|
if (options.externalDbConnectionId) {
|
|
query += ` AND external_db_connection_id = $${paramIndex++}`;
|
|
params.push(options.externalDbConnectionId);
|
|
}
|
|
|
|
query += `
|
|
ORDER BY updated_at DESC, name ASC
|
|
`;
|
|
|
|
const result = await pool.query(query, params);
|
|
|
|
logger.info("디지털 트윈 매핑 템플릿 목록 조회", {
|
|
companyCode,
|
|
count: result.rowCount,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data: result.rows as DigitalTwinLayoutTemplate[],
|
|
};
|
|
} catch (error: any) {
|
|
logger.error("디지털 트윈 매핑 템플릿 목록 조회 실패", error);
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
message: "매핑 템플릿 목록 조회 중 오류가 발생했습니다.",
|
|
};
|
|
}
|
|
}
|
|
|
|
static async getTemplateById(
|
|
companyCode: string,
|
|
id: string,
|
|
): Promise<ServiceResponse<DigitalTwinLayoutTemplate>> {
|
|
try {
|
|
const query = `
|
|
SELECT *
|
|
FROM digital_twin_layout_template
|
|
WHERE id = $1 AND company_code = $2
|
|
`;
|
|
|
|
const result = await pool.query(query, [id, companyCode]);
|
|
|
|
if (result.rowCount === 0) {
|
|
return {
|
|
success: false,
|
|
message: "매핑 템플릿을 찾을 수 없습니다.",
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: result.rows[0] as DigitalTwinLayoutTemplate,
|
|
};
|
|
} catch (error: any) {
|
|
logger.error("디지털 트윈 매핑 템플릿 조회 실패", error);
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
message: "매핑 템플릿 조회 중 오류가 발생했습니다.",
|
|
};
|
|
}
|
|
}
|
|
|
|
static async createTemplate(
|
|
companyCode: string,
|
|
userId: string,
|
|
payload: {
|
|
name: string;
|
|
description?: string;
|
|
externalDbConnectionId: number;
|
|
layoutType?: string;
|
|
config: any;
|
|
},
|
|
): Promise<ServiceResponse<DigitalTwinLayoutTemplate>> {
|
|
try {
|
|
const query = `
|
|
INSERT INTO digital_twin_layout_template (
|
|
company_code,
|
|
name,
|
|
description,
|
|
external_db_connection_id,
|
|
layout_type,
|
|
config,
|
|
created_by,
|
|
created_at,
|
|
updated_by,
|
|
updated_at
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $7, NOW())
|
|
RETURNING *
|
|
`;
|
|
|
|
const values = [
|
|
companyCode,
|
|
payload.name,
|
|
payload.description || null,
|
|
payload.externalDbConnectionId,
|
|
payload.layoutType || "yard-3d",
|
|
JSON.stringify(payload.config),
|
|
userId,
|
|
];
|
|
|
|
const result = await pool.query(query, values);
|
|
|
|
logger.info("디지털 트윈 매핑 템플릿 생성", {
|
|
companyCode,
|
|
templateId: result.rows[0].id,
|
|
externalDbConnectionId: payload.externalDbConnectionId,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data: result.rows[0] as DigitalTwinLayoutTemplate,
|
|
};
|
|
} catch (error: any) {
|
|
logger.error("디지털 트윈 매핑 템플릿 생성 실패", error);
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
message: "매핑 템플릿 생성 중 오류가 발생했습니다.",
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|