/** * 바코드 라벨 관리 컨트롤러 * ZD421 등 바코드 프린터용 라벨 CRUD 및 레이아웃/템플릿 */ import { Request, Response, NextFunction } from "express"; import barcodeLabelService from "../services/barcodeLabelService"; function getUserId(req: Request): string { return (req as any).user?.userId || "SYSTEM"; } export class BarcodeLabelController { async getLabels(req: Request, res: Response, next: NextFunction) { try { const page = Math.max(1, parseInt((req.query.page as string) || "1", 10)); const limit = Math.min(100, Math.max(1, parseInt((req.query.limit as string) || "20", 10))); const searchText = (req.query.searchText as string) || ""; const useYn = (req.query.useYn as string) || "Y"; const sortBy = (req.query.sortBy as string) || "created_at"; const sortOrder = (req.query.sortOrder as "ASC" | "DESC") || "DESC"; const data = await barcodeLabelService.getLabels({ page, limit, searchText, useYn, sortBy, sortOrder, }); return res.json({ success: true, data }); } catch (error) { return next(error); } } async getLabelById(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const label = await barcodeLabelService.getLabelById(labelId); if (!label) { return res.status(404).json({ success: false, message: "바코드 라벨을 찾을 수 없습니다.", }); } return res.json({ success: true, data: label }); } catch (error) { return next(error); } } async getLayout(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const layout = await barcodeLabelService.getLayout(labelId); if (!layout) { return res.status(404).json({ success: false, message: "레이아웃을 찾을 수 없습니다.", }); } return res.json({ success: true, data: layout }); } catch (error) { return next(error); } } async createLabel(req: Request, res: Response, next: NextFunction) { try { const body = req.body as { labelNameKor?: string; labelNameEng?: string; description?: string; templateId?: string; }; if (!body?.labelNameKor?.trim()) { return res.status(400).json({ success: false, message: "라벨명(한글)은 필수입니다.", }); } const labelId = await barcodeLabelService.createLabel( { labelNameKor: body.labelNameKor.trim(), labelNameEng: body.labelNameEng?.trim(), description: body.description?.trim(), templateId: body.templateId?.trim(), }, getUserId(req) ); return res.status(201).json({ success: true, data: { labelId }, message: "바코드 라벨이 생성되었습니다.", }); } catch (error) { return next(error); } } async updateLabel(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const body = req.body as { labelNameKor?: string; labelNameEng?: string; description?: string; useYn?: string; }; const success = await barcodeLabelService.updateLabel( labelId, { labelNameKor: body.labelNameKor?.trim(), labelNameEng: body.labelNameEng?.trim(), description: body.description !== undefined ? body.description : undefined, useYn: body.useYn, }, getUserId(req) ); if (!success) { return res.status(404).json({ success: false, message: "바코드 라벨을 찾을 수 없습니다.", }); } return res.json({ success: true, message: "수정되었습니다." }); } catch (error) { return next(error); } } async saveLayout(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const layout = req.body as { width_mm: number; height_mm: number; components: any[] }; if (!layout || typeof layout.width_mm !== "number" || typeof layout.height_mm !== "number" || !Array.isArray(layout.components)) { return res.status(400).json({ success: false, message: "width_mm, height_mm, components 배열이 필요합니다.", }); } await barcodeLabelService.saveLayout( labelId, { width_mm: layout.width_mm, height_mm: layout.height_mm, components: layout.components }, getUserId(req) ); return res.json({ success: true, message: "레이아웃이 저장되었습니다." }); } catch (error) { return next(error); } } async deleteLabel(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const success = await barcodeLabelService.deleteLabel(labelId); if (!success) { return res.status(404).json({ success: false, message: "바코드 라벨을 찾을 수 없습니다.", }); } return res.json({ success: true, message: "삭제되었습니다." }); } catch (error) { return next(error); } } async copyLabel(req: Request, res: Response, next: NextFunction) { try { const { labelId } = req.params; const newId = await barcodeLabelService.copyLabel(labelId, getUserId(req)); if (!newId) { return res.status(404).json({ success: false, message: "바코드 라벨을 찾을 수 없습니다.", }); } return res.json({ success: true, data: { labelId: newId }, message: "복사되었습니다.", }); } catch (error) { return next(error); } } async getTemplates(req: Request, res: Response, next: NextFunction) { try { const templates = await barcodeLabelService.getTemplates(); return res.json({ success: true, data: templates }); } catch (error) { return next(error); } } async getTemplateById(req: Request, res: Response, next: NextFunction) { try { const { templateId } = req.params; const template = await barcodeLabelService.getTemplateById(templateId); if (!template) { return res.status(404).json({ success: false, message: "템플릿을 찾을 수 없습니다.", }); } const layout = JSON.parse(template.layout_json); return res.json({ success: true, data: { ...template, layout } }); } catch (error) { return next(error); } } } export default new BarcodeLabelController();