WIP: preset + inspection (임시, 나중에 squash)
This commit is contained in:
@@ -127,6 +127,7 @@ import screenEmbeddingRoutes from "./routes/screenEmbeddingRoutes"; // 화면
|
||||
import screenGroupRoutes from "./routes/screenGroupRoutes"; // 화면 그룹 관리
|
||||
import popActionRoutes from "./routes/popActionRoutes"; // POP 액션 실행
|
||||
import popProductionRoutes from "./routes/popProductionRoutes"; // POP 생산 관리 (공정 생성/타이머)
|
||||
import inspectionResultRoutes from "./routes/inspectionResultRoutes"; // POP 검사 결과 관리
|
||||
import vehicleTripRoutes from "./routes/vehicleTripRoutes"; // 차량 운행 이력 관리
|
||||
import approvalRoutes from "./routes/approvalRoutes"; // 결재 시스템
|
||||
import driverRoutes from "./routes/driverRoutes"; // 공차중계 운전자 관리
|
||||
@@ -287,6 +288,7 @@ app.use("/api/screen-management", screenManagementRoutes);
|
||||
app.use("/api/screen-groups", screenGroupRoutes); // 화면 그룹 관리
|
||||
app.use("/api/pop", popActionRoutes); // POP 액션 실행
|
||||
app.use("/api/pop/production", popProductionRoutes); // POP 생산 관리
|
||||
app.use("/api/pop/inspection-result", inspectionResultRoutes); // POP 검사 결과 관리
|
||||
app.use("/api/common-codes", commonCodeRoutes);
|
||||
app.use("/api/dynamic-form", dynamicFormRoutes);
|
||||
app.use("/api/files", fileRoutes);
|
||||
|
||||
191
backend-node/src/routes/inspectionResultRoutes.ts
Normal file
191
backend-node/src/routes/inspectionResultRoutes.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import { Router, Request, Response } from "express";
|
||||
import { getPool } from "../database/db";
|
||||
import { authenticateToken } from "../middleware/authMiddleware";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.use(authenticateToken);
|
||||
|
||||
// ---- 검사 기준 조회 (item_inspection_info) ----
|
||||
// GET /api/pop/inspection-result/info?itemCode=ITEM-001&inspectionType=입고검사
|
||||
router.get("/info", async (req: Request, res: Response) => {
|
||||
const pool = getPool();
|
||||
const companyCode = (req as any).user?.companyCode;
|
||||
const { itemCode, itemId, inspectionType } = req.query;
|
||||
|
||||
if (!companyCode) {
|
||||
return res.status(401).json({ success: false, message: "인증 정보 없음" });
|
||||
}
|
||||
|
||||
const conditions: string[] = ["company_code = $1", "is_active = 'Y'"];
|
||||
const params: unknown[] = [companyCode];
|
||||
let idx = 2;
|
||||
|
||||
if (itemCode) {
|
||||
conditions.push(`item_code = $${idx++}`);
|
||||
params.push(itemCode);
|
||||
}
|
||||
if (itemId) {
|
||||
conditions.push(`item_id = $${idx++}`);
|
||||
params.push(itemId);
|
||||
}
|
||||
if (inspectionType) {
|
||||
conditions.push(`inspection_type = $${idx++}`);
|
||||
params.push(inspectionType);
|
||||
}
|
||||
|
||||
const sql = `
|
||||
SELECT id, item_id, item_code, item_name,
|
||||
inspection_type, inspection_item_name, inspection_standard,
|
||||
inspection_method, pass_criteria, is_required, sort_order, memo
|
||||
FROM item_inspection_info
|
||||
WHERE ${conditions.join(" AND ")}
|
||||
ORDER BY sort_order, inspection_item_name
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await pool.query(sql, params);
|
||||
return res.json({ success: true, data: result.rows });
|
||||
} catch (err: any) {
|
||||
return res.status(500).json({ success: false, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ---- 검사 결과 조회 ----
|
||||
// GET /api/pop/inspection-result?referenceId=xxx&referenceTable=yyy&screenId=zzz
|
||||
router.get("/", async (req: Request, res: Response) => {
|
||||
const pool = getPool();
|
||||
const companyCode = (req as any).user?.companyCode;
|
||||
const { referenceId, referenceTable, screenId } = req.query;
|
||||
|
||||
if (!companyCode) {
|
||||
return res.status(401).json({ success: false, message: "인증 정보 없음" });
|
||||
}
|
||||
|
||||
const conditions: string[] = ["company_code = $1"];
|
||||
const params: unknown[] = [companyCode];
|
||||
let idx = 2;
|
||||
|
||||
if (referenceId) {
|
||||
conditions.push(`reference_id = $${idx++}`);
|
||||
params.push(referenceId);
|
||||
}
|
||||
if (referenceTable) {
|
||||
conditions.push(`reference_table = $${idx++}`);
|
||||
params.push(referenceTable);
|
||||
}
|
||||
if (screenId) {
|
||||
conditions.push(`screen_id = $${idx++}`);
|
||||
params.push(screenId);
|
||||
}
|
||||
|
||||
const sql = `
|
||||
SELECT *
|
||||
FROM inspection_result
|
||||
WHERE ${conditions.join(" AND ")}
|
||||
ORDER BY created_date DESC
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await pool.query(sql, params);
|
||||
return res.json({ success: true, data: result.rows });
|
||||
} catch (err: any) {
|
||||
return res.status(500).json({ success: false, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ---- 검사 결과 저장 (INSERT or UPDATE) ----
|
||||
// POST /api/pop/inspection-result
|
||||
router.post("/", async (req: Request, res: Response) => {
|
||||
const pool = getPool();
|
||||
const companyCode = (req as any).user?.companyCode;
|
||||
const writer = (req as any).user?.userId;
|
||||
|
||||
if (!companyCode) {
|
||||
return res.status(401).json({ success: false, message: "인증 정보 없음" });
|
||||
}
|
||||
|
||||
const {
|
||||
referenceTable,
|
||||
referenceId,
|
||||
screenId,
|
||||
itemId,
|
||||
itemCode,
|
||||
itemName,
|
||||
inspectionType,
|
||||
items, // 검사 항목별 결과 배열
|
||||
overallJudgment,
|
||||
memo,
|
||||
isCompleted,
|
||||
} = req.body;
|
||||
|
||||
if (!items || !Array.isArray(items) || items.length === 0) {
|
||||
return res.status(400).json({ success: false, message: "검사 항목이 없습니다" });
|
||||
}
|
||||
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
await client.query("BEGIN");
|
||||
|
||||
// 기존 결과 삭제 (동일 referenceId + referenceTable 기준 덮어쓰기)
|
||||
if (referenceId && referenceTable) {
|
||||
await client.query(
|
||||
`DELETE FROM inspection_result
|
||||
WHERE company_code = $1 AND reference_id = $2 AND reference_table = $3`,
|
||||
[companyCode, referenceId, referenceTable]
|
||||
);
|
||||
}
|
||||
|
||||
const insertedIds: string[] = [];
|
||||
for (const item of items) {
|
||||
const completedFlag = isCompleted ? "Y" : "N";
|
||||
const completedDate = isCompleted ? new Date() : null;
|
||||
const insertSql = `
|
||||
INSERT INTO inspection_result (
|
||||
company_code, writer,
|
||||
reference_table, reference_id, screen_id,
|
||||
inspection_info_id, item_id, item_code, item_name,
|
||||
inspection_type, inspection_item_name, inspection_standard, pass_criteria, is_required,
|
||||
measured_value, judgment, overall_judgment, memo,
|
||||
is_completed, completed_date
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20
|
||||
)
|
||||
RETURNING id
|
||||
`;
|
||||
const result = await client.query(insertSql, [
|
||||
companyCode,
|
||||
writer,
|
||||
referenceTable || null,
|
||||
referenceId || null,
|
||||
screenId || null,
|
||||
item.inspectionInfoId || null,
|
||||
itemId || item.itemId || null,
|
||||
itemCode || item.itemCode || null,
|
||||
itemName || item.itemName || null,
|
||||
inspectionType || item.inspectionType || null,
|
||||
item.inspectionItemName || null,
|
||||
item.inspectionStandard || null,
|
||||
item.passCriteria || null,
|
||||
item.isRequired || "Y",
|
||||
item.measuredValue || null,
|
||||
item.judgment || null,
|
||||
overallJudgment || null,
|
||||
memo || null,
|
||||
completedFlag,
|
||||
completedDate,
|
||||
]);
|
||||
insertedIds.push(result.rows[0].id);
|
||||
}
|
||||
|
||||
await client.query("COMMIT");
|
||||
return res.json({ success: true, data: { ids: insertedIds } });
|
||||
} catch (err: any) {
|
||||
await client.query("ROLLBACK");
|
||||
return res.status(500).json({ success: false, message: err.message });
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user