Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into feature/screen-management

This commit is contained in:
kjs
2025-12-18 14:34:38 +09:00
19 changed files with 4617 additions and 491 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -56,6 +56,11 @@ router.post("/upload-image", upload.single("image"), (req, res, next) =>
reportController.uploadImage(req, res, next)
);
// WORD(DOCX) 내보내기
router.post("/export-word", (req, res, next) =>
reportController.exportToWord(req, res, next)
);
// 리포트 목록
router.get("/", (req, res, next) =>
reportController.getReports(req, res, next)

View File

@@ -477,6 +477,12 @@ export class ReportService {
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
`;
// components가 이미 문자열이면 그대로, 객체면 JSON.stringify
const componentsData =
typeof originalLayout.components === "string"
? originalLayout.components
: JSON.stringify(originalLayout.components);
await client.query(copyLayoutQuery, [
newLayoutId,
newReportId,
@@ -487,7 +493,7 @@ export class ReportService {
originalLayout.margin_bottom,
originalLayout.margin_left,
originalLayout.margin_right,
JSON.stringify(originalLayout.components),
componentsData,
userId,
]);
}
@@ -561,7 +567,7 @@ export class ReportService {
}
/**
* 레이아웃 저장 (쿼리 포함)
* 레이아웃 저장 (쿼리 포함) - 페이지 기반 구조
*/
async saveLayout(
reportId: string,
@@ -569,6 +575,19 @@ export class ReportService {
userId: string
): Promise<boolean> {
return transaction(async (client) => {
// 첫 번째 페이지 정보를 기본 레이아웃으로 사용
const firstPage = data.layoutConfig.pages[0];
const canvasWidth = firstPage?.width || 210;
const canvasHeight = firstPage?.height || 297;
const pageOrientation =
canvasWidth > canvasHeight ? "landscape" : "portrait";
const margins = firstPage?.margins || {
top: 20,
bottom: 20,
left: 20,
right: 20,
};
// 1. 레이아웃 저장
const existingQuery = `
SELECT layout_id FROM report_layout WHERE report_id = $1
@@ -576,7 +595,7 @@ export class ReportService {
const existing = await client.query(existingQuery, [reportId]);
if (existing.rows.length > 0) {
// 업데이트
// 업데이트 - components 컬럼에 전체 layoutConfig 저장
const updateQuery = `
UPDATE report_layout
SET
@@ -594,14 +613,14 @@ export class ReportService {
`;
await client.query(updateQuery, [
data.canvasWidth,
data.canvasHeight,
data.pageOrientation,
data.marginTop,
data.marginBottom,
data.marginLeft,
data.marginRight,
JSON.stringify(data.components),
canvasWidth,
canvasHeight,
pageOrientation,
margins.top,
margins.bottom,
margins.left,
margins.right,
JSON.stringify(data.layoutConfig), // 전체 layoutConfig 저장
userId,
reportId,
]);
@@ -627,14 +646,14 @@ export class ReportService {
await client.query(insertQuery, [
layoutId,
reportId,
data.canvasWidth,
data.canvasHeight,
data.pageOrientation,
data.marginTop,
data.marginBottom,
data.marginLeft,
data.marginRight,
JSON.stringify(data.components),
canvasWidth,
canvasHeight,
pageOrientation,
margins.top,
margins.bottom,
margins.left,
margins.right,
JSON.stringify(data.layoutConfig), // 전체 layoutConfig 저장
userId,
]);
}

View File

@@ -116,22 +116,38 @@ export interface UpdateReportRequest {
useYn?: string;
}
// 페이지 설정
export interface PageConfig {
page_id: string;
page_name: string;
page_order: number;
width: number;
height: number;
background_color: string;
margins: {
top: number;
bottom: number;
left: number;
right: number;
};
components: any[];
}
// 레이아웃 설정
export interface ReportLayoutConfig {
pages: PageConfig[];
}
// 레이아웃 저장 요청
export interface SaveLayoutRequest {
canvasWidth: number;
canvasHeight: number;
pageOrientation: string;
marginTop: number;
marginBottom: number;
marginLeft: number;
marginRight: number;
components: any[];
layoutConfig: ReportLayoutConfig;
queries?: Array<{
id: string;
name: string;
type: "MASTER" | "DETAIL";
sqlQuery: string;
parameters: string[];
externalConnectionId?: number;
}>;
}