diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-28 02:13:30 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-04-28 02:13:30 +0000 |
| commit | ef4c533ebacc2cdc97e518f30e9a9350004fcdfb (patch) | |
| tree | 345251a3ed0f4429716fa5edaa31024d8f4cb560 /lib/project-avl/service.ts | |
| parent | 9ceed79cf32c896f8a998399bf1b296506b2cd4a (diff) | |
~20250428 작업사항
Diffstat (limited to 'lib/project-avl/service.ts')
| -rw-r--r-- | lib/project-avl/service.ts | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/project-avl/service.ts b/lib/project-avl/service.ts new file mode 100644 index 00000000..6ba10c5e --- /dev/null +++ b/lib/project-avl/service.ts @@ -0,0 +1,106 @@ +// src/lib/projectApprovedVendors/service.ts +"use server"; // Next.js 서버 액션에서 직접 import하려면 (선택) + +import { revalidateTag, unstable_noStore } from "next/cache"; +import db from "@/db/db"; +import { customAlphabet } from "nanoid"; + +import { filterColumns } from "@/lib/filter-columns"; +import { unstable_cache } from "@/lib/unstable-cache"; +import { getErrorMessage } from "@/lib/handle-error"; + +import { asc, desc, ilike, inArray, and, gte, lte, not, or ,eq} from "drizzle-orm"; +import { GetProjectAVLSchema } from "./validations"; +import { projectApprovedVendors } from "@/db/schema"; +import { countProjectAVLs, selectProejctAVLs } from "./repository"; + + +/* ----------------------------------------------------- + 1) 조회 관련 +----------------------------------------------------- */ + +/** + * 복잡한 조건으로 Item 목록을 조회 (+ pagination) 하고, + * 총 개수에 따라 pageCount를 계산해서 리턴. + * Next.js의 unstable_cache를 사용해 일정 시간 캐시. + */ +export async function getProjecTAVL(input: GetProjectAVLSchema) { + + return unstable_cache( + async () => { + try { + const offset = (input.page - 1) * input.perPage; + + // const advancedTable = input.flags.includes("advancedTable"); + const advancedTable = true; + + // advancedTable 모드면 filterColumns()로 where 절 구성 + const advancedWhere = filterColumns({ + table: projectApprovedVendors, + filters: input.filters, + joinOperator: input.joinOperator, + }); + + + let globalWhere + if (input.search) { + const s = `%${input.search}%` + globalWhere = + or( + ilike(projectApprovedVendors.vendor_name, s), + ilike(projectApprovedVendors.tax_id, s) + , ilike(projectApprovedVendors.vendor_email, s) + , ilike(projectApprovedVendors.vendor_type_name_ko, s) + , ilike(projectApprovedVendors.project_name, s) + , ilike(projectApprovedVendors.project_code, s) + ) + // 필요시 여러 칼럼 OR조건 (status, priority, etc) + } + + const finalWhere = and( + // advancedWhere or your existing conditions + advancedWhere, + globalWhere // and()함수로 결합 or or() 등으로 결합 + ) + + + // 아니면 ilike, inArray, gte 등으로 where 절 구성 + const where = finalWhere + + + const orderBy = + input.sort.length > 0 + ? input.sort.map((item) => + item.desc ? desc(projectApprovedVendors[item.id]) : asc(projectApprovedVendors[item.id]) + ) + : [asc(projectApprovedVendors.approved_at)]; + + // 트랜잭션 내부에서 Repository 호출 + const { data, total } = await db.transaction(async (tx) => { + const data = await selectProejctAVLs(tx, { + where, + orderBy, + offset, + limit: input.perPage, + }); + + const total = await countProjectAVLs(tx, where); + return { data, total }; + }); + + const pageCount = Math.ceil(total / input.perPage); + + return { data, pageCount }; + } catch (err) { + // 에러 발생 시 디폴트 + return { data: [], pageCount: 0 }; + } + }, + [JSON.stringify(input)], // 캐싱 키 + { + revalidate: 3600, + tags: ["project-approved-vendors"], // revalidateTag("projectApprovedVendors") 호출 시 무효화 + } + )(); +} + |
