Phase 1-4 완료

This commit is contained in:
dohyeons
2025-10-20 09:53:31 +09:00
parent 3f60bba109
commit 8932f61298
8 changed files with 317 additions and 518 deletions

View File

@@ -1,111 +0,0 @@
import { getPool } from "../database/db";
export class MaterialService {
// 임시 자재 마스터 목록 조회
async getTempMaterials(params: {
search?: string;
category?: string;
page?: number;
limit?: number;
}) {
const { search, category, page = 1, limit = 20 } = params;
const offset = (page - 1) * limit;
let whereConditions: string[] = ["is_active = true"];
const queryParams: any[] = [];
let paramIndex = 1;
if (search) {
whereConditions.push(
`(material_code ILIKE $${paramIndex} OR material_name ILIKE $${paramIndex})`
);
queryParams.push(`%${search}%`);
paramIndex++;
}
if (category) {
whereConditions.push(`category = $${paramIndex}`);
queryParams.push(category);
paramIndex++;
}
const whereClause =
whereConditions.length > 0
? `WHERE ${whereConditions.join(" AND ")}`
: "";
const pool = getPool();
// 전체 개수 조회
const countQuery = `SELECT COUNT(*) as total FROM temp_material_master ${whereClause}`;
const countResult = await pool.query(countQuery, queryParams);
const total = parseInt(countResult.rows[0].total);
// 데이터 조회
const dataQuery = `
SELECT
id,
material_code,
material_name,
category,
unit,
default_color,
description,
created_at
FROM temp_material_master
${whereClause}
ORDER BY material_code ASC
LIMIT $${paramIndex} OFFSET $${paramIndex + 1}
`;
queryParams.push(limit, offset);
const dataResult = await pool.query(dataQuery, queryParams);
return {
data: dataResult.rows,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
},
};
}
// 특정 자재 상세 조회
async getTempMaterialByCode(materialCode: string) {
const query = `
SELECT
id,
material_code,
material_name,
category,
unit,
default_color,
description,
created_at
FROM temp_material_master
WHERE material_code = $1 AND is_active = true
`;
const pool = getPool();
const result = await pool.query(query, [materialCode]);
return result.rows[0] || null;
}
// 카테고리 목록 조회
async getCategories() {
const query = `
SELECT DISTINCT category
FROM temp_material_master
WHERE is_active = true AND category IS NOT NULL
ORDER BY category ASC
`;
const pool = getPool();
const result = await pool.query(query);
return result.rows.map((row) => row.category);
}
}
export default new MaterialService();

View File

@@ -101,7 +101,6 @@ export class YardLayoutService {
SELECT
id,
yard_layout_id,
external_material_id,
material_code,
material_name,
quantity,
@@ -113,6 +112,9 @@ export class YardLayoutService {
size_y,
size_z,
color,
data_source_type,
data_source_config,
data_binding,
memo,
created_at,
updated_at
@@ -126,12 +128,11 @@ export class YardLayoutService {
return result.rows;
}
// 야드에 자재 배치 추가
// 야드에 자재 배치 추가 (빈 요소 또는 설정된 요소)
async addMaterialPlacement(layoutId: number, data: any) {
const query = `
INSERT INTO yard_material_placement (
yard_layout_id,
external_material_id,
material_code,
material_name,
quantity,
@@ -143,52 +144,68 @@ export class YardLayoutService {
size_y,
size_z,
color,
data_source_type,
data_source_config,
data_binding,
memo
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
RETURNING *
`;
const pool = getPool();
const result = await pool.query(query, [
layoutId,
data.external_material_id,
data.material_code,
data.material_name,
data.quantity,
data.unit,
data.material_code || null,
data.material_name || null,
data.quantity || null,
data.unit || null,
data.position_x || 0,
data.position_y || 0,
data.position_z || 0,
data.size_x || 5,
data.size_y || 5,
data.size_z || 5,
data.color || "#3b82f6",
data.color || "#9ca3af", // 미설정 시 회색
data.data_source_type || null,
data.data_source_config ? JSON.stringify(data.data_source_config) : null,
data.data_binding ? JSON.stringify(data.data_binding) : null,
data.memo || null,
]);
return result.rows[0];
}
// 배치 정보 수정 (위치, 크기, 색상, 메모만)
// 배치 정보 수정 (위치, 크기, 색상, 데이터 바인딩 등)
async updatePlacement(placementId: number, data: any) {
const query = `
UPDATE yard_material_placement
SET
position_x = COALESCE($1, position_x),
position_y = COALESCE($2, position_y),
position_z = COALESCE($3, position_z),
size_x = COALESCE($4, size_x),
size_y = COALESCE($5, size_y),
size_z = COALESCE($6, size_z),
color = COALESCE($7, color),
memo = COALESCE($8, memo),
material_code = COALESCE($1, material_code),
material_name = COALESCE($2, material_name),
quantity = COALESCE($3, quantity),
unit = COALESCE($4, unit),
position_x = COALESCE($5, position_x),
position_y = COALESCE($6, position_y),
position_z = COALESCE($7, position_z),
size_x = COALESCE($8, size_x),
size_y = COALESCE($9, size_y),
size_z = COALESCE($10, size_z),
color = COALESCE($11, color),
data_source_type = COALESCE($12, data_source_type),
data_source_config = COALESCE($13, data_source_config),
data_binding = COALESCE($14, data_binding),
memo = COALESCE($15, memo),
updated_at = CURRENT_TIMESTAMP
WHERE id = $9
WHERE id = $16
RETURNING *
`;
const pool = getPool();
const result = await pool.query(query, [
data.material_code,
data.material_name,
data.quantity,
data.unit,
data.position_x,
data.position_y,
data.position_z,
@@ -196,6 +213,9 @@ export class YardLayoutService {
data.size_y,
data.size_z,
data.color,
data.data_source_type,
data.data_source_config ? JSON.stringify(data.data_source_config) : null,
data.data_binding ? JSON.stringify(data.data_binding) : null,
data.memo,
placementId,
]);
@@ -230,8 +250,9 @@ export class YardLayoutService {
size_x = $4,
size_y = $5,
size_z = $6,
color = $7,
updated_at = CURRENT_TIMESTAMP
WHERE id = $7 AND yard_layout_id = $8
WHERE id = $8 AND yard_layout_id = $9
RETURNING *
`;
@@ -242,6 +263,7 @@ export class YardLayoutService {
placement.size_x,
placement.size_y,
placement.size_z,
placement.color,
placement.id,
layoutId,
]);
@@ -299,14 +321,14 @@ export class YardLayoutService {
await client.query(
`
INSERT INTO yard_material_placement (
yard_layout_id, external_material_id, material_code, material_name,
yard_layout_id, material_code, material_name,
quantity, unit, position_x, position_y, position_z,
size_x, size_y, size_z, color, memo
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
size_x, size_y, size_z, color,
data_source_type, data_source_config, data_binding, memo
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
`,
[
newLayout.id,
placement.external_material_id,
placement.material_code,
placement.material_name,
placement.quantity,
@@ -318,6 +340,9 @@ export class YardLayoutService {
placement.size_y,
placement.size_z,
placement.color,
placement.data_source_type,
placement.data_source_config,
placement.data_binding,
placement.memo,
]
);