Merge branch 'ksh-v2-work' into main
POP 화면 관리 기능 일괄 병합: - POP 컴포넌트 연결/상태변경 규칙/후속 액션 - POP 장바구니(CartList) 모드 + 멀티필드 입력 - POP 화면 복사 기능 (단일 + 카테고리 일괄) - POP 화면관리 UX 개선 (스크롤/접기) - PC/POP 화면 데이터 분리 (excludePop 필터) - .gitignore 미사용 항목 정리 충돌 1건 해결 (screenManagementRoutes.ts import 양쪽 통합)
This commit is contained in:
@@ -108,42 +108,49 @@ export class ScreenManagementService {
|
||||
companyCode: string,
|
||||
page: number = 1,
|
||||
size: number = 20,
|
||||
searchTerm?: string, // 검색어 추가
|
||||
searchTerm?: string,
|
||||
options?: { excludePop?: boolean },
|
||||
): Promise<PaginatedResponse<ScreenDefinition>> {
|
||||
const offset = (page - 1) * size;
|
||||
|
||||
// WHERE 절 동적 생성
|
||||
const whereConditions: string[] = ["is_active != 'D'"];
|
||||
const whereConditions: string[] = ["sd.is_active != 'D'"];
|
||||
const params: any[] = [];
|
||||
|
||||
if (companyCode !== "*") {
|
||||
whereConditions.push(`company_code = $${params.length + 1}`);
|
||||
whereConditions.push(`sd.company_code = $${params.length + 1}`);
|
||||
params.push(companyCode);
|
||||
}
|
||||
|
||||
// 검색어 필터링 추가 (화면명, 화면 코드, 테이블명 검색)
|
||||
if (searchTerm && searchTerm.trim() !== "") {
|
||||
whereConditions.push(`(
|
||||
screen_name ILIKE $${params.length + 1} OR
|
||||
screen_code ILIKE $${params.length + 1} OR
|
||||
table_name ILIKE $${params.length + 1}
|
||||
sd.screen_name ILIKE $${params.length + 1} OR
|
||||
sd.screen_code ILIKE $${params.length + 1} OR
|
||||
sd.table_name ILIKE $${params.length + 1}
|
||||
)`);
|
||||
params.push(`%${searchTerm.trim()}%`);
|
||||
}
|
||||
|
||||
// POP 화면 제외 필터: screen_layouts_pop에 레이아웃이 있는 화면 제외
|
||||
if (options?.excludePop) {
|
||||
whereConditions.push(
|
||||
`NOT EXISTS (SELECT 1 FROM screen_layouts_pop slp WHERE slp.screen_id = sd.screen_id)`
|
||||
);
|
||||
}
|
||||
|
||||
const whereSQL = whereConditions.join(" AND ");
|
||||
|
||||
// 페이징 쿼리 (Raw Query)
|
||||
const [screens, totalResult] = await Promise.all([
|
||||
query<any>(
|
||||
`SELECT * FROM screen_definitions
|
||||
`SELECT sd.* FROM screen_definitions sd
|
||||
WHERE ${whereSQL}
|
||||
ORDER BY created_date DESC
|
||||
ORDER BY sd.created_date DESC
|
||||
LIMIT $${params.length + 1} OFFSET $${params.length + 2}`,
|
||||
[...params, size, offset],
|
||||
),
|
||||
query<{ count: string }>(
|
||||
`SELECT COUNT(*)::text as count FROM screen_definitions
|
||||
`SELECT COUNT(*)::text as count FROM screen_definitions sd
|
||||
WHERE ${whereSQL}`,
|
||||
params,
|
||||
),
|
||||
@@ -5814,28 +5821,24 @@ export class ScreenManagementService {
|
||||
async getScreenIdsWithPopLayout(
|
||||
companyCode: string,
|
||||
): Promise<number[]> {
|
||||
console.log(`=== POP 레이아웃 존재 화면 ID 조회 ===`);
|
||||
console.log(`회사 코드: ${companyCode}`);
|
||||
|
||||
let result: { screen_id: number }[];
|
||||
|
||||
if (companyCode === "*") {
|
||||
// 최고 관리자: 모든 POP 레이아웃 조회
|
||||
result = await query<{ screen_id: number }>(
|
||||
`SELECT DISTINCT screen_id FROM screen_layouts_pop`,
|
||||
[],
|
||||
);
|
||||
} else {
|
||||
// 일반 회사: 해당 회사 또는 공통(*) 레이아웃 조회
|
||||
// 일반 회사: 해당 회사 레이아웃만 조회 (company_code='*'는 최고관리자 전용)
|
||||
result = await query<{ screen_id: number }>(
|
||||
`SELECT DISTINCT screen_id FROM screen_layouts_pop
|
||||
WHERE company_code = $1 OR company_code = '*'`,
|
||||
WHERE company_code = $1`,
|
||||
[companyCode],
|
||||
);
|
||||
}
|
||||
|
||||
const screenIds = result.map((r) => r.screen_id);
|
||||
console.log(`POP 레이아웃 존재 화면 수: ${screenIds.length}개`);
|
||||
logger.info("POP 레이아웃 존재 화면 ID 조회", { companyCode, count: screenIds.length });
|
||||
return screenIds;
|
||||
}
|
||||
|
||||
@@ -5873,6 +5876,512 @@ export class ScreenManagementService {
|
||||
console.log(`POP 레이아웃 삭제 완료`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// POP 화면 배포 (다른 회사로 복사)
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* POP layout_data 내 다른 화면 참조를 스캔하여 연결 관계 분석
|
||||
*/
|
||||
async analyzePopScreenLinks(
|
||||
screenId: number,
|
||||
companyCode: string,
|
||||
): Promise<{
|
||||
linkedScreenIds: number[];
|
||||
references: Array<{
|
||||
componentId: string;
|
||||
referenceType: string;
|
||||
targetScreenId: number;
|
||||
}>;
|
||||
}> {
|
||||
const layoutResult = await queryOne<{ layout_data: any }>(
|
||||
`SELECT layout_data FROM screen_layouts_pop
|
||||
WHERE screen_id = $1 AND company_code = $2`,
|
||||
[screenId, companyCode],
|
||||
);
|
||||
|
||||
if (!layoutResult?.layout_data) {
|
||||
return { linkedScreenIds: [], references: [] };
|
||||
}
|
||||
|
||||
const layoutData = layoutResult.layout_data;
|
||||
const references: Array<{
|
||||
componentId: string;
|
||||
referenceType: string;
|
||||
targetScreenId: number;
|
||||
}> = [];
|
||||
|
||||
const scanComponents = (components: Record<string, any>) => {
|
||||
for (const [compId, comp] of Object.entries(components)) {
|
||||
const config = (comp as any).config || {};
|
||||
|
||||
if (config.cart?.cartScreenId) {
|
||||
const sid = parseInt(config.cart.cartScreenId);
|
||||
if (!isNaN(sid) && sid !== screenId) {
|
||||
references.push({
|
||||
componentId: compId,
|
||||
referenceType: "cartScreenId",
|
||||
targetScreenId: sid,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (config.cartListMode?.sourceScreenId) {
|
||||
const sid =
|
||||
typeof config.cartListMode.sourceScreenId === "number"
|
||||
? config.cartListMode.sourceScreenId
|
||||
: parseInt(config.cartListMode.sourceScreenId);
|
||||
if (!isNaN(sid) && sid !== screenId) {
|
||||
references.push({
|
||||
componentId: compId,
|
||||
referenceType: "sourceScreenId",
|
||||
targetScreenId: sid,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(config.followUpActions)) {
|
||||
for (const action of config.followUpActions) {
|
||||
if (action.targetScreenId) {
|
||||
const sid = parseInt(action.targetScreenId);
|
||||
if (!isNaN(sid) && sid !== screenId) {
|
||||
references.push({
|
||||
componentId: compId,
|
||||
referenceType: "targetScreenId",
|
||||
targetScreenId: sid,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.action?.modalScreenId) {
|
||||
const sid = parseInt(config.action.modalScreenId);
|
||||
if (!isNaN(sid) && sid !== screenId) {
|
||||
references.push({
|
||||
componentId: compId,
|
||||
referenceType: "modalScreenId",
|
||||
targetScreenId: sid,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (layoutData.components) {
|
||||
scanComponents(layoutData.components);
|
||||
}
|
||||
|
||||
if (Array.isArray(layoutData.modals)) {
|
||||
for (const modal of layoutData.modals) {
|
||||
if (modal.components) {
|
||||
scanComponents(modal.components);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const linkedScreenIds = [
|
||||
...new Set(references.map((r) => r.targetScreenId)),
|
||||
];
|
||||
|
||||
return { linkedScreenIds, references };
|
||||
}
|
||||
|
||||
/**
|
||||
* POP 화면 배포 (최고관리자 화면을 특정 회사로 복사)
|
||||
* - screen_definitions + screen_layouts_pop 복사
|
||||
* - 화면 간 참조(cartScreenId, sourceScreenId 등) 자동 치환
|
||||
* - numberingRuleId 초기화
|
||||
*/
|
||||
async deployPopScreens(data: {
|
||||
screens: Array<{
|
||||
sourceScreenId: number;
|
||||
screenName: string;
|
||||
screenCode: string;
|
||||
}>;
|
||||
groupStructure?: {
|
||||
sourceGroupId: number;
|
||||
groupName: string;
|
||||
groupCode: string;
|
||||
children?: Array<{
|
||||
sourceGroupId: number;
|
||||
groupName: string;
|
||||
groupCode: string;
|
||||
screenIds: number[];
|
||||
}>;
|
||||
screenIds: number[];
|
||||
};
|
||||
targetCompanyCode: string;
|
||||
companyCode: string;
|
||||
userId: string;
|
||||
}): Promise<{
|
||||
deployedScreens: Array<{
|
||||
sourceScreenId: number;
|
||||
newScreenId: number;
|
||||
screenName: string;
|
||||
screenCode: string;
|
||||
}>;
|
||||
createdGroups?: number;
|
||||
}> {
|
||||
if (data.companyCode !== "*") {
|
||||
throw new Error("최고 관리자만 POP 화면을 배포할 수 있습니다.");
|
||||
}
|
||||
|
||||
return await transaction(async (client) => {
|
||||
const screenIdMap = new Map<number, number>();
|
||||
const deployedScreens: Array<{
|
||||
sourceScreenId: number;
|
||||
newScreenId: number;
|
||||
screenName: string;
|
||||
screenCode: string;
|
||||
}> = [];
|
||||
|
||||
// 1단계: screen_definitions 복사
|
||||
for (const screen of data.screens) {
|
||||
const sourceResult = await client.query<any>(
|
||||
`SELECT * FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
|
||||
[screen.sourceScreenId],
|
||||
);
|
||||
|
||||
if (sourceResult.rows.length === 0) {
|
||||
throw new Error(
|
||||
`원본 화면(ID: ${screen.sourceScreenId})을 찾을 수 없습니다.`,
|
||||
);
|
||||
}
|
||||
|
||||
const sourceScreen = sourceResult.rows[0];
|
||||
|
||||
const existingResult = await client.query<any>(
|
||||
`SELECT screen_id FROM screen_definitions
|
||||
WHERE screen_code = $1 AND company_code = $2 AND deleted_date IS NULL
|
||||
LIMIT 1`,
|
||||
[screen.screenCode, data.targetCompanyCode],
|
||||
);
|
||||
|
||||
if (existingResult.rows.length > 0) {
|
||||
throw new Error(
|
||||
`화면 코드 "${screen.screenCode}"가 대상 회사에 이미 존재합니다.`,
|
||||
);
|
||||
}
|
||||
|
||||
const newScreenResult = await client.query<any>(
|
||||
`INSERT INTO screen_definitions (
|
||||
screen_code, screen_name, description, company_code, table_name,
|
||||
is_active, created_by, created_date, updated_by, updated_date
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $7, NOW())
|
||||
RETURNING *`,
|
||||
[
|
||||
screen.screenCode,
|
||||
screen.screenName,
|
||||
sourceScreen.description,
|
||||
data.targetCompanyCode,
|
||||
sourceScreen.table_name,
|
||||
"Y",
|
||||
data.userId,
|
||||
],
|
||||
);
|
||||
|
||||
const newScreen = newScreenResult.rows[0];
|
||||
screenIdMap.set(screen.sourceScreenId, newScreen.screen_id);
|
||||
|
||||
deployedScreens.push({
|
||||
sourceScreenId: screen.sourceScreenId,
|
||||
newScreenId: newScreen.screen_id,
|
||||
screenName: screen.screenName,
|
||||
screenCode: screen.screenCode,
|
||||
});
|
||||
|
||||
logger.info("POP 화면 배포 - screen_definitions 생성", {
|
||||
sourceScreenId: screen.sourceScreenId,
|
||||
newScreenId: newScreen.screen_id,
|
||||
targetCompanyCode: data.targetCompanyCode,
|
||||
});
|
||||
}
|
||||
|
||||
// 2단계: screen_layouts_pop 복사 + 참조 치환
|
||||
for (const screen of data.screens) {
|
||||
const newScreenId = screenIdMap.get(screen.sourceScreenId);
|
||||
if (!newScreenId) continue;
|
||||
|
||||
// 원본 POP 레이아웃 조회 (company_code = '*' 우선, fallback)
|
||||
let layoutResult = await client.query<{ layout_data: any }>(
|
||||
`SELECT layout_data FROM screen_layouts_pop
|
||||
WHERE screen_id = $1 AND company_code = '*'`,
|
||||
[screen.sourceScreenId],
|
||||
);
|
||||
|
||||
let layoutData = layoutResult.rows[0]?.layout_data;
|
||||
if (!layoutData) {
|
||||
const fallbackResult = await client.query<{ layout_data: any }>(
|
||||
`SELECT layout_data FROM screen_layouts_pop
|
||||
WHERE screen_id = $1 LIMIT 1`,
|
||||
[screen.sourceScreenId],
|
||||
);
|
||||
layoutData = fallbackResult.rows[0]?.layout_data;
|
||||
}
|
||||
|
||||
if (!layoutData) {
|
||||
logger.warn("POP 레이아웃 없음, 건너뜀", {
|
||||
sourceScreenId: screen.sourceScreenId,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const updatedLayoutData = this.updatePopLayoutScreenReferences(
|
||||
JSON.parse(JSON.stringify(layoutData)),
|
||||
screenIdMap,
|
||||
);
|
||||
|
||||
await client.query(
|
||||
`INSERT INTO screen_layouts_pop (screen_id, company_code, layout_data, created_at, updated_at, created_by, updated_by)
|
||||
VALUES ($1, $2, $3, NOW(), NOW(), $4, $4)
|
||||
ON CONFLICT (screen_id, company_code)
|
||||
DO UPDATE SET layout_data = $3, updated_at = NOW(), updated_by = $4`,
|
||||
[
|
||||
newScreenId,
|
||||
data.targetCompanyCode,
|
||||
JSON.stringify(updatedLayoutData),
|
||||
data.userId,
|
||||
],
|
||||
);
|
||||
|
||||
logger.info("POP 레이아웃 복사 완료", {
|
||||
sourceScreenId: screen.sourceScreenId,
|
||||
newScreenId,
|
||||
componentCount: Object.keys(updatedLayoutData.components || {})
|
||||
.length,
|
||||
});
|
||||
}
|
||||
|
||||
// 3단계: 그룹 구조 복사 (groupStructure가 있는 경우)
|
||||
let createdGroups = 0;
|
||||
if (data.groupStructure) {
|
||||
const gs = data.groupStructure;
|
||||
|
||||
// 대상 회사의 POP 루트 그룹 찾기/생성
|
||||
let popRootResult = await client.query<any>(
|
||||
`SELECT id FROM screen_groups
|
||||
WHERE hierarchy_path = 'POP' AND company_code = $1 LIMIT 1`,
|
||||
[data.targetCompanyCode],
|
||||
);
|
||||
|
||||
let popRootId: number;
|
||||
if (popRootResult.rows.length > 0) {
|
||||
popRootId = popRootResult.rows[0].id;
|
||||
} else {
|
||||
const createRootResult = await client.query<any>(
|
||||
`INSERT INTO screen_groups (group_name, group_code, hierarchy_path, company_code, writer, is_active, display_order)
|
||||
VALUES ('POP 화면', 'POP_ROOT', 'POP', $1, $2, 'Y', 0) RETURNING id`,
|
||||
[data.targetCompanyCode, data.userId],
|
||||
);
|
||||
popRootId = createRootResult.rows[0].id;
|
||||
}
|
||||
|
||||
// 메인 그룹 생성 (중복 코드 방지: _COPY 접미사 추가)
|
||||
const mainGroupCode = gs.groupCode + "_COPY";
|
||||
const dupCheck = await client.query<any>(
|
||||
`SELECT id FROM screen_groups WHERE group_code = $1 AND company_code = $2`,
|
||||
[mainGroupCode, data.targetCompanyCode],
|
||||
);
|
||||
|
||||
let mainGroupId: number;
|
||||
if (dupCheck.rows.length > 0) {
|
||||
mainGroupId = dupCheck.rows[0].id;
|
||||
} else {
|
||||
const mainGroupResult = await client.query<any>(
|
||||
`INSERT INTO screen_groups (group_name, group_code, hierarchy_path, company_code, parent_group_id, writer, is_active, display_order)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, 'Y', 0) RETURNING id`,
|
||||
[
|
||||
gs.groupName,
|
||||
mainGroupCode,
|
||||
`POP/${mainGroupCode}`,
|
||||
data.targetCompanyCode,
|
||||
popRootId,
|
||||
data.userId,
|
||||
],
|
||||
);
|
||||
mainGroupId = mainGroupResult.rows[0].id;
|
||||
createdGroups++;
|
||||
}
|
||||
|
||||
// 메인 그룹에 화면 연결
|
||||
for (const oldScreenId of gs.screenIds) {
|
||||
const newScreenId = screenIdMap.get(oldScreenId);
|
||||
if (!newScreenId) continue;
|
||||
await client.query(
|
||||
`INSERT INTO screen_group_screens (group_id, screen_id, screen_role, display_order, is_default, company_code)
|
||||
VALUES ($1, $2, 'main', 0, 'N', $3)
|
||||
ON CONFLICT DO NOTHING`,
|
||||
[mainGroupId, newScreenId, data.targetCompanyCode],
|
||||
);
|
||||
}
|
||||
|
||||
// 하위 그룹 생성 + 화면 연결
|
||||
if (gs.children) {
|
||||
for (let i = 0; i < gs.children.length; i++) {
|
||||
const child = gs.children[i];
|
||||
const childGroupCode = child.groupCode + "_COPY";
|
||||
|
||||
const childDupCheck = await client.query<any>(
|
||||
`SELECT id FROM screen_groups WHERE group_code = $1 AND company_code = $2`,
|
||||
[childGroupCode, data.targetCompanyCode],
|
||||
);
|
||||
|
||||
let childGroupId: number;
|
||||
if (childDupCheck.rows.length > 0) {
|
||||
childGroupId = childDupCheck.rows[0].id;
|
||||
} else {
|
||||
const childResult = await client.query<any>(
|
||||
`INSERT INTO screen_groups (group_name, group_code, hierarchy_path, company_code, parent_group_id, writer, is_active, display_order)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, 'Y', $7) RETURNING id`,
|
||||
[
|
||||
child.groupName,
|
||||
childGroupCode,
|
||||
`POP/${mainGroupCode}/${childGroupCode}`,
|
||||
data.targetCompanyCode,
|
||||
mainGroupId,
|
||||
data.userId,
|
||||
i,
|
||||
],
|
||||
);
|
||||
childGroupId = childResult.rows[0].id;
|
||||
createdGroups++;
|
||||
}
|
||||
|
||||
for (const oldScreenId of child.screenIds) {
|
||||
const newScreenId = screenIdMap.get(oldScreenId);
|
||||
if (!newScreenId) continue;
|
||||
await client.query(
|
||||
`INSERT INTO screen_group_screens (group_id, screen_id, screen_role, display_order, is_default, company_code)
|
||||
VALUES ($1, $2, 'main', 0, 'N', $3)
|
||||
ON CONFLICT DO NOTHING`,
|
||||
[childGroupId, newScreenId, data.targetCompanyCode],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("POP 그룹 구조 복사 완료", {
|
||||
targetCompanyCode: data.targetCompanyCode,
|
||||
createdGroups,
|
||||
mainGroupName: gs.groupName,
|
||||
});
|
||||
}
|
||||
|
||||
return { deployedScreens, createdGroups };
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* POP layout_data 내 screen_id 참조 치환
|
||||
* componentId, connectionId는 레이아웃 내부 식별자이므로 변경 불필요
|
||||
*/
|
||||
private updatePopLayoutScreenReferences(
|
||||
layoutData: any,
|
||||
screenIdMap: Map<number, number>,
|
||||
): any {
|
||||
if (!layoutData?.components) return layoutData;
|
||||
|
||||
const updateComponents = (
|
||||
components: Record<string, any>,
|
||||
): Record<string, any> => {
|
||||
const updated: Record<string, any> = {};
|
||||
|
||||
for (const [compId, comp] of Object.entries(components)) {
|
||||
const updatedComp = JSON.parse(JSON.stringify(comp));
|
||||
const config = updatedComp.config || {};
|
||||
|
||||
// cart.cartScreenId (string)
|
||||
if (config.cart?.cartScreenId) {
|
||||
const oldId = parseInt(config.cart.cartScreenId);
|
||||
const newId = screenIdMap.get(oldId);
|
||||
if (newId) {
|
||||
config.cart.cartScreenId = String(newId);
|
||||
logger.info(`POP 참조 치환: cartScreenId ${oldId} -> ${newId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// cartListMode.sourceScreenId (number)
|
||||
if (config.cartListMode?.sourceScreenId) {
|
||||
const oldId =
|
||||
typeof config.cartListMode.sourceScreenId === "number"
|
||||
? config.cartListMode.sourceScreenId
|
||||
: parseInt(config.cartListMode.sourceScreenId);
|
||||
const newId = screenIdMap.get(oldId);
|
||||
if (newId) {
|
||||
config.cartListMode.sourceScreenId = newId;
|
||||
logger.info(
|
||||
`POP 참조 치환: sourceScreenId ${oldId} -> ${newId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// followUpActions[].targetScreenId (string)
|
||||
if (Array.isArray(config.followUpActions)) {
|
||||
for (const action of config.followUpActions) {
|
||||
if (action.targetScreenId) {
|
||||
const oldId = parseInt(action.targetScreenId);
|
||||
const newId = screenIdMap.get(oldId);
|
||||
if (newId) {
|
||||
action.targetScreenId = String(newId);
|
||||
logger.info(
|
||||
`POP 참조 치환: targetScreenId ${oldId} -> ${newId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// action.modalScreenId (숫자형이면 화면 참조로 간주)
|
||||
if (config.action?.modalScreenId) {
|
||||
const oldId = parseInt(config.action.modalScreenId);
|
||||
if (!isNaN(oldId)) {
|
||||
const newId = screenIdMap.get(oldId);
|
||||
if (newId) {
|
||||
config.action.modalScreenId = String(newId);
|
||||
logger.info(
|
||||
`POP 참조 치환: modalScreenId ${oldId} -> ${newId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// numberingRuleId 초기화 (배포 후 대상 회사에서 재설정 필요)
|
||||
if (config.numberingRuleId) {
|
||||
logger.info(`POP 채번규칙 초기화: ${config.numberingRuleId}`);
|
||||
config.numberingRuleId = "";
|
||||
}
|
||||
if (config.autoGenMappings) {
|
||||
for (const mapping of Object.values(config.autoGenMappings) as any[]) {
|
||||
if (mapping?.numberingRuleId) {
|
||||
logger.info(
|
||||
`POP 채번규칙 초기화: ${mapping.numberingRuleId}`,
|
||||
);
|
||||
mapping.numberingRuleId = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatedComp.config = config;
|
||||
updated[compId] = updatedComp;
|
||||
}
|
||||
|
||||
return updated;
|
||||
};
|
||||
|
||||
layoutData.components = updateComponents(layoutData.components);
|
||||
|
||||
if (Array.isArray(layoutData.modals)) {
|
||||
for (const modal of layoutData.modals) {
|
||||
if (modal.components) {
|
||||
modal.components = updateComponents(modal.components);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return layoutData;
|
||||
}
|
||||
}
|
||||
|
||||
// 서비스 인스턴스 export
|
||||
|
||||
Reference in New Issue
Block a user