feat: enhance survey sales API and component integration
- 조사매물 조회 시 권한 확인 로직 추가
This commit is contained in:
parent
c6664e9827
commit
e756465250
@ -1,18 +1,60 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import { prisma } from '@/libs/prisma'
|
import { prisma } from '@/libs/prisma'
|
||||||
import { convertToSnakeCase } from '@/utils/common-utils'
|
import { convertToSnakeCase } from '@/utils/common-utils'
|
||||||
|
import { SessionData } from '@/types/Auth'
|
||||||
|
|
||||||
|
type SessionParams = {
|
||||||
|
role: string | null
|
||||||
|
storeId: string | null
|
||||||
|
builderNo: string | null
|
||||||
|
isLoggedIn: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkRole = (survey: any, sessionParams: SessionParams) => {
|
||||||
|
switch (sessionParams.role) {
|
||||||
|
case 'T01':
|
||||||
|
return true
|
||||||
|
case 'Admin':
|
||||||
|
if (survey.SUBMISSION_STATUS) {
|
||||||
|
return survey.SUBMISSION_TARGET_ID === sessionParams.storeId
|
||||||
|
}
|
||||||
|
return survey.STORE_ID === sessionParams.storeId
|
||||||
|
case 'Admin_Sub':
|
||||||
|
if (survey.SUBMISSION_STATUS) {
|
||||||
|
return survey.SUBMISSION_TARGET_ID === sessionParams.builderNo
|
||||||
|
}
|
||||||
|
return survey.STORE_ID === sessionParams.storeId && survey.CONSTRUCTION_POINT_ID === sessionParams.builderNo
|
||||||
|
case 'Partner':
|
||||||
|
case 'Builder':
|
||||||
|
return survey.CONSTRUCTION_POINT_ID === sessionParams.builderNo
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||||
try {
|
try {
|
||||||
const { id } = await params
|
const { id } = await params
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
|
||||||
|
const sessionParams: SessionParams = {
|
||||||
|
role: searchParams.get('role'),
|
||||||
|
storeId: searchParams.get('storeId'),
|
||||||
|
builderNo: searchParams.get('builderNo'),
|
||||||
|
isLoggedIn: searchParams.get('isLoggedIn'),
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const survey = await prisma.SD_SURVEY_SALES_BASIC_INFO.findUnique({
|
const survey = await prisma.SD_SURVEY_SALES_BASIC_INFO.findFirst({
|
||||||
where: { ID: Number(id) },
|
where: {
|
||||||
|
ID: Number(id),
|
||||||
|
},
|
||||||
include: {
|
include: {
|
||||||
DETAIL_INFO: true,
|
DETAIL_INFO: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return NextResponse.json(survey)
|
if (checkRole(survey, sessionParams)) {
|
||||||
|
return NextResponse.json(survey)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching survey:', error)
|
console.error('Error fetching survey:', error)
|
||||||
return NextResponse.json({ error: 'Failed to fetch survey' }, { status: 500 })
|
return NextResponse.json({ error: 'Failed to fetch survey' }, { status: 500 })
|
||||||
|
|||||||
@ -4,16 +4,20 @@ import { useEffect, useState } from 'react'
|
|||||||
import { useSurveySaleTabState } from '@/store/surveySaleTabState'
|
import { useSurveySaleTabState } from '@/store/surveySaleTabState'
|
||||||
import type { SurveyBasicRequest } from '@/types/Survey'
|
import type { SurveyBasicRequest } from '@/types/Survey'
|
||||||
import type { Mode } from 'fs'
|
import type { Mode } from 'fs'
|
||||||
import { useSessionStore } from '@/store/session'
|
|
||||||
import { usePopupController } from '@/store/popupController'
|
import { usePopupController } from '@/store/popupController'
|
||||||
import { useAddressStore } from '@/store/addressStore'
|
import { useAddressStore } from '@/store/addressStore'
|
||||||
|
import { SessionData } from '@/types/Auth'
|
||||||
|
|
||||||
export default function BasicForm(props: { basicInfo: SurveyBasicRequest; setBasicInfo: (basicInfo: SurveyBasicRequest) => void; mode: Mode }) {
|
export default function BasicForm(props: {
|
||||||
const { basicInfo, setBasicInfo, mode } = props
|
basicInfo: SurveyBasicRequest
|
||||||
|
setBasicInfo: (basicInfo: SurveyBasicRequest) => void
|
||||||
|
mode: Mode
|
||||||
|
session: SessionData
|
||||||
|
}) {
|
||||||
|
const { basicInfo, setBasicInfo, mode, session } = props
|
||||||
const { setBasicInfoSelected } = useSurveySaleTabState()
|
const { setBasicInfoSelected } = useSurveySaleTabState()
|
||||||
const [isFlip, setIsFlip] = useState<boolean>(true)
|
const [isFlip, setIsFlip] = useState<boolean>(true)
|
||||||
|
|
||||||
const { session } = useSessionStore()
|
|
||||||
const { addressData } = useAddressStore()
|
const { addressData } = useAddressStore()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -32,10 +32,12 @@ export default function ButtonForm(props: {
|
|||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
// 권한
|
// 권한
|
||||||
|
|
||||||
// 제출권한 ㅇ
|
// 제출권한 있는 회원
|
||||||
const [isSubmiter, setIsSubmiter] = useState(false)
|
const [isSubmiter, setIsSubmiter] = useState(false)
|
||||||
// 작성자
|
// 작성자
|
||||||
const [isWriter, setIsWriter] = useState(false)
|
const [isWriter, setIsWriter] = useState(false)
|
||||||
|
// 제출받은 대상자
|
||||||
|
const [isReceiver, setIsReceiver] = useState(false)
|
||||||
const isSubmit = props.data.basic.submissionStatus
|
const isSubmit = props.data.basic.submissionStatus
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -44,11 +46,13 @@ export default function ButtonForm(props: {
|
|||||||
// T01 제출권한 없음
|
// T01 제출권한 없음
|
||||||
case 'T01':
|
case 'T01':
|
||||||
setIsSubmiter(false)
|
setIsSubmiter(false)
|
||||||
|
setIsReceiver(!props.data.basic.submissionTargetId && !props.data.basic.submissionTargetNm)
|
||||||
break
|
break
|
||||||
// 1차 판매점(Order) + 2차 판매점(Musubi) => 같은 판매점 제출권한
|
// 1차 판매점(Order) + 2차 판매점(Musubi) => 같은 판매점 제출권한
|
||||||
case 'Admin':
|
case 'Admin':
|
||||||
case 'Admin_Sub':
|
case 'Admin_Sub':
|
||||||
setIsSubmiter(session.storeNm === props.data.basic.store && session.builderNo === props.data.basic.constructionPointId)
|
setIsSubmiter(session.storeNm === props.data.basic.store && session.builderNo === props.data.basic.constructionPointId)
|
||||||
|
setIsReceiver(session?.storeId === props.data.basic.submissionTargetId)
|
||||||
break
|
break
|
||||||
// 시공권한 User(Musubi) + Partner => 같은 시공ID 제출권한
|
// 시공권한 User(Musubi) + Partner => 같은 시공ID 제출권한
|
||||||
case 'Builder':
|
case 'Builder':
|
||||||
@ -59,7 +63,6 @@ export default function ButtonForm(props: {
|
|||||||
setIsSubmiter(false)
|
setIsSubmiter(false)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsWriter(session.userNm === props.data.basic.representative)
|
setIsWriter(session.userNm === props.data.basic.representative)
|
||||||
}
|
}
|
||||||
setSaveData({
|
setSaveData({
|
||||||
@ -175,19 +178,11 @@ export default function ButtonForm(props: {
|
|||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
// 제출 완료 된 매물의 경우 제출 권한 있으면 수정/삭제 불가능
|
if (!session?.isLoggedIn) {
|
||||||
if (mode === 'READ' && isSubmit && isSubmiter) {
|
return <></>
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="sale-form-btn-wrap">
|
|
||||||
<div className="btn-flex-wrap">
|
|
||||||
<ListButton />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (mode === 'READ' && session?.role === 'T01' && (!isSubmit || (props.data.basic.submissionTargetId && props.data.basic.submissionTargetNm))) {
|
|
||||||
|
if (mode === 'READ' && isSubmit && isSubmiter) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="sale-form-btn-wrap">
|
<div className="sale-form-btn-wrap">
|
||||||
@ -205,8 +200,8 @@ export default function ButtonForm(props: {
|
|||||||
<div className="sale-form-btn-wrap">
|
<div className="sale-form-btn-wrap">
|
||||||
<div className="btn-flex-wrap">
|
<div className="btn-flex-wrap">
|
||||||
<ListButton />
|
<ListButton />
|
||||||
<EditButton setMode={setMode} id={id.toString()} mode={mode} />
|
{(isSubmiter || (isReceiver && isSubmit)) && <EditButton setMode={setMode} id={id.toString()} mode={mode} />}
|
||||||
{(isWriter || !isSubmiter) && <DeleteButton handleDelete={handleDelete} />}
|
{(isWriter || (isReceiver && isSubmit)) && <DeleteButton handleDelete={handleDelete} />}
|
||||||
{!isSubmit && isSubmiter && <SubmitButton handleSubmit={handleSubmit} />}
|
{!isSubmit && isSubmiter && <SubmitButton handleSubmit={handleSubmit} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,7 +213,7 @@ export default function ButtonForm(props: {
|
|||||||
<ListButton />
|
<ListButton />
|
||||||
<TempButton setMode={setMode} handleSave={() => handleSave(true, false)} />
|
<TempButton setMode={setMode} handleSave={() => handleSave(true, false)} />
|
||||||
<SaveButton handleSave={() => handleSave(false, false)} />
|
<SaveButton handleSave={() => handleSave(false, false)} />
|
||||||
{session?.role === 'T01' || props.data.basic.submissionStatus ? <></> : <SubmitButton handleSubmit={handleSubmit} />}
|
{session?.role === 'T01' || isSubmit ? <></> : <SubmitButton handleSubmit={handleSubmit} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import BasicForm from './BasicForm'
|
|||||||
import RoofForm from './RoofForm'
|
import RoofForm from './RoofForm'
|
||||||
import { useParams, useSearchParams } from 'next/navigation'
|
import { useParams, useSearchParams } from 'next/navigation'
|
||||||
import { useSurvey } from '@/hooks/useSurvey'
|
import { useSurvey } from '@/hooks/useSurvey'
|
||||||
|
import { useSessionStore } from '@/store/session'
|
||||||
|
|
||||||
const roofInfoForm: SurveyDetailRequest = {
|
const roofInfoForm: SurveyDetailRequest = {
|
||||||
contractCapacity: null,
|
contractCapacity: null,
|
||||||
@ -74,6 +75,7 @@ export default function DetailForm() {
|
|||||||
const id = Number(routeId) ? Number(routeId) : Number(idParam)
|
const id = Number(routeId) ? Number(routeId) : Number(idParam)
|
||||||
|
|
||||||
const { surveyDetail, validateSurveyDetail } = useSurvey(Number(id))
|
const { surveyDetail, validateSurveyDetail } = useSurvey(Number(id))
|
||||||
|
const { session } = useSessionStore()
|
||||||
|
|
||||||
const [mode, setMode] = useState<Mode>(modeset)
|
const [mode, setMode] = useState<Mode>(modeset)
|
||||||
const [basicInfoData, setBasicInfoData] = useState<SurveyBasicRequest>(basicInfoForm)
|
const [basicInfoData, setBasicInfoData] = useState<SurveyBasicRequest>(basicInfoForm)
|
||||||
@ -81,7 +83,7 @@ export default function DetailForm() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Number(idParam) !== 0 || surveyDetail === null) {
|
if (Number(idParam) !== 0 || surveyDetail === null) {
|
||||||
alert('データが見つかりません。')
|
alert('権限がありません。')
|
||||||
window.location.href = '/survey-sale'
|
window.location.href = '/survey-sale'
|
||||||
}
|
}
|
||||||
if (surveyDetail && (mode === 'EDIT' || mode === 'READ')) {
|
if (surveyDetail && (mode === 'EDIT' || mode === 'READ')) {
|
||||||
@ -94,7 +96,7 @@ export default function DetailForm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [surveyDetail, id])
|
}, [surveyDetail, id, mode, session])
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
basic: basicInfoData,
|
basic: basicInfoData,
|
||||||
@ -107,7 +109,7 @@ export default function DetailForm() {
|
|||||||
<>
|
<>
|
||||||
<div className="sale-detail-toggle-wrap">
|
<div className="sale-detail-toggle-wrap">
|
||||||
{/* 기본정보 */}
|
{/* 기본정보 */}
|
||||||
<BasicForm basicInfo={basicInfoData} setBasicInfo={setBasicInfoData} mode={mode} />
|
<BasicForm basicInfo={basicInfoData} setBasicInfo={setBasicInfoData} mode={mode} session={session} />
|
||||||
{/* 전기/지붕정보 */}
|
{/* 전기/지붕정보 */}
|
||||||
<RoofForm roofInfo={roofInfoData} setRoofInfo={setRoofInfoData} mode={mode} />
|
<RoofForm roofInfo={roofInfoData} setRoofInfo={setRoofInfoData} mode={mode} />
|
||||||
<ButtonForm {...buttonFormProps} />
|
<ButtonForm {...buttonFormProps} />
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
|||||||
import { useSessionStore } from '@/store/session'
|
import { useSessionStore } from '@/store/session'
|
||||||
import { useAxios } from './useAxios'
|
import { useAxios } from './useAxios'
|
||||||
import { queryStringFormatter } from '@/utils/common-utils'
|
import { queryStringFormatter } from '@/utils/common-utils'
|
||||||
|
import { AxiosError } from 'axios'
|
||||||
|
|
||||||
export const requiredFields = [
|
export const requiredFields = [
|
||||||
{
|
{
|
||||||
@ -111,8 +112,18 @@ export function useSurvey(id?: number): {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (id === undefined) throw new Error('id is required')
|
if (id === undefined) throw new Error('id is required')
|
||||||
if (id === null || isNaN(id)) return null
|
if (id === null || isNaN(id)) return null
|
||||||
const resp = await axiosInstance(null).get<SurveyBasicInfo>(`/api/survey-sales/${id}`)
|
if (session?.isLoggedIn) {
|
||||||
return resp.data
|
const resp = await axiosInstance(null).get<SurveyBasicInfo>(`/api/survey-sales/${id}`, {
|
||||||
|
params: {
|
||||||
|
role: session?.role,
|
||||||
|
storeId: session?.storeId,
|
||||||
|
builderNo: session?.builderNo,
|
||||||
|
isLoggedIn: session?.isLoggedIn,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return resp.data
|
||||||
|
}
|
||||||
|
return null
|
||||||
},
|
},
|
||||||
enabled: id !== undefined,
|
enabled: id !== undefined,
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user