feat(pop): POP 화면 복사 기능 구현 (단일 화면 + 카테고리 일괄 복사)
최고관리자의 POP 화면을 다른 회사로 복사하는 기능 추가. 화면 단위 복사와 카테고리(그룹) 단위 일괄 복사를 모두 지원하며, 화면 간 참조(cartScreenId, sourceScreenId 등)를 자동 치환하고 카테고리 구조까지 대상 회사에 재생성한다. [백엔드] - analyzePopScreenLinks: POP 레이아웃 내 다른 화면 참조 스캔 - deployPopScreens: screen_definitions + screen_layouts_pop 복사, screenId 참조 치환, numberingRuleId 초기화, 그룹 구조 복사 - POP 그룹 조회 쿼리 개선 (screen_layouts_pop JOIN으로 실제 POP 화면만 카운트) - ensurePopRootGroup 최고관리자 전용으로 변경 [프론트엔드] - PopDeployModal: 단일 화면/카테고리 일괄 복사 모달 (대상 회사 선택, 연결 화면 감지, 카테고리 트리 미리보기) - PopCategoryTree: 그룹 컨텍스트 메뉴에 '카테고리 복사' 추가, 하위 그룹 화면까지 재귀 수집 - PopScreenSettingModal: UI 간소화 및 화면명 저장 기능 보완 - screenApi: analyzePopScreenLinks, deployPopScreens 클라이언트 함수 추가
This commit is contained in:
@@ -1237,3 +1237,82 @@ export const copyCascadingRelation = async (
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// POP 화면 연결 분석
|
||||
export const analyzePopScreenLinks = async (
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { screenId } = req.params;
|
||||
const { companyCode } = req.user as any;
|
||||
|
||||
const result = await screenManagementService.analyzePopScreenLinks(
|
||||
parseInt(screenId),
|
||||
companyCode,
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (error: any) {
|
||||
console.error("POP 화면 연결 분석 실패:", error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || "POP 화면 연결 분석에 실패했습니다.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// POP 화면 배포 (다른 회사로 복사)
|
||||
export const deployPopScreens = async (
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { screens, targetCompanyCode, groupStructure } = req.body;
|
||||
const { companyCode, userId } = req.user as any;
|
||||
|
||||
if (!screens || !Array.isArray(screens) || screens.length === 0) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "배포할 화면 목록이 필요합니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!targetCompanyCode) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "대상 회사 코드가 필요합니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (companyCode !== "*") {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "최고 관리자만 POP 화면을 배포할 수 있습니다.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await screenManagementService.deployPopScreens({
|
||||
screens,
|
||||
groupStructure: groupStructure || undefined,
|
||||
targetCompanyCode,
|
||||
companyCode,
|
||||
userId,
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result,
|
||||
message: `POP 화면 ${result.deployedScreens.length}개가 ${targetCompanyCode}에 배포되었습니다.`,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error("POP 화면 배포 실패:", error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || "POP 화면 배포에 실패했습니다.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user