import { Request, Response } from "express"; import { ScreenManagementService } from "../services/screenManagementService"; import { CreateScreenRequest, UpdateScreenRequest, SaveLayoutRequest, MenuAssignmentRequest, ColumnWebTypeSetting, WebType, } from "../types/screen"; import { logger } from "../utils/logger"; export class ScreenManagementController { private screenService: ScreenManagementService; constructor() { this.screenService = new ScreenManagementService(); } // ======================================== // 화면 정의 관리 // ======================================== /** * 화면 목록 조회 (회사별) */ async getScreens(req: Request, res: Response): Promise { try { const { page = 1, size = 20 } = req.query; const userCompanyCode = (req as any).user?.company_code || "*"; const result = await this.screenService.getScreensByCompany( userCompanyCode, Number(page), Number(size) ); res.json({ success: true, data: result.data, pagination: result.pagination, }); } catch (error) { logger.error("화면 목록 조회 실패:", error); res.status(500).json({ success: false, message: "화면 목록을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } /** * 화면 생성 */ async createScreen(req: Request, res: Response): Promise { try { const screenData: CreateScreenRequest = req.body; const userCompanyCode = (req as any).user?.company_code || "*"; const userId = (req as any).user?.user_id || "system"; // 사용자 회사 코드 자동 설정 if (userCompanyCode !== "*") { screenData.companyCode = userCompanyCode; } screenData.createdBy = userId; const screen = await this.screenService.createScreen( screenData, userCompanyCode ); res.status(201).json({ success: true, data: screen, message: "화면이 성공적으로 생성되었습니다.", }); } catch (error) { logger.error("화면 생성 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "화면 생성에 실패했습니다.", }); } } /** * 화면 조회 */ async getScreen(req: Request, res: Response): Promise { try { const { screenId } = req.params; const screen = await this.screenService.getScreenById(Number(screenId)); if (!screen) { res.status(404).json({ success: false, message: "화면을 찾을 수 없습니다.", }); return; } res.json({ success: true, data: screen, }); } catch (error) { logger.error("화면 조회 실패:", error); res.status(500).json({ success: false, message: "화면을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } /** * 화면 수정 */ async updateScreen(req: Request, res: Response): Promise { try { const { screenId } = req.params; const updateData: UpdateScreenRequest = req.body; const userCompanyCode = (req as any).user?.company_code || "*"; const userId = (req as any).user?.user_id || "system"; updateData.updatedBy = userId; const screen = await this.screenService.updateScreen( Number(screenId), updateData, userCompanyCode ); res.json({ success: true, data: screen, message: "화면이 성공적으로 수정되었습니다.", }); } catch (error) { logger.error("화면 수정 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "화면 수정에 실패했습니다.", }); } } /** * 화면 삭제 */ async deleteScreen(req: Request, res: Response): Promise { try { const { screenId } = req.params; const userCompanyCode = (req as any).user?.company_code || "*"; await this.screenService.deleteScreen(Number(screenId), userCompanyCode); res.json({ success: true, message: "화면이 성공적으로 삭제되었습니다.", }); } catch (error) { logger.error("화면 삭제 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "화면 삭제에 실패했습니다.", }); } } // ======================================== // 레이아웃 관리 // ======================================== /** * 레이아웃 조회 */ async getLayout(req: Request, res: Response): Promise { try { const { screenId } = req.params; const layout = await this.screenService.getLayout(Number(screenId)); if (!layout) { res.json({ success: true, data: { components: [], gridSettings: { columns: 12, gap: 16, padding: 16, }, }, }); return; } res.json({ success: true, data: layout, }); } catch (error) { logger.error("레이아웃 조회 실패:", error); res.status(500).json({ success: false, message: "레이아웃을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } /** * 레이아웃 저장 */ async saveLayout(req: Request, res: Response): Promise { try { const { screenId } = req.params; const layoutData: SaveLayoutRequest = req.body; await this.screenService.saveLayout(Number(screenId), layoutData); res.json({ success: true, message: "레이아웃이 성공적으로 저장되었습니다.", }); } catch (error) { logger.error("레이아웃 저장 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "레이아웃 저장에 실패했습니다.", }); } } // ======================================== // 템플릿 관리 // ======================================== /** * 템플릿 목록 조회 */ async getTemplates(req: Request, res: Response): Promise { try { const { type, isPublic } = req.query; const userCompanyCode = (req as any).user?.company_code || "*"; const templates = await this.screenService.getTemplatesByCompany( userCompanyCode, type as string, isPublic === "true" ); res.json({ success: true, data: templates, }); } catch (error) { logger.error("템플릿 목록 조회 실패:", error); res.status(500).json({ success: false, message: "템플릿 목록을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } /** * 템플릿 생성 */ async createTemplate(req: Request, res: Response): Promise { try { const templateData = req.body; const userCompanyCode = (req as any).user?.company_code || "*"; const userId = (req as any).user?.user_id || "system"; templateData.company_code = userCompanyCode; templateData.created_by = userId; const template = await this.screenService.createTemplate(templateData); res.status(201).json({ success: true, data: template, message: "템플릿이 성공적으로 생성되었습니다.", }); } catch (error) { logger.error("템플릿 생성 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "템플릿 생성에 실패했습니다.", }); } } // ======================================== // 메뉴 할당 관리 // ======================================== /** * 화면-메뉴 할당 */ async assignScreenToMenu(req: Request, res: Response): Promise { try { const { screenId } = req.params; const assignmentData: MenuAssignmentRequest = req.body; const userCompanyCode = (req as any).user?.company_code || "*"; const userId = (req as any).user?.user_id || "system"; // 사용자 회사 코드 자동 설정 if (userCompanyCode !== "*") { assignmentData.companyCode = userCompanyCode; } assignmentData.createdBy = userId; await this.screenService.assignScreenToMenu( Number(screenId), assignmentData ); res.json({ success: true, message: "화면이 메뉴에 성공적으로 할당되었습니다.", }); } catch (error) { logger.error("메뉴 할당 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "메뉴 할당에 실패했습니다.", }); } } /** * 메뉴별 화면 목록 조회 */ async getScreensByMenu(req: Request, res: Response): Promise { try { const { menuObjid } = req.params; const userCompanyCode = (req as any).user?.company_code || "*"; const screens = await this.screenService.getScreensByMenu( Number(menuObjid), userCompanyCode ); res.json({ success: true, data: screens, }); } catch (error) { logger.error("메뉴별 화면 목록 조회 실패:", error); res.status(500).json({ success: false, message: "메뉴별 화면 목록을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } // ======================================== // 테이블 타입 연계 // ======================================== /** * 테이블 컬럼 정보 조회 */ async getTableColumns(req: Request, res: Response): Promise { try { const { tableName } = req.params; const columns = await this.screenService.getColumnInfo(tableName); res.json({ success: true, data: columns, }); } catch (error) { logger.error("테이블 컬럼 정보 조회 실패:", error); res.status(500).json({ success: false, message: "테이블 컬럼 정보를 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } /** * 컬럼 웹 타입 설정 */ async setColumnWebType(req: Request, res: Response): Promise { try { const { tableName, columnName } = req.params; const { webType, ...additionalSettings } = req.body; await this.screenService.setColumnWebType( tableName, columnName, webType as WebType, additionalSettings ); res.json({ success: true, message: "컬럼 웹 타입이 성공적으로 설정되었습니다.", }); } catch (error) { logger.error("컬럼 웹 타입 설정 실패:", error); res.status(400).json({ success: false, message: error instanceof Error ? error.message : "컬럼 웹 타입 설정에 실패했습니다.", }); } } /** * 테이블 목록 조회 (화면 생성용) */ async getTables(req: Request, res: Response): Promise { try { // PostgreSQL에서 사용 가능한 테이블 목록 조회 const tables = await (this.screenService as any).prisma.$queryRaw` SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' ORDER BY table_name `; res.json({ success: true, data: tables, }); } catch (error) { logger.error("테이블 목록 조회 실패:", error); res.status(500).json({ success: false, message: "테이블 목록을 조회하는 중 오류가 발생했습니다.", error: error instanceof Error ? error.message : "Unknown error", }); } } }