From 4c15b99d9586aa48693213c78c02fba4639ebb85 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 1 Jul 2025 11:47:47 +0000 Subject: (최겸) 인포메이션 기능 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/information/service.ts | 224 +++++++++++++++++---------------------------- 1 file changed, 82 insertions(+), 142 deletions(-) (limited to 'lib/information/service.ts') diff --git a/lib/information/service.ts b/lib/information/service.ts index 8f1e5679..30a651f1 100644 --- a/lib/information/service.ts +++ b/lib/information/service.ts @@ -9,7 +9,6 @@ import db from "@/db/db" import { pageInformation, menuAssignments } from "@/db/schema" import type { - CreateInformationSchema, UpdateInformationSchema, GetInformationSchema } from "./validations" @@ -17,11 +16,8 @@ import type { import { selectInformation, countInformation, - getInformationByPageCode, - insertInformation, + getInformationByPagePath, updateInformation, - deleteInformationById, - deleteInformationByIds, getInformationById, selectInformationLists, countInformationLists @@ -34,57 +30,65 @@ export async function getInformationLists(input: GetInformationSchema) { return unstable_cache( async () => { try { - const offset = (input.page - 1) * input.perPage + // 고급 검색 로직 + const { page, perPage, search, filters, joinOperator, pagePath, pageName, informationContent, isActive } = input - // 고급 필터링 - const advancedWhere = filterColumns({ - table: pageInformation, - filters: input.filters, - joinOperator: input.joinOperator, - }) + // 기본 검색 조건들 + const conditions = [] - // 전역 검색 - let globalWhere - if (input.search) { - const s = `%${input.search}%` - globalWhere = or( - ilike(pageInformation.pageCode, s), - ilike(pageInformation.pageName, s), - ilike(pageInformation.title, s), - ilike(pageInformation.description, s) - ) + // 검색어가 있으면 여러 필드에서 검색 + if (search && search.trim()) { + const searchConditions = [ + ilike(pageInformation.pagePath, `%${search}%`), + ilike(pageInformation.pageName, `%${search}%`), + ilike(pageInformation.informationContent, `%${search}%`) + ] + conditions.push(or(...searchConditions)) } - // 기본 필터들 - let basicWhere - const basicConditions = [] - - if (input.pageCode) { - basicConditions.push(ilike(pageInformation.pageCode, `%${input.pageCode}%`)) + // 개별 필드 조건들 + if (pagePath && pagePath.trim()) { + conditions.push(ilike(pageInformation.pagePath, `%${pagePath}%`)) } - - if (input.pageName) { - basicConditions.push(ilike(pageInformation.pageName, `%${input.pageName}%`)) + + if (pageName && pageName.trim()) { + conditions.push(ilike(pageInformation.pageName, `%${pageName}%`)) } - - if (input.title) { - basicConditions.push(ilike(pageInformation.title, `%${input.title}%`)) + + if (informationContent && informationContent.trim()) { + conditions.push(ilike(pageInformation.informationContent, `%${informationContent}%`)) } - - if (input.isActive !== undefined && input.isActive !== null) { - basicConditions.push(eq(pageInformation.isActive, input.isActive)) - } - - if (basicConditions.length > 0) { - basicWhere = and(...basicConditions) - } - - // 최종 where 조건 - const finalWhere = and( - advancedWhere, - globalWhere, - basicWhere - ) + + if (isActive !== null && isActive !== undefined) { + conditions.push(eq(pageInformation.isActive, isActive)) + } + + // 고급 필터 처리 + if (filters && filters.length > 0) { + const advancedConditions = filters.map(() => + filterColumns({ + table: pageInformation, + filters: filters, + joinOperator: joinOperator, + }) + ) + + if (advancedConditions.length > 0) { + if (joinOperator === "or") { + conditions.push(or(...advancedConditions)) + } else { + conditions.push(and(...advancedConditions)) + } + } + } + + // 전체 WHERE 조건 조합 + const finalWhere = conditions.length > 0 + ? (joinOperator === "or" ? or(...conditions) : and(...conditions)) + : undefined + + // 페이지네이션 + const offset = (page - 1) * perPage // 정렬 처리 const orderBy = input.sort.length > 0 @@ -93,12 +97,12 @@ export async function getInformationLists(input: GetInformationSchema) { return item.desc ? desc(pageInformation.createdAt) : asc(pageInformation.createdAt) } else if (item.id === "updatedAt") { return item.desc ? desc(pageInformation.updatedAt) : asc(pageInformation.updatedAt) - } else if (item.id === "pageCode") { - return item.desc ? desc(pageInformation.pageCode) : asc(pageInformation.pageCode) + } else if (item.id === "pagePath") { + return item.desc ? desc(pageInformation.pagePath) : asc(pageInformation.pagePath) } else if (item.id === "pageName") { return item.desc ? desc(pageInformation.pageName) : asc(pageInformation.pageName) - } else if (item.id === "title") { - return item.desc ? desc(pageInformation.title) : asc(pageInformation.title) + } else if (item.id === "informationContent") { + return item.desc ? desc(pageInformation.informationContent) : asc(pageInformation.informationContent) } else if (item.id === "isActive") { return item.desc ? desc(pageInformation.isActive) : asc(pageInformation.isActive) } else { @@ -129,7 +133,7 @@ export async function getInformationLists(input: GetInformationSchema) { return { data: [], pageCount: 0, total: 0 } } }, - [JSON.stringify(input)], // 캐싱 키 + [JSON.stringify(input)], { revalidate: 3600, tags: ["information-lists"], @@ -161,18 +165,18 @@ export async function getInformationList(input: Partial & } // 페이지별 인포메이션 조회 (일반 사용자용) -export async function getPageInformation(pageCode: string): Promise { +export async function getPageInformation(pagePath: string): Promise { try { - return await getInformationByPageCode(pageCode) + return await getInformationByPagePath(pagePath) } catch (error) { - console.error(`Failed to get information for page ${pageCode}:`, error) + console.error(`Failed to get information for page ${pagePath}:`, error) return null } } // 캐시된 페이지별 인포메이션 조회 export const getCachedPageInformation = unstable_cache( - async (pageCode: string) => getPageInformation(pageCode), + async (pagePath: string) => getPageInformation(pagePath), ["page-information"], { tags: ["page-information"], @@ -180,34 +184,20 @@ export const getCachedPageInformation = unstable_cache( } ) -// 인포메이션 생성 -export async function createInformation(input: CreateInformationSchema) { - try { - const result = await insertInformation(input) - - revalidateTag("page-information") - revalidateTag("information-lists") - revalidateTag("information-edit-permission") - - return { - success: true, - data: result, - message: "인포메이션이 성공적으로 생성되었습니다." - } - } catch (error) { - console.error("Failed to create information:", error) - return { - success: false, - message: getErrorMessage(error) - } - } -} - -// 인포메이션 수정 +// 인포메이션 수정 (내용과 첨부파일만) export async function updateInformationData(input: UpdateInformationSchema) { try { const { id, ...updateData } = input - const result = await updateInformation(id, updateData) + + // 수정 가능한 필드만 허용 + const allowedFields = { + informationContent: updateData.informationContent, + attachmentFilePath: updateData.attachmentFilePath, + attachmentFileName: updateData.attachmentFileName, + updatedAt: new Date() + } + + const result = await updateInformation(id, allowedFields) if (!result) { return { @@ -233,56 +223,6 @@ export async function updateInformationData(input: UpdateInformationSchema) { } } -// 인포메이션 삭제 -export async function deleteInformation(id: number) { - try { - const success = await deleteInformationById(id) - - if (!success) { - return { - success: false, - message: "인포메이션을 찾을 수 없거나 삭제에 실패했습니다." - } - } - - revalidateTag("page-information") - revalidateTag("information-lists") - - return { - success: true, - message: "인포메이션이 성공적으로 삭제되었습니다." - } - } catch (error) { - console.error("Failed to delete information:", error) - return { - success: false, - message: getErrorMessage(error) - } - } -} - -// 인포메이션 다중 삭제 -export async function deleteMultipleInformation(ids: number[]) { - try { - const deletedCount = await deleteInformationByIds(ids) - - revalidateTag("page-information") - revalidateTag("information-lists") - - return { - success: true, - deletedCount, - message: `${deletedCount}개의 인포메이션이 성공적으로 삭제되었습니다.` - } - } catch (error) { - console.error("Failed to delete multiple information:", error) - return { - success: false, - message: getErrorMessage(error) - } - } -} - // ID로 인포메이션 조회 export async function getInformationDetail(id: number): Promise { try { @@ -294,18 +234,18 @@ export async function getInformationDetail(id: number): Promise { +export async function checkInformationEditPermission(pagePath: string, userId: string): Promise { try { - // pageCode를 menuPath로 변환 (pageCode가 menuPath의 마지막 부분이라고 가정) - // 예: pageCode "vendor-list" -> menuPath "/evcp/vendor-list" 또는 "/partners/vendor-list" + // pagePath를 menuPath로 변환 (pagePath가 menuPath의 마지막 부분이라고 가정) + // 예: pagePath "vendor-list" -> menuPath "/evcp/vendor-list" 또는 "/partners/vendor-list" const menuPathQueries = [ - `/evcp/${pageCode}`, - `/partners/${pageCode}`, - `/${pageCode}`, // 루트 경로 - pageCode // 정확한 매칭 + `/evcp/${pagePath}`, + `/partners/${pagePath}`, + `/${pagePath}`, // 루트 경로 + pagePath // 정확한 매칭 ] - // menu_assignments에서 해당 pageCode와 매칭되는 메뉴 찾기 + // menu_assignments에서 해당 pagePath와 매칭되는 메뉴 찾기 const menuAssignment = await db .select() .from(menuAssignments) @@ -334,7 +274,7 @@ export async function checkInformationEditPermission(pageCode: string, userId: s // 캐시된 권한 확인 export const getCachedEditPermission = unstable_cache( - async (pageCode: string, userId: string) => checkInformationEditPermission(pageCode, userId), + async (pagePath: string, userId: string) => checkInformationEditPermission(pagePath, userId), ["information-edit-permission"], { tags: ["information-edit-permission"], -- cgit v1.2.3