From d59a5175210c18fcc675cde93865339abf37a406 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 30 May 2025 01:54:09 +0000 Subject: (최겸) 기술영업 아이템리스트 filter, sort 적용 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/items-tech/service.ts | 70 ++++++++++++++++------- lib/items-tech/table/hull/offshore-hull-table.tsx | 19 +++--- lib/items-tech/table/ship/Items-ship-table.tsx | 29 ++++++---- lib/items-tech/table/top/offshore-top-table.tsx | 18 +++--- lib/items-tech/validations.ts | 57 ++++++++++++++---- 5 files changed, 127 insertions(+), 66 deletions(-) (limited to 'lib/items-tech') diff --git a/lib/items-tech/service.ts b/lib/items-tech/service.ts index 9fa35148..6047552f 100644 --- a/lib/items-tech/service.ts +++ b/lib/items-tech/service.ts @@ -9,7 +9,7 @@ import { unstable_cache } from "@/lib/unstable-cache"; import { getErrorMessage } from "@/lib/handle-error"; import { asc, desc, ilike, and, or, eq, count, inArray, sql } from "drizzle-orm"; -import { GetItemsSchema, UpdateItemSchema, ShipbuildingItemCreateData, TypedItemCreateData, OffshoreTopItemCreateData, OffshoreHullItemCreateData } from "./validations"; +import { GetShipbuildingSchema, GetOffshoreTopSchema, GetOffshoreHullSchema, UpdateItemSchema, ShipbuildingItemCreateData, TypedItemCreateData, OffshoreTopItemCreateData, OffshoreHullItemCreateData } from "./validations"; import { Item, items, itemShipbuilding, itemOffshoreTop, itemOffshoreHull, ItemOffshoreTop, ItemOffshoreHull } from "@/db/schema/items"; import { findAllItems } from "./repository"; import { findAllOffshoreItems } from "./repository"; @@ -23,7 +23,7 @@ import { findAllOffshoreItems } from "./repository"; * 총 개수에 따라 pageCount를 계산해서 리턴. * Next.js의 unstable_cache를 사용해 일정 시간 캐시. */ -export async function getShipbuildingItems(input: GetItemsSchema) { +export async function getShipbuildingItems(input: GetShipbuildingSchema) { return unstable_cache( async () => { try { @@ -34,6 +34,12 @@ export async function getShipbuildingItems(input: GetItemsSchema) { table: items, filters: input.filters, joinOperator: input.joinOperator, + joinedTables: { itemShipbuilding }, + customColumnMapping: { + workType: { table: itemShipbuilding, column: "workType" }, + shipTypes: { table: itemShipbuilding, column: "shipTypes" }, + itemList: { table: itemShipbuilding, column: "itemList" }, + }, }); let globalWhere; @@ -41,8 +47,7 @@ export async function getShipbuildingItems(input: GetItemsSchema) { const s = `%${input.search}%`; globalWhere = or( ilike(items.itemCode, s), - ilike(items.itemName, s), - ilike(items.description, s) + ilike(itemShipbuilding.itemList, s) ); } @@ -55,10 +60,13 @@ export async function getShipbuildingItems(input: GetItemsSchema) { const orderBy = input.sort.length > 0 - ? input.sort.map((item) => - item.desc ? desc(items[item.id]) : asc(items[item.id]) - ) - : [asc(items.createdAt)]; + ? input.sort.map((item) => { + const column = item.id === "workType" || item.id === "shipTypes" || item.id === "itemList" + ? itemShipbuilding[item.id] + : items[item.id]; + return item.desc ? desc(column) : asc(column); + }) + : [desc(items.createdAt)]; // 조선 아이템 테이블과 기본 아이템 테이블 조인하여 조회 const result = await db.select({ @@ -103,7 +111,7 @@ export async function getShipbuildingItems(input: GetItemsSchema) { )(); } -export async function getOffshoreTopItems(input: GetItemsSchema) { +export async function getOffshoreTopItems(input: GetOffshoreTopSchema) { return unstable_cache( async () => { try { @@ -114,6 +122,12 @@ export async function getOffshoreTopItems(input: GetItemsSchema) { table: items, filters: input.filters, joinOperator: input.joinOperator, + joinedTables: { itemOffshoreTop }, + customColumnMapping: { + workType: { table: itemOffshoreTop, column: "workType" }, + itemList: { table: itemOffshoreTop, column: "itemList" }, + subItemList: { table: itemOffshoreTop, column: "subItemList" }, + }, }); let globalWhere; @@ -121,8 +135,8 @@ export async function getOffshoreTopItems(input: GetItemsSchema) { const s = `%${input.search}%`; globalWhere = or( ilike(items.itemCode, s), - ilike(items.itemName, s), - ilike(items.description, s) + ilike(itemOffshoreTop.itemList, s), + ilike(itemOffshoreTop.subItemList, s) ); } @@ -135,10 +149,13 @@ export async function getOffshoreTopItems(input: GetItemsSchema) { const orderBy = input.sort.length > 0 - ? input.sort.map((item) => - item.desc ? desc(items[item.id]) : asc(items[item.id]) - ) - : [asc(items.createdAt)]; + ? input.sort.map((item) => { + const column = item.id === "workType" || item.id === "itemList" || item.id === "subItemList" + ? itemOffshoreTop[item.id] + : items[item.id]; + return item.desc ? desc(column) : asc(column); + }) + : [desc(items.createdAt)]; // 해양 TOP 아이템 테이블과 기본 아이템 테이블 조인하여 조회 const result = await db.select({ @@ -183,7 +200,7 @@ export async function getOffshoreTopItems(input: GetItemsSchema) { )(); } -export async function getOffshoreHullItems(input: GetItemsSchema) { +export async function getOffshoreHullItems(input: GetOffshoreHullSchema) { return unstable_cache( async () => { try { @@ -194,6 +211,12 @@ export async function getOffshoreHullItems(input: GetItemsSchema) { table: items, filters: input.filters, joinOperator: input.joinOperator, + joinedTables: { itemOffshoreHull }, + customColumnMapping: { + workType: { table: itemOffshoreHull, column: "workType" }, + itemList: { table: itemOffshoreHull, column: "itemList" }, + subItemList: { table: itemOffshoreHull, column: "subItemList" }, + }, }); let globalWhere; @@ -201,8 +224,8 @@ export async function getOffshoreHullItems(input: GetItemsSchema) { const s = `%${input.search}%`; globalWhere = or( ilike(items.itemCode, s), - ilike(items.itemName, s), - ilike(items.description, s) + ilike(itemOffshoreHull.itemList, s), + ilike(itemOffshoreHull.subItemList, s) ); } @@ -215,10 +238,13 @@ export async function getOffshoreHullItems(input: GetItemsSchema) { const orderBy = input.sort.length > 0 - ? input.sort.map((item) => - item.desc ? desc(items[item.id]) : asc(items[item.id]) - ) - : [asc(items.createdAt)]; + ? input.sort.map((item) => { + const column = item.id === "workType" || item.id === "itemList" || item.id === "subItemList" + ? itemOffshoreHull[item.id] + : items[item.id]; + return item.desc ? desc(column) : asc(column); + }) + : [desc(items.createdAt)]; // 해양 HULL 아이템 테이블과 기본 아이템 테이블 조인하여 조회 const result = await db.select({ diff --git a/lib/items-tech/table/hull/offshore-hull-table.tsx b/lib/items-tech/table/hull/offshore-hull-table.tsx index 00f2c466..2a6f3173 100644 --- a/lib/items-tech/table/hull/offshore-hull-table.tsx +++ b/lib/items-tech/table/hull/offshore-hull-table.tsx @@ -69,20 +69,17 @@ export function OffshoreHullTable({ promises }: OffshoreHullTableProps) { label: "Item Code", type: "text", }, - { - id: "itemName", - label: "Item Name", - type: "text", - }, - { - id: "description", - label: "Description", - type: "text", - }, { id: "workType", label: "기능(공종)", - type: "text", + type: "select", + options: [ + { label: "HA", value: "HA" }, + { label: "HE", value: "HE" }, + { label: "HH", value: "HH" }, + { label: "HM", value: "HM" }, + { label: "NC", value: "NC" }, + ], }, { id: "itemList", diff --git a/lib/items-tech/table/ship/Items-ship-table.tsx b/lib/items-tech/table/ship/Items-ship-table.tsx index 29ad8f8a..61e8d8b4 100644 --- a/lib/items-tech/table/ship/Items-ship-table.tsx +++ b/lib/items-tech/table/ship/Items-ship-table.tsx @@ -80,25 +80,30 @@ export function ItemsShipTable({ promises }: ItemsTableProps) { label: "Item Code", type: "text", }, - { - id: "itemName", - label: "Item Name", - type: "text", - }, - { - id: "description", - label: "Description", - type: "text", - }, { id: "workType", label: "기능(공종)", - type: "text", + type: "select", + options: [ + { label: "기장", value: "기장" }, + { label: "전장", value: "전장" }, + { label: "선실", value: "선실" }, + { label: "배관", value: "배관" }, + { label: "철의", value: "철의" }, + ], }, { id: "shipTypes", label: "선종", - type: "text", + type: "select", + options: [ + { label: "A-MAX", value: "A-MAX" }, + { label: "S-MAX", value: "S-MAX" }, + { label: "LNGC", value: "LNGC" }, + { label: "VLCC", value: "VLCC" }, + { label: "CONT", value: "CONT" }, + { label: "OPTION", value: "OPTION" }, + ], }, { id: "itemList", diff --git a/lib/items-tech/table/top/offshore-top-table.tsx b/lib/items-tech/table/top/offshore-top-table.tsx index 689f1db3..c038de13 100644 --- a/lib/items-tech/table/top/offshore-top-table.tsx +++ b/lib/items-tech/table/top/offshore-top-table.tsx @@ -65,20 +65,16 @@ export function OffshoreTopTable({ promises }: OffshoreTopTableProps) { label: "Item Code", type: "text", }, - { - id: "itemName", - label: "Item Name", - type: "text", - }, - { - id: "description", - label: "Description", - type: "text", - }, { id: "workType", label: "기능(공종)", - type: "text", + type: "select", + options: [ + { label: "TM", value: "TM" }, + { label: "TS", value: "TS" }, + { label: "TE", value: "TE" }, + { label: "TP", value: "TP" }, + ], }, { id: "itemList", diff --git a/lib/items-tech/validations.ts b/lib/items-tech/validations.ts index 399193b2..09c7878b 100644 --- a/lib/items-tech/validations.ts +++ b/lib/items-tech/validations.ts @@ -8,25 +8,59 @@ import { import * as z from "zod" import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers" -import { Item } from "@/db/schema/items"; +import { ItemOffshoreTop, ItemOffshoreHull, ItemShipbuilding } from "@/db/schema/items"; -export const searchParamsCache = createSearchParamsCache({ - flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault( - [] - ), +// 조선 아이템 검색 파라미터 캐시 +export const shipbuildingSearchParamsCache = createSearchParamsCache({ + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), page: parseAsInteger.withDefault(1), perPage: parseAsInteger.withDefault(10), - sort: getSortingStateParser().withDefault([ + sort: getSortingStateParser().withDefault([ { id: "createdAt", desc: true }, ]), itemCode: parseAsString.withDefault(""), - itemName: parseAsString.withDefault(""), - description: parseAsString.withDefault(""), + workType: parseAsString.withDefault(""), + shipTypes: parseAsString.withDefault(""), + itemList: parseAsString.withDefault(""), + filters: getFiltersStateParser().withDefault([]), + joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + search: parseAsString.withDefault(""), + +}) + +// 해양 TOP 아이템 검색 파라미터 캐시 +export const offshoreTopSearchParamsCache = createSearchParamsCache({ + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), + page: parseAsInteger.withDefault(1), + perPage: parseAsInteger.withDefault(10), + sort: getSortingStateParser().withDefault([ + { id: "createdAt", desc: true }, + ]), + itemCode: parseAsString.withDefault(""), + workType: parseAsString.withDefault(""), + itemList: parseAsString.withDefault(""), + subItemList: parseAsString.withDefault(""), + filters: getFiltersStateParser().withDefault([]), + joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + search: parseAsString.withDefault(""), +}) - // advanced filter +// 해양 HULL 아이템 검색 파라미터 캐시 +export const offshoreHullSearchParamsCache = createSearchParamsCache({ + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), + page: parseAsInteger.withDefault(1), + perPage: parseAsInteger.withDefault(10), + sort: getSortingStateParser().withDefault([ + { id: "createdAt", desc: true }, + ]), + itemCode: parseAsString.withDefault(""), + workType: parseAsString.withDefault(""), + itemList: parseAsString.withDefault(""), + subItemList: parseAsString.withDefault(""), filters: getFiltersStateParser().withDefault([]), joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), search: parseAsString.withDefault(""), + }) export const createItemSchema = z.object({ @@ -51,7 +85,10 @@ export const updateShipbuildingItemSchema = z.object({ itemList: z.string().optional(), }) -export type GetItemsSchema = Awaited> +export type GetShipbuildingSchema = Awaited> +export type GetOffshoreTopSchema = Awaited> +export type GetOffshoreHullSchema = Awaited> + export type CreateItemSchema = z.infer export type UpdateItemSchema = z.infer export type UpdateShipbuildingItemSchema = z.infer -- cgit v1.2.3