Merge branch 'feature/v2-renewal' of http://39.117.244.52:3000/kjs/ERP-node into feature/v2-unified-renewal
This commit is contained in:
@@ -1461,11 +1461,8 @@ async function cleanupMenuRelatedData(menuObjid: number): Promise<void> {
|
||||
[menuObjid]
|
||||
);
|
||||
|
||||
// 4. numbering_rules에서 menu_objid를 NULL로 설정
|
||||
await query(
|
||||
`UPDATE numbering_rules SET menu_objid = NULL WHERE menu_objid = $1`,
|
||||
[menuObjid]
|
||||
);
|
||||
// 4. numbering_rules: 새 스키마에서는 메뉴와 연결되지 않음 (스킵)
|
||||
// 새 스키마: table_name + column_name + company_code 기반
|
||||
|
||||
// 5. rel_menu_auth에서 관련 권한 삭제
|
||||
await query(
|
||||
|
||||
@@ -344,13 +344,65 @@ export const deleteScreenGroup = async (req: AuthenticatedRequest, res: Response
|
||||
childGroupIds: groupIdsToDelete
|
||||
});
|
||||
|
||||
// 2. menu_info에서 삭제될 screen_group 참조를 NULL로 정리
|
||||
// 2. 삭제될 그룹에 연결된 메뉴 정리
|
||||
if (groupIdsToDelete.length > 0) {
|
||||
await client.query(`
|
||||
UPDATE menu_info
|
||||
SET screen_group_id = NULL
|
||||
// 2-1. 삭제할 메뉴 objid 수집
|
||||
const menusToDelete = await client.query(`
|
||||
SELECT objid FROM menu_info
|
||||
WHERE screen_group_id = ANY($1::int[])
|
||||
`, [groupIdsToDelete]);
|
||||
AND company_code = $2
|
||||
`, [groupIdsToDelete, targetCompanyCode]);
|
||||
const menuObjids = menusToDelete.rows.map((r: any) => r.objid);
|
||||
|
||||
if (menuObjids.length > 0) {
|
||||
// 2-2. screen_menu_assignments에서 해당 메뉴 관련 데이터 삭제
|
||||
await client.query(`
|
||||
DELETE FROM screen_menu_assignments
|
||||
WHERE menu_objid = ANY($1::bigint[])
|
||||
AND company_code = $2
|
||||
`, [menuObjids, targetCompanyCode]);
|
||||
|
||||
// 2-3. menu_info에서 해당 메뉴 삭제
|
||||
await client.query(`
|
||||
DELETE FROM menu_info
|
||||
WHERE screen_group_id = ANY($1::int[])
|
||||
AND company_code = $2
|
||||
`, [groupIdsToDelete, targetCompanyCode]);
|
||||
|
||||
logger.info("그룹 삭제 시 연결된 메뉴 삭제", {
|
||||
groupIds: groupIdsToDelete,
|
||||
deletedMenuCount: menuObjids.length,
|
||||
companyCode: targetCompanyCode
|
||||
});
|
||||
}
|
||||
|
||||
// 2-4. 해당 회사의 채번 규칙 삭제 (최상위 그룹 삭제 시)
|
||||
// 삭제되는 그룹이 최상위인지 확인
|
||||
const isRootGroup = await client.query(
|
||||
`SELECT 1 FROM screen_groups WHERE id = $1 AND parent_group_id IS NULL`,
|
||||
[id]
|
||||
);
|
||||
|
||||
if (isRootGroup.rows.length > 0) {
|
||||
// 최상위 그룹 삭제 시 해당 회사의 채번 규칙도 삭제
|
||||
// 먼저 파트 삭제
|
||||
await client.query(
|
||||
`DELETE FROM numbering_rule_parts
|
||||
WHERE rule_id IN (SELECT rule_id FROM numbering_rules WHERE company_code = $1)`,
|
||||
[targetCompanyCode]
|
||||
);
|
||||
// 규칙 삭제
|
||||
const deletedRules = await client.query(
|
||||
`DELETE FROM numbering_rules WHERE company_code = $1 RETURNING rule_id`,
|
||||
[targetCompanyCode]
|
||||
);
|
||||
if (deletedRules.rowCount && deletedRules.rowCount > 0) {
|
||||
logger.info("그룹 삭제 시 채번 규칙 삭제", {
|
||||
companyCode: targetCompanyCode,
|
||||
deletedCount: deletedRules.rowCount
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. screen_groups 삭제 (해당 그룹만 - 하위 그룹은 프론트엔드에서 순차 삭제)
|
||||
|
||||
@@ -557,7 +557,16 @@ export async function updateColumnInputType(
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { tableName, columnName } = req.params;
|
||||
const { inputType, detailSettings } = req.body;
|
||||
let { inputType, detailSettings } = req.body;
|
||||
|
||||
// 🔥 "direct" 또는 "auto"는 프론트엔드의 입력 방식 구분값이므로
|
||||
// DB의 input_type(웹타입)으로 저장하면 안 됨 - "text"로 변환
|
||||
if (inputType === "direct" || inputType === "auto") {
|
||||
logger.warn(
|
||||
`잘못된 inputType 값 감지: ${inputType} → 'text'로 변환 (${tableName}.${columnName})`
|
||||
);
|
||||
inputType = "text";
|
||||
}
|
||||
|
||||
// 🔥 회사 코드 추출 (JWT에서 또는 DB에서 조회)
|
||||
let companyCode = req.user?.companyCode;
|
||||
@@ -1360,8 +1369,17 @@ export async function updateColumnWebType(
|
||||
`레거시 API 사용: updateColumnWebType → updateColumnInputType 사용 권장`
|
||||
);
|
||||
|
||||
// webType을 inputType으로 변환
|
||||
const convertedInputType = inputType || webType || "text";
|
||||
// 🔥 inputType이 "direct" 또는 "auto"이면 무시하고 webType 사용
|
||||
// "direct"/"auto"는 프론트엔드의 입력 방식(직접입력/자동입력) 구분값이지
|
||||
// DB에 저장할 웹 타입(text, number, date 등)이 아님
|
||||
let convertedInputType = webType || "text";
|
||||
if (inputType && inputType !== "direct" && inputType !== "auto") {
|
||||
convertedInputType = inputType;
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`웹타입 변환: webType=${webType}, inputType=${inputType} → ${convertedInputType}`
|
||||
);
|
||||
|
||||
// 새로운 메서드 호출
|
||||
req.body = { inputType: convertedInputType, detailSettings };
|
||||
|
||||
Reference in New Issue
Block a user