feat: Implement screen group screens duplication in menu copy service
- Added a new method `copyScreenGroupScreens` to handle the duplication of screen group screens during the menu copy process. - Implemented logic to create a mapping of screen group IDs from the source to the target company. - Enhanced the existing menu copy functionality to include the copying of screen group screens, ensuring that the screen-role and display order are preserved. - Added logging for better traceability of the duplication process. This update improves the menu copy service by allowing for a more comprehensive duplication of associated screen group screens, enhancing the overall functionality of the menu management system.
This commit is contained in:
parent
772514c270
commit
4f639dec34
|
|
@ -1127,6 +1127,16 @@ export class MenuCopyService {
|
|||
logger.info("\n🔄 [6.5단계] 메뉴 URL 화면 ID 재매핑");
|
||||
await this.updateMenuUrls(menuIdMap, screenIdMap, client);
|
||||
|
||||
// === 6.7단계: screen_group_screens 복제 ===
|
||||
logger.info("\n🏷️ [6.7단계] screen_group_screens 복제");
|
||||
await this.copyScreenGroupScreens(
|
||||
screenIds,
|
||||
screenIdMap,
|
||||
sourceCompanyCode,
|
||||
targetCompanyCode,
|
||||
client
|
||||
);
|
||||
|
||||
// === 7단계: 테이블 타입 설정 복사 ===
|
||||
if (additionalCopyOptions?.copyTableTypeColumns) {
|
||||
logger.info("\n📦 [7단계] 테이블 타입 설정 복사");
|
||||
|
|
@ -2108,6 +2118,26 @@ export class MenuCopyService {
|
|||
|
||||
logger.info(`📂 메뉴 복사 중: ${menus.length}개`);
|
||||
|
||||
// screen_group_id 재매핑 맵 생성 (source company → target company)
|
||||
const screenGroupIdMap = new Map<number, number>();
|
||||
const sourceGroupIds = [...new Set(menus.map(m => m.screen_group_id).filter(Boolean))] as number[];
|
||||
if (sourceGroupIds.length > 0) {
|
||||
const sourceGroups = await client.query<{ id: number; group_name: string }>(
|
||||
`SELECT id, group_name FROM screen_groups WHERE id = ANY($1)`,
|
||||
[sourceGroupIds]
|
||||
);
|
||||
for (const sg of sourceGroups.rows) {
|
||||
const targetGroup = await client.query<{ id: number }>(
|
||||
`SELECT id FROM screen_groups WHERE group_name = $1 AND company_code = $2 LIMIT 1`,
|
||||
[sg.group_name, targetCompanyCode]
|
||||
);
|
||||
if (targetGroup.rows.length > 0) {
|
||||
screenGroupIdMap.set(sg.id, targetGroup.rows[0].id);
|
||||
}
|
||||
}
|
||||
logger.info(`🏷️ screen_group 매핑: ${screenGroupIdMap.size}/${sourceGroupIds.length}개`);
|
||||
}
|
||||
|
||||
// 위상 정렬 (부모 먼저 삽입)
|
||||
const sortedMenus = this.topologicalSortMenus(menus);
|
||||
|
||||
|
|
@ -2252,7 +2282,7 @@ export class MenuCopyService {
|
|||
menu.menu_code,
|
||||
sourceMenuObjid,
|
||||
menu.menu_icon,
|
||||
menu.screen_group_id,
|
||||
menu.screen_group_id ? (screenGroupIdMap.get(menu.screen_group_id) || menu.screen_group_id) : null,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
@ -2500,6 +2530,82 @@ export class MenuCopyService {
|
|||
logger.info(`✅ 메뉴 URL 업데이트: ${updatedUrlCount}개, screen_code 업데이트: ${updatedCodeCount}개`);
|
||||
}
|
||||
|
||||
/**
|
||||
* screen_group_screens 복제 (화면-스크린그룹 매핑)
|
||||
*/
|
||||
private async copyScreenGroupScreens(
|
||||
screenIds: Set<number>,
|
||||
screenIdMap: Map<number, number>,
|
||||
sourceCompanyCode: string,
|
||||
targetCompanyCode: string,
|
||||
client: PoolClient
|
||||
): Promise<void> {
|
||||
if (screenIds.size === 0 || screenIdMap.size === 0) {
|
||||
logger.info("📭 screen_group_screens 복제 대상 없음");
|
||||
return;
|
||||
}
|
||||
|
||||
// 기존 COMPANY_10의 screen_group_screens 삭제 (깨진 이전 데이터 정리)
|
||||
await client.query(
|
||||
`DELETE FROM screen_group_screens WHERE company_code = $1`,
|
||||
[targetCompanyCode]
|
||||
);
|
||||
|
||||
// 소스 회사의 screen_group_screens 조회
|
||||
const sourceScreenIds = Array.from(screenIds);
|
||||
const sourceResult = await client.query<{
|
||||
group_id: number;
|
||||
screen_id: number;
|
||||
screen_role: string;
|
||||
display_order: number;
|
||||
is_default: string;
|
||||
}>(
|
||||
`SELECT group_id, screen_id, screen_role, display_order, is_default
|
||||
FROM screen_group_screens
|
||||
WHERE company_code = $1 AND screen_id = ANY($2)`,
|
||||
[sourceCompanyCode, sourceScreenIds]
|
||||
);
|
||||
|
||||
if (sourceResult.rows.length === 0) {
|
||||
logger.info("📭 소스에 screen_group_screens 없음");
|
||||
return;
|
||||
}
|
||||
|
||||
// screen_group ID 매핑 (source group_name → target group_id)
|
||||
const sourceGroupIds = [...new Set(sourceResult.rows.map(r => r.group_id))];
|
||||
const sourceGroups = await client.query<{ id: number; group_name: string }>(
|
||||
`SELECT id, group_name FROM screen_groups WHERE id = ANY($1)`,
|
||||
[sourceGroupIds]
|
||||
);
|
||||
const groupIdMap = new Map<number, number>();
|
||||
for (const sg of sourceGroups.rows) {
|
||||
const targetGroup = await client.query<{ id: number }>(
|
||||
`SELECT id FROM screen_groups WHERE group_name = $1 AND company_code = $2 LIMIT 1`,
|
||||
[sg.group_name, targetCompanyCode]
|
||||
);
|
||||
if (targetGroup.rows.length > 0) {
|
||||
groupIdMap.set(sg.id, targetGroup.rows[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
let insertedCount = 0;
|
||||
for (const row of sourceResult.rows) {
|
||||
const newGroupId = groupIdMap.get(row.group_id);
|
||||
const newScreenId = screenIdMap.get(row.screen_id);
|
||||
if (!newGroupId || !newScreenId) continue;
|
||||
|
||||
await client.query(
|
||||
`INSERT INTO screen_group_screens (group_id, screen_id, screen_role, display_order, is_default, company_code, writer)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, 'system')
|
||||
ON CONFLICT DO NOTHING`,
|
||||
[newGroupId, newScreenId, row.screen_role, row.display_order, row.is_default, targetCompanyCode]
|
||||
);
|
||||
insertedCount++;
|
||||
}
|
||||
|
||||
logger.info(`✅ screen_group_screens 복제: ${insertedCount}개`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 코드 카테고리 + 코드 복사 (최적화: 배치 조회/삽입)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue