From cc8ef6a7d3f0f813819a20b8742dee9617b371df Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Mon, 28 Apr 2025 16:51:01 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/suitable.ts | 21 ++++++- src/app/api/suitable/category/route.ts | 16 +++++ src/app/api/suitable/list/route.ts | 37 ++++++++++-- src/components/Suitable.tsx | 35 ++++++++--- src/components/SuitableSearch.tsx | 82 +++++++++++++++++++++++--- src/hooks/useSuitable.ts | 30 ++++++++++ src/store/useSuitableStore.ts | 68 +++++++++++++++++++++ 7 files changed, 266 insertions(+), 23 deletions(-) create mode 100644 src/app/api/suitable/category/route.ts create mode 100644 src/hooks/useSuitable.ts create mode 100644 src/store/useSuitableStore.ts diff --git a/src/api/suitable.ts b/src/api/suitable.ts index e8458c4..277bc7e 100644 --- a/src/api/suitable.ts +++ b/src/api/suitable.ts @@ -38,14 +38,31 @@ export interface Suitable { } export const suitableApi = { - getList: async (): Promise => { - const response = await axiosInstance.get('/api/suitable/list') + getList: async (category?: string, keyword?: string): Promise => { + let condition: any = {} + if (category) { + condition['category'] = category + } + if (keyword) { + condition['keyword'] = { + contains: keyword, + } + } + console.log('🚀 ~ getList: ~ condition:', condition) + const response = await axiosInstance.get('/api/suitable/list', { params: condition }) console.log('🚀 ~ getList: ~ response:', response) return response.data }, + getCategory: async (): Promise => { + const response = await axiosInstance.get('/api/suitable/category') + console.log('🚀 ~ getCategory: ~ response:', response) + return response.data + }, + getDetails: async (roofMaterial: string): Promise => { const response = await axiosInstance.get(`/api/suitable/details?roof-material=${roofMaterial}`) + console.log('🚀 ~ getDetails: ~ response:', response) return response.data }, diff --git a/src/app/api/suitable/category/route.ts b/src/app/api/suitable/category/route.ts new file mode 100644 index 0000000..288a74a --- /dev/null +++ b/src/app/api/suitable/category/route.ts @@ -0,0 +1,16 @@ +import { NextResponse } from 'next/server' +import { prisma } from '@/libs/prisma' + +export async function GET() { + // @ts-ignore + const roofMaterialCategory = await prisma.MS_SUITABLE.findMany({ + select: { + roof_material: true, + }, + distinct: ['roof_material'], + orderBy: { + roof_material: 'asc', + }, + }) + return NextResponse.json(roofMaterialCategory) +} diff --git a/src/app/api/suitable/list/route.ts b/src/app/api/suitable/list/route.ts index e1a44cb..22c3d8a 100644 --- a/src/app/api/suitable/list/route.ts +++ b/src/app/api/suitable/list/route.ts @@ -1,8 +1,35 @@ -import { NextResponse } from 'next/server' +import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/libs/prisma' -export async function GET() { - // @ts-ignore - const suitables = await prisma.MS_SUITABLE.findMany() - return NextResponse.json(suitables) + +export async function GET(request: NextRequest) { + try { + const searchParams = request.nextUrl.searchParams + const category = searchParams.get('category') + const keyword = searchParams.get('keyword') + + let whereCondition: any = {} + if (category) { + whereCondition['roof_material'] = category + } + if (keyword) { + whereCondition['product_name'] = { + contains: keyword, + } + } + console.log('🚀 ~ /api/suitable/list: ~ prisma where condition:', whereCondition) + + // @ts-ignore + const suitables = await prisma.MS_SUITABLE.findMany({ + where: whereCondition, + orderBy: { + product_name: 'asc', + }, + }) + + return NextResponse.json(suitables) + } catch (error) { + console.error('❌ 데이터 조회 중 오류가 발생했습니다:', error) + return NextResponse.json({ error: '데이터 조회 중 오류가 발생했습니다' }, { status: 500 }) + } } diff --git a/src/components/Suitable.tsx b/src/components/Suitable.tsx index f5766f1..1af6d86 100644 --- a/src/components/Suitable.tsx +++ b/src/components/Suitable.tsx @@ -1,16 +1,23 @@ 'use client' -import { suitableApi } from '@/api/suitable' +import { useSuitableStore } from '@/store/useSuitableStore' import { useQuery } from '@tanstack/react-query' import { useRouter } from 'next/navigation' +import type { Suitable as SuitableType } from '@/api/suitable' export default function Suitable() { const router = useRouter() - const { data, error, isPending } = useQuery({ - queryKey: ['suitable-list'], - queryFn: suitableApi.getList, + const { selectedItems, addSelectedItem } = useSuitableStore() + + const { data: suitableList, isLoading } = useQuery({ + queryKey: ['suitables', 'search'], + enabled: false, }) + if (isLoading || !suitableList) { + return
Loading...
+ } + return ( <>

Suitable

@@ -22,9 +29,23 @@ export default function Suitable() { > HOME - {error &&
Error: {error.message}
} - {isPending &&
Loading...
} - {data && data.map((item) =>
{item.product_name}
)} +
+

선택된 아이템

+ {selectedItems.length > 0 ? selectedItems.map((item) =>
{item.product_name}
) :
선택된 아이템이 없습니다.
} +
+
+
+

데이터 목록

+ {suitableList ? ( + suitableList.map((item: SuitableType) => ( +
addSelectedItem(item)}> + {item.product_name} +
+ )) + ) : ( +
검색 결과가 없습니다.
+ )} +
) } diff --git a/src/components/SuitableSearch.tsx b/src/components/SuitableSearch.tsx index 9583ede..e339f80 100644 --- a/src/components/SuitableSearch.tsx +++ b/src/components/SuitableSearch.tsx @@ -1,21 +1,85 @@ 'use client' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' +import { useQuery } from '@tanstack/react-query' +import { useSuitable } from '@/hooks/useSuitable' export default function SuitableSearch() { const router = useRouter() - const [selectedValue, setSelectedValue] = useState('') + const [selectedCategory, setSelectedCategory] = useState('') + const [searchValue, setSearchValue] = useState('') + const { getCategories, getSuitables } = useSuitable() + + const { data: categories } = useQuery({ + queryKey: ['categories'], + queryFn: getCategories, + staleTime: 1000 * 60 * 60, // 60분 + }) + + const { data: suitableList } = useQuery({ + queryKey: ['suitables', 'list'], + queryFn: async () => await getSuitables(), + staleTime: 1000 * 60 * 10, // 10분 + gcTime: 1000 * 60 * 10, // 10분 + }) + + const { data: suitableSearch, refetch: refetchBySearch } = useQuery({ + queryKey: ['suitables', 'search'], + queryFn: async () => { + // api를 호출하는 검색 방법 + // return await updateSearchResults(selectedCategory || undefined, searchValue || undefined) + // useQuery 캐시 데이터를 사용하는 검색 방법 + return ( + suitableList?.filter((item) => { + const categoryMatch = !selectedCategory || item.roof_material === selectedCategory + const searchMatch = !searchValue || item.product_name.includes(searchValue) + return categoryMatch && searchMatch + }) ?? [] + ) + }, + staleTime: 1000 * 60 * 10, + gcTime: 1000 * 60 * 10, + enabled: false, + }) + + // 초기 데이터 로딩된 후 검색 결과 없으면 검색 결과 로딩 + useEffect(() => { + if (suitableList && (!suitableSearch || suitableSearch.length === 0)) { + refetchBySearch() + } + }, [suitableList, suitableSearch]) + + // 카테고리 선택 시 검색 결과 로딩 + useEffect(() => { + refetchBySearch() + }, [selectedCategory]) + + const handleSearch = async () => { + if (!searchValue.trim()) { + alert('검색어를 입력하세요.') + return + } + refetchBySearch() + } return ( <> - - +
+ + +
+
+ setSearchValue(e.target.value)} /> + +
) } diff --git a/src/hooks/useSuitable.ts b/src/hooks/useSuitable.ts new file mode 100644 index 0000000..62f00e2 --- /dev/null +++ b/src/hooks/useSuitable.ts @@ -0,0 +1,30 @@ +import { suitableApi } from '@/api/suitable' + +export function useSuitable() { + const getCategories = async () => { + try { + return await suitableApi.getCategory() + } catch (error) { + console.error('카테고리 데이터 로드 실패:', error) + return [] + } + } + + const getSuitables = async () => { + try { + return await suitableApi.getList() + } catch (error) { + console.error('지붕재 데이터 로드 실패:', error) + } + } + + const updateSearchResults = async (selectedCategory: string | undefined, searchValue: string | undefined) => { + try { + return await suitableApi.getList(selectedCategory, searchValue) + } catch (error) { + console.error('지붕재 데이터 검색 실패:', error) + } + } + + return { getCategories, getSuitables, updateSearchResults } +} diff --git a/src/store/useSuitableStore.ts b/src/store/useSuitableStore.ts new file mode 100644 index 0000000..17b88c5 --- /dev/null +++ b/src/store/useSuitableStore.ts @@ -0,0 +1,68 @@ +import { create } from 'zustand' +import { Suitable, suitableApi } from '@/api/suitable' + +interface SuitableState { + // // 검색 결과 리스트 + // searchResults: Suitable[] + // // 초기 데이터 로드 + // fetchInitializeData: () => Promise + // // 검색 결과 설정 + // setSearchResults: (results: Suitable[]) => void + // // 검색 결과 초기화 + // resetSearchResults: () => void + + // 선택된 아이템 리스트 + selectedItems: Suitable[] + // 선택된 아이템 추가 + addSelectedItem: (item: Suitable) => void + // 선택된 아이템 제거 + removeSelectedItem: (itemId: number) => void + // 선택된 아이템 모두 제거 + clearSelectedItems: () => void +} + +export const useSuitableStore = create((set) => ({ + // // 초기 상태 + // searchResults: [], + + // // 초기 데이터 로드 + // fetchInitializeData: async () => { + // const suitables = await fetchInitialSuitablee() + // set({ searchResults: suitables }) + // }, + + // // 검색 결과 설정 + // setSearchResults: (results) => set({ searchResults: results }), + + // // 검색 결과 초기화 + // resetSearchResults: () => set({ searchResults: [] }), + + // 초기 상태 + selectedItems: [], + + // 선택된 아이템 추가 (중복 방지) + addSelectedItem: (item) => + set((state) => ({ + selectedItems: state.selectedItems.some((i) => i.id === item.id) ? state.selectedItems : [...state.selectedItems, item], + })), + + // 선택된 아이템 제거 + removeSelectedItem: (itemId) => + set((state) => ({ + selectedItems: state.selectedItems.filter((item) => item.id !== itemId), + })), + + // 선택된 아이템 모두 제거 + clearSelectedItems: () => set({ selectedItems: [] }), +})) + +// // 전체 데이터 초기화 함수 +// async function fetchInitialSuitablee() { +// try { +// const suitable = await suitableApi.getList() +// return suitable +// } catch (error) { +// console.error('초기 데이터 로드 실패:', error) +// return [] +// } +// } From bfbbdc01b8dce44375f7516cf9ed6ff358e5b63f Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 29 Apr 2025 10:49:58 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=84=A0=ED=83=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Suitable.tsx | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/components/Suitable.tsx b/src/components/Suitable.tsx index 1af6d86..eb725a2 100644 --- a/src/components/Suitable.tsx +++ b/src/components/Suitable.tsx @@ -1,16 +1,25 @@ 'use client' import { useSuitableStore } from '@/store/useSuitableStore' -import { useQuery } from '@tanstack/react-query' +import { useQuery, useQueryClient } from '@tanstack/react-query' import { useRouter } from 'next/navigation' import type { Suitable as SuitableType } from '@/api/suitable' export default function Suitable() { const router = useRouter() - const { selectedItems, addSelectedItem } = useSuitableStore() + const queryClient = useQueryClient() + const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore() + const handleItemClick = (item: SuitableType) => { + if (!item.id) return // 초기 데이터 import 때문에 Suitable.id가 optional 타입이라서 방어 처리 추가 + selectedItems.some((selected) => selected.id === item.id) ? removeSelectedItem(item.id) : addSelectedItem(item) + } const { data: suitableList, isLoading } = useQuery({ queryKey: ['suitables', 'search'], + queryFn: async () => { + const data = queryClient.getQueryData(['suitables', 'search']) as SuitableType[] + return data ?? [] + }, enabled: false, }) @@ -31,14 +40,22 @@ export default function Suitable() {

선택된 아이템

- {selectedItems.length > 0 ? selectedItems.map((item) =>
{item.product_name}
) :
선택된 아이템이 없습니다.
} + {selectedItems.length > 0 ? ( + selectedItems.map((item) => ( +
handleItemClick(item)}> + {item.product_name} +
+ )) + ) : ( +
선택된 아이템이 없습니다.
+ )}

데이터 목록

{suitableList ? ( suitableList.map((item: SuitableType) => ( -
addSelectedItem(item)}> +
handleItemClick(item)}> {item.product_name}
)) From adfe6d7a3281f476adf7f3fcf37b9e94cccacd87 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Wed, 30 Apr 2025 16:20:36 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EC=A0=81=ED=95=A9=EC=84=B1=20pdf=20=EA=B8=B0=EB=B3=B8=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/suitable/details/route.ts | 1 + src/components/Suitable.tsx | 3 +- src/components/SuitableDetails.tsx | 74 +++++++++++++--- src/components/SuitablePdf.tsx | 116 ++++++++++++++++++++++++++ src/components/SuitableSearch.tsx | 5 +- 5 files changed, 184 insertions(+), 15 deletions(-) create mode 100644 src/components/SuitablePdf.tsx diff --git a/src/app/api/suitable/details/route.ts b/src/app/api/suitable/details/route.ts index 2645411..d29f666 100644 --- a/src/app/api/suitable/details/route.ts +++ b/src/app/api/suitable/details/route.ts @@ -1,4 +1,5 @@ import { NextResponse } from 'next/server' +import { prisma } from '@/libs/prisma' export async function GET(request: Request) { const { searchParams } = new URL(request.url) diff --git a/src/components/Suitable.tsx b/src/components/Suitable.tsx index eb725a2..e21b4d4 100644 --- a/src/components/Suitable.tsx +++ b/src/components/Suitable.tsx @@ -9,6 +9,7 @@ export default function Suitable() { const router = useRouter() const queryClient = useQueryClient() const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore() + const handleItemClick = (item: SuitableType) => { if (!item.id) return // 초기 데이터 import 때문에 Suitable.id가 optional 타입이라서 방어 처리 추가 selectedItems.some((selected) => selected.id === item.id) ? removeSelectedItem(item.id) : addSelectedItem(item) @@ -23,7 +24,7 @@ export default function Suitable() { enabled: false, }) - if (isLoading || !suitableList) { + if (isLoading || !suitableList || suitableList.length === 0) { return
Loading...
} diff --git a/src/components/SuitableDetails.tsx b/src/components/SuitableDetails.tsx index 795fcdc..748c28f 100644 --- a/src/components/SuitableDetails.tsx +++ b/src/components/SuitableDetails.tsx @@ -1,23 +1,71 @@ 'use client' -import { Suitable, suitableApi } from '@/api/suitable' -import { useQuery, useQueryClient } from '@tanstack/react-query' +import { suitableApi } from '@/api/suitable' +import { useQuery } from '@tanstack/react-query' +import generatePDF, { usePDF, Options } from 'react-to-pdf' +import PDFContent from './SuitablePdf' + +const pdfOptions: Options = { + filename: 'page.pdf', + method: 'save', + page: { format: 'a4', margin: 10 }, + overrides: { + pdf: { + compress: true, + }, + }, +} export default function SuitableDetails({ roofMaterial }: { roofMaterial: string }) { - console.log('🚀 ~ SuitableDetails ~ roofMaterial:', roofMaterial) - // const { data, error, isPending } = useQuery({ - // queryKey: ['suitable-details'], - // queryFn: () => suitableApi.getDetails(roofMaterial), - // staleTime: 0, - // }) - const cache = useQueryClient() - const listData = cache.getQueryData(['suitable-list']) as Suitable[] - const data = listData.filter((item) => item.roof_material === roofMaterial) + const { data, isLoading } = useQuery({ + queryKey: ['suitable-details'], + queryFn: () => suitableApi.getDetails(roofMaterial), + staleTime: 0, + enabled: !!roofMaterial, + }) + + const { toPDF, targetRef } = usePDF({ ...pdfOptions, method: 'open' }) + + if (isLoading) { + return
Loading...
+ } return ( <> -

Searched Roof Material: {roofMaterial}

- {data && data.map((item) =>
{item.product_name}
)} + + + {/* */} + {/*
*/} +
+

Searched Roof Material: {decodeURIComponent(roofMaterial as string)}

+ {data && + data.map((item) => ( +
+
+
product_name: {item.product_name}
+
manufacturer: {item.manufacturer}
+
roof_material: {item.roof_material}
+
shape: {item.shape}
+
support_roof_tile: {item.support_roof_tile}
+
support_roof_bracket: {item.support_roof_bracket}
+
yg_anchor: {item.yg_anchor}
+
+ ))} +
+ {/*
*/} +
+
+

PDF 내용 나와라

+ +
+
) } diff --git a/src/components/SuitablePdf.tsx b/src/components/SuitablePdf.tsx new file mode 100644 index 0000000..f059744 --- /dev/null +++ b/src/components/SuitablePdf.tsx @@ -0,0 +1,116 @@ +import { Suitable } from '@/api/suitable' + +interface StatusInfo { + statusIcon: string + statusText: string +} + +interface FittingItem { + name: string + value: string + memo: string +} + +function getStatusInfo(value: string): StatusInfo | null { + const val = value?.trim()?.replace(/ー|-/g, '-') || '' + + if (['○', '〇'].includes(val)) { + return { + statusIcon: '✅', + statusText: '設置可', + } + } + + if (['×', '✕'].includes(val)) { + return { + statusIcon: '❌', + statusText: '設置不可', + } + } + + if (['-', '-', 'ー'].includes(val)) { + return { + statusIcon: '❓', + statusText: 'お問い合わせください', + } + } + + if (val === '') return null + + return { + statusIcon: '✅', + statusText: `${val} で設置可`, + } +} + +function getFittingItems(item: Suitable): FittingItem[] { + return [ + { name: '屋根瓦用支持金具', value: item.support_roof_tile, memo: item.support_roof_tile_memo }, + { name: '屋根ブラケット用支持金具', value: item.support_roof_bracket, memo: item.support_roof_bracket_memo }, + { name: 'YGアンカー', value: item.yg_anchor, memo: item.yg_anchor_memo }, + { name: 'RG屋根瓦パーツ', value: item.rg_roof_tile_part, memo: item.rg_roof_tile_part_memo }, + { name: 'DIDOハント支持瓦2', value: item.dido_hunt_support_tile_2, memo: item.dido_hunt_support_tile_2_memo }, + { name: '高島パワーベース', value: item.takashima_power_base, memo: item.takashima_power_base_memo }, + { name: '高島瓦ブラケット', value: item.takashima_tile_bracket, memo: item.takashima_tile_bracket_memo }, + { name: 'スレートブラケット4', value: item.slate_bracket_4, memo: item.slate_bracket_4_memo }, + { name: 'スレートシングルメタルブラケット', value: item.slate_single_metal_bracket, memo: item.slate_single_metal_bracket_memo }, + { name: 'DIDOハントショートラック4', value: item.dido_hunt_short_rack_4, memo: item.dido_hunt_short_rack_4_memo }, + { + name: '高島スレートブラケットスレートシングル', + value: item.takashima_slate_bracket_slate_single, + memo: item.takashima_slate_bracket_slate_single_memo, + }, + { name: 'DFメタルブラケット', value: item.df_metal_bracket, memo: item.df_metal_bracket_memo }, + { name: 'スレートメタルブラケット', value: item.slate_metal_bracket, memo: item.slate_metal_bracket_memo }, + { name: '高島スレートブラケットメタル屋根', value: item.takashima_slate_bracket_metal_roof, memo: item.takashima_slate_bracket_metal_roof_memo }, + ] +} + +function FittingItem({ fitting }: { fitting: FittingItem }) { + const statusInfo = getStatusInfo(fitting.value) + if (!statusInfo) return null + + return ( +
  • + {statusInfo.statusIcon} + + {fitting.name}:{statusInfo.statusText} + + {fitting.memo && ( + + 備考: + {fitting.memo} + + )} +
  • + ) +} + +export default function PDFContent({ data }: { data: Suitable[] }) { + return ( +
    + +

    適合結果 (적합결과)

    + {data.map((item) => ( +
    +
    +

    + {item.product_name}({item.manufacturer} / {item.roof_material} / {item.shape}) +

    +
      + {getFittingItems(item).map((fitting, index) => ( + + ))} +
    +
    + ))} +
    + ) +} diff --git a/src/components/SuitableSearch.tsx b/src/components/SuitableSearch.tsx index e339f80..4e3aa13 100644 --- a/src/components/SuitableSearch.tsx +++ b/src/components/SuitableSearch.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import { useQuery } from '@tanstack/react-query' import { useSuitable } from '@/hooks/useSuitable' +import Link from 'next/link' export default function SuitableSearch() { const router = useRouter() @@ -74,7 +75,9 @@ export default function SuitableSearch() { ))} - + + 지붕재 종류 상세보기 페이지 이동 +
    setSearchValue(e.target.value)} /> From bc1c1579ccddb925b5360bba41e5c75a0c42e987 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 13 May 2025 09:35:21 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EC=A0=81=ED=95=A9=EC=84=B1=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prisma/schema.prisma | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3a511a3..4efd2aa 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -79,13 +79,13 @@ model SD_SERVEY_SALES_DETAIL_INFO { id Int @id @default(autoincrement()) contract_capacity String? @db.VarChar(20) retail_company String? @db.VarChar(100) - supplementary_facilities Int? + supplementary_facilities String? @db.VarChar(20) supplementary_facilities_etc String? @db.VarChar(200) installation_system Int? installation_system_etc String? @db.VarChar(200) construction_year Int? construction_year_etc String? @db.VarChar(200) - roof_material Int? + roof_material String? @db.VarChar(20) roof_material_etc String? @db.VarChar(200) roof_shape Int? roof_shape_etc String? @db.VarChar(200) @@ -177,3 +177,33 @@ model BC_COMM_L { @@id([HEAD_CD, CODE], map: "PK_BC_COMM_L") } + +model MS_SUITABLE_ROOF_MATERIAL_GROUP { + id Int @id @default(autoincrement()) + roof_material_group String @db.VarChar(200) + roof_material String @db.VarChar(200) + created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__4F7CD00D") + updated_at DateTime +} + +model MS_SUITABLE_DETAIL { + id Int @id @default(autoincrement()) + main_id Int + trestle_manufacturer_product_code String? @db.VarChar(200) + trestle_manufacturer_product_name String? @db.VarChar(200) + memo String? @db.VarChar(500) + created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__571DF1D5") + updated_at DateTime? + MS_SUITABLE_MAIN MS_SUITABLE_MAIN @relation(fields: [main_id], references: [id], onUpdate: NoAction, map: "MS_SUITABLE_DETAIL_MS_SUITABLE_MAIN_FK") +} + +model MS_SUITABLE_MAIN { + id Int @id @default(autoincrement()) + product_name String @db.VarChar(200) + manufacturer String? @db.VarChar(200) + roof_material String? @db.VarChar(100) + shape String? @db.VarChar(200) + created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__5441852A") + updated_at DateTime? @updatedAt + details MS_SUITABLE_DETAIL[] +} From 186843e1548ed5c4d61844c9b7100e2aa5f7b384 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 13 May 2025 09:40:08 +0900 Subject: [PATCH 5/8] =?UTF-8?q?remove:=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SuitablePdf.tsx | 116 --------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 src/components/SuitablePdf.tsx diff --git a/src/components/SuitablePdf.tsx b/src/components/SuitablePdf.tsx deleted file mode 100644 index f059744..0000000 --- a/src/components/SuitablePdf.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { Suitable } from '@/api/suitable' - -interface StatusInfo { - statusIcon: string - statusText: string -} - -interface FittingItem { - name: string - value: string - memo: string -} - -function getStatusInfo(value: string): StatusInfo | null { - const val = value?.trim()?.replace(/ー|-/g, '-') || '' - - if (['○', '〇'].includes(val)) { - return { - statusIcon: '✅', - statusText: '設置可', - } - } - - if (['×', '✕'].includes(val)) { - return { - statusIcon: '❌', - statusText: '設置不可', - } - } - - if (['-', '-', 'ー'].includes(val)) { - return { - statusIcon: '❓', - statusText: 'お問い合わせください', - } - } - - if (val === '') return null - - return { - statusIcon: '✅', - statusText: `${val} で設置可`, - } -} - -function getFittingItems(item: Suitable): FittingItem[] { - return [ - { name: '屋根瓦用支持金具', value: item.support_roof_tile, memo: item.support_roof_tile_memo }, - { name: '屋根ブラケット用支持金具', value: item.support_roof_bracket, memo: item.support_roof_bracket_memo }, - { name: 'YGアンカー', value: item.yg_anchor, memo: item.yg_anchor_memo }, - { name: 'RG屋根瓦パーツ', value: item.rg_roof_tile_part, memo: item.rg_roof_tile_part_memo }, - { name: 'DIDOハント支持瓦2', value: item.dido_hunt_support_tile_2, memo: item.dido_hunt_support_tile_2_memo }, - { name: '高島パワーベース', value: item.takashima_power_base, memo: item.takashima_power_base_memo }, - { name: '高島瓦ブラケット', value: item.takashima_tile_bracket, memo: item.takashima_tile_bracket_memo }, - { name: 'スレートブラケット4', value: item.slate_bracket_4, memo: item.slate_bracket_4_memo }, - { name: 'スレートシングルメタルブラケット', value: item.slate_single_metal_bracket, memo: item.slate_single_metal_bracket_memo }, - { name: 'DIDOハントショートラック4', value: item.dido_hunt_short_rack_4, memo: item.dido_hunt_short_rack_4_memo }, - { - name: '高島スレートブラケットスレートシングル', - value: item.takashima_slate_bracket_slate_single, - memo: item.takashima_slate_bracket_slate_single_memo, - }, - { name: 'DFメタルブラケット', value: item.df_metal_bracket, memo: item.df_metal_bracket_memo }, - { name: 'スレートメタルブラケット', value: item.slate_metal_bracket, memo: item.slate_metal_bracket_memo }, - { name: '高島スレートブラケットメタル屋根', value: item.takashima_slate_bracket_metal_roof, memo: item.takashima_slate_bracket_metal_roof_memo }, - ] -} - -function FittingItem({ fitting }: { fitting: FittingItem }) { - const statusInfo = getStatusInfo(fitting.value) - if (!statusInfo) return null - - return ( -
  • - {statusInfo.statusIcon} - - {fitting.name}:{statusInfo.statusText} - - {fitting.memo && ( - - 備考: - {fitting.memo} - - )} -
  • - ) -} - -export default function PDFContent({ data }: { data: Suitable[] }) { - return ( -
    - -

    適合結果 (적합결과)

    - {data.map((item) => ( -
    -
    -

    - {item.product_name}({item.manufacturer} / {item.roof_material} / {item.shape}) -

    -
      - {getFittingItems(item).map((fitting, index) => ( - - ))} -
    -
    - ))} -
    - ) -} From 2c75a6b416a4d7b6d8131b2a8c1550efb36d4d2c Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 13 May 2025 10:51:17 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EC=A0=81=ED=95=A9=EC=84=B1=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prisma/schema.prisma | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 4efd2aa..3cc1c4c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -179,31 +179,31 @@ model BC_COMM_L { } model MS_SUITABLE_ROOF_MATERIAL_GROUP { - id Int @id @default(autoincrement()) - roof_material_group String @db.VarChar(200) - roof_material String @db.VarChar(200) - created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__4F7CD00D") - updated_at DateTime + ID Int @id @default(autoincrement()) + ROOF_MATERIAL_GROUP String @db.VarChar(200) + ROOF_MATERIAL String @db.VarChar(200) + REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__4F7CD00D") + UPT_DT DateTime } model MS_SUITABLE_DETAIL { - id Int @id @default(autoincrement()) - main_id Int - trestle_manufacturer_product_code String? @db.VarChar(200) - trestle_manufacturer_product_name String? @db.VarChar(200) - memo String? @db.VarChar(500) - created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__571DF1D5") - updated_at DateTime? - MS_SUITABLE_MAIN MS_SUITABLE_MAIN @relation(fields: [main_id], references: [id], onUpdate: NoAction, map: "MS_SUITABLE_DETAIL_MS_SUITABLE_MAIN_FK") + ID Int @id @default(autoincrement()) + MAIN_ID Int + TRESTLE_MANUFACTURER_PRODUCT_CODE String? @db.VarChar(200) + TRESTLE_MANUFACTURER_PRODUCT_NAME String? @db.VarChar(200) + MEMO String? @db.VarChar(500) + REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__571DF1D5") + UPT_DT DateTime? + MS_SUITABLE_MAIN MS_SUITABLE_MAIN @relation(fields: [MAIN_ID], references: [ID], onUpdate: NoAction, map: "MS_SUITABLE_DETAIL_MS_SUITABLE_MAIN_FK") } model MS_SUITABLE_MAIN { - id Int @id @default(autoincrement()) - product_name String @db.VarChar(200) - manufacturer String? @db.VarChar(200) - roof_material String? @db.VarChar(100) - shape String? @db.VarChar(200) - created_at DateTime @default(now(), map: "DF__MS_SUITAB__creat__5441852A") - updated_at DateTime? @updatedAt - details MS_SUITABLE_DETAIL[] + ID Int @id @default(autoincrement()) + PRODUCT_NAME String @db.VarChar(200) + MANUFACTURER String? @db.VarChar(200) + ROOT_MATERIAL String? @db.VarChar(100) + SHAPE String? @db.VarChar(200) + REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__5441852A") + UPT_DT DateTime? + MS_SUITABLE_DETAIL MS_SUITABLE_DETAIL[] } From 9f4c3de2cf16f8e563b983b77bc27605cab1bef9 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 13 May 2025 11:00:20 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EC=A0=81=ED=95=A9=EC=84=B1=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EA=B3=B5=ED=86=B5=EC=BD=94?= =?UTF-8?q?=EB=93=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prisma/schema.prisma | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3cc1c4c..296042d 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -181,7 +181,7 @@ model BC_COMM_L { model MS_SUITABLE_ROOF_MATERIAL_GROUP { ID Int @id @default(autoincrement()) ROOF_MATERIAL_GROUP String @db.VarChar(200) - ROOF_MATERIAL String @db.VarChar(200) + ROOF_MT_CD String @db.VarChar(200) REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__4F7CD00D") UPT_DT DateTime } @@ -189,7 +189,7 @@ model MS_SUITABLE_ROOF_MATERIAL_GROUP { model MS_SUITABLE_DETAIL { ID Int @id @default(autoincrement()) MAIN_ID Int - TRESTLE_MANUFACTURER_PRODUCT_CODE String? @db.VarChar(200) + TRESTLE_MFPC_CD String? @db.VarChar(200) TRESTLE_MANUFACTURER_PRODUCT_NAME String? @db.VarChar(200) MEMO String? @db.VarChar(500) REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__571DF1D5") @@ -200,9 +200,9 @@ model MS_SUITABLE_DETAIL { model MS_SUITABLE_MAIN { ID Int @id @default(autoincrement()) PRODUCT_NAME String @db.VarChar(200) - MANUFACTURER String? @db.VarChar(200) - ROOT_MATERIAL String? @db.VarChar(100) - SHAPE String? @db.VarChar(200) + MANU_FT_CD String? @db.VarChar(200) + ROOF_MT_CD String? @db.VarChar(100) + ROOF_SH_CD String? @db.VarChar(200) REG_DT DateTime @default(now(), map: "DF__MS_SUITAB__creat__5441852A") UPT_DT DateTime? MS_SUITABLE_DETAIL MS_SUITABLE_DETAIL[] From e5affe0df5853f65b860263cafc64ae63fe6c13d Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 13 May 2025 13:28:46 +0900 Subject: [PATCH 8/8] chore: update environment variables and dependencies; add database configuration for QPARTNER login --- .env.development | 9 +++- .env.production | 9 +++- package.json | 4 +- pnpm-lock.yaml | 78 ++++++++++++++--------------- prisma/schema.prisma | 114 +++++++++++++++++++++---------------------- 5 files changed, 114 insertions(+), 100 deletions(-) diff --git a/.env.development b/.env.development index 9d7881a..75df0fa 100644 --- a/.env.development +++ b/.env.development @@ -7,4 +7,11 @@ NEXT_PUBLIC_API_URL=http://localhost:3000 NEXT_PUBLIC_QSP_API_URL=http://1.248.227.176:8120 #1:1문의 api -NEXT_PUBLIC_INQUIRY_API_URL=http://1.248.227.176:38080 \ No newline at end of file +NEXT_PUBLIC_INQUIRY_API_URL=http://1.248.227.176:38080 + +#QPARTNER 로그인 api +DB_HOST=asdf +DB_USER=asdf +DB_PASSWORD=asdf +DB_DATABASE=asdf +DB_PORT=3306 \ No newline at end of file diff --git a/.env.production b/.env.production index 3d04f51..e1a6d43 100644 --- a/.env.production +++ b/.env.production @@ -5,4 +5,11 @@ NEXT_PUBLIC_API_URL=http://172.30.1.35:3000 NEXT_PUBLIC_QSP_API_URL=http://1.248.227.176:8120 #1:1문의 api -NEXT_PUBLIC_INQUIRY_API_URL=http://1.248.227.176:38080 \ No newline at end of file +NEXT_PUBLIC_INQUIRY_API_URL=http://1.248.227.176:38080 + +#QPARTNER 로그인 api +DB_HOST=asdf +DB_USER=asdf +DB_PASSWORD=asdf +DB_DATABASE=asdf +DB_PORT=3306 \ No newline at end of file diff --git a/package.json b/package.json index 61c7e67..7d5da52 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "^6.5.0", + "@prisma/client": "^6.7.0", "@tanstack/react-query": "^5.71.0", "@tanstack/react-query-devtools": "^5.71.0", "axios": "^1.8.4", @@ -28,7 +28,7 @@ "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "prisma": "^6.5.0", + "prisma": "^6.7.0", "tailwindcss": "^4", "typescript": "^5" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08d920f..9ebc4c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@prisma/client': - specifier: ^6.5.0 - version: 6.5.0(prisma@6.5.0(typescript@5.8.2))(typescript@5.8.2) + specifier: ^6.7.0 + version: 6.7.0(prisma@6.7.0(typescript@5.8.2))(typescript@5.8.2) '@tanstack/react-query': specifier: ^5.71.0 version: 5.71.0(react@19.1.0) @@ -61,8 +61,8 @@ importers: specifier: ^19 version: 19.0.4(@types/react@19.0.12) prisma: - specifier: ^6.5.0 - version: 6.5.0(typescript@5.8.2) + specifier: ^6.7.0 + version: 6.7.0(typescript@5.8.2) tailwindcss: specifier: ^4 version: 4.0.17 @@ -538,8 +538,8 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@prisma/client@6.5.0': - resolution: {integrity: sha512-M6w1Ql/BeiGoZmhMdAZUXHu5sz5HubyVcKukbLs3l0ELcQb8hTUJxtGEChhv4SVJ0QJlwtLnwOLgIRQhpsm9dw==} + '@prisma/client@6.7.0': + resolution: {integrity: sha512-+k61zZn1XHjbZul8q6TdQLpuI/cvyfil87zqK2zpreNIXyXtpUv3+H/oM69hcsFcZXaokHJIzPAt5Z8C8eK2QA==} engines: {node: '>=18.18'} peerDependencies: prisma: '*' @@ -550,23 +550,23 @@ packages: typescript: optional: true - '@prisma/config@6.5.0': - resolution: {integrity: sha512-sOH/2Go9Zer67DNFLZk6pYOHj+rumSb0VILgltkoxOjYnlLqUpHPAN826vnx8HigqnOCxj9LRhT6U7uLiIIWgw==} + '@prisma/config@6.7.0': + resolution: {integrity: sha512-di8QDdvSz7DLUi3OOcCHSwxRNeW7jtGRUD2+Z3SdNE3A+pPiNT8WgUJoUyOwJmUr5t+JA2W15P78C/N+8RXrOA==} - '@prisma/debug@6.5.0': - resolution: {integrity: sha512-fc/nusYBlJMzDmDepdUtH9aBsJrda2JNErP9AzuHbgUEQY0/9zQYZdNlXmKoIWENtio+qarPNe/+DQtrX5kMcQ==} + '@prisma/debug@6.7.0': + resolution: {integrity: sha512-RabHn9emKoYFsv99RLxvfG2GHzWk2ZI1BuVzqYtmMSIcuGboHY5uFt3Q3boOREM9de6z5s3bQoyKeWnq8Fz22w==} - '@prisma/engines-version@6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60': - resolution: {integrity: sha512-iK3EmiVGFDCmXjSpdsKGNqy9hOdLnvYBrJB61far/oP03hlIxrb04OWmDjNTwtmZ3UZdA5MCvI+f+3k2jPTflQ==} + '@prisma/engines-version@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': + resolution: {integrity: sha512-EvpOFEWf1KkJpDsBCrih0kg3HdHuaCnXmMn7XFPObpFTzagK1N0Q0FMnYPsEhvARfANP5Ok11QyoTIRA2hgJTA==} - '@prisma/engines@6.5.0': - resolution: {integrity: sha512-FVPQYHgOllJklN9DUyujXvh3hFJCY0NX86sDmBErLvoZjy2OXGiZ5FNf3J/C4/RZZmCypZBYpBKEhx7b7rEsdw==} + '@prisma/engines@6.7.0': + resolution: {integrity: sha512-3wDMesnOxPrOsq++e5oKV9LmIiEazFTRFZrlULDQ8fxdub5w4NgRBoxtWbvXmj2nJVCnzuz6eFix3OhIqsZ1jw==} - '@prisma/fetch-engine@6.5.0': - resolution: {integrity: sha512-3LhYA+FXP6pqY8FLHCjewyE8pGXXJ7BxZw2rhPq+CZAhvflVzq4K8Qly3OrmOkn6wGlz79nyLQdknyCG2HBTuA==} + '@prisma/fetch-engine@6.7.0': + resolution: {integrity: sha512-zLlAGnrkmioPKJR4Yf7NfW3hftcvqeNNEHleMZK9yX7RZSkhmxacAYyfGsCcqRt47jiZ7RKdgE0Wh2fWnm7WsQ==} - '@prisma/get-platform@6.5.0': - resolution: {integrity: sha512-xYcvyJwNMg2eDptBYFqFLUCfgi+wZLcj6HDMsj0Qw0irvauG4IKmkbywnqwok0B+k+W+p+jThM2DKTSmoPCkzw==} + '@prisma/get-platform@6.7.0': + resolution: {integrity: sha512-i9IH5lO4fQwnMLvQLYNdgVh9TK3PuWBfQd7QLk/YurnAIg+VeADcZDbmhAi4XBBDD+hDif9hrKyASu0hbjwabw==} '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -1181,8 +1181,8 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} - prisma@6.5.0: - resolution: {integrity: sha512-yUGXmWqv5F4PByMSNbYFxke/WbnyTLjnJ5bKr8fLkcnY7U5rU9rUTh/+Fja+gOrRxEgtCbCtca94IeITj4j/pg==} + prisma@6.7.0: + resolution: {integrity: sha512-vArg+4UqnQ13CVhc2WUosemwh6hr6cr6FY2uzDvCIFwH8pu8BXVv38PktoMLVjtX7sbYThxbnZF5YiR8sN2clw==} engines: {node: '>=18.18'} hasBin: true peerDependencies: @@ -1754,38 +1754,38 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true - '@prisma/client@6.5.0(prisma@6.5.0(typescript@5.8.2))(typescript@5.8.2)': + '@prisma/client@6.7.0(prisma@6.7.0(typescript@5.8.2))(typescript@5.8.2)': optionalDependencies: - prisma: 6.5.0(typescript@5.8.2) + prisma: 6.7.0(typescript@5.8.2) typescript: 5.8.2 - '@prisma/config@6.5.0': + '@prisma/config@6.7.0': dependencies: esbuild: 0.25.2 esbuild-register: 3.6.0(esbuild@0.25.2) transitivePeerDependencies: - supports-color - '@prisma/debug@6.5.0': {} + '@prisma/debug@6.7.0': {} - '@prisma/engines-version@6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60': {} + '@prisma/engines-version@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': {} - '@prisma/engines@6.5.0': + '@prisma/engines@6.7.0': dependencies: - '@prisma/debug': 6.5.0 - '@prisma/engines-version': 6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60 - '@prisma/fetch-engine': 6.5.0 - '@prisma/get-platform': 6.5.0 + '@prisma/debug': 6.7.0 + '@prisma/engines-version': 6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed + '@prisma/fetch-engine': 6.7.0 + '@prisma/get-platform': 6.7.0 - '@prisma/fetch-engine@6.5.0': + '@prisma/fetch-engine@6.7.0': dependencies: - '@prisma/debug': 6.5.0 - '@prisma/engines-version': 6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60 - '@prisma/get-platform': 6.5.0 + '@prisma/debug': 6.7.0 + '@prisma/engines-version': 6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed + '@prisma/get-platform': 6.7.0 - '@prisma/get-platform@6.5.0': + '@prisma/get-platform@6.7.0': dependencies: - '@prisma/debug': 6.5.0 + '@prisma/debug': 6.7.0 '@swc/counter@0.1.3': {} @@ -2413,10 +2413,10 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - prisma@6.5.0(typescript@5.8.2): + prisma@6.7.0(typescript@5.8.2): dependencies: - '@prisma/config': 6.5.0 - '@prisma/engines': 6.5.0 + '@prisma/config': 6.7.0 + '@prisma/engines': 6.7.0 optionalDependencies: fsevents: 2.3.3 typescript: 5.8.2 diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 296042d..7996ce0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -57,65 +57,65 @@ model MS_SUITABLE { updated_at DateTime @updatedAt } -model SD_SERVEY_SALES_BASIC_INFO { - id Int @id @default(autoincrement()) - representative String @db.VarChar(200) - store String? @db.VarChar(200) - construction_point String? @db.VarChar(200) - investigation_date String? @db.VarChar(10) - building_name String? @db.VarChar(200) - customer_name String? @db.VarChar(200) - post_code String? @db.VarChar(10) - address String? @db.VarChar(200) - address_detail String? @db.VarChar(300) - submission_status Boolean @default(false) - submission_date DateTime? @db.Date - created_at DateTime @default(now()) - updated_at DateTime @updatedAt - detail_info SD_SERVEY_SALES_DETAIL_INFO? +model SD_SURVEY_SALES_BASIC_INFO { + ID Int @id @default(autoincrement()) + REPRESENTATIVE String @db.VarChar(200) + STORE String? @db.VarChar(200) + CONSTRUCTION_POINT String? @db.VarChar(200) + INVESTIGATION_DATE String? @db.VarChar(10) + BUILDING_NAME String? @db.VarChar(200) + CUSTOMER_NAME String? @db.VarChar(200) + POST_CODE String? @db.VarChar(10) + ADDRESS String? @db.VarChar(200) + ADDRESS_DETAIL String? @db.VarChar(300) + SUBMISSION_STATUS Boolean @default(false) + SUBMISSION_DATE DateTime? @db.Date + REG_DT DateTime @default(now()) + UPT_DT DateTime @updatedAt + DETAIL_INFO SD_SURVEY_SALES_DETAIL_INFO? } -model SD_SERVEY_SALES_DETAIL_INFO { - id Int @id @default(autoincrement()) - contract_capacity String? @db.VarChar(20) - retail_company String? @db.VarChar(100) - supplementary_facilities String? @db.VarChar(20) - supplementary_facilities_etc String? @db.VarChar(200) - installation_system Int? - installation_system_etc String? @db.VarChar(200) - construction_year Int? - construction_year_etc String? @db.VarChar(200) - roof_material String? @db.VarChar(20) - roof_material_etc String? @db.VarChar(200) - roof_shape Int? - roof_shape_etc String? @db.VarChar(200) - roof_slope String? @db.VarChar(5) - house_structure Int? - house_structure_etc String? @db.VarChar(200) - rafter_material Int? - rafter_material_etc String? @db.VarChar(200) - rafter_size Int? - rafter_size_etc String? @db.VarChar(200) - rafter_pitch Int? - rafter_pitch_etc String? @db.VarChar(200) - rafter_direction Int? - open_field_plate_kind Int? - open_field_plate_kind_etc String? @db.VarChar(200) - open_field_plate_thickness String? @db.VarChar(5) - leak_trace Boolean? @default(false) - waterproof_material Int? - waterproof_material_etc String? @db.VarChar(200) - insulation_presence Int? - insulation_presence_etc String? @db.VarChar(200) - structure_order Int? - structure_order_etc String? @db.VarChar(200) - installation_availability Int? - installation_availability_etc String? @db.VarChar(200) - memo String? @db.VarChar(500) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt - basic_info_id Int @unique - basic_info SD_SERVEY_SALES_BASIC_INFO @relation(fields: [basic_info_id], references: [id]) +model SD_SURVEY_SALES_DETAIL_INFO { + ID Int @id @default(autoincrement()) + CONTRACT_CAPACITY String? @db.VarChar(20) + RETAIL_COMPANY String? @db.VarChar(100) + SUPPLEMENTARY_FACILITIES String? @db.VarChar(20) + SUPPLEMENTARY_FACILITIES_ETC String? @db.VarChar(200) + INSTALLATION_SYSTEM String? @db.VarChar(20) + INSTALLATION_SYSTEM_ETC String? @db.VarChar(200) + CONSTRUCTION_YEAR String? @db.VarChar(200) + CONSTRUCTION_YEAR_ETC String? @db.VarChar(200) + ROOF_MATERIAL String? @db.VarChar(20) + ROOF_MATERIAL_ETC String? @db.VarChar(200) + ROOF_SHAPE String? @db.VarChar(20) + ROOF_SHAPE_ETC String? @db.VarChar(200) + ROOF_SLOPE String? @db.VarChar(5) + HOUSE_STRUCTURE String? @db.VarChar(20) + HOUSE_STRUCTURE_ETC String? @db.VarChar(200) + RAFTER_MATERIAL String? @db.VarChar(20) + RAFTER_MATERIAL_ETC String? @db.VarChar(200) + RAFTER_SIZE String? @db.VarChar(20) + RAFTER_SIZE_ETC String? @db.VarChar(200) + RAFTER_PITCH String? @db.VarChar(20) + RAFTER_PITCH_ETC String? @db.VarChar(200) + RAFTER_DIRECTION String? @db.VarChar(20) + OPEN_FIELD_PLATE_KIND String? @db.VarChar(20) + OPEN_FIELD_PLATE_KIND_ETC String? @db.VarChar(200) + OPEN_FIELD_PLATE_THICKNESS String? @db.VarChar(5) + LEAK_TRACE Boolean? @default(false) + WATERPROOF_MATERIAL String? @db.VarChar(20) + WATERPROOF_MATERIAL_ETC String? @db.VarChar(200) + INSULATION_PRESENCE String? @db.VarChar(20) + INSULATION_PRESENCE_ETC String? @db.VarChar(200) + STRUCTURE_ORDER String? @db.VarChar(20) + STRUCTURE_ORDER_ETC String? @db.VarChar(200) + INSTALLATION_AVAILABILITY String? @db.VarChar(20) + INSTALLATION_AVAILABILITY_ETC String? @db.VarChar(200) + MEMO String? @db.VarChar(500) + REG_DT DateTime @default(now()) + UPT_DT DateTime @updatedAt + BASIC_INFO_ID Int @unique + BASIC_INFO SD_SURVEY_SALES_BASIC_INFO @relation(fields: [BASIC_INFO_ID], references: [ID]) } model BC_COMM_H {