From 6ce9a6e26fea92f82ab26cf4bb0837f170162dd0 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 30 May 2025 02:24:07 +0000 Subject: (최겸) 기술영업 아이템리스트 isEmpty, isNotEmpty 처리 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/items-tech/service.ts | 209 +++++++++++----------------------------------- 1 file changed, 48 insertions(+), 161 deletions(-) (limited to 'lib') diff --git a/lib/items-tech/service.ts b/lib/items-tech/service.ts index 6047552f..be985adb 100644 --- a/lib/items-tech/service.ts +++ b/lib/items-tech/service.ts @@ -32,7 +32,11 @@ export async function getShipbuildingItems(input: GetShipbuildingSchema) { // advancedTable 모드면 filterColumns()로 where 절 구성 const advancedWhere = filterColumns({ table: items, - filters: input.filters, + filters: input.filters.filter(filter => { + // enum 필드에 대한 isEmpty/isNotEmpty는 제외 + return !((filter.id === 'workType' || filter.id === 'shipTypes') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + }), joinOperator: input.joinOperator, joinedTables: { itemShipbuilding }, customColumnMapping: { @@ -51,9 +55,19 @@ export async function getShipbuildingItems(input: GetShipbuildingSchema) { ); } + // enum 필드에 대한 isEmpty/isNotEmpty 처리 + const enumConditions = input.filters + .filter(filter => (filter.id === 'workType' || filter.id === 'shipTypes') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + .map(filter => { + const column = itemShipbuilding[filter.id]; + return filter.operator === 'isEmpty' ? sql`${column} is null` : sql`${column} is not null`; + }); + const finalWhere = and( advancedWhere, - globalWhere + globalWhere, + ...enumConditions ); const where = finalWhere; @@ -120,7 +134,11 @@ export async function getOffshoreTopItems(input: GetOffshoreTopSchema) { // advancedTable 모드면 filterColumns()로 where 절 구성 const advancedWhere = filterColumns({ table: items, - filters: input.filters, + filters: input.filters.filter(filter => { + // enum 필드에 대한 isEmpty/isNotEmpty는 제외 + return !((filter.id === 'workType') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + }), joinOperator: input.joinOperator, joinedTables: { itemOffshoreTop }, customColumnMapping: { @@ -140,9 +158,19 @@ export async function getOffshoreTopItems(input: GetOffshoreTopSchema) { ); } + // enum 필드에 대한 isEmpty/isNotEmpty 처리 + const enumConditions = input.filters + .filter(filter => (filter.id === 'workType') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + .map(filter => { + const column = itemOffshoreTop.workType; + return filter.operator === 'isEmpty' ? sql`${column} is null` : sql`${column} is not null`; + }); + const finalWhere = and( advancedWhere, - globalWhere + globalWhere, + ...enumConditions ); const where = finalWhere; @@ -209,7 +237,11 @@ export async function getOffshoreHullItems(input: GetOffshoreHullSchema) { // advancedTable 모드면 filterColumns()로 where 절 구성 const advancedWhere = filterColumns({ table: items, - filters: input.filters, + filters: input.filters.filter(filter => { + // enum 필드에 대한 isEmpty/isNotEmpty는 제외 + return !((filter.id === 'workType') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + }), joinOperator: input.joinOperator, joinedTables: { itemOffshoreHull }, customColumnMapping: { @@ -229,9 +261,19 @@ export async function getOffshoreHullItems(input: GetOffshoreHullSchema) { ); } + // enum 필드에 대한 isEmpty/isNotEmpty 처리 + const enumConditions = input.filters + .filter(filter => (filter.id === 'workType') && + (filter.operator === 'isEmpty' || filter.operator === 'isNotEmpty')) + .map(filter => { + const column = itemOffshoreHull.workType; + return filter.operator === 'isEmpty' ? sql`${column} is null` : sql`${column} is not null`; + }); + const finalWhere = and( advancedWhere, - globalWhere + globalWhere, + ...enumConditions ); const where = finalWhere; @@ -1034,158 +1076,3 @@ export async function getAllOffshoreItems(): Promise<(ItemOffshoreHull | ItemOff throw new Error("Failed to get items"); } } - - -// ----------------------------------------------------------- -// 기술영업을 위한 로직 -// ----------------------------------------------------------- - -// 조선 공종 타입 -export type WorkType = '기장' | '전장' | '선실' | '배관' | '철의' - -// 조선 아이템 with 공종 정보 -export interface ShipbuildingItem { - id: number - itemCode: string - itemName: string - description: string | null - workType: WorkType - itemList: string | null // 실제 아이템명 - shipTypes: string - createdAt: Date - updatedAt: Date -} - -// 공종별 아이템 조회 -export async function getShipbuildingItemsByWorkType(workType?: WorkType) { - try { - const query = db - .select({ - id: itemShipbuilding.id, - itemCode: itemShipbuilding.itemCode, - itemName: items.itemName, - description: items.description, - workType: itemShipbuilding.workType, - itemList: itemShipbuilding.itemList, - shipTypes: itemShipbuilding.shipTypes, - createdAt: itemShipbuilding.createdAt, - updatedAt: itemShipbuilding.updatedAt, - }) - .from(itemShipbuilding) - .leftJoin(items, eq(itemShipbuilding.itemCode, items.itemCode)) - - if (workType) { - query.where(eq(itemShipbuilding.workType, workType)) - } - - const result = await query - - return { - data: result as ShipbuildingItem[], - error: null - } - } catch (error) { - console.error("조선 아이템 조회 오류:", error) - return { - data: null, - error: error instanceof Error ? error.message : "알 수 없는 오류" - } - } -} - -// 아이템 검색 -export async function searchShipbuildingItems(searchQuery: string, workType?: WorkType) { - try { - const searchConditions = [ - ilike(itemShipbuilding.itemCode, `%${searchQuery}%`), - ilike(items.itemName, `%${searchQuery}%`), - ilike(items.description, `%${searchQuery}%`), - ilike(itemShipbuilding.itemList, `%${searchQuery}%`) - ] - - let whereCondition = or(...searchConditions) - - if (workType) { - whereCondition = and( - eq(itemShipbuilding.workType, workType), - or(...searchConditions) - ) - } - - const result = await db - .select({ - id: itemShipbuilding.id, - itemCode: itemShipbuilding.itemCode, - itemName: items.itemName, - description: items.description, - workType: itemShipbuilding.workType, - itemList: itemShipbuilding.itemList, - shipTypes: itemShipbuilding.shipTypes, - createdAt: itemShipbuilding.createdAt, - updatedAt: itemShipbuilding.updatedAt, - }) - .from(itemShipbuilding) - .leftJoin(items, eq(itemShipbuilding.itemCode, items.itemCode)) - .where(whereCondition) - - return { - data: result as ShipbuildingItem[], - error: null - } - } catch (error) { - console.error("조선 아이템 검색 오류:", error) - return { - data: null, - error: error instanceof Error ? error.message : "알 수 없는 오류" - } - } -} - -// 모든 공종 목록 조회 -export async function getWorkTypes() { - return [ - { code: '기장' as WorkType, name: '기장', description: '기계 장치' }, - { code: '전장' as WorkType, name: '전장', description: '전기 장치' }, - { code: '선실' as WorkType, name: '선실', description: '선실' }, - { code: '배관' as WorkType, name: '배관', description: '배관' }, - { code: '철의' as WorkType, name: '철의', description: '선체 강재' }, - ] -} - -// 특정 아이템 코드들로 아이템 조회 -export async function getShipbuildingItemsByCodes(itemCodes: string[]) { - try { - const result = await db - .select({ - id: itemShipbuilding.id, - itemCode: itemShipbuilding.itemCode, - itemName: items.itemName, - description: items.description, - workType: itemShipbuilding.workType, - itemList: itemShipbuilding.itemList, - shipTypes: itemShipbuilding.shipTypes, - createdAt: itemShipbuilding.createdAt, - updatedAt: itemShipbuilding.updatedAt, - }) - .from(itemShipbuilding) - .leftJoin(items, eq(itemShipbuilding.itemCode, items.itemCode)) - .where( - or(...itemCodes.map(code => eq(itemShipbuilding.itemCode, code))) - ) - - return { - data: result as ShipbuildingItem[], - error: null - } - } catch (error) { - console.error("조선 아이템 코드별 조회 오류:", error) - return { - data: null, - error: error instanceof Error ? error.message : "알 수 없는 오류" - } - } -} - -// ----------------------------------------------------------- -// 기술영업을 위한 로직 끝 -// ----------------------------------------------------------- \ No newline at end of file -- cgit v1.2.3