Merge branch 'dev' into feature/test-jy
This commit is contained in:
commit
7bc2d9acd6
@ -32,6 +32,7 @@
|
|||||||
"react-icons": "^5.3.0",
|
"react-icons": "^5.3.0",
|
||||||
"react-loading-skeleton": "^3.5.0",
|
"react-loading-skeleton": "^3.5.0",
|
||||||
"react-responsive-modal": "^6.4.2",
|
"react-responsive-modal": "^6.4.2",
|
||||||
|
"react-spinners": "^0.14.1",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"sweetalert2": "^11.14.1",
|
"sweetalert2": "^11.14.1",
|
||||||
"sweetalert2-react-content": "^5.0.7",
|
"sweetalert2-react-content": "^5.0.7",
|
||||||
|
|||||||
@ -1,23 +1,40 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { createContext, useEffect, useState } from 'react'
|
||||||
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
||||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import ServerError from './error'
|
import ServerError from './error'
|
||||||
|
|
||||||
import '@/styles/common.scss'
|
import '@/styles/common.scss'
|
||||||
|
import GlobalSpinner from '@/components/common/spinner/GlobalSpinner'
|
||||||
|
|
||||||
|
export const QcastContext = createContext({
|
||||||
|
qcastState: {},
|
||||||
|
setQcastState: () => {},
|
||||||
|
isGlobalLoading: false,
|
||||||
|
setIsGlobalLoading: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
export const QcastProvider = ({ children }) => {
|
export const QcastProvider = ({ children }) => {
|
||||||
const [planSave, setPlanSave] = useState(false)
|
const [planSave, setPlanSave] = useState(false)
|
||||||
|
const [isGlobalLoading, setIsGlobalLoading] = useState(false)
|
||||||
const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan()
|
const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan()
|
||||||
const { commonCode, findCommonCode } = useCommonCode()
|
const { commonCode, findCommonCode } = useCommonCode()
|
||||||
|
|
||||||
|
const [qcastState, setQcastState] = useState({
|
||||||
|
saleStoreId: '',
|
||||||
|
saleStoreName: '',
|
||||||
|
objectList: [],
|
||||||
|
businessCharger: null,
|
||||||
|
businessChargerMail: null,
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const targetElement = document.getElementById('canvas')
|
const targetElement = document.getElementById('canvas')
|
||||||
if (!targetElement && currentCanvasPlan?.id && planSave) {
|
if (!targetElement && currentCanvasPlan?.id && planSave) {
|
||||||
setPlanSave((prev) => !prev)
|
setPlanSave((prev) => !prev)
|
||||||
checkUnsavedCanvasPlan(currentCanvasPlan.userId)
|
checkUnsavedCanvasPlan(currentCanvasPlan.userId)
|
||||||
} else if (targetElement && currentCanvasPlan?.id) {
|
} else if (targetElement && currentCanvasPlan?.id) {
|
||||||
setPlanSave(true)
|
setPlanSave(true)
|
||||||
}
|
}
|
||||||
@ -30,7 +47,14 @@ export const QcastProvider = ({ children }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ErrorBoundary fallback={<ServerError />}>{children}</ErrorBoundary>
|
{isGlobalLoading && (
|
||||||
|
<div className="fixed inset-0 bg-white z-50 flex items-center justify-center">
|
||||||
|
<GlobalSpinner />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<QcastContext.Provider value={{ qcastState, setQcastState, isGlobalLoading, setIsGlobalLoading }}>
|
||||||
|
<ErrorBoundary fallback={<ServerError />}>{children}</ErrorBoundary>
|
||||||
|
</QcastContext.Provider>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import fs from 'fs/promises'
|
|||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
|
|
||||||
export async function GET(req) {
|
export async function GET(req) {
|
||||||
const path = 'public/mapImages'
|
const path = 'public/plan-map-images'
|
||||||
const q = req.nextUrl.searchParams.get('q')
|
const q = req.nextUrl.searchParams.get('q')
|
||||||
const fileNm = req.nextUrl.searchParams.get('fileNm')
|
const fileNm = req.nextUrl.searchParams.get('fileNm')
|
||||||
const zoom = req.nextUrl.searchParams.get('zoom')
|
const zoom = req.nextUrl.searchParams.get('zoom')
|
||||||
|
|||||||
25
src/app/api/image-upload/route.js
Normal file
25
src/app/api/image-upload/route.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
|
||||||
|
export async function POST(req) {
|
||||||
|
const path = 'public/plan-bg-images'
|
||||||
|
|
||||||
|
const formData = await req.formData()
|
||||||
|
const file = formData.get('file')
|
||||||
|
const arrayBuffer = await file.arrayBuffer()
|
||||||
|
const buffer = Buffer.from(arrayBuffer)
|
||||||
|
// const buffer = new Uint8Array(arrayBuffer)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.readdir(path)
|
||||||
|
} catch {
|
||||||
|
await fs.mkdir(path)
|
||||||
|
} finally {
|
||||||
|
await fs.writeFile(`${path}/${file.name}`, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ fileNm: `${file.name}` })
|
||||||
|
}
|
||||||
@ -1,9 +1,73 @@
|
|||||||
'ues client'
|
'ues client'
|
||||||
|
|
||||||
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
import { correntObjectNoState } from '@/store/settingAtom'
|
||||||
import ServerError from '../error'
|
import { notFound, usePathname, useSearchParams } from 'next/navigation'
|
||||||
|
// import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
||||||
|
// import ServerError from '../error'
|
||||||
|
import { createContext, useEffect, useReducer, useState } from 'react'
|
||||||
|
import { useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
export const FloorPlanProvider = ({ children }) => {
|
const reducer = (prevState, nextState) => {
|
||||||
console.log('FloorPlanProvider')
|
return { ...prevState, ...nextState }
|
||||||
return <ErrorBoundary fallback={<ServerError />}>{children}</ErrorBoundary>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultEstimateData = {
|
||||||
|
estimateDate: new Date(), //견적일
|
||||||
|
charger: '', //담당자
|
||||||
|
objectName: '', //안건명
|
||||||
|
objectNameOmit: '', //경칭코드
|
||||||
|
estimateType: '', //주문분류
|
||||||
|
remarks: '', //비고
|
||||||
|
estimateOption: '', //견적특이사항
|
||||||
|
itemList: [],
|
||||||
|
fileList: [],
|
||||||
|
fileFlg: '0', //후일 자료 제출 (체크 1 노체크 0)
|
||||||
|
priceCd: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FloorPlanContext = createContext({
|
||||||
|
floorPlanState: {},
|
||||||
|
setFloorPlanState: () => {},
|
||||||
|
estimateContextState: {},
|
||||||
|
setEstimateContextState: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
const FloorPlanProvider = ({ children }) => {
|
||||||
|
const pathname = usePathname()
|
||||||
|
const setCurrentObjectNo = useSetRecoilState(correntObjectNoState)
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
const objectNo = searchParams.get('objectNo')
|
||||||
|
const pid = searchParams.get('pid')
|
||||||
|
|
||||||
|
if (pathname === '/floor-plan') {
|
||||||
|
if (pid === undefined || pid === '' || objectNo === undefined || objectNo === '') {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
setCurrentObjectNo(objectNo)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [floorPlanState, setFloorPlanState] = useState({
|
||||||
|
// 플랜 파일 업로드 모달 오픈 제어
|
||||||
|
refFileModalOpen: false,
|
||||||
|
// 플랜 회전 모드 제어
|
||||||
|
toggleRotate: false,
|
||||||
|
// 물건 번호
|
||||||
|
objectNo,
|
||||||
|
// 플랜 번호
|
||||||
|
pid,
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ FloorPlanProvider ~ floorPlanState:', floorPlanState)
|
||||||
|
}, [floorPlanState])
|
||||||
|
|
||||||
|
const [estimateContextState, setEstimateContextState] = useReducer(reducer, defaultEstimateData)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FloorPlanContext.Provider value={{ floorPlanState, setFloorPlanState, estimateContextState, setEstimateContextState }}>
|
||||||
|
{children}
|
||||||
|
</FloorPlanContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FloorPlanProvider
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import FloorPlanProvider from './FloorPlanProvider'
|
||||||
import FloorPlan from '@/components/floor-plan/FloorPlan'
|
import FloorPlan from '@/components/floor-plan/FloorPlan'
|
||||||
import { FloorPlanProvider } from './FloorPlanProvider'
|
|
||||||
import CanvasLayout from '@/components/floor-plan/CanvasLayout'
|
import CanvasLayout from '@/components/floor-plan/CanvasLayout'
|
||||||
|
|
||||||
export default function FloorPlanLayout({ children }) {
|
export default function FloorPlanLayout({ children }) {
|
||||||
console.log('FloorPlanLayout')
|
console.log('🚀 ~ FloorPlanLayout ~ FloorPlanLayout:')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FloorPlanProvider>
|
<FloorPlanProvider>
|
||||||
|
|||||||
@ -62,16 +62,16 @@ export default async function RootLayout({ children }) {
|
|||||||
{headerPathname === '/login' || headerPathname === '/join' ? (
|
{headerPathname === '/login' || headerPathname === '/join' ? (
|
||||||
<QcastProvider>{children}</QcastProvider>
|
<QcastProvider>{children}</QcastProvider>
|
||||||
) : (
|
) : (
|
||||||
<div className="wrap">
|
<QcastProvider>
|
||||||
<Header userSession={sessionProps} />
|
<div className="wrap">
|
||||||
<div className="content">
|
<Header userSession={sessionProps} />
|
||||||
<Dimmed />
|
<div className="content">
|
||||||
<QcastProvider>
|
<Dimmed />
|
||||||
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
||||||
</QcastProvider>
|
</div>
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
</QcastProvider>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<QModal />
|
<QModal />
|
||||||
<PopupManager />
|
<PopupManager />
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import '@/styles/contents.scss'
|
|||||||
import ChangePasswordPop from './main/ChangePasswordPop'
|
import ChangePasswordPop from './main/ChangePasswordPop'
|
||||||
import { searchState } from '@/store/boardAtom'
|
import { searchState } from '@/store/boardAtom'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export default function MainPage() {
|
export default function MainPage() {
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
@ -26,18 +27,20 @@ export default function MainPage() {
|
|||||||
|
|
||||||
const [searchRadioType, setSearchRadioType] = useState('object')
|
const [searchRadioType, setSearchRadioType] = useState('object')
|
||||||
|
|
||||||
const [saleStoreId, setSaleStoreId] = useState('')
|
// const [saleStoreId, setSaleStoreId] = useState('')
|
||||||
const [saleStoreName, setSaleStoreName] = useState('')
|
// const [saleStoreName, setSaleStoreName] = useState('')
|
||||||
|
|
||||||
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
||||||
|
|
||||||
const [searchForm, setSearchForm] = useRecoilState(searchState)
|
const [searchForm, setSearchForm] = useRecoilState(searchState)
|
||||||
|
|
||||||
useEffect(() => {
|
const { qcastState } = useContext(QcastContext)
|
||||||
if (session.pwdInitYn === 'Y') {
|
|
||||||
fetchObjectList()
|
// useEffect(() => {
|
||||||
}
|
// if (session.pwdInitYn === 'Y') {
|
||||||
}, [session])
|
// fetchObjectList()
|
||||||
|
// }
|
||||||
|
// }, [session])
|
||||||
|
|
||||||
const fetchObjectList = async () => {
|
const fetchObjectList = async () => {
|
||||||
try {
|
try {
|
||||||
@ -108,7 +111,7 @@ export default function MainPage() {
|
|||||||
</div>
|
</div>
|
||||||
<span className="store-arr"></span>
|
<span className="store-arr"></span>
|
||||||
<div className="store-id-name">
|
<div className="store-id-name">
|
||||||
{saleStoreId} / {saleStoreName}
|
{qcastState?.saleStoreId} / {qcastState?.saleStoreName}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="main-search-wrap">
|
<div className="main-search-wrap">
|
||||||
|
|||||||
@ -80,79 +80,32 @@ export default function Login() {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const formData = new FormData(e.target)
|
const formData = new FormData(e.target)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
// 로그인 처리 시작
|
||||||
// 임시 로그인 처리
|
const param = {
|
||||||
setSession({
|
loginId: formData.get('id'),
|
||||||
userId: 'NEW0166102',
|
pwd: formData.get('password'),
|
||||||
saleStoreId: null,
|
|
||||||
name: null,
|
|
||||||
mail: null,
|
|
||||||
tel: null,
|
|
||||||
storeId: 'TEMP02',
|
|
||||||
userNm: 'ㅇㅇ6610',
|
|
||||||
userNmKana: '신규사용자 16610',
|
|
||||||
category: '인상6610',
|
|
||||||
telNo: '336610',
|
|
||||||
fax: null,
|
|
||||||
email: 't10t@naver.com',
|
|
||||||
pwdInitYn: 'Y',
|
|
||||||
storeLvl: '1',
|
|
||||||
groupId: '60000',
|
|
||||||
custCd: '100000',
|
|
||||||
})
|
|
||||||
setSessionState({
|
|
||||||
userId: 'NEW0166102',
|
|
||||||
saleStoreId: null,
|
|
||||||
name: null,
|
|
||||||
mail: null,
|
|
||||||
tel: null,
|
|
||||||
storeId: 'TEMP02',
|
|
||||||
userNm: 'ㅇㅇ6610',
|
|
||||||
userNmKana: '신규사용자 16610',
|
|
||||||
category: '인상6610',
|
|
||||||
telNo: '336610',
|
|
||||||
fax: null,
|
|
||||||
email: 't10t@naver.com',
|
|
||||||
pwdInitYn: 'Y',
|
|
||||||
storeLvl: '1',
|
|
||||||
groupId: '60000',
|
|
||||||
custCd: '100000',
|
|
||||||
})
|
|
||||||
if (chkLoginId) {
|
|
||||||
Cookies.set('chkLoginId', formData.get('id'), { expires: 7 })
|
|
||||||
} else {
|
|
||||||
Cookies.remove('chkLoginId')
|
|
||||||
}
|
}
|
||||||
router.push('/')
|
await promisePost({ url: '/api/login/v1.0/login', data: param })
|
||||||
// 임시 로그인 처리 끝
|
.then((res) => {
|
||||||
///////////////////////////////////////////////////////////
|
if (res) {
|
||||||
|
if (res.data.result.resultCode === 'S') {
|
||||||
// 로그인 처리 시작 - ** 상단 임시 로그인 추후 삭제 필요 **
|
setSession(res.data.data)
|
||||||
// const param = {
|
setSessionState(res.data.data)
|
||||||
// loginId: formData.get('id'),
|
// ID SAVE 체크되어 있는 경우, 쿠키 저장
|
||||||
// pwd: formData.get('password'),
|
if (chkLoginId) {
|
||||||
// }
|
Cookies.set('chkLoginId', formData.get('id'), { expires: 7 })
|
||||||
// await promisePost({ url: '/api/login/v1.0/login', data: param })
|
} else {
|
||||||
// .then((res) => {
|
Cookies.remove('chkLoginId')
|
||||||
// if (res) {
|
}
|
||||||
// if (res.data.result.resultCode === 'S') {
|
router.push('/')
|
||||||
// setSession(res.data.data)
|
} else {
|
||||||
// setSessionState(res.data.data)
|
alert(res.data.result.resultMsg)
|
||||||
// // ID SAVE 체크되어 있는 경우, 쿠키 저장
|
}
|
||||||
// if (chkLoginId) {
|
}
|
||||||
// Cookies.set('chkLoginId', formData.get('id'), { expires: 7 })
|
})
|
||||||
// } else {
|
.catch((error) => {
|
||||||
// Cookies.remove('chkLoginId')
|
alert(error.response.data.message)
|
||||||
// }
|
})
|
||||||
// router.push('/')
|
|
||||||
// } else {
|
|
||||||
// alert(res.data.result.resultMsg)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .catch((error) => {
|
|
||||||
// alert(error.response.data.message)
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 비밀번호 초기화 관련
|
// 비밀번호 초기화 관련
|
||||||
|
|||||||
7
src/components/common/spinner/GlobalSpinner.jsx
Normal file
7
src/components/common/spinner/GlobalSpinner.jsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { HashLoader } from 'react-spinners'
|
||||||
|
|
||||||
|
export default function GlobalSpinner() {
|
||||||
|
return <HashLoader />
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -13,13 +13,12 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
const [schDownload, setSchDownload] = useState('EXCEL')
|
const [schDownload, setSchDownload] = useState('EXCEL')
|
||||||
//다운로드 파일 EXCEL
|
//다운로드 파일 EXCEL
|
||||||
const [schUnitPriceFlg, setSchUnitPriceFlg] = useState('0')
|
const [schUnitPriceFlg, setSchUnitPriceFlg] = useState('0')
|
||||||
|
|
||||||
//견적제출서 표시명
|
//견적제출서 표시명
|
||||||
const [schDisplayFlg, setSchSchDisplayFlg] = useState('0')
|
const [schDisplayFlg, setSchSchDisplayFlg] = useState('0')
|
||||||
//가대 중량표 포함
|
//가대 중량표 포함(포함:1 미포함 : 0)
|
||||||
const [schWeightFlg, setSchWeightFlg] = useState('0')
|
const [schWeightFlg, setSchWeightFlg] = useState('1')
|
||||||
//도면/시뮬레이션 파일 포함
|
//도면/시뮬레이션 파일 포함
|
||||||
const [schDrawingFlg, setSchDrawingFlg] = useState('0')
|
const [schDrawingFlg, setSchDrawingFlg] = useState('1')
|
||||||
|
|
||||||
// recoil 물건번호
|
// recoil 물건번호
|
||||||
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
||||||
@ -38,6 +37,18 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
sendUnitPriceFlg = '1'
|
sendUnitPriceFlg = '1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//schDrawingFlg 선택값은 의미없어짐
|
||||||
|
//가대중량표 포함, 도면/시뮬레이션 파일 포함 선택값에따라 schDrawingFlg에 |구분자로 보냄
|
||||||
|
//SchDrawingFlg (1 : 견적서,2 : 발전시뮬레이션, 3 : 도면, 4 : 가대)
|
||||||
|
// ex) 1|2|3|4
|
||||||
|
let defaultSchDrawingFlg = '1'
|
||||||
|
if (schWeightFlg === '1') {
|
||||||
|
defaultSchDrawingFlg = defaultSchDrawingFlg.concat('|', '4')
|
||||||
|
}
|
||||||
|
if (schDrawingFlg === '1') {
|
||||||
|
defaultSchDrawingFlg = defaultSchDrawingFlg.concat('|', '2', '|', '3')
|
||||||
|
}
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
objectNo: objectRecoil.floorPlanObjectNo,
|
objectNo: objectRecoil.floorPlanObjectNo,
|
||||||
planNo: planNo,
|
planNo: planNo,
|
||||||
@ -45,25 +56,27 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
schUnitPriceFlg: sendUnitPriceFlg,
|
schUnitPriceFlg: sendUnitPriceFlg,
|
||||||
schDisplayFlg: schDisplayFlg,
|
schDisplayFlg: schDisplayFlg,
|
||||||
schWeightFlg: schWeightFlg,
|
schWeightFlg: schWeightFlg,
|
||||||
schDrawingFlg: schDrawingFlg,
|
schDrawingFlg: defaultSchDrawingFlg,
|
||||||
|
pwrGnrSimType: 'D', //default 화면에 안보여줌
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = { responseType: 'blob' }
|
const options = { responseType: 'blob' }
|
||||||
let fileName
|
|
||||||
console.log('다운로드 PARAM:::', params)
|
|
||||||
await promisePost({ url: url, data: params, option: options })
|
await promisePost({ url: url, data: params, option: options })
|
||||||
.then((resultData) => {
|
.then((resultData) => {
|
||||||
if (resultData) {
|
if (resultData) {
|
||||||
console.log('결과::::::', resultData)
|
let fileName = 'unknow'
|
||||||
const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' })
|
const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' })
|
||||||
const fileUrl = window.URL.createObjectURL(blob)
|
const fileUrl = window.URL.createObjectURL(blob)
|
||||||
|
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = fileUrl
|
link.href = fileUrl
|
||||||
|
|
||||||
if (schDownload === 'EXCEL') {
|
//서버에서 내려오는 파일명
|
||||||
fileName = 'EXCEL_DOWN.xlsx'
|
const contentDisposition = resultData.headers['content-disposition']
|
||||||
} else {
|
if (contentDisposition) {
|
||||||
fileName = 'PDF_DOWN.pdf'
|
fileName = contentDisposition.split('filename=')[1].replace(/['"]/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
link.download = fileName
|
link.download = fileName
|
||||||
document.body.appendChild(link)
|
document.body.appendChild(link)
|
||||||
link.click()
|
link.click()
|
||||||
@ -211,19 +224,6 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className="form-flex-wrap">
|
<div className="form-flex-wrap">
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="schWeightFlg"
|
|
||||||
id="schWeightFlg0"
|
|
||||||
value={'0'}
|
|
||||||
checked={schWeightFlg === '0'}
|
|
||||||
onChange={(e) => {
|
|
||||||
setSchWeightFlg(e.target.value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<label htmlFor="schWeightFlg0">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg0')}</label>
|
|
||||||
</div>
|
|
||||||
<div className="d-check-radio light">
|
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="schWeightFlg"
|
name="schWeightFlg"
|
||||||
@ -236,6 +236,19 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
/>
|
/>
|
||||||
<label htmlFor="schWeightFlg1">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg1')}</label>
|
<label htmlFor="schWeightFlg1">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg1')}</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="d-check-radio light">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="schWeightFlg"
|
||||||
|
id="schWeightFlg0"
|
||||||
|
value={'0'}
|
||||||
|
checked={schWeightFlg === '0'}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSchWeightFlg(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label htmlFor="schWeightFlg0">{getMessage('estimate.detail.docPopup.schWeightFlg.schWeightFlg0')}</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -244,6 +257,19 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className="form-flex-wrap">
|
<div className="form-flex-wrap">
|
||||||
<div className="d-check-radio light mr10">
|
<div className="d-check-radio light mr10">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="schDrawingFlg"
|
||||||
|
id="schDrawingFlg1"
|
||||||
|
value={'1'}
|
||||||
|
checked={schDrawingFlg === '1'}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSchDrawingFlg(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label htmlFor="schDrawingFlg1">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1')}</label>
|
||||||
|
</div>
|
||||||
|
<div className="d-check-radio light">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="schDrawingFlg"
|
name="schDrawingFlg"
|
||||||
@ -256,19 +282,6 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen }) {
|
|||||||
/>
|
/>
|
||||||
<label htmlFor="schDrawingFlg0">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0')}</label>
|
<label htmlFor="schDrawingFlg0">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio light">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="schDrawingFlg"
|
|
||||||
id="schDrawingFlg01"
|
|
||||||
value={'1'}
|
|
||||||
checked={schDrawingFlg === '1'}
|
|
||||||
onChange={(e) => {
|
|
||||||
setSchDrawingFlg(e.target.value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<label htmlFor="schDrawingFlg01">{getMessage('estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1')}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
313
src/components/estimate/popup/EstimateCopyPop.jsx
Normal file
313
src/components/estimate/popup/EstimateCopyPop.jsx
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
'use client'
|
||||||
|
import { useEffect, useState, useContext, useRef } from 'react'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import Select, { components } from 'react-select'
|
||||||
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
import { isEmptyArray, isObjectNotEmpty } from '@/util/common-utils'
|
||||||
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
|
|
||||||
|
export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) {
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
const { get } = useAxios()
|
||||||
|
|
||||||
|
const { handleEstimateCopy, state } = useEstimateController(planNo)
|
||||||
|
|
||||||
|
const { session } = useContext(SessionContext)
|
||||||
|
|
||||||
|
const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트
|
||||||
|
const [favoriteStoreList, setFavoriteStoreList] = useState([]) //즐겨찾기한 판매점목록
|
||||||
|
const [showSaleStoreList, setShowSaleStoreList] = useState([]) //보여줄 판매점목록
|
||||||
|
const [otherSaleStoreList, setOtherSaleStoreList] = useState([])
|
||||||
|
const [originOtherSaleStoreList, setOriginOtherSaleStoreList] = useState([])
|
||||||
|
|
||||||
|
const [saleStoreId, setSaleStoreId] = useState('') //선택한 1차점
|
||||||
|
const [otherSaleStoreId, setOtherSaleStoreId] = useState('') //선택한 1차점 이외
|
||||||
|
|
||||||
|
const [sendPlanNo, setSendPlanNo] = useState('1')
|
||||||
|
const [copyReceiveUser, setCopyReceiveUser] = useState('')
|
||||||
|
|
||||||
|
const ref = useRef() //2차점 자동완성 초기화용
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let url
|
||||||
|
let firstList
|
||||||
|
let favList
|
||||||
|
let otherList
|
||||||
|
if (session.storeId === 'T01') {
|
||||||
|
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
||||||
|
} else {
|
||||||
|
if (session.storeLvl === '1') {
|
||||||
|
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||||
|
} else {
|
||||||
|
//T01 or 1차점만 복사버튼 노출됨으로
|
||||||
|
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get({ url: url }).then((res) => {
|
||||||
|
if (!isEmptyArray(res)) {
|
||||||
|
res.map((row) => {
|
||||||
|
//자동완성 검색을 위한 필드명 셋팅
|
||||||
|
row.value = row.saleStoreId
|
||||||
|
row.label = row.saleStoreName
|
||||||
|
})
|
||||||
|
|
||||||
|
if (session.storeId === 'T01') {
|
||||||
|
firstList = res
|
||||||
|
//T01을 첫번째로 정렬
|
||||||
|
firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId)
|
||||||
|
favList = firstList.filter((row) => row.saleStoreId === 'T01' || row.priority !== 'B')
|
||||||
|
|
||||||
|
setSaleStoreList(firstList)
|
||||||
|
setFavoriteStoreList(favList)
|
||||||
|
setShowSaleStoreList(favList)
|
||||||
|
setSaleStoreId(session?.storeId)
|
||||||
|
|
||||||
|
// T01때 디폴트로 T01셋팅하고 하위 2차목록 조회하기 바꾸면(onSelectionChange..) 바꾼거로 2차목록 조회하기
|
||||||
|
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=0&userId=${session?.userId}`
|
||||||
|
get({ url: url }).then((res) => {
|
||||||
|
if (!isEmptyArray(res)) {
|
||||||
|
res.map((row) => {
|
||||||
|
row.value == row.saleStoreId
|
||||||
|
row.label = row.saleStoreName
|
||||||
|
})
|
||||||
|
otherList = res
|
||||||
|
setOtherSaleStoreList(otherList)
|
||||||
|
setOriginOtherSaleStoreList(otherList)
|
||||||
|
} else {
|
||||||
|
setOtherSaleStoreList([])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (session.storeLvl === '1') {
|
||||||
|
firstList = res
|
||||||
|
favList = res.filter((row) => row.priority !== 'B')
|
||||||
|
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
||||||
|
setSaleStoreList(firstList)
|
||||||
|
setFavoriteStoreList(firstList)
|
||||||
|
setShowSaleStoreList(firstList)
|
||||||
|
setSaleStoreId(firstList[0].saleStoreId)
|
||||||
|
|
||||||
|
setOtherSaleStoreList(otherList)
|
||||||
|
} else {
|
||||||
|
//T01 or 1차점만 복사버튼 노출됨으로
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (planNo) {
|
||||||
|
setSendPlanNo(planNo)
|
||||||
|
}
|
||||||
|
}, [planNo])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (state?.charger) {
|
||||||
|
setCopyReceiveUser(state.charger)
|
||||||
|
}
|
||||||
|
}, [state.charger])
|
||||||
|
|
||||||
|
//T01 1차점 자동완성 인풋때 목록 변환
|
||||||
|
const onInputChange = (key) => {
|
||||||
|
if (key !== '') {
|
||||||
|
setShowSaleStoreList(saleStoreList)
|
||||||
|
} else {
|
||||||
|
setShowSaleStoreList(favoriteStoreList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1차점 변경 이벤트
|
||||||
|
const onSelectionChange = (key) => {
|
||||||
|
if (isObjectNotEmpty(key)) {
|
||||||
|
if (key.saleStoreId === saleStoreId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObjectNotEmpty(key)) {
|
||||||
|
setSaleStoreId(key.saleStoreId)
|
||||||
|
const url = `/api/object/saleStore/${key.saleStoreId}/list?firstFlg=0&userId=${session?.userId}`
|
||||||
|
let otherList
|
||||||
|
get({ url: url }).then((res) => {
|
||||||
|
if (!isEmptyArray(res)) {
|
||||||
|
res.map((row) => {
|
||||||
|
row.value = row.saleStoreId
|
||||||
|
row.label = row.saleStoreName
|
||||||
|
})
|
||||||
|
|
||||||
|
otherList = res
|
||||||
|
setOtherSaleStoreList(otherList)
|
||||||
|
setOtherSaleStoreId('')
|
||||||
|
} else {
|
||||||
|
setOtherSaleStoreId('')
|
||||||
|
setOtherSaleStoreList([])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setSaleStoreId('')
|
||||||
|
//otherSaleStoreId는 onSelectionChange2에서 초기화됨
|
||||||
|
setOtherSaleStoreList(originOtherSaleStoreList)
|
||||||
|
handleClear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2차점 변경 이벤트
|
||||||
|
const onSelectionChange2 = (key) => {
|
||||||
|
if (isObjectNotEmpty(key)) {
|
||||||
|
if (key.saleStoreId === otherSaleStoreId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObjectNotEmpty(key)) {
|
||||||
|
setOtherSaleStoreId(key.saleStoreId)
|
||||||
|
} else {
|
||||||
|
setOtherSaleStoreId('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2차점 자동완성 초기화
|
||||||
|
const handleClear = () => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.clearValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="modal-popup">
|
||||||
|
<div className="modal-dialog">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h1 className="title">{getMessage('estimate.detail.estimateCopyPopup.title')}</h1>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="modal-close"
|
||||||
|
onClick={() => {
|
||||||
|
setEstimateCopyPopupOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('estimate.detail.estimateCopyPopup.close')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="modal-body-inner">
|
||||||
|
<div className="explane">{getMessage('estimate.detail.estimateCopyPopup.explane')}</div>
|
||||||
|
<div className="estimate-copy-info-wrap">
|
||||||
|
<div className="estimate-copy-info-item">
|
||||||
|
<div className="estimate-copy-info-tit">
|
||||||
|
{getMessage('estimate.detail.estimateCopyPopup.label.saleStoreId')} <span className="red">*</span>
|
||||||
|
</div>
|
||||||
|
{session.storeId === 'T01' && (
|
||||||
|
<div className="estimate-copy-info-box">
|
||||||
|
<div className="estimate-copy-sel">
|
||||||
|
<Select
|
||||||
|
id="long-value-select1"
|
||||||
|
instanceId="long-value-select1"
|
||||||
|
className="react-select-custom"
|
||||||
|
classNamePrefix="custom"
|
||||||
|
placeholder="Select"
|
||||||
|
options={showSaleStoreList}
|
||||||
|
onInputChange={onInputChange}
|
||||||
|
onChange={onSelectionChange}
|
||||||
|
getOptionLabel={(x) => x.saleStoreName}
|
||||||
|
getOptionValue={(x) => x.saleStoreId}
|
||||||
|
isClearable={true}
|
||||||
|
isDisabled={false}
|
||||||
|
value={saleStoreList.filter(function (option) {
|
||||||
|
return option.saleStoreId === saleStoreId
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="estimate-copy-id">{saleStoreId}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{session.storeId !== 'T01' && session.storeLvl === '1' && (
|
||||||
|
<div className="estimate-copy-info-box">
|
||||||
|
<div className="estimate-copy-sel">
|
||||||
|
<Select
|
||||||
|
id="long-value-select1"
|
||||||
|
instanceId="long-value-select1"
|
||||||
|
className="react-select-custom"
|
||||||
|
classNamePrefix="custom"
|
||||||
|
placeholder="Select"
|
||||||
|
options={showSaleStoreList[0]}
|
||||||
|
onChange={onSelectionChange}
|
||||||
|
getOptionLabel={(x) => x.saleStoreName}
|
||||||
|
getOptionValue={(x) => x.saleStoreId}
|
||||||
|
isClearable={false}
|
||||||
|
isDisabled={session?.storeLvl !== '1' ? true : session?.storeId !== 'T01' ? true : false}
|
||||||
|
value={showSaleStoreList.filter(function (option) {
|
||||||
|
return option.saleStoreId === saleStoreId
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="estimate-copy-id">{saleStoreId}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="estimate-copy-info-item">
|
||||||
|
<div className="estimate-copy-info-tit">{getMessage('estimate.detail.estimateCopyPopup.label.otherSaleStoreId')}</div>
|
||||||
|
<div className="estimate-copy-info-box">
|
||||||
|
<div className="estimate-copy-sel">
|
||||||
|
<Select
|
||||||
|
id="long-value-select2"
|
||||||
|
instanceId="long-value-select2"
|
||||||
|
className="react-select-custom"
|
||||||
|
classNamePrefix="custom"
|
||||||
|
placeholder="Select"
|
||||||
|
ref={ref}
|
||||||
|
options={otherSaleStoreList}
|
||||||
|
onChange={onSelectionChange2}
|
||||||
|
getOptionLabel={(x) => x.saleStoreName}
|
||||||
|
getOptionValue={(x) => x.saleStoreId}
|
||||||
|
isClearable={true}
|
||||||
|
isDisabled={otherSaleStoreList.length > 0 ? false : true}
|
||||||
|
value={otherSaleStoreList.filter(function (option) {
|
||||||
|
return option.saleStoreId === otherSaleStoreId
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="estimate-copy-id">{otherSaleStoreId}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="estimate-copy-info-item">
|
||||||
|
<div className="estimate-copy-info-tit">
|
||||||
|
{getMessage('estimate.detail.estimateCopyPopup.label.receiveUser')} <span className="red">*</span>
|
||||||
|
</div>
|
||||||
|
<div className="input-wrap">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-light"
|
||||||
|
required
|
||||||
|
defaultValue={state?.charger}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCopyReceiveUser(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="footer-btn-wrap">
|
||||||
|
<button type="button" className="btn-origin grey mr5" onClick={() => setEstimateCopyPopupOpen(false)}>
|
||||||
|
{getMessage('estimate.detail.estimateCopyPopup.close')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-origin navy"
|
||||||
|
onClick={() => {
|
||||||
|
handleEstimateCopy(sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('estimate.detail.estimateCopyPopup.copyBtn')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -42,7 +42,8 @@ export default function ProductFeaturesPop({ specialNoteList, showProductFeature
|
|||||||
return (
|
return (
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{row.codeNm}</dt>
|
<dt>{row.codeNm}</dt>
|
||||||
<dd dangerouslySetInnerHTML={{ __html: row.remarks }}></dd>
|
{/* <dd dangerouslySetInnerHTML={{ __html: row.remarks }}></dd> */}
|
||||||
|
<dd dangerouslySetInnerHTML={{ __html: row.remarks }} style={{ whiteSpace: 'pre-wrap' }}></dd>
|
||||||
</dl>
|
</dl>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitial
|
|||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
|
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
||||||
|
|
||||||
export default function CanvasFrame() {
|
export default function CanvasFrame() {
|
||||||
const canvasRef = useRef(null)
|
const canvasRef = useRef(null)
|
||||||
@ -76,6 +77,8 @@ export default function CanvasFrame() {
|
|||||||
MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
|
MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
|
||||||
].includes(currentMenu) &&
|
].includes(currentMenu) &&
|
||||||
totalDisplay && <PanelBatchStatistics />}
|
totalDisplay && <PanelBatchStatistics />}
|
||||||
|
{/* 이미지 로드 팝업 */}
|
||||||
|
<ImgLoad />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import CanvasFrame from './CanvasFrame'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
@ -14,7 +14,8 @@ export default function CanvasLayout({ children }) {
|
|||||||
// const { menuNumber } = props
|
// const { menuNumber } = props
|
||||||
const { menuNumber } = useCanvasMenu()
|
const { menuNumber } = useCanvasMenu()
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const [objectNo, setObjectNo] = useState('test123240822001') // 이후 삭제 필요
|
const { floorPlanState } = useContext(FloorPlanContext)
|
||||||
|
const { objectNo, pid } = floorPlanState
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -22,7 +23,7 @@ export default function CanvasLayout({ children }) {
|
|||||||
const { plans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
|
const { plans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadCanvasPlanData(session.userId, objectNo)
|
loadCanvasPlanData(session.userId, objectNo, pid)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
@ -35,6 +35,12 @@ import { MENU } from '@/common/common'
|
|||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
import { estimateState } from '@/store/floorPlanObjectAtom'
|
import { estimateState } from '@/store/floorPlanObjectAtom'
|
||||||
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
import EstimateCopyPop from '../estimate/popup/EstimateCopyPop'
|
||||||
|
|
||||||
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
|
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const { menuNumber, setMenuNumber } = props
|
const { menuNumber, setMenuNumber } = props
|
||||||
@ -59,6 +65,7 @@ export default function CanvasMenu(props) {
|
|||||||
const { handleEstimateSubmit } = useEstimateController()
|
const { handleEstimateSubmit } = useEstimateController()
|
||||||
const estimateRecoilState = useRecoilValue(estimateState)
|
const estimateRecoilState = useRecoilValue(estimateState)
|
||||||
const [estimatePopupOpen, setEstimatePopupOpen] = useState(false)
|
const [estimatePopupOpen, setEstimatePopupOpen] = useState(false)
|
||||||
|
const [estimateCopyPopupOpen, setEstimateCopyPopupOpen] = useState(false)
|
||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { currentCanvasPlan, saveCanvas } = usePlan()
|
const { currentCanvasPlan, saveCanvas } = usePlan()
|
||||||
@ -67,6 +74,7 @@ export default function CanvasMenu(props) {
|
|||||||
const commonUtils = useRecoilValue(commonUtilsState)
|
const commonUtils = useRecoilValue(commonUtilsState)
|
||||||
const { commonFunctions } = useCommonUtils()
|
const { commonFunctions } = useCommonUtils()
|
||||||
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
|
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
|
||||||
|
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||||
|
|
||||||
const onClickNav = (menu) => {
|
const onClickNav = (menu) => {
|
||||||
setMenuNumber(menu.index)
|
setMenuNumber(menu.index)
|
||||||
@ -161,20 +169,6 @@ export default function CanvasMenu(props) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 견적서 복사버튼
|
|
||||||
* (견적서 번호(estimateRecoilState.docNo)가 생성된 이후 버튼 활성화 )
|
|
||||||
* T01관리자 계정 및 1차판매점에게만 제공
|
|
||||||
*/
|
|
||||||
|
|
||||||
const handleEstimateCopy = () => {
|
|
||||||
// console.log('estimateRecoilState::', estimateRecoilState)
|
|
||||||
//objectNo, planNo
|
|
||||||
console.log('복사')
|
|
||||||
console.log('물건정보+도면+견적서를 모두 복사')
|
|
||||||
console.log('견적서 가격은 정가를 표시')
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (globalLocale === 'ko') {
|
if (globalLocale === 'ko') {
|
||||||
setAppMessageState(KO)
|
setAppMessageState(KO)
|
||||||
@ -184,7 +178,7 @@ export default function CanvasMenu(props) {
|
|||||||
}, [type, globalLocale])
|
}, [type, globalLocale])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (['2', '3'].includes(canvasSetting?.roofSizeSet?.toString())) {
|
if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet)) {
|
||||||
setMenuNumber(3)
|
setMenuNumber(3)
|
||||||
setType('surface')
|
setType('surface')
|
||||||
setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING)
|
setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING)
|
||||||
@ -195,8 +189,60 @@ export default function CanvasMenu(props) {
|
|||||||
}
|
}
|
||||||
}, [canvasSetting])
|
}, [canvasSetting])
|
||||||
|
|
||||||
|
const checkMenuState = (menu) => {
|
||||||
|
return ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 발전시물레이션 Excel/PDF 다운
|
||||||
|
const { promisePost } = useAxios(globalLocale)
|
||||||
|
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
||||||
|
const pwrGnrSimTypeRecoil = useRecoilValue(pwrGnrSimTypeState)
|
||||||
|
|
||||||
|
const { plans } = usePlan()
|
||||||
|
const plan = plans.find((plan) => plan.isCurrent === true)
|
||||||
|
|
||||||
|
const handleExcelPdfFileDown = async (donwloadType, drawingFlg) => {
|
||||||
|
const url = '/api/estimate/excel-download'
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
objectNo: objectRecoil.floorPlanObjectNo,
|
||||||
|
planNo: plan?.id,
|
||||||
|
schDownload: donwloadType,
|
||||||
|
schDrawingFlg: drawingFlg,
|
||||||
|
pwrGnrSimType: pwrGnrSimTypeRecoil.type,
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = { responseType: 'blob' }
|
||||||
|
await promisePost({ url: url, data: params, option: options })
|
||||||
|
.then((resultData) => {
|
||||||
|
if (resultData) {
|
||||||
|
let fileName = 'unknow'
|
||||||
|
const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' })
|
||||||
|
const fileUrl = window.URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = fileUrl
|
||||||
|
|
||||||
|
//서버에서 내려오는 파일명
|
||||||
|
const contentDisposition = resultData.headers['content-disposition']
|
||||||
|
if (contentDisposition) {
|
||||||
|
fileName = contentDisposition.split('filename=')[1].replace(/['"]/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
link.download = fileName
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
link.remove()
|
||||||
|
window.URL.revokeObjectURL(fileUrl)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
alert('File does not exist.')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`canvas-menu-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
|
<div className={`canvas-menu-wrap ${[2, 3, 4].some((num) => num === menuNumber) ? 'active' : ''}`}>
|
||||||
<div className="canvas-menu-inner">
|
<div className="canvas-menu-inner">
|
||||||
<ul className="canvas-menu-list">
|
<ul className="canvas-menu-list">
|
||||||
{canvasMenus.map((menu) => {
|
{canvasMenus.map((menu) => {
|
||||||
@ -205,11 +251,12 @@ export default function CanvasMenu(props) {
|
|||||||
key={`canvas-menu-${menu.index}`}
|
key={`canvas-menu-${menu.index}`}
|
||||||
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (['2', '3'].includes(canvasSetting?.roofSizeSet?.toString()) && menu.index === 2) return
|
if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) return
|
||||||
|
if (menuNumber === 4 && menu.index === 2) return
|
||||||
onClickNav(menu)
|
onClickNav(menu)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button className={['2', '3'].includes(canvasSetting?.roofSizeSet?.toString()) && menu.index === 2 ? 'no-click' : ''}>
|
<button className={checkMenuState(menu) ? 'no-click' : ''}>
|
||||||
<span className={`menu-icon ${menu.icon}`}></span>
|
<span className={`menu-icon ${menu.icon}`}></span>
|
||||||
{getMessage(menu.name)}
|
{getMessage(menu.name)}
|
||||||
</button>
|
</button>
|
||||||
@ -218,7 +265,7 @@ export default function CanvasMenu(props) {
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="canvas-side-btn-wrap">
|
<div className="canvas-side-btn-wrap">
|
||||||
{menuNumber !== 6 && menuNumber !== 5 && (
|
{![5, 6].some((num) => num === menuNumber) && (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
<div className={`vertical-horizontal ${verticalHorizontalMode ? 'on' : ''}`}>
|
<div className={`vertical-horizontal ${verticalHorizontalMode ? 'on' : ''}`}>
|
||||||
@ -235,7 +282,10 @@ export default function CanvasMenu(props) {
|
|||||||
<QSelectBox title={'瓦53A'} option={SelectOption} />
|
<QSelectBox title={'瓦53A'} option={SelectOption} />
|
||||||
</div>
|
</div>
|
||||||
<div className="btn-from">
|
<div className="btn-from">
|
||||||
<button className="btn10"></button>
|
<button
|
||||||
|
className={`btn10 ${floorPlanState.refFileModalOpen && 'active'}`}
|
||||||
|
onClick={() => setFloorPlanState({ ...floorPlanState, refFileModalOpen: true })}
|
||||||
|
></button>
|
||||||
{/*<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>*/}
|
{/*<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>*/}
|
||||||
<button className="btn04" onClick={handlePopup}></button>
|
<button className="btn04" onClick={handlePopup}></button>
|
||||||
<button className="btn05"></button>
|
<button className="btn05"></button>
|
||||||
@ -248,7 +298,7 @@ export default function CanvasMenu(props) {
|
|||||||
handleZoom(false)
|
handleZoom(false)
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<span>{canvasZoom}%</span>
|
<span onClick={handleZoomClear}>{canvasZoom}%</span>
|
||||||
<button
|
<button
|
||||||
className="control-btn plus"
|
className="control-btn plus"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -274,7 +324,6 @@ export default function CanvasMenu(props) {
|
|||||||
<span className="ico ico02"></span>
|
<span className="ico ico02"></span>
|
||||||
<span>{getMessage('plan.menu.estimate.save')}</span>
|
<span>{getMessage('plan.menu.estimate.save')}</span>
|
||||||
</button>
|
</button>
|
||||||
{/* {estimateRecoilState?.docNo != null && ( */}
|
|
||||||
<button
|
<button
|
||||||
className="btn-frame gray ico-flx"
|
className="btn-frame gray ico-flx"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -284,28 +333,29 @@ export default function CanvasMenu(props) {
|
|||||||
<span className="ico ico03"></span>
|
<span className="ico ico03"></span>
|
||||||
<span>{getMessage('plan.menu.estimate.reset')}</span>
|
<span>{getMessage('plan.menu.estimate.reset')}</span>
|
||||||
</button>
|
</button>
|
||||||
{/* )} */}
|
|
||||||
|
|
||||||
<button
|
{estimateRecoilState?.docNo !== null && (sessionState.storeId === 'T01' || sessionState.storeLvl === '1') && (
|
||||||
className="btn-frame gray ico-flx"
|
<button
|
||||||
onClick={() => {
|
className="btn-frame gray ico-flx"
|
||||||
handleEstimateCopy()
|
onClick={() => {
|
||||||
}}
|
setEstimateCopyPopupOpen(true)
|
||||||
>
|
}}
|
||||||
<span className="ico ico04"></span>
|
>
|
||||||
<span>{getMessage('plan.menu.estimate.copy')}</span>
|
<span className="ico ico04"></span>
|
||||||
</button>
|
<span>{getMessage('plan.menu.estimate.copy')}</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{menuNumber === 6 && (
|
{menuNumber === 6 && (
|
||||||
<>
|
<>
|
||||||
<div className="ico-btn-from">
|
<div className="ico-btn-from">
|
||||||
<button className="btn-frame gray ico-flx">
|
<button type="button" className="btn-frame gray ico-flx" onClick={() => handleExcelPdfFileDown('EXCEL', '2')}>
|
||||||
<span className="ico ico01"></span>
|
<span className="ico ico01"></span>
|
||||||
<span>{getMessage('plan.menu.simulation.excel')}</span>
|
<span>{getMessage('plan.menu.simulation.excel')}</span>
|
||||||
</button>
|
</button>
|
||||||
<button className="btn-frame gray ico-flx">
|
<button type="button" className="btn-frame gray ico-flx" onClick={() => handleExcelPdfFileDown('PDF', '2')}>
|
||||||
<span className="ico ico01"></span>
|
<span className="ico ico01"></span>
|
||||||
<span>{getMessage('plan.menu.simulation.pdf')}</span>
|
<span>{getMessage('plan.menu.simulation.pdf')}</span>
|
||||||
</button>
|
</button>
|
||||||
@ -314,11 +364,13 @@ export default function CanvasMenu(props) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`canvas-depth2-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
|
<div className={`canvas-depth2-wrap ${[2, 3, 4].some((num) => num === menuNumber) ? 'active' : ''}`}>
|
||||||
{(menuNumber === 2 || menuNumber === 3 || menuNumber === 4) && <MenuDepth01 />}
|
{[2, 3, 4].some((num) => num === menuNumber) && <MenuDepth01 />}
|
||||||
</div>
|
</div>
|
||||||
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */}
|
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */}
|
||||||
{estimatePopupOpen && <DocDownOptionPop planNo={estimateRecoilState?.planNo} setEstimatePopupOpen={setEstimatePopupOpen} />}
|
{estimatePopupOpen && <DocDownOptionPop planNo={estimateRecoilState?.planNo} setEstimatePopupOpen={setEstimatePopupOpen} />}
|
||||||
|
{/* 견적서(menuNumber ===5)복사 팝업 */}
|
||||||
|
{estimateCopyPopupOpen && <EstimateCopyPop planNo={estimateRecoilState?.planNo} setEstimateCopyPopupOpen={setEstimateCopyPopupOpen} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,14 @@ import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@
|
|||||||
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import '@/styles/contents.scss'
|
import '@/styles/contents.scss'
|
||||||
|
|
||||||
export default function FloorPlan({ children }) {
|
export default function FloorPlan({ children }) {
|
||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
||||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
||||||
|
const { closeAll } = usePopup()
|
||||||
|
|
||||||
const { menuNumber, setMenuNumber } = useCanvasMenu()
|
const { menuNumber, setMenuNumber } = useCanvasMenu()
|
||||||
|
|
||||||
@ -24,6 +26,9 @@ export default function FloorPlan({ children }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSettings()
|
fetchSettings()
|
||||||
|
return () => {
|
||||||
|
closeAll()
|
||||||
|
}
|
||||||
}, [objectNo])
|
}, [objectNo])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import { useContext, useEffect } from 'react'
|
||||||
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useRefFiles } from '@/hooks/common/useRefFiles'
|
import { useRefFiles } from '@/hooks/common/useRefFiles'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
@ -20,9 +23,24 @@ export default function ImgLoad() {
|
|||||||
} = useRefFiles()
|
} = useRefFiles()
|
||||||
const { currentCanvasPlan } = usePlan()
|
const { currentCanvasPlan } = usePlan()
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||||
|
|
||||||
|
const handleModal = () => {
|
||||||
|
setFloorPlanState({ ...floorPlanState, refFileModalOpen: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ ImgLoad ~ floorPlanState.refFileModalOpen:', floorPlanState.refFileModalOpen)
|
||||||
|
console.log('🚀 ~ ImgLoad ~ currentCanvasPlan:', currentCanvasPlan)
|
||||||
|
}, [floorPlanState.refFileModalOpen])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const refFileMethod = currentCanvasPlan?.mapPositionAddress === null ? '1' : '2'
|
||||||
|
setRefFileMethod(refFileMethod)
|
||||||
|
}, [currentCanvasPlan])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true}>
|
<WithDraggable isShow={floorPlanState.refFileModalOpen} pos={{ x: 1000, y: 200 }} handle=".modal">
|
||||||
<div className={`modal-pop-wrap r`}>
|
<div className={`modal-pop-wrap r`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage('common.input.file')}</h1>
|
<h1 className="title">{getMessage('common.input.file')}</h1>
|
||||||
@ -32,7 +50,11 @@ export default function ImgLoad() {
|
|||||||
<div className="img-flex-box">
|
<div className="img-flex-box">
|
||||||
<span className="normal-font mr10">サイズ調整と回転</span>
|
<span className="normal-font mr10">サイズ調整と回転</span>
|
||||||
<label className="toggle-btn">
|
<label className="toggle-btn">
|
||||||
<input type="checkbox" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={floorPlanState.toggleRotate}
|
||||||
|
onChange={(e) => setFloorPlanState({ ...floorPlanState, toggleRotate: e.target.checked })}
|
||||||
|
/>
|
||||||
<span className="slider"></span>
|
<span className="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -48,13 +70,18 @@ export default function ImgLoad() {
|
|||||||
<span className="img-edit"></span>
|
<span className="img-edit"></span>
|
||||||
ファイルの追加
|
ファイルの追加
|
||||||
</label>
|
</label>
|
||||||
<input type="file" id="img_file" style={{ display: 'none' }} onChange={(e) => handleRefFile(e.target.files[0])} />
|
<input
|
||||||
|
type="file"
|
||||||
|
id="img_file"
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onChange={refFileMethod === '1' ? (e) => handleRefFile(e.target.files[0]) : () => {}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="img-name-wrap">
|
<div className="img-name-wrap">
|
||||||
{/* <input type="text" className="input-origin al-l" defaultValue={'IMG_Name.PNG'} readOnly />
|
{/* <input type="text" className="input-origin al-l" defaultValue={'IMG_Name.PNG'} readOnly />
|
||||||
<button className="img-check"></button> */}
|
<button className="img-check"></button> */}
|
||||||
{currentCanvasPlan?.bgImageName === null ? (
|
{currentCanvasPlan?.bgImageName === null ? (
|
||||||
<input type="text" className="input-origin al-l" defaultValue={''} value={refImage ? refImage.name : ''} readOnly />
|
<input type="text" className="input-origin al-l" value={refImage ? refImage.name : ''} readOnly />
|
||||||
) : (
|
) : (
|
||||||
<input type="text" className="input-origin al-l" value={currentCanvasPlan?.bgImageName} readOnly />
|
<input type="text" className="input-origin al-l" value={currentCanvasPlan?.bgImageName} readOnly />
|
||||||
)}
|
)}
|
||||||
@ -64,13 +91,20 @@ export default function ImgLoad() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="img-load-item">
|
<div className="img-load-item">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio03" id="ra06" value={'2'} onChange={(e) => handleRefFileMethod(e)} checked={refFileMethod === '2'} />
|
<input type="radio" name="radio03" id="ra07" value={'2'} onChange={(e) => handleRefFileMethod(e)} checked={refFileMethod === '2'} />
|
||||||
<label htmlFor="ra06">アドレスを読み込む</label>
|
<label htmlFor="ra07">アドレスを読み込む</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="img-flex-box for-address">
|
<div className="img-flex-box for-address">
|
||||||
<input type="text" className="input-origin al-l mr10" placeholder={'住所入力'} />
|
<input
|
||||||
|
type="text"
|
||||||
|
ref={queryRef}
|
||||||
|
className="input-origin al-l mr10"
|
||||||
|
placeholder={'住所入力'}
|
||||||
|
value={mapPositionAddress}
|
||||||
|
onChange={(e) => setMapPositionAddress(e.target.value)}
|
||||||
|
/>
|
||||||
<div className="img-edit-wrap">
|
<div className="img-edit-wrap">
|
||||||
<button className="img-edit-btn" onClick={handleMapImageDown}>
|
<button className="img-edit-btn" onClick={refFileMethod === '2' ? handleMapImageDown : () => {}}>
|
||||||
完了
|
完了
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -80,7 +114,9 @@ export default function ImgLoad() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal act">完了</button>
|
<button className="btn-frame modal act" onClick={handleModal}>
|
||||||
|
完了
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,84 +0,0 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { useRecoilValue } from 'recoil'
|
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
export default function AuxiliaryCopy(props) {
|
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
|
||||||
const { id, pos = contextPopupPosition } = props
|
|
||||||
const { getMessage } = useMessage()
|
|
||||||
const { closePopup } = usePopup()
|
|
||||||
const [arrow1, setArrow1] = useState(null)
|
|
||||||
const [arrow2, setArrow2] = useState(null)
|
|
||||||
return (
|
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
|
||||||
<div className={`modal-pop-wrap xm mount`}>
|
|
||||||
<div className="modal-head">
|
|
||||||
<h1 className="title">{getMessage('modal.auxiliary.copy')} </h1>
|
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
|
||||||
닫기
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="modal-body">
|
|
||||||
<div className="grid-option-tit">{getMessage('modal.auxiliary.copy.info')}</div>
|
|
||||||
<div className="grid-option-wrap">
|
|
||||||
<div className="grid-option-box">
|
|
||||||
<div className="move-form">
|
|
||||||
<p className="mb5">{getMessage('length')}</p>
|
|
||||||
<div className="input-move-wrap mb5">
|
|
||||||
<div className="input-move">
|
|
||||||
<input type="text" className="input-origin" defaultValue={910} />
|
|
||||||
</div>
|
|
||||||
<span>mm</span>
|
|
||||||
<div className="direction-move-wrap">
|
|
||||||
<button
|
|
||||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
|
||||||
onClick={() => {
|
|
||||||
setArrow1('↑')
|
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
|
||||||
}}
|
|
||||||
></button>
|
|
||||||
<button
|
|
||||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
|
||||||
onClick={() => {
|
|
||||||
setArrow1('↓')
|
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
|
||||||
}}
|
|
||||||
></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="input-move-wrap">
|
|
||||||
<div className="input-move">
|
|
||||||
<input type="text" className="input-origin" defaultValue={910} />
|
|
||||||
</div>
|
|
||||||
<span>mm</span>
|
|
||||||
<div className="direction-move-wrap">
|
|
||||||
<button
|
|
||||||
className={`direction left ${arrow2 === '←' ? 'act' : ''}`}
|
|
||||||
onClick={() => {
|
|
||||||
setArrow2('←')
|
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
|
||||||
}}
|
|
||||||
></button>
|
|
||||||
<button
|
|
||||||
className={`direction right ${arrow2 === '→' ? 'act' : ''}`}
|
|
||||||
onClick={() => {
|
|
||||||
setArrow2('→')
|
|
||||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
|
||||||
}}
|
|
||||||
></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="grid-btn-wrap">
|
|
||||||
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</WithDraggable>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,37 +1,62 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
|
import { useLine } from '@/hooks/useLine'
|
||||||
|
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
||||||
|
|
||||||
export default function AuxiliaryMove(props) {
|
export default function AuxiliaryEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition } = props
|
const { id, pos = contextPopupPosition, type } = props
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
|
const { move, copy } = useAuxiliaryDrawing()
|
||||||
|
const [verticalSize, setVerticalSize] = useState('0')
|
||||||
|
const [horizonSize, setHorizonSize] = useState('0')
|
||||||
const [arrow1, setArrow1] = useState(null)
|
const [arrow1, setArrow1] = useState(null)
|
||||||
const [arrow2, setArrow2] = useState(null)
|
const [arrow2, setArrow2] = useState(null)
|
||||||
|
const { addLine, removeLine } = useLine()
|
||||||
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
const handleSave = () => {
|
||||||
|
if (type === 'copy') {
|
||||||
|
if (currentObject) {
|
||||||
|
copy(
|
||||||
|
currentObject,
|
||||||
|
arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize),
|
||||||
|
arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
move(
|
||||||
|
currentObject,
|
||||||
|
arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize),
|
||||||
|
arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
closePopup(id)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap xm mount`}>
|
<div className={`modal-pop-wrap xm mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage('modal.auxiliary.move')}</h1>
|
<h1 className="title">{getMessage(type === 'copy' ? 'modal.auxiliary.copy' : 'modal.auxiliary.move')} </h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
닫기
|
닫기
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<div className="grid-option-tit">{getMessage('modal.auxiliary.move.info')}</div>
|
<div className="grid-option-tit">{getMessage(type === 'copy' ? 'modal.auxiliary.copy.info' : 'modal.auxiliary.move.info')}</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-wrap">
|
||||||
<div className="grid-option-box">
|
<div className="grid-option-box">
|
||||||
<div className="move-form">
|
<div className="move-form">
|
||||||
<p className="mb5">{getMessage('length')}</p>
|
<p className="mb5">{getMessage('length')}</p>
|
||||||
<div className="input-move-wrap mb5">
|
<div className="input-move-wrap mb5">
|
||||||
<div className="input-move">
|
<div className="input-move">
|
||||||
<input type="text" className="input-origin" defaultValue={910} />
|
<input type="text" className="input-origin" value={verticalSize} onChange={(e) => setVerticalSize(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
@ -53,7 +78,7 @@ export default function AuxiliaryMove(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="input-move-wrap">
|
<div className="input-move-wrap">
|
||||||
<div className="input-move">
|
<div className="input-move">
|
||||||
<input type="text" className="input-origin" defaultValue={910} />
|
<input type="text" className="input-origin" value={horizonSize} onChange={(e) => setHorizonSize(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
@ -77,7 +102,9 @@ export default function AuxiliaryMove(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
|
<button className="btn-frame modal act" onClick={handleSave}>
|
||||||
|
{getMessage('modal.common.save')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,6 +35,12 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const placementRef = {
|
||||||
|
isChidori: useRef('false'),
|
||||||
|
setupLocation: useRef(null),
|
||||||
|
isMaxSetup: useRef('false'),
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap lx-2`}>
|
<div className={`modal-pop-wrap lx-2`}>
|
||||||
@ -55,7 +61,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
{tabNum === 1 && <Orientation ref={orientationRef} tabNum={tabNum} setTabNum={setTabNum} />}
|
{tabNum === 1 && <Orientation ref={orientationRef} tabNum={tabNum} setTabNum={setTabNum} />}
|
||||||
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
|
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
|
||||||
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 2 && <Module setTabNum={setTabNum} />}
|
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 2 && <Module setTabNum={setTabNum} />}
|
||||||
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 3 && <Placement setTabNum={setTabNum} />}
|
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 3 && <Placement setTabNum={setTabNum} ref={placementRef} />}
|
||||||
|
|
||||||
{/*배치면 초기설정 - 입력방법: 육지붕*/}
|
{/*배치면 초기설정 - 입력방법: 육지붕*/}
|
||||||
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && <PitchModule setTabNum={setTabNum} />}
|
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && <PitchModule setTabNum={setTabNum} />}
|
||||||
@ -78,7 +84,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
<button className="btn-frame modal mr5" onClick={manualModuleSetup}>
|
<button className="btn-frame modal mr5" onClick={manualModuleSetup}>
|
||||||
{getMessage('modal.module.basic.setting.passivity.placement')}
|
{getMessage('modal.module.basic.setting.passivity.placement')}
|
||||||
</button>
|
</button>
|
||||||
<button className="btn-frame modal act" onClick={autoModuleSetup}>
|
<button className="btn-frame modal act" onClick={() => autoModuleSetup(placementRef)}>
|
||||||
{getMessage('modal.module.basic.setting.auto.placement')}
|
{getMessage('modal.module.basic.setting.auto.placement')}
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { forwardRef, useImperativeHandle, useState } from 'react'
|
import { forwardRef, useImperativeHandle, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useOrientation } from '@/hooks/popup/useOrientation'
|
import { useOrientation } from '@/hooks/module/useOrientation'
|
||||||
import { getDegreeInOrientation } from '@/util/canvas-util'
|
import { getDegreeInOrientation } from '@/util/canvas-util'
|
||||||
|
|
||||||
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { forwardRef, useState } from 'react'
|
||||||
|
|
||||||
export default function Placement() {
|
const Placement = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const [isChidori, setIsChidori] = useState('false')
|
||||||
|
|
||||||
const moduleData = {
|
const moduleData = {
|
||||||
header: [
|
header: [
|
||||||
{ type: 'check', name: '', prop: 'check', width: 70 },
|
{ type: 'check', name: '', prop: 'check', width: 70 },
|
||||||
@ -24,6 +27,12 @@ export default function Placement() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleChangeChidori = (e) => {
|
||||||
|
setIsChidori(e.target.value)
|
||||||
|
refs.isChidori.current = e.target.value
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="module-table-flex-wrap mb10">
|
<div className="module-table-flex-wrap mb10">
|
||||||
@ -96,12 +105,20 @@ export default function Placement() {
|
|||||||
<div className="self-item-td">
|
<div className="self-item-td">
|
||||||
<div className="pop-form-radio">
|
<div className="pop-form-radio">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra01" />
|
<input type="radio" name="radio01" id="ra01" checked={isChidori === 'true'} value={'true'} onChange={handleChangeChidori} />
|
||||||
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.module.placement.do')}</label>
|
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.module.placement.do')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra02" />
|
<input
|
||||||
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label>
|
type="radio"
|
||||||
|
name="radio02"
|
||||||
|
id="ra02"
|
||||||
|
value={'false'}
|
||||||
|
defaultChecked
|
||||||
|
checked={isChidori === 'false'}
|
||||||
|
onChange={handleChangeChidori}
|
||||||
|
/>
|
||||||
|
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -137,4 +154,6 @@ export default function Placement() {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
|
export default Placement
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { contextPopupPositionState } from '@/store/popupAtom'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||||
import { FLOW_DIRECTION_TYPE, useFlowDirectionSetting } from '@/hooks/popup/useFlowDirectionSetting'
|
import { FLOW_DIRECTION_TYPE, useFlowDirectionSetting } from '@/hooks/contextpopup/useFlowDirectionSetting'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
export default function FlowDirectionSetting(props) {
|
export default function FlowDirectionSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
|
||||||
import { useState } from 'react'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { useRecoilValue } from 'recoil'
|
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
|
|
||||||
export default function ImageSizeSetting(props) {
|
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
|
||||||
const { id, pos = contextPopupPosition, size, setSize } = props
|
|
||||||
const [sizeValue, setSizeValue] = useState(100)
|
|
||||||
const { getMessage } = useMessage()
|
|
||||||
const { closePopup } = usePopup()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
|
||||||
<div className={`modal-pop-wrap xxxm mount`}>
|
|
||||||
<div className="modal-head">
|
|
||||||
<h1 className="title">{getMessage('modal.image.size.setting')} </h1>
|
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
|
||||||
닫기
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="modal-body">
|
|
||||||
<div className="range-wrap">
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
id="size"
|
|
||||||
name="volume"
|
|
||||||
min="20"
|
|
||||||
max="200"
|
|
||||||
step={10}
|
|
||||||
value={sizeValue}
|
|
||||||
onChange={(e) => setSizeValue(e.target.value)}
|
|
||||||
/>
|
|
||||||
<label htmlFor="size">{sizeValue}%</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</WithDraggable>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -12,7 +12,6 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide'
|
import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide'
|
||||||
import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide'
|
import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide'
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
|
||||||
|
|
||||||
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
||||||
const [objectNo, setObjectNo] = useState('test123241008001') // 후에 삭제 필요
|
const [objectNo, setObjectNo] = useState('test123241008001') // 후에 삭제 필요
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { Fragment, useCallback, useEffect, useState } from 'react'
|
import { Fragment, useCallback, useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { usePathname } from 'next/navigation'
|
import { usePathname } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { dimmedStore, sessionStore } from '@/store/commonAtom'
|
import { dimmedStore, sessionStore } from '@/store/commonAtom'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
@ -16,6 +16,9 @@ import UserInfoModal from '@/components/myInfo/UserInfoModal'
|
|||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
|
import { stuffSearchState } from '@/store/stuffAtom'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export const ToggleonMouse = (e, act, target) => {
|
export const ToggleonMouse = (e, act, target) => {
|
||||||
const listWrap = e.target.closest(target)
|
const listWrap = e.target.closest(target)
|
||||||
const ListItem = Array.from(listWrap.childNodes)
|
const ListItem = Array.from(listWrap.childNodes)
|
||||||
@ -34,6 +37,8 @@ export const ToggleonMouse = (e, act, target) => {
|
|||||||
export default function Header(props) {
|
export default function Header(props) {
|
||||||
const [userInfoModal, setUserInfoModal] = useState(false)
|
const [userInfoModal, setUserInfoModal] = useState(false)
|
||||||
|
|
||||||
|
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
||||||
|
|
||||||
const { userSession } = props
|
const { userSession } = props
|
||||||
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -43,6 +48,8 @@ export default function Header(props) {
|
|||||||
// }
|
// }
|
||||||
const [selected, setSelected] = useState('')
|
const [selected, setSelected] = useState('')
|
||||||
|
|
||||||
|
const { isGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
const dimmedState = useRecoilValue(dimmedStore)
|
const dimmedState = useRecoilValue(dimmedStore)
|
||||||
const isDimmed = dimmedState ? 'opacity-50 bg-black' : ''
|
const isDimmed = dimmedState ? 'opacity-50 bg-black' : ''
|
||||||
|
|
||||||
@ -160,45 +167,56 @@ export default function Header(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
|
<>
|
||||||
<header className={isDimmed}>
|
{!isGlobalLoading && !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
|
||||||
<div className="header-inner">
|
<header className={isDimmed}>
|
||||||
<div className="header-right">
|
<div className="header-inner">
|
||||||
<h1 className="logo">
|
<div className="header-right">
|
||||||
<Link href={'/'}></Link>
|
<h1 className="logo">
|
||||||
</h1>
|
<Link href={'/'}></Link>
|
||||||
<nav>
|
</h1>
|
||||||
<ul className="nav-list ">{getMenuTemplate(menus)}</ul>
|
<nav>
|
||||||
</nav>
|
<ul className="nav-list ">{getMenuTemplate(menus)}</ul>
|
||||||
</div>
|
</nav>
|
||||||
<div className="header-left">
|
|
||||||
<div className="profile-box">
|
|
||||||
<Link
|
|
||||||
href="#"
|
|
||||||
onClick={() => {
|
|
||||||
setUserInfoModal(true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button className="profile">{userSession.userNm}</button>
|
|
||||||
</Link>
|
|
||||||
{userInfoModal && <UserInfoModal userId={sessionState.userId} userInfoModal={userInfoModal} setUserInfoModal={setUserInfoModal} />}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="sign-out-box">
|
<div className="header-left">
|
||||||
<button className="sign-out" onClick={() => logout()}>
|
<div className="profile-box">
|
||||||
{getMessage('header.logout')}
|
<Link
|
||||||
</button>
|
href="#"
|
||||||
</div>
|
onClick={() => {
|
||||||
<div className="select-box">
|
setUserInfoModal(true)
|
||||||
<QSelectBox options={SelectOptions} onChange={onChangeSelect} />
|
}}
|
||||||
</div>
|
>
|
||||||
<div className="btn-wrap">
|
<button className="profile">{userSession.userNm}</button>
|
||||||
<button className="btn-frame small dark" onClick={() => navPage()}>
|
</Link>
|
||||||
{getMessage('header.go')}
|
{userInfoModal && <UserInfoModal userId={sessionState.userId} userInfoModal={userInfoModal} setUserInfoModal={setUserInfoModal} />}
|
||||||
</button>
|
</div>
|
||||||
|
<div className="sign-out-box">
|
||||||
|
<button
|
||||||
|
className="sign-out"
|
||||||
|
onClick={() => {
|
||||||
|
setStuffSearch({
|
||||||
|
...stuffSearch,
|
||||||
|
code: 'DELETE',
|
||||||
|
})
|
||||||
|
logout()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('header.logout')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="select-box">
|
||||||
|
<QSelectBox options={SelectOptions} onChange={onChangeSelect} />
|
||||||
|
</div>
|
||||||
|
<div className="btn-wrap">
|
||||||
|
<button className="btn-frame small dark" onClick={() => navPage()}>
|
||||||
|
{getMessage('header.go')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</header>
|
||||||
</header>
|
)}
|
||||||
)
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState, useContext } from 'react'
|
import { useEffect, useState, useContext } from 'react'
|
||||||
import ProductItem from './ProductItem'
|
import ProductItem from './ProductItem'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
@ -10,6 +12,8 @@ import { globalLocaleStore } from '@/store/localeAtom'
|
|||||||
import { queryStringFormatter } from '@/util/common-utils'
|
import { queryStringFormatter } from '@/util/common-utils'
|
||||||
import MainSkeleton from '../ui/MainSkeleton'
|
import MainSkeleton from '../ui/MainSkeleton'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
import { useMainContentsController } from '@/hooks/main/useMainContentsController'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export default function MainContents() {
|
export default function MainContents() {
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
@ -19,7 +23,7 @@ export default function MainContents() {
|
|||||||
const { promiseGet } = useAxios(globalLocaleState)
|
const { promiseGet } = useAxios(globalLocaleState)
|
||||||
|
|
||||||
//최근 물건
|
//최근 물건
|
||||||
const [objectList, setObjectList] = useState([])
|
// const [objectList, setObjectList] = useState([])
|
||||||
|
|
||||||
//공지사항
|
//공지사항
|
||||||
const [recentNoticeList, setRecentNoticeList] = useState([])
|
const [recentNoticeList, setRecentNoticeList] = useState([])
|
||||||
@ -28,36 +32,42 @@ export default function MainContents() {
|
|||||||
const [recentFaqList, setRecentFaqList] = useState([])
|
const [recentFaqList, setRecentFaqList] = useState([])
|
||||||
|
|
||||||
//Sales Contact info
|
//Sales Contact info
|
||||||
const [businessCharger, setBusinessCharger] = useState(null)
|
// const [businessCharger, setBusinessCharger] = useState(null)
|
||||||
const [businessChargerMail, setBusinessChargerMail] = useState(null)
|
// const [businessChargerMail, setBusinessChargerMail] = useState(null)
|
||||||
|
|
||||||
|
const { qcastState } = useContext(QcastContext)
|
||||||
|
const { fetchObjectList, initObjectList } = useMainContentsController()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchObjectList()
|
fetchObjectList()
|
||||||
fetchNoticeList()
|
fetchNoticeList()
|
||||||
fetchFaqList()
|
fetchFaqList()
|
||||||
|
return () => {
|
||||||
|
initObjectList()
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
//최근 갱신 물건목록 / Sales Contact info 정보
|
//최근 갱신 물건목록 / Sales Contact info 정보
|
||||||
const fetchObjectList = async () => {
|
// const fetchObjectList = async () => {
|
||||||
try {
|
// try {
|
||||||
const apiUrl = `/api/main-page/object/${session?.storeId}/list`
|
// const apiUrl = `/api/main-page/object/${session?.storeId}/list`
|
||||||
await promiseGet({
|
// await promiseGet({
|
||||||
url: apiUrl,
|
// url: apiUrl,
|
||||||
}).then((res) => {
|
// }).then((res) => {
|
||||||
if (res.status === 200) {
|
// if (res.status === 200) {
|
||||||
setObjectList(res.data.objectList)
|
// setObjectList(res.data.objectList)
|
||||||
setBusinessCharger(res.data.businessCharger)
|
// setBusinessCharger(res.data.businessCharger)
|
||||||
setBusinessChargerMail(res.data.businessChargerMail)
|
// setBusinessChargerMail(res.data.businessChargerMail)
|
||||||
} else {
|
// } else {
|
||||||
setObjectList([])
|
// setObjectList([])
|
||||||
setBusinessCharger(null)
|
// setBusinessCharger(null)
|
||||||
setBusinessChargerMail(null)
|
// setBusinessChargerMail(null)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.error('MAIN API fetching error:', error)
|
// console.error('MAIN API fetching error:', error)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
//공지사항 호출
|
//공지사항 호출
|
||||||
const fetchNoticeList = async () => {
|
const fetchNoticeList = async () => {
|
||||||
@ -109,9 +119,9 @@ export default function MainContents() {
|
|||||||
<div className="main-product-list-wrap">
|
<div className="main-product-list-wrap">
|
||||||
<div className="main-product-list">
|
<div className="main-product-list">
|
||||||
<ProductItem num={1} name={getMessage('main.content.objectList')}>
|
<ProductItem num={1} name={getMessage('main.content.objectList')}>
|
||||||
{objectList.length > 0 ? (
|
{qcastState?.objectList.length > 0 ? (
|
||||||
<ul className="recently-list">
|
<ul className="recently-list">
|
||||||
{objectList.map((row) => {
|
{qcastState?.objectList.map((row) => {
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
key={row.objectNo}
|
key={row.objectNo}
|
||||||
@ -190,7 +200,7 @@ export default function MainContents() {
|
|||||||
<div className="icon-box">
|
<div className="icon-box">
|
||||||
<Image src="/static/images/main/user.svg" alt="react" width={20} height={20} />
|
<Image src="/static/images/main/user.svg" alt="react" width={20} height={20} />
|
||||||
</div>
|
</div>
|
||||||
{(businessCharger && <div className="infor-data">{businessCharger}</div>) || (
|
{(qcastState?.businessCharger && <div className="infor-data">{qcastState?.businessCharger}</div>) || (
|
||||||
<div className="infor-data pre">{getMessage('main.content.noBusiness')}</div>
|
<div className="infor-data pre">{getMessage('main.content.noBusiness')}</div>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
@ -198,7 +208,7 @@ export default function MainContents() {
|
|||||||
<div className="icon-box">
|
<div className="icon-box">
|
||||||
<Image src="/static/images/main/mail.svg" alt="react" width={20} height={20} />
|
<Image src="/static/images/main/mail.svg" alt="react" width={20} height={20} />
|
||||||
</div>
|
</div>
|
||||||
{(businessChargerMail && <div className="infor-data pre">{businessChargerMail}</div>) || (
|
{(qcastState?.businessChargerMail && <div className="infor-data pre">{qcastState?.businessChargerMail}</div>) || (
|
||||||
<div className="infor-data pre">{getMessage('main.content.noBusiness')}</div>
|
<div className="infor-data pre">{getMessage('main.content.noBusiness')}</div>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -16,7 +16,11 @@ import JA from '@/locales/ja.json'
|
|||||||
import QPagination from '../common/pagination/QPagination'
|
import QPagination from '../common/pagination/QPagination'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export default function Stuff() {
|
export default function Stuff() {
|
||||||
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
|
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const setAppMessageState = useSetRecoilState(appMessageStore)
|
const setAppMessageState = useSetRecoilState(appMessageStore)
|
||||||
@ -39,14 +43,15 @@ export default function Stuff() {
|
|||||||
const copyNo = async (value) => {
|
const copyNo = async (value) => {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(value)
|
await navigator.clipboard.writeText(value)
|
||||||
alert(getMessage('stuff.detail.header.message2'))
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(getMessage('stuff.detail.header.message3'))
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//물건번호 복사버튼 옆에 영역
|
//물건번호 복사버튼 옆에 영역
|
||||||
const onDoubleClick = (data) => {
|
const onDoubleClick = (data) => {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
if (data.tempFlg === '0') {
|
if (data.tempFlg === '0') {
|
||||||
router.push(`${pathname}/detail?objectNo=${data.objectNo.toString()}`, { scroll: false })
|
router.push(`${pathname}/detail?objectNo=${data.objectNo.toString()}`, { scroll: false })
|
||||||
} else {
|
} else {
|
||||||
@ -149,6 +154,7 @@ export default function Stuff() {
|
|||||||
} else {
|
} else {
|
||||||
//T 면 임시 R은 진짜
|
//T 면 임시 R은 진짜
|
||||||
if (event.data.objectNo) {
|
if (event.data.objectNo) {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
if (event.data.tempFlg === '0') {
|
if (event.data.tempFlg === '0') {
|
||||||
router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
|
router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
|
||||||
} else {
|
} else {
|
||||||
@ -172,14 +178,14 @@ export default function Stuff() {
|
|||||||
schDateType: stuffSearchParams.schDateType,
|
schDateType: stuffSearchParams.schDateType,
|
||||||
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
|
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
|
||||||
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
|
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
|
||||||
startRow: (pageNo - 1) * pageSize + 1,
|
startRow: (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1,
|
||||||
// endRow: pageNo * pageSize,
|
|
||||||
endRow: stuffSearchParams?.endRow,
|
endRow: stuffSearchParams?.endRow,
|
||||||
schSelSaleStoreId: stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : '',
|
schSelSaleStoreId: stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : '',
|
||||||
schOtherSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : '',
|
schOtherSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : '',
|
||||||
schSortType: stuffSearchParams.schSortType,
|
schSortType: stuffSearchParams.schSortType,
|
||||||
|
pageNo: stuffSearchParams?.pageNo ? stuffSearchParams.pageNo : 1,
|
||||||
|
pageSize: stuffSearchParams?.pageSize ? stuffSearchParams.pageSize : 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
|
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
|
||||||
await get({
|
await get({
|
||||||
@ -188,10 +194,20 @@ export default function Stuff() {
|
|||||||
if (!isEmptyArray(res)) {
|
if (!isEmptyArray(res)) {
|
||||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||||
setTotalCount(res[0].totCnt)
|
setTotalCount(res[0].totCnt)
|
||||||
|
} else {
|
||||||
|
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
||||||
|
setTotalCount(0)
|
||||||
|
|
||||||
|
setPageNo(1)
|
||||||
|
setPageSize(stuffSearchParams.pageSize)
|
||||||
|
stuffSearchParams.pageNo = 1
|
||||||
|
stuffSearchParams.startRow = 1
|
||||||
|
stuffSearchParams.endRow = 1 * stuffSearchParams.pageSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setIsGlobalLoading(false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData()
|
fetchData()
|
||||||
} else if (stuffSearchParams?.code === 'M') {
|
} else if (stuffSearchParams?.code === 'M') {
|
||||||
const params = {
|
const params = {
|
||||||
@ -209,15 +225,18 @@ export default function Stuff() {
|
|||||||
endRow: pageNo * pageSize,
|
endRow: pageNo * pageSize,
|
||||||
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
||||||
schSortType: 'R',
|
schSortType: 'R',
|
||||||
|
code: 'S',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
}
|
}
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
...params,
|
...params,
|
||||||
})
|
})
|
||||||
} else if (stuffSearchParams?.code === 'E') {
|
} else if (stuffSearchParams?.code === 'E') {
|
||||||
stuffSearchParams.startRow = 1
|
stuffSearchParams.startRow = (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1
|
||||||
stuffSearchParams.endRow = 1 * pageSize
|
stuffSearchParams.endRow = stuffSearchParams.pageNo * stuffSearchParams.pageSize
|
||||||
stuffSearchParams.schSortType = defaultSortType
|
stuffSearchParams.schSortType = defaultSortType
|
||||||
setPageNo(1)
|
stuffSearchParams.pageNo = stuffSearchParams.pageNo
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
||||||
@ -228,10 +247,17 @@ export default function Stuff() {
|
|||||||
} else {
|
} else {
|
||||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
||||||
setTotalCount(0)
|
setTotalCount(0)
|
||||||
|
|
||||||
|
setPageNo(1)
|
||||||
|
setPageSize(stuffSearchParams.pageSize)
|
||||||
|
stuffSearchParams.pageNo = 1
|
||||||
|
stuffSearchParams.startRow = 1
|
||||||
|
stuffSearchParams.endRow = 1 * stuffSearchParams.pageSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setIsGlobalLoading(false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData()
|
fetchData()
|
||||||
} else if (stuffSearchParams?.code === 'C') {
|
} else if (stuffSearchParams?.code === 'C') {
|
||||||
resetStuffRecoil()
|
resetStuffRecoil()
|
||||||
@ -240,6 +266,7 @@ export default function Stuff() {
|
|||||||
stuffSearchParams.endRow = 1 * pageSize
|
stuffSearchParams.endRow = 1 * pageSize
|
||||||
stuffSearchParams.schSortType = defaultSortType
|
stuffSearchParams.schSortType = defaultSortType
|
||||||
setPageNo(1)
|
setPageNo(1)
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
||||||
await get({ url: apiUrl }).then((res) => {
|
await get({ url: apiUrl }).then((res) => {
|
||||||
@ -252,8 +279,32 @@ export default function Stuff() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData()
|
fetchData()
|
||||||
|
} else if (stuffSearchParams?.code === 'DELETE') {
|
||||||
|
const newParams = {
|
||||||
|
saleStoreId: session.storeId,
|
||||||
|
schObjectNo: '',
|
||||||
|
schAddress: '',
|
||||||
|
schObjectName: '',
|
||||||
|
schSaleStoreName: '',
|
||||||
|
schReceiveUser: '',
|
||||||
|
schDispCompanyName: '',
|
||||||
|
schDateType: 'U',
|
||||||
|
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
|
||||||
|
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
|
||||||
|
startRow: 1,
|
||||||
|
endRow: 100,
|
||||||
|
schSelSaleStoreId: '',
|
||||||
|
schOtherSelSaleStoreId: '',
|
||||||
|
schSortType: 'R',
|
||||||
|
code: 'S',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
setStuffSearch({
|
||||||
|
...newParams,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}, [stuffSearchParams])
|
}, [stuffSearchParams])
|
||||||
|
|
||||||
@ -262,62 +313,46 @@ export default function Stuff() {
|
|||||||
let startRow = (1 - 1) * e.target.value + 1
|
let startRow = (1 - 1) * e.target.value + 1
|
||||||
stuffSearchParams.startRow = startRow
|
stuffSearchParams.startRow = startRow
|
||||||
stuffSearchParams.endRow = 1 * e.target.value
|
stuffSearchParams.endRow = 1 * e.target.value
|
||||||
stuffSearchParams.schSelSaleStoreId = stuffSearchParams?.schOtherSelSaleStoreId
|
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
|
||||||
? stuffSearchParams.schOtherSelSaleStoreId
|
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
|
||||||
: stuffSearchParams.schSelSaleStoreId
|
stuffSearchParams.pageNo = startRow
|
||||||
|
stuffSearchParams.pageSize = 1 * e.target.value
|
||||||
setPageSize(e.target.value)
|
setPageSize(e.target.value)
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
// ...stuffSearchParams,
|
|
||||||
...stuffSearch,
|
...stuffSearch,
|
||||||
code: 'S',
|
code: 'S',
|
||||||
startRow: startRow,
|
startRow: startRow,
|
||||||
endRow: 1 * e.target.value,
|
endRow: 1 * e.target.value,
|
||||||
|
pageSize: e.target.value,
|
||||||
})
|
})
|
||||||
|
|
||||||
setPageNo(1)
|
setPageNo(1)
|
||||||
|
|
||||||
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
|
||||||
get({ url: apiUrl }).then((res) => {
|
|
||||||
if (!isEmptyArray(res)) {
|
|
||||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
|
||||||
setTotalCount(res[0].totCnt)
|
|
||||||
} else {
|
|
||||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
|
||||||
setTotalCount(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//최근 등록일 수정일 정렬 이벤트
|
//최근 등록일 수정일 정렬 이벤트
|
||||||
const onChangeSortType = (e) => {
|
const onChangeSortType = (e) => {
|
||||||
let startRow = (1 - 1) * pageSize + 1
|
// let startRow = (stuffSearchParams.pageNo - 1) * pageSize + 1
|
||||||
|
let startRow = (1 - 1) * stuffSearchParams.pageSize + 1
|
||||||
stuffSearchParams.startRow = startRow
|
stuffSearchParams.startRow = startRow
|
||||||
stuffSearchParams.endRow = 1 * pageSize
|
stuffSearchParams.endRow = startRow * stuffSearchParams.pageSize
|
||||||
|
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
|
||||||
|
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
|
||||||
|
stuffSearchParams.pageNo = startRow
|
||||||
|
stuffSearchParams.pageSize = 1 * stuffSearchParams.pageSize
|
||||||
|
setPageSize(stuffSearchParams.pageSize)
|
||||||
stuffSearchParams.schSortType = e.target.value
|
stuffSearchParams.schSortType = e.target.value
|
||||||
stuffSearchParams.schSelSaleStoreId = stuffSearchParams?.schOtherSelSaleStoreId
|
|
||||||
? stuffSearchParams.schOtherSelSaleStoreId
|
|
||||||
: stuffSearchParams.schSelSaleStoreId
|
|
||||||
setDefaultSortType(e.target.value)
|
setDefaultSortType(e.target.value)
|
||||||
|
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
...stuffSearch,
|
...stuffSearch,
|
||||||
code: 'S',
|
code: 'S',
|
||||||
startRow: startRow,
|
startRow: startRow,
|
||||||
endRow: 1 * pageSize,
|
endRow: startRow * stuffSearchParams.pageSize,
|
||||||
|
pageSize: stuffSearchParams.pageSize,
|
||||||
schSortType: e.target.value,
|
schSortType: e.target.value,
|
||||||
})
|
})
|
||||||
|
|
||||||
setPageNo(1)
|
setPageNo(1)
|
||||||
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
|
||||||
get({ url: apiUrl }).then((res) => {
|
|
||||||
if (!isEmptyArray(res)) {
|
|
||||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
|
||||||
setTotalCount(res[0].totCnt)
|
|
||||||
} else {
|
|
||||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
|
||||||
setTotalCount(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -331,19 +366,24 @@ export default function Stuff() {
|
|||||||
// 페이징 현재페이지 변경
|
// 페이징 현재페이지 변경
|
||||||
const handleChangePage = (page) => {
|
const handleChangePage = (page) => {
|
||||||
stuffSearchParams.code = 'S'
|
stuffSearchParams.code = 'S'
|
||||||
stuffSearchParams.schSelSaleStoreId = stuffSearchParams?.schOtherSelSaleStoreId
|
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
|
||||||
? stuffSearchParams.schOtherSelSaleStoreId
|
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
|
||||||
: stuffSearchParams.schSelSaleStoreId
|
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
...stuffSearch,
|
...stuffSearch,
|
||||||
code: 'S',
|
code: 'S',
|
||||||
startRow: (page - 1) * pageSize + 1,
|
startRow: (page - 1) * pageSize + 1,
|
||||||
endRow: page * pageSize,
|
endRow: page * stuffSearchParams?.pageSize,
|
||||||
|
pageNo: page,
|
||||||
})
|
})
|
||||||
|
|
||||||
setPageNo(page)
|
setPageNo(page)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* 퍼블시작 */}
|
{/* 퍼블시작 */}
|
||||||
@ -361,13 +401,13 @@ export default function Stuff() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="left-unit-box">
|
<div className="left-unit-box">
|
||||||
<div className="select-box mr5" style={{ width: '110px' }}>
|
<div className="select-box mr5" style={{ width: '110px' }}>
|
||||||
<select className="select-light black" onChange={onChangeSortType} defaultValue={stuffSearch.schSortType}>
|
<select className="select-light black" onChange={onChangeSortType} value={stuffSearch.schSortType}>
|
||||||
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
|
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
|
||||||
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
|
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="select-box" style={{ width: '80px' }}>
|
<div className="select-box" style={{ width: '80px' }}>
|
||||||
<select className="select-light black" onChange={onChangePerPage} defaultValue={stuffSearch.endRow}>
|
<select className="select-light black" onChange={onChangePerPage} value={stuffSearch.pageSize}>
|
||||||
<option value="100">100</option>
|
<option value="100">100</option>
|
||||||
<option value="200">200</option>
|
<option value="200">200</option>
|
||||||
<option value="300">300</option>
|
<option value="300">300</option>
|
||||||
@ -379,7 +419,13 @@ export default function Stuff() {
|
|||||||
<div className="q-grid">
|
<div className="q-grid">
|
||||||
<StuffQGrid {...gridProps} getCellDoubleClicked={getCellDoubleClicked} gridRef={gridRef} />
|
<StuffQGrid {...gridProps} getCellDoubleClicked={getCellDoubleClicked} gridRef={gridRef} />
|
||||||
<div className="pagination-wrap">
|
<div className="pagination-wrap">
|
||||||
<QPagination pageNo={pageNo} pageSize={pageSize} pagePerBlock={10} totalCount={totalCount} handleChangePage={handleChangePage} />
|
<QPagination
|
||||||
|
pageNo={stuffSearch.pageNo}
|
||||||
|
pageSize={stuffSearch.pageSize}
|
||||||
|
pagePerBlock={10}
|
||||||
|
totalCount={totalCount}
|
||||||
|
handleChangePage={handleChangePage}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
|
|||||||
import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty } from '@/util/common-utils'
|
import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty } from '@/util/common-utils'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useForm } from 'react-hook-form'
|
import { useForm } from 'react-hook-form'
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilValue, useSetRecoilState, useResetRecoilState, useRecoilState } from 'recoil'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import FindAddressPop from './popup/FindAddressPop'
|
import FindAddressPop from './popup/FindAddressPop'
|
||||||
import PlanRequestPop from './popup/PlanRequestPop'
|
import PlanRequestPop from './popup/PlanRequestPop'
|
||||||
@ -20,8 +20,13 @@ import StuffPlanQGrid from './StuffPlanQGrid'
|
|||||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
import { ManagementContext } from '@/app/management/ManagementProvider'
|
import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||||
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
|
import { stuffSearchState } from '@/store/stuffAtom'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
export default function StuffDetail() {
|
export default function StuffDetail() {
|
||||||
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
|
||||||
|
const stuffSearchParams = useRecoilValue(stuffSearchState)
|
||||||
|
|
||||||
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //견적서 화면용 물건번호리코일
|
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //견적서 화면용 물건번호리코일
|
||||||
|
|
||||||
const [estimatePopupOpen, setEstimatePopupOpen] = useState(false)
|
const [estimatePopupOpen, setEstimatePopupOpen] = useState(false)
|
||||||
@ -301,10 +306,12 @@ export default function StuffDetail() {
|
|||||||
}
|
}
|
||||||
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.data != null) {
|
if (isObjectNotEmpty(res.data)) {
|
||||||
setManagementState(res.data)
|
setManagementState(res.data)
|
||||||
} else {
|
} else {
|
||||||
setManagementState({})
|
setManagementState({})
|
||||||
|
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
||||||
|
router.push('/management/stuff')
|
||||||
}
|
}
|
||||||
if (isNotEmptyArray(res.data.planList)) {
|
if (isNotEmptyArray(res.data.planList)) {
|
||||||
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
|
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
|
||||||
@ -314,6 +321,9 @@ export default function StuffDetail() {
|
|||||||
} else {
|
} else {
|
||||||
setManagementState({})
|
setManagementState({})
|
||||||
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
||||||
|
|
||||||
|
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
||||||
|
router.push('/management/stuff')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -409,6 +419,8 @@ export default function StuffDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setIsGlobalLoading(false)
|
||||||
}
|
}
|
||||||
}, [objectNo, session])
|
}, [objectNo, session])
|
||||||
|
|
||||||
@ -428,158 +440,163 @@ export default function StuffDetail() {
|
|||||||
}, [commonCode])
|
}, [commonCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isObjectNotEmpty(managementState)) {
|
if (objectNo) {
|
||||||
// 도도부현API
|
if (isObjectNotEmpty(managementState)) {
|
||||||
get({ url: '/api/object/prefecture/list' }).then((res) => {
|
// 도도부현API
|
||||||
if (!isEmptyArray(res)) {
|
get({ url: '/api/object/prefecture/list' }).then((res) => {
|
||||||
setPrefCodeList(res)
|
if (!isEmptyArray(res)) {
|
||||||
}
|
setPrefCodeList(res)
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
|
||||||
//1차점 : X167 T01
|
//1차점 : X167 T01
|
||||||
//2차점 : 10X22, 201X112
|
//2차점 : 10X22, 201X112
|
||||||
let url
|
let url
|
||||||
let firstList
|
let firstList
|
||||||
let otherList
|
let otherList
|
||||||
let favList
|
let favList
|
||||||
|
|
||||||
if (session?.storeId === 'T01') {
|
if (session?.storeId === 'T01') {
|
||||||
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
||||||
} else {
|
|
||||||
if (session.storeLvl === '1') {
|
|
||||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
|
||||||
} else {
|
} else {
|
||||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
if (session.storeLvl === '1') {
|
||||||
}
|
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||||
}
|
|
||||||
get({ url: url }).then((res) => {
|
|
||||||
if (!isEmptyArray(res)) {
|
|
||||||
if (session?.storeId === 'T01') {
|
|
||||||
firstList = res.filter((row) => row.saleStoreLevel === '1')
|
|
||||||
firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId)
|
|
||||||
favList = firstList.filter((row) => row.saleStoreId === 'T01' || row.priority !== 'B')
|
|
||||||
setSaleStoreList(firstList)
|
|
||||||
setFavoriteStoreList(favList)
|
|
||||||
setShowSaleStoreList(favList)
|
|
||||||
|
|
||||||
if (managementState.firstAgentId != null) {
|
|
||||||
form.setValue('saleStoreId', managementState.firstAgentId)
|
|
||||||
setSelOptions(managementState.firstAgentId)
|
|
||||||
} else {
|
|
||||||
form.setValue('saleStoreId', managementState.saleStoreId)
|
|
||||||
setSelOptions(managementState.saleStoreId)
|
|
||||||
}
|
|
||||||
|
|
||||||
//상세데이터의 1차점 아이디로 2차점 목록 조회하기
|
|
||||||
|
|
||||||
let data = managementState?.firstAgentId ? managementState.firstAgentId : managementState.saleStoreId
|
|
||||||
url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}`
|
|
||||||
|
|
||||||
get({ url: url }).then((res) => {
|
|
||||||
if (!isEmptyArray(res)) {
|
|
||||||
res.map((row) => {
|
|
||||||
row.value = row.saleStoreId
|
|
||||||
row.label = row.saleStoreName
|
|
||||||
})
|
|
||||||
|
|
||||||
otherList = res
|
|
||||||
setOriginOtherSaleStoreList(otherList)
|
|
||||||
setOtherSaleStoreList(otherList)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
//1차점 셀렉트박스
|
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||||
if (session?.storeLvl === '1') {
|
|
||||||
firstList = res
|
|
||||||
favList = res.filter((row) => row.priority !== 'B')
|
|
||||||
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
|
||||||
|
|
||||||
setSaleStoreList(firstList)
|
|
||||||
setFavoriteStoreList(firstList)
|
|
||||||
setShowSaleStoreList(firstList)
|
|
||||||
|
|
||||||
setOtherSaleStoreList(otherList)
|
|
||||||
} else {
|
|
||||||
setSelOptions(res[0].saleStoreId)
|
|
||||||
form.setValue('saleStoreId', res[0].saleStoreId)
|
|
||||||
form.setValue('saleStoreLevel', res[0].storeLvl)
|
|
||||||
setSaleStoreList(res)
|
|
||||||
setFavoriteStoreList(res)
|
|
||||||
setShowSaleStoreList(res)
|
|
||||||
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
|
||||||
setOtherSaleStoreList(otherList)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
get({ url: url }).then((res) => {
|
||||||
|
if (!isEmptyArray(res)) {
|
||||||
|
if (session?.storeId === 'T01') {
|
||||||
|
firstList = res.filter((row) => row.saleStoreLevel === '1')
|
||||||
|
firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId)
|
||||||
|
favList = firstList.filter((row) => row.saleStoreId === 'T01' || row.priority !== 'B')
|
||||||
|
setSaleStoreList(firstList)
|
||||||
|
setFavoriteStoreList(favList)
|
||||||
|
setShowSaleStoreList(favList)
|
||||||
|
|
||||||
//상세데이터가 1차점이면 1차점에 세팅
|
if (managementState.firstAgentId != null) {
|
||||||
//상세데이터가 2차점이면 2차점에 세팅하고 세션으로 1차점 세팅
|
form.setValue('saleStoreId', managementState.firstAgentId)
|
||||||
if (managementState.saleStoreLevel === '1') {
|
setSelOptions(managementState.firstAgentId)
|
||||||
setSelOptions(managementState.saleStoreId)
|
} else {
|
||||||
form.setValue('saleStoreId', managementState.saleStoreId)
|
form.setValue('saleStoreId', managementState.saleStoreId)
|
||||||
form.setValue('saleStoreLevel', managementState.saleStoreLevel)
|
setSelOptions(managementState.saleStoreId)
|
||||||
} else {
|
}
|
||||||
setOtherSelOptions(managementState.saleStoreId)
|
|
||||||
form.setValue('otherSaleStoreId', managementState.saleStoreId)
|
|
||||||
form.setValue('otherSaleStoreLevel', managementState.saleStoreLevel)
|
|
||||||
|
|
||||||
form.setValue('saleStoreLevel', '1')
|
//상세데이터의 1차점 아이디로 2차점 목록 조회하기
|
||||||
}
|
|
||||||
|
|
||||||
//설계의뢰No.
|
let data = managementState?.firstAgentId ? managementState.firstAgentId : managementState.saleStoreId
|
||||||
form.setValue('planReqNo', managementState.planReqNo)
|
url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}`
|
||||||
//담당자
|
|
||||||
form.setValue('receiveUser', managementState.receiveUser)
|
|
||||||
|
|
||||||
//물건구분objectStatusId
|
get({ url: url }).then((res) => {
|
||||||
setSelectObjectStatusId(managementState.objectStatusId)
|
if (!isEmptyArray(res)) {
|
||||||
form.setValue('objectStatusId', managementState.objectStatusId)
|
res.map((row) => {
|
||||||
|
row.value = row.saleStoreId
|
||||||
|
row.label = row.saleStoreName
|
||||||
|
})
|
||||||
|
|
||||||
//물건명
|
otherList = res
|
||||||
form.setValue('objectName', managementState.objectName)
|
setOriginOtherSaleStoreList(otherList)
|
||||||
|
setOtherSaleStoreList(otherList)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
//1차점 셀렉트박스
|
||||||
|
if (session?.storeLvl === '1') {
|
||||||
|
firstList = res
|
||||||
|
favList = res.filter((row) => row.priority !== 'B')
|
||||||
|
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
||||||
|
|
||||||
//경칭코드
|
setSaleStoreList(firstList)
|
||||||
setSelHonorificCode(managementState.objectNameOmit)
|
setFavoriteStoreList(firstList)
|
||||||
form.setValue('objectNameOmit', managementState.objectNameOmit)
|
setShowSaleStoreList(firstList)
|
||||||
|
|
||||||
//물건명 후리가나
|
setOtherSaleStoreList(otherList)
|
||||||
form.setValue('objectNameKana', managementState.objectNameKana)
|
} else {
|
||||||
|
setSelOptions(res[0].saleStoreId)
|
||||||
|
form.setValue('saleStoreId', res[0].saleStoreId)
|
||||||
|
form.setValue('saleStoreLevel', res[0].storeLvl)
|
||||||
|
setSaleStoreList(res)
|
||||||
|
setFavoriteStoreList(res)
|
||||||
|
setShowSaleStoreList(res)
|
||||||
|
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
||||||
|
setOtherSaleStoreList(otherList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//우편번호
|
//상세데이터가 1차점이면 1차점에 세팅
|
||||||
form.setValue('zipNo', managementState.zipNo)
|
//상세데이터가 2차점이면 2차점에 세팅하고 세션으로 1차점 세팅
|
||||||
|
if (managementState.saleStoreLevel === '1') {
|
||||||
|
setSelOptions(managementState.saleStoreId)
|
||||||
|
form.setValue('saleStoreId', managementState.saleStoreId)
|
||||||
|
form.setValue('saleStoreLevel', managementState.saleStoreLevel)
|
||||||
|
} else {
|
||||||
|
setOtherSelOptions(managementState.saleStoreId)
|
||||||
|
form.setValue('otherSaleStoreId', managementState.saleStoreId)
|
||||||
|
form.setValue('otherSaleStoreLevel', managementState.saleStoreLevel)
|
||||||
|
|
||||||
//도도부현 / 주소
|
form.setValue('saleStoreLevel', '1')
|
||||||
setPrefValue(managementState.prefId)
|
}
|
||||||
form.setValue('prefId', managementState.prefId)
|
|
||||||
form.setValue('prefName', managementState.prefName)
|
|
||||||
form.setValue('address', managementState.address)
|
|
||||||
//발전시뮬
|
|
||||||
form.setValue('areaId', managementState.areaId)
|
|
||||||
|
|
||||||
//기준풍속
|
//설계의뢰No.
|
||||||
form.setValue('standardWindSpeedId', managementState.standardWindSpeedId)
|
form.setValue('planReqNo', managementState.planReqNo)
|
||||||
//수직적설량
|
//담당자
|
||||||
form.setValue('verticalSnowCover', managementState.verticalSnowCover)
|
form.setValue('receiveUser', managementState.receiveUser)
|
||||||
//한랭지대책시행 coldRegionFlg 1이면 true
|
|
||||||
form.setValue('coldRegionFlg', managementState.coldRegionFlg === '1' ? true : false)
|
|
||||||
|
|
||||||
//면조도구분 surfaceType null로 내려오면 셋팅 안하고 저장할때 필수값 체크하도록
|
//물건구분objectStatusId
|
||||||
// form.setValue('surfaceType', 'Ⅱ')
|
setSelectObjectStatusId(managementState.objectStatusId)
|
||||||
// form.setValue('surfaceType', 'Ⅲ・Ⅳ')
|
form.setValue('objectStatusId', managementState.objectStatusId)
|
||||||
form.setValue('surfaceType', managementState.surfaceType)
|
|
||||||
//염해지역용아이템사용 saltAreaFlg 1이면 true
|
//물건명
|
||||||
form.setValue('saltAreaFlg', managementState.saltAreaFlg === '1' ? true : false)
|
form.setValue('objectName', managementState.objectName)
|
||||||
//설치높이
|
|
||||||
form.setValue('installHeight', managementState.installHeight)
|
//경칭코드
|
||||||
//계약조건 null로 내려오면 0으로 디폴트셋팅
|
setSelHonorificCode(managementState.objectNameOmit)
|
||||||
if (managementState.conType === null) {
|
form.setValue('objectNameOmit', managementState.objectNameOmit)
|
||||||
form.setValue('conType', '0')
|
|
||||||
} else {
|
//물건명 후리가나
|
||||||
form.setValue('conType', managementState.conType)
|
form.setValue('objectNameKana', managementState.objectNameKana)
|
||||||
}
|
|
||||||
//메모
|
//우편번호
|
||||||
form.setValue('remarks', managementState.remarks)
|
form.setValue('zipNo', managementState.zipNo)
|
||||||
})
|
|
||||||
|
//도도부현 / 주소
|
||||||
|
setPrefValue(managementState.prefId)
|
||||||
|
form.setValue('prefId', managementState.prefId)
|
||||||
|
form.setValue('prefName', managementState.prefName)
|
||||||
|
form.setValue('address', managementState.address)
|
||||||
|
//발전시뮬
|
||||||
|
form.setValue('areaId', managementState.areaId)
|
||||||
|
|
||||||
|
//기준풍속
|
||||||
|
form.setValue('standardWindSpeedId', managementState.standardWindSpeedId)
|
||||||
|
//수직적설량
|
||||||
|
form.setValue('verticalSnowCover', managementState.verticalSnowCover)
|
||||||
|
//한랭지대책시행 coldRegionFlg 1이면 true
|
||||||
|
form.setValue('coldRegionFlg', managementState.coldRegionFlg === '1' ? true : false)
|
||||||
|
|
||||||
|
//면조도구분 surfaceType null로 내려오면 셋팅 안하고 저장할때 필수값 체크하도록
|
||||||
|
// form.setValue('surfaceType', 'Ⅱ')
|
||||||
|
// form.setValue('surfaceType', 'Ⅲ・Ⅳ')
|
||||||
|
form.setValue('surfaceType', managementState.surfaceType)
|
||||||
|
//염해지역용아이템사용 saltAreaFlg 1이면 true
|
||||||
|
form.setValue('saltAreaFlg', managementState.saltAreaFlg === '1' ? true : false)
|
||||||
|
//설치높이
|
||||||
|
form.setValue('installHeight', managementState.installHeight)
|
||||||
|
//계약조건 null로 내려오면 0으로 디폴트셋팅
|
||||||
|
if (managementState.conType === null) {
|
||||||
|
form.setValue('conType', '0')
|
||||||
|
} else {
|
||||||
|
form.setValue('conType', managementState.conType)
|
||||||
|
}
|
||||||
|
//메모
|
||||||
|
form.setValue('remarks', managementState.remarks)
|
||||||
|
})
|
||||||
|
|
||||||
|
//상세끝
|
||||||
|
setIsGlobalLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [managementState])
|
}, [managementState])
|
||||||
|
|
||||||
@ -1262,7 +1279,7 @@ export default function StuffDetail() {
|
|||||||
if (res.status === 201) {
|
if (res.status === 201) {
|
||||||
alert(getMessage('stuff.detail.save'))
|
alert(getMessage('stuff.detail.save'))
|
||||||
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
|
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
|
||||||
router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`)
|
router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -1271,8 +1288,7 @@ export default function StuffDetail() {
|
|||||||
if (res.status === 201) {
|
if (res.status === 201) {
|
||||||
setFloorPlanObjectNo({ floorPlanObjectNo: res.data.objectNo })
|
setFloorPlanObjectNo({ floorPlanObjectNo: res.data.objectNo })
|
||||||
alert(getMessage('stuff.detail.save'))
|
alert(getMessage('stuff.detail.save'))
|
||||||
// router.refresh()
|
router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
|
||||||
router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1307,6 +1323,7 @@ export default function StuffDetail() {
|
|||||||
tempFlg: '1',
|
tempFlg: '1',
|
||||||
workNo: null,
|
workNo: null,
|
||||||
workName: null,
|
workName: null,
|
||||||
|
objectNo: objectNo ? objectNo : '',
|
||||||
}
|
}
|
||||||
|
|
||||||
//1차점 or 2차점 안고르고 임시저장하면
|
//1차점 or 2차점 안고르고 임시저장하면
|
||||||
@ -1315,12 +1332,22 @@ export default function StuffDetail() {
|
|||||||
params.saleStoreLevel = session.storeLvl
|
params.saleStoreLevel = session.storeLvl
|
||||||
}
|
}
|
||||||
|
|
||||||
await promisePost({ url: '/api/object/save-object', data: params }).then((res) => {
|
const apiUrl = '/api/object/save-object'
|
||||||
if (res.status === 201) {
|
if (objectNo) {
|
||||||
alert(getMessage('stuff.detail.tempSave.message1'))
|
await promisePut({ url: apiUrl, data: params }).then((res) => {
|
||||||
router.push(`${pathname}?objectNo=${res.data.objectNo.toString()}`)
|
if (res.status === 201) {
|
||||||
}
|
alert(getMessage('stuff.detail.tempSave.message1'))
|
||||||
})
|
router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await promisePost({ url: apiUrl, data: params }).then((res) => {
|
||||||
|
if (res.status === 201) {
|
||||||
|
alert(getMessage('stuff.detail.tempSave.message1'))
|
||||||
|
router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 물건삭제
|
// 물건삭제
|
||||||
@ -1332,6 +1359,11 @@ export default function StuffDetail() {
|
|||||||
if (confirm(getMessage('common.message.data.delete'))) {
|
if (confirm(getMessage('common.message.data.delete'))) {
|
||||||
del({ url: `/api/object/${objectNo}` }).then(() => {
|
del({ url: `/api/object/${objectNo}` }).then(() => {
|
||||||
setFloorPlanObjectNo({ floorPlanObjectNo: '' })
|
setFloorPlanObjectNo({ floorPlanObjectNo: '' })
|
||||||
|
if (session.storeId === 'T01') {
|
||||||
|
stuffSearchParams.code = 'DELETE'
|
||||||
|
} else {
|
||||||
|
resetStuffRecoil()
|
||||||
|
}
|
||||||
router.push('/management/stuff')
|
router.push('/management/stuff')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import { isObjectNotEmpty } from '@/util/common-utils'
|
|||||||
|
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export default function StuffSearchCondition() {
|
export default function StuffSearchCondition() {
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const setAppMessageState = useSetRecoilState(appMessageStore)
|
const setAppMessageState = useSetRecoilState(appMessageStore)
|
||||||
@ -66,31 +68,64 @@ export default function StuffSearchCondition() {
|
|||||||
const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) //1차점 이외 판매점목록
|
const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) //1차점 이외 판매점목록
|
||||||
const [otherSaleStoreId, setOtherSaleStoreId] = useState('')
|
const [otherSaleStoreId, setOtherSaleStoreId] = useState('')
|
||||||
|
|
||||||
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
// 조회
|
// 조회
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
let diff = dayjs(endDate).diff(startDate, 'day')
|
let diff = dayjs(endDate).diff(startDate, 'day')
|
||||||
|
|
||||||
if (diff > 366) {
|
if (diff > 366) {
|
||||||
return alert(getMessage('stuff.message.periodError'))
|
return alert(getMessage('stuff.message.periodError'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNaN(diff)) {
|
||||||
|
return alert(getMessage('stuff.message.periodError'))
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsGlobalLoading(true)
|
||||||
|
|
||||||
if (stuffSearch.code === 'S') {
|
if (stuffSearch.code === 'S') {
|
||||||
setStuffSearch({
|
if (stuffSearch.pageNo !== 1) {
|
||||||
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
setStuffSearch({
|
||||||
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
||||||
schAddress: address ? address : '',
|
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
||||||
schObjectName: objectName ? objectName : '',
|
schAddress: address ? address : '',
|
||||||
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
schObjectName: objectName ? objectName : '',
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
schReceiveUser: receiveUser ? receiveUser : '',
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
schDateType: dateType,
|
schReceiveUser: receiveUser ? receiveUser : '',
|
||||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
schDateType: dateType,
|
||||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
code: 'E',
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
startRow: 1,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
endRow: 1 * stuffSearch?.pageSize,
|
||||||
})
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setStuffSearch({
|
||||||
|
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
||||||
|
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
||||||
|
schAddress: address ? address : '',
|
||||||
|
schObjectName: objectName ? objectName : '',
|
||||||
|
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
||||||
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
|
schReceiveUser: receiveUser ? receiveUser : '',
|
||||||
|
schDateType: dateType,
|
||||||
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
|
code: 'E',
|
||||||
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: stuffSearch?.pageNo,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
}
|
||||||
} else if (stuffSearch.code === 'FINISH') {
|
} else if (stuffSearch.code === 'FINISH') {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo,
|
schObjectNo: objectNo,
|
||||||
@ -102,13 +137,98 @@ export default function StuffSearchCondition() {
|
|||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: receiveUser,
|
schReceiveUser: receiveUser,
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
})
|
})
|
||||||
|
} else if (stuffSearch.code === 'E') {
|
||||||
|
if (session.storeId !== 'T01' && session.storeLvl === '1') {
|
||||||
|
setStuffSearch({
|
||||||
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
||||||
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
||||||
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
||||||
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
||||||
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
||||||
|
schSelSaleStoreId: otherSaleStoreId ? schSelSaleStoreId : '',
|
||||||
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
||||||
|
schDateType: dateType,
|
||||||
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
|
code: 'E',
|
||||||
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: stuffSearch?.pageNo,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
} else if (session.storeId === 'T01') {
|
||||||
|
if (stuffSearch.pageNo !== 1) {
|
||||||
|
setStuffSearch({
|
||||||
|
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
||||||
|
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
||||||
|
schAddress: address ? address : '',
|
||||||
|
schObjectName: objectName ? objectName : '',
|
||||||
|
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
||||||
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
|
schReceiveUser: receiveUser ? receiveUser : '',
|
||||||
|
schDateType: dateType,
|
||||||
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
|
code: 'E',
|
||||||
|
startRow: 1,
|
||||||
|
endRow: 1 * stuffSearch?.pageSize,
|
||||||
|
// schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
schSortType: 'R',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setStuffSearch({
|
||||||
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
||||||
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
||||||
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
||||||
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
||||||
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
||||||
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
||||||
|
schDateType: dateType,
|
||||||
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
|
code: 'E',
|
||||||
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: stuffSearch?.pageNo,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setStuffSearch({
|
||||||
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
||||||
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
||||||
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
||||||
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
||||||
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
||||||
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
||||||
|
schDateType: dateType,
|
||||||
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
|
code: 'E',
|
||||||
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: stuffSearch?.pageNo,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo,
|
schObjectNo: objectNo,
|
||||||
@ -116,16 +236,18 @@ export default function StuffSearchCondition() {
|
|||||||
schAddress: address,
|
schAddress: address,
|
||||||
schObjectName: objectName,
|
schObjectName: objectName,
|
||||||
schDispCompanyName: dispCompanyName,
|
schDispCompanyName: dispCompanyName,
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId,
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: receiveUser,
|
schReceiveUser: receiveUser,
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||||
|
pageNo: stuffSearch?.pageNo,
|
||||||
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,8 +277,21 @@ export default function StuffSearchCondition() {
|
|||||||
handleClear1() //판매대리점선택 자동완성 클리어
|
handleClear1() //판매대리점선택 자동완성 클리어
|
||||||
resetStuffRecoil()
|
resetStuffRecoil()
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
|
schObjectNo: '',
|
||||||
|
schAddress: '',
|
||||||
|
schObjectName: '',
|
||||||
|
schSaleStoreName: '',
|
||||||
|
schReceiveUser: '',
|
||||||
|
schDispCompanyName: '',
|
||||||
schSelSaleStoreId: '',
|
schSelSaleStoreId: '',
|
||||||
schOtherSelSaleStoreId: '',
|
schOtherSelSaleStoreId: '',
|
||||||
|
schDateType: 'U',
|
||||||
|
startRow: 1,
|
||||||
|
endRow: 100,
|
||||||
|
schSortType: 'R',
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
code: 'S',
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (otherSaleStoreList.length > 1) {
|
if (otherSaleStoreList.length > 1) {
|
||||||
@ -313,7 +448,11 @@ export default function StuffSearchCondition() {
|
|||||||
//X누름
|
//X누름
|
||||||
//화면에선 지우는데 리코일은 조회누르지 않으면 보존
|
//화면에선 지우는데 리코일은 조회누르지 않으면 보존
|
||||||
setSchSelSaleStoreId('')
|
setSchSelSaleStoreId('')
|
||||||
// stuffSearch.schSelSaleStoreId = ''
|
setOtherSaleStoreId('')
|
||||||
|
if (stuffSearch.code === 'S') {
|
||||||
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
|
}
|
||||||
|
|
||||||
//2차점 판매점목록비우기
|
//2차점 판매점목록비우기
|
||||||
setOtherSaleStoreList([])
|
setOtherSaleStoreList([])
|
||||||
@ -330,14 +469,17 @@ export default function StuffSearchCondition() {
|
|||||||
stuffSearch.schSelSaleStoreId = schSelSaleStoreId
|
stuffSearch.schSelSaleStoreId = schSelSaleStoreId
|
||||||
} else {
|
} else {
|
||||||
//X누르면 검색조건에 1차점으로 셋팅
|
//X누르면 검색조건에 1차점으로 셋팅
|
||||||
|
|
||||||
if (session.storeLvl === '1') {
|
if (session.storeLvl === '1') {
|
||||||
if (stuffSearch.schOtherSelSaleStoreId === '') {
|
if (stuffSearch.schOtherSelSaleStoreId === '') {
|
||||||
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
||||||
// stuffSearch.schSelSaleStoreId = ''
|
|
||||||
setSchSelSaleStoreId(session.storeId)
|
setSchSelSaleStoreId(session.storeId)
|
||||||
} else {
|
} else {
|
||||||
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
// 화면에선 지우는데 조회누르기 전이면 리코일은 남김
|
||||||
setOtherSaleStoreId('')
|
setOtherSaleStoreId('')
|
||||||
|
if (stuffSearch.code === 'S') {
|
||||||
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setOtherSaleStoreId('')
|
setOtherSaleStoreId('')
|
||||||
@ -349,14 +491,52 @@ export default function StuffSearchCondition() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setStartDate(stuffSearch?.schFromDt ? stuffSearch.schFromDt : dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'))
|
//X42
|
||||||
setEndDate(stuffSearch?.schToDt ? stuffSearch.schToDt : dayjs(new Date()).format('YYYY-MM-DD'))
|
if (session?.storeId === 'T01') {
|
||||||
setObjectNo(stuffSearch.schObjectNo ? stuffSearch.schObjectNo : objectNo)
|
if (stuffSearch.code === 'DELETE') {
|
||||||
setSaleStoreName(stuffSearch.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName)
|
setObjectNo('')
|
||||||
setAddress(stuffSearch.schAddress ? stuffSearch.schAddress : address)
|
setSaleStoreName('')
|
||||||
setobjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
|
setAddress('')
|
||||||
setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName)
|
setobjectName('')
|
||||||
setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser)
|
setDispCompanyName('')
|
||||||
|
setReceiveUser('')
|
||||||
|
objectNoRef.current.value = ''
|
||||||
|
saleStoreNameRef.current.value = ''
|
||||||
|
addressRef.current.value = ''
|
||||||
|
objectNameRef.current.value = ''
|
||||||
|
dispCompanyNameRef.current.value = ''
|
||||||
|
receiveUserRef.current.value = ''
|
||||||
|
stuffSearch.schObjectNo = ''
|
||||||
|
stuffSearch.schAddress = ''
|
||||||
|
stuffSearch.schObjectName = ''
|
||||||
|
stuffSearch.schSaleStoreName = ''
|
||||||
|
stuffSearch.schReceiveUser = ''
|
||||||
|
stuffSearch.schDispCompanyName = ''
|
||||||
|
stuffSearch.schDateType = 'U'
|
||||||
|
stuffSearch.schFromDt = dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD')
|
||||||
|
stuffSearch.schToDt = dayjs(new Date()).format('YYYY-MM-DD')
|
||||||
|
stuffSearch.startRow = 1
|
||||||
|
stuffSearch.endRow = 100
|
||||||
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
|
stuffSearch.schSortType = 'R'
|
||||||
|
stuffSearch.pageNo = 1
|
||||||
|
stuffSearch.pageSize = 100
|
||||||
|
|
||||||
|
setSchSelSaleStoreId('')
|
||||||
|
setOtherSaleStoreId('')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setStartDate(stuffSearch?.schFromDt ? stuffSearch.schFromDt : dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'))
|
||||||
|
setEndDate(stuffSearch?.schToDt ? stuffSearch.schToDt : dayjs(new Date()).format('YYYY-MM-DD'))
|
||||||
|
setObjectNo(stuffSearch.schObjectNo ? stuffSearch.schObjectNo : objectNo)
|
||||||
|
setSaleStoreName(stuffSearch.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName)
|
||||||
|
setAddress(stuffSearch.schAddress ? stuffSearch.schAddress : address)
|
||||||
|
setobjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
|
||||||
|
setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName)
|
||||||
|
setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser)
|
||||||
|
setDateType(stuffSearch.schDateType ? stuffSearch.schDateType : dateType)
|
||||||
|
}
|
||||||
}, [stuffSearch])
|
}, [stuffSearch])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -386,14 +566,14 @@ export default function StuffSearchCondition() {
|
|||||||
<div className="left-unit-box">
|
<div className="left-unit-box">
|
||||||
<Link href="/management/stuff/tempdetail" scroll={false}>
|
<Link href="/management/stuff/tempdetail" scroll={false}>
|
||||||
<button type="button" className="btn-origin navy mr5">
|
<button type="button" className="btn-origin navy mr5">
|
||||||
{getMessage('stuff.search.btn1')}
|
{getMessage('stuff.search.btn.register')}
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<button type="button" className="btn-origin navy mr5" onClick={onSubmit}>
|
<button type="button" className="btn-origin navy mr5" onClick={onSubmit}>
|
||||||
{getMessage('stuff.search.btn2')}
|
{getMessage('stuff.search.btn.search')}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" className="btn-origin grey" onClick={resetRecoil}>
|
<button type="button" className="btn-origin grey" onClick={resetRecoil}>
|
||||||
{getMessage('stuff.search.btn3')}
|
{getMessage('stuff.search.btn.reset')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -420,6 +600,7 @@ export default function StuffSearchCondition() {
|
|||||||
className="input-light"
|
className="input-light"
|
||||||
defaultValue={stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo}
|
defaultValue={stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schObjectNo = objectNoRef.current.value
|
||||||
setObjectNo(objectNoRef.current.value)
|
setObjectNo(objectNoRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -435,6 +616,7 @@ export default function StuffSearchCondition() {
|
|||||||
className="input-light"
|
className="input-light"
|
||||||
defaultValue={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
|
defaultValue={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schSaleStoreName = saleStoreNameRef.current.value
|
||||||
setSaleStoreName(saleStoreNameRef.current.value)
|
setSaleStoreName(saleStoreNameRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -450,6 +632,7 @@ export default function StuffSearchCondition() {
|
|||||||
className="input-light"
|
className="input-light"
|
||||||
defaultValue={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
|
defaultValue={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schAddress = addressRef.current.value
|
||||||
setAddress(addressRef.current.value)
|
setAddress(addressRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -465,6 +648,7 @@ export default function StuffSearchCondition() {
|
|||||||
className="input-light"
|
className="input-light"
|
||||||
defaultValue={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
|
defaultValue={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schDispCompanyName = dispCompanyNameRef.current.value
|
||||||
setDispCompanyName(dispCompanyNameRef.current.value)
|
setDispCompanyName(dispCompanyNameRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -482,6 +666,7 @@ export default function StuffSearchCondition() {
|
|||||||
className="input-light"
|
className="input-light"
|
||||||
defaultValue={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
|
defaultValue={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schObjectName = objectNameRef.current.value
|
||||||
setobjectName(objectNameRef.current.value)
|
setobjectName(objectNameRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -497,6 +682,7 @@ export default function StuffSearchCondition() {
|
|||||||
ref={receiveUserRef}
|
ref={receiveUserRef}
|
||||||
defaultValue={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser}
|
defaultValue={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
|
stuffSearch.schReceiveUser = receiveUserRef.current.value
|
||||||
setReceiveUser(receiveUserRef.current.value)
|
setReceiveUser(receiveUserRef.current.value)
|
||||||
}}
|
}}
|
||||||
onKeyUp={handleByOnKeyUp}
|
onKeyUp={handleByOnKeyUp}
|
||||||
@ -638,7 +824,7 @@ export default function StuffSearchCondition() {
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="radio_ptype"
|
name="radio_ptype"
|
||||||
id="radio_u"
|
id="radio_u"
|
||||||
checked={stuffSearch.schDateType === 'U' ? true : false}
|
defaultChecked={stuffSearch.schDateType === 'U' ? true : false}
|
||||||
value={'U'}
|
value={'U'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setDateType(e.target.value)
|
setDateType(e.target.value)
|
||||||
@ -652,7 +838,7 @@ export default function StuffSearchCondition() {
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="radio_ptype"
|
name="radio_ptype"
|
||||||
id="radio_r"
|
id="radio_r"
|
||||||
checked={stuffSearch.schDateType === 'R' ? true : false}
|
defaultChecked={stuffSearch.schDateType === 'R' ? true : false}
|
||||||
value={'R'}
|
value={'R'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setDateType(e.target.value)
|
setDateType(e.target.value)
|
||||||
|
|||||||
@ -27,10 +27,10 @@ export default function StuffSubHeader({ type }) {
|
|||||||
|
|
||||||
const param = {
|
const param = {
|
||||||
pid: '1',
|
pid: '1',
|
||||||
|
objectNo: objectNo,
|
||||||
}
|
}
|
||||||
//확인필요
|
|
||||||
const url = `/floor-plan?${queryStringFormatter(param)}`
|
const url = `/floor-plan?${queryStringFormatter(param)}`
|
||||||
console.log(url)
|
|
||||||
router.push(url)
|
router.push(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ export default function StuffSubHeader({ type }) {
|
|||||||
<span>{getMessage('header.menus.management')}</span>
|
<span>{getMessage('header.menus.management')}</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="location-item">
|
<li className="location-item">
|
||||||
<span>{getMessage('header.menus.management.newStuff')}</span>
|
<span>{getMessage('header.menus.management.detail')}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -5,8 +5,9 @@ import { Bar } from 'react-chartjs-2'
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
import { useEffect, useState, useRef } from 'react'
|
import { useEffect, useState, useRef } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue, useRecoilState } from 'recoil'
|
||||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
|
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
||||||
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
@ -41,6 +42,7 @@ export default function Simulator() {
|
|||||||
|
|
||||||
// 차트 관련
|
// 차트 관련
|
||||||
const [chartData, setChartData] = useState([])
|
const [chartData, setChartData] = useState([])
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||||
datasets: [
|
datasets: [
|
||||||
@ -105,8 +107,10 @@ export default function Simulator() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (objectNo) {
|
if (objectNo) {
|
||||||
fetchObjectDetail(objectNo)
|
fetchObjectDetail(objectNo)
|
||||||
|
fetchSimulatorNotice()
|
||||||
|
setPwrGnrSimType('D')
|
||||||
|
setPwrRecoil({ ...pwrRecoil, type: 'D' })
|
||||||
}
|
}
|
||||||
fetchSimulatorNotice()
|
|
||||||
}, [objectNo, plan])
|
}, [objectNo, plan])
|
||||||
|
|
||||||
// 물건 상세 정보 조회
|
// 물건 상세 정보 조회
|
||||||
@ -118,13 +122,30 @@ export default function Simulator() {
|
|||||||
// 파워컨디셔너 조회
|
// 파워컨디셔너 조회
|
||||||
const [pcsInfoList, setPcsInfoList] = useState([])
|
const [pcsInfoList, setPcsInfoList] = useState([])
|
||||||
|
|
||||||
|
// 타입별 list 조회
|
||||||
|
const [hatsudenryouAll, setHatsudenryouAll] = useState([])
|
||||||
|
const [hatsudenryouAllSnow, setHatsudenryouAllSnow] = useState([])
|
||||||
|
const [hatsudenryouPeakcutAll, setHatsudenryouPeakcutAll] = useState([])
|
||||||
|
const [hatsudenryouPeakcutAllSnow, setHatsudenryouPeakcutAllSnow] = useState([])
|
||||||
|
|
||||||
const fetchObjectDetail = async (objectNo) => {
|
const fetchObjectDetail = async (objectNo) => {
|
||||||
const apiUrl = `/api/pwrGnrSimulation/calculations?objectNo=${objectNo}&planNo=${plan?.id}`
|
const apiUrl = `/api/pwrGnrSimulation/calculations?objectNo=${objectNo}&planNo=${plan?.id}`
|
||||||
|
|
||||||
const resultData = await get({ url: apiUrl })
|
const resultData = await get({ url: apiUrl })
|
||||||
if (resultData) {
|
if (resultData) {
|
||||||
setObjectDetail(resultData)
|
setObjectDetail(resultData)
|
||||||
if (resultData.frcPwrGnrList) {
|
if (resultData.hatsudenryouAll) {
|
||||||
setChartData(resultData.frcPwrGnrList)
|
setHatsudenryouAll(resultData.hatsudenryouAll)
|
||||||
|
}
|
||||||
|
if (resultData.hatsudenryouAllSnow) {
|
||||||
|
setHatsudenryouAllSnow(resultData.hatsudenryouAllSnow)
|
||||||
|
}
|
||||||
|
if (resultData.hatsudenryouPeakcutAll) {
|
||||||
|
setHatsudenryouPeakcutAll(resultData.hatsudenryouPeakcutAll)
|
||||||
|
}
|
||||||
|
if (resultData.hatsudenryouPeakcutAllSnow) {
|
||||||
|
setHatsudenryouPeakcutAllSnow(resultData.hatsudenryouPeakcutAllSnow)
|
||||||
|
setChartData(resultData.hatsudenryouPeakcutAllSnow)
|
||||||
}
|
}
|
||||||
if (resultData.pcsList) {
|
if (resultData.pcsList) {
|
||||||
setPcsInfoList(resultData.pcsList)
|
setPcsInfoList(resultData.pcsList)
|
||||||
@ -148,6 +169,28 @@ export default function Simulator() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 차트 데이터 변경 시, list type 셋팅
|
||||||
|
const [pwrGnrSimType, setPwrGnrSimType] = useState('D')
|
||||||
|
const [pwrRecoil, setPwrRecoil] = useRecoilState(pwrGnrSimTypeState)
|
||||||
|
|
||||||
|
const handleChartChangeData = (type) => {
|
||||||
|
setPwrRecoil({ ...pwrRecoil, type: type })
|
||||||
|
switch (type) {
|
||||||
|
case 'A':
|
||||||
|
setChartData(hatsudenryouAll)
|
||||||
|
break
|
||||||
|
case 'B':
|
||||||
|
setChartData(hatsudenryouAllSnow)
|
||||||
|
break
|
||||||
|
case 'C':
|
||||||
|
setChartData(hatsudenryouPeakcutAll)
|
||||||
|
break
|
||||||
|
case 'D':
|
||||||
|
setChartData(hatsudenryouPeakcutAllSnow)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sub-content estimate">
|
<div className="sub-content estimate">
|
||||||
<div className="sub-content-inner">
|
<div className="sub-content-inner">
|
||||||
@ -158,23 +201,25 @@ export default function Simulator() {
|
|||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub1')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub1')}</div>
|
||||||
<div className="estimate-name">
|
<div className="estimate-name">
|
||||||
{objectDetail.objectNo} (Plan No: {objectDetail.planNo})
|
{objectDetail.objectNo} (Plan No: {plan?.id})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 작성일 */}
|
{/* 작성일 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub2')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub2')}</div>
|
||||||
<div className="estimate-name">{`${dayjs(objectDetail.drawingEstimateCreateDate).format('YYYY.MM.DD')}`}</div>
|
<div className="estimate-name">
|
||||||
|
{objectDetail.drawingEstimateCreateDate ? `${dayjs(objectDetail.drawingEstimateCreateDate).format('YYYY.MM.DD')}` : ''}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 시스템용량 */}
|
{/* 시스템용량 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub3')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub3')}</div>
|
||||||
<div className="estimate-name">{convertNumberToPriceDecimal(objectDetail.capacity)}kW</div>
|
<div className="estimate-name">{objectDetail.capacity ? `${convertNumberToPriceDecimal(objectDetail.capacity)}kW` : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 연간예측발전량 */}
|
{/* 연간예측발전량 */}
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('simulator.title.sub4')}</div>
|
<div className="estimate-tit">{getMessage('simulator.title.sub4')}</div>
|
||||||
<div className="estimate-name">{convertNumberToPriceDecimal(objectDetail.anlFrcsGnrt)}</div>
|
<div className="estimate-name">{chartData[chartData.length - 1]}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-list-wrap">
|
<div className="estimate-list-wrap">
|
||||||
@ -206,6 +251,24 @@ export default function Simulator() {
|
|||||||
<div className="chart-inner">
|
<div className="chart-inner">
|
||||||
<div className="sub-table-box">
|
<div className="sub-table-box">
|
||||||
<div className="chart-box">
|
<div className="chart-box">
|
||||||
|
{/* chart */}
|
||||||
|
<div className="select-wrap">
|
||||||
|
<select
|
||||||
|
style={{ width: '30%' }}
|
||||||
|
className="select-light"
|
||||||
|
value={pwrGnrSimType}
|
||||||
|
defaultValue={`D`}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChartChangeData(e.target.value)
|
||||||
|
setPwrGnrSimType(e.target.value)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value={`A`}>積雪考慮なし(ピークカットなし発電量)</option>
|
||||||
|
<option value={`B`}>積雪考慮なし(ピークカットあり発電量)</option>
|
||||||
|
<option value={`C`}>積雪考慮あり(ピークカットなし発電量)</option>
|
||||||
|
<option value={`D`}>積雪考慮あり(ピークカットあり発電量)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<Bar ref={chartRef} data={data} options={options} />
|
<Bar ref={chartRef} data={data} options={options} />
|
||||||
</div>
|
</div>
|
||||||
<div className="table-box-title-wrap">
|
<div className="table-box-title-wrap">
|
||||||
@ -237,7 +300,7 @@ export default function Simulator() {
|
|||||||
{chartData.length > 0 ? (
|
{chartData.length > 0 ? (
|
||||||
<tr>
|
<tr>
|
||||||
{chartData.map((data) => (
|
{chartData.map((data) => (
|
||||||
<td key={data}>{convertNumberToPriceDecimal(data)}</td>
|
<td key={data}>{data}</td>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -40,19 +40,19 @@ export function useCanvasConfigInitialize() {
|
|||||||
const flowTexts = canvas.getObjects().filter((obj) => obj.name === 'flowText')
|
const flowTexts = canvas.getObjects().filter((obj) => obj.name === 'flowText')
|
||||||
if (basicSetting.roofAngleSet === 'slope') {
|
if (basicSetting.roofAngleSet === 'slope') {
|
||||||
offsetTexts.forEach((obj) => {
|
offsetTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${obj.pitch}${angleUnit}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${angleUnit}` })
|
||||||
})
|
})
|
||||||
flowTexts.forEach((obj) => {
|
flowTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${obj.pitch}${pitchText}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${pitchText}` })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basicSetting.roofAngleSet === 'flat') {
|
if (basicSetting.roofAngleSet === 'flat') {
|
||||||
offsetTexts.forEach((obj) => {
|
offsetTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${getDegreeByChon(obj.pitch)}${angleUnit}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${angleUnit}` })
|
||||||
})
|
})
|
||||||
flowTexts.forEach((obj) => {
|
flowTexts.forEach((obj) => {
|
||||||
obj.set({ text: `${obj.originText}-∠${getDegreeByChon(obj.pitch)}${pitchText}` })
|
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${pitchText}` })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,30 @@
|
|||||||
import { menuNumberState } from '@/store/menuAtom'
|
import { menuNumberState } from '@/store/menuAtom'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
export const useCanvasMenu = () => {
|
export const useCanvasMenu = () => {
|
||||||
const [menuNumber, setMenuNumber] = useRecoilState(menuNumberState)
|
const [menuNumber, setMenuNumber] = useRecoilState(menuNumberState)
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { drawDirectionArrow } = usePolygon()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
/*
|
||||||
|
* 모듈,회로 구성을 벗어나면 방향 표시 초기화 필요
|
||||||
|
* */
|
||||||
|
if (!canvas) return
|
||||||
|
if (![4, 5].includes(menuNumber)) {
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
.forEach((obj) => {
|
||||||
|
obj.set('moduleCompass', null)
|
||||||
|
drawDirectionArrow(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [menuNumber])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
menuNumber,
|
menuNumber,
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { convertDwgToPng } from '@/lib/cadAction'
|
|
||||||
import { useAxios } from '../useAxios'
|
import { useAxios } from '../useAxios'
|
||||||
import { currentCanvasPlanState } from '@/store/canvasAtom'
|
import { currentCanvasPlanState } from '@/store/canvasAtom'
|
||||||
|
import { convertDwgToPng, writeImageBuffer } from '@/lib/fileAction'
|
||||||
|
|
||||||
export function useRefFiles() {
|
export function useRefFiles() {
|
||||||
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
||||||
@ -16,7 +16,7 @@ export function useRefFiles() {
|
|||||||
const queryRef = useRef(null)
|
const queryRef = useRef(null)
|
||||||
|
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { get, promisePut } = useAxios()
|
const { get, promisePut, promisePost } = useAxios()
|
||||||
// const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan()
|
// const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +25,11 @@ export function useRefFiles() {
|
|||||||
*/
|
*/
|
||||||
const handleRefFile = (file) => {
|
const handleRefFile = (file) => {
|
||||||
setRefImage(file)
|
setRefImage(file)
|
||||||
file.name.split('.').pop() === 'dwg' ? handleUploadRefFile(file) : () => {}
|
/**
|
||||||
|
* 파일 확장자가 dwg일 경우 변환하여 이미지로 저장
|
||||||
|
* 파일 확장자가 이미지일 경우 이미지 저장
|
||||||
|
*/
|
||||||
|
file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file)
|
||||||
// handleUploadRefFile(file)
|
// handleUploadRefFile(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,22 +62,29 @@ export function useRefFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 현재 플랜이 변경되면 플랜 상태 저장
|
* 이미지 파일 업로드
|
||||||
|
* @param {*} file
|
||||||
*/
|
*/
|
||||||
// useEffect(() => {
|
const handleUploadImageRefFile = async (file) => {
|
||||||
// const handleCurrentPlan = async () => {
|
console.log('🚀 ~ handleUploadImageRefFile ~ file:', file)
|
||||||
// await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => {
|
const formData = new FormData()
|
||||||
// console.log('🚀 ~ awaitpromisePut ~ res:', res)
|
formData.append('file', file)
|
||||||
// })
|
|
||||||
// }
|
const response = await fetch('http://localhost:3000/api/image-upload', {
|
||||||
// handleCurrentPlan()
|
method: 'POST',
|
||||||
// }, [currentCanvasPlan])
|
body: formData,
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await response.json()
|
||||||
|
console.log('🚀 ~ handleUploadImageRefFile ~ res:', result)
|
||||||
|
// writeImageBuffer(file)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RefFile이 캐드 도면 파일일 경우 변환하여 이미지로 저장
|
* RefFile이 캐드 도면 파일일 경우 변환하여 이미지로 저장
|
||||||
* @param {*} file
|
* @param {*} file
|
||||||
*/
|
*/
|
||||||
const handleUploadRefFile = async (file) => {
|
const handleUploadConvertRefFile = async (file) => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
|
||||||
@ -95,6 +106,19 @@ export function useRefFiles() {
|
|||||||
setRefFileMethod(e.target.value)
|
setRefFileMethod(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 현재 플랜이 변경되면 플랜 상태 저장
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan)
|
||||||
|
// const handleCurrentPlan = async () => {
|
||||||
|
// await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => {
|
||||||
|
// console.log('🚀 ~ awaitpromisePut ~ res:', res)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// handleCurrentPlan()
|
||||||
|
}, [currentCanvasPlan])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refImage,
|
refImage,
|
||||||
queryRef,
|
queryRef,
|
||||||
|
|||||||
@ -6,27 +6,11 @@ import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom
|
|||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
const reducer = (prevState, nextState) => {
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
return { ...prevState, ...nextState }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const ESTIMATE_API_ENDPOINT = '/api/estimates' // API 엔드포인트 정의
|
const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의
|
||||||
|
|
||||||
const defaultEstimateData = {
|
|
||||||
estimateDate: new Date(), //견적일
|
|
||||||
charger: '', //담당자
|
|
||||||
objectName: '', //안건명
|
|
||||||
objectNameOmit: '', //경칭코드
|
|
||||||
estimateType: '', //주문분류
|
|
||||||
remarks: '', //비고
|
|
||||||
estimateOption: '', //견적특이사항
|
|
||||||
itemList: [],
|
|
||||||
fileList: [],
|
|
||||||
fileFlg: '0', //후일 자료 제출 (체크 1 노체크 0)
|
|
||||||
priceCd: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
const updateItemInList = (itemList, dispOrder, updates) => {
|
const updateItemInList = (itemList, dispOrder, updates) => {
|
||||||
@ -34,6 +18,7 @@ const updateItemInList = (itemList, dispOrder, updates) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useEstimateController = (planNo) => {
|
export const useEstimateController = (planNo) => {
|
||||||
|
const router = useRouter()
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
const objectRecoil = useRecoilValue(floorPlanObjectState)
|
||||||
@ -41,25 +26,32 @@ export const useEstimateController = (planNo) => {
|
|||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
const { get, post, promisePost } = useAxios(globalLocaleState)
|
const { promiseGet, post, promisePost } = useAxios(globalLocaleState)
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [state, setState] = useReducer(reducer, defaultEstimateData)
|
const { estimateContextState, setEstimateContextState } = useContext(FloorPlanContext)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoading) {
|
if (planNo && !isLoading) {
|
||||||
if (objectRecoil.floorPlanObjectNo && planNo) {
|
if (objectRecoil.floorPlanObjectNo && planNo) {
|
||||||
fetchSetting()
|
fetchSetting(objectRecoil.floorPlanObjectNo, planNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// 상세 조회
|
// 상세 조회
|
||||||
const fetchSetting = async () => {
|
const fetchSetting = async (objectNo, planNo) => {
|
||||||
try {
|
try {
|
||||||
await get({ url: `/api/estimate/${objectRecoil.floorPlanObjectNo}/${planNo}/detail` }).then((res) => {
|
await promiseGet({ url: `/api/estimate/${objectNo}/${planNo}/detail` }).then((res) => {
|
||||||
if (isObjectNotEmpty(res)) {
|
if (res.status === 200) {
|
||||||
setState(res)
|
if (isObjectNotEmpty(res.data)) {
|
||||||
|
if (res.data.itemList.length > 0) {
|
||||||
|
res.data.itemList.map((item) => {
|
||||||
|
item.delFlg = '0'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setEstimateContextState(res.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@ -70,16 +62,17 @@ export const useEstimateController = (planNo) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updateItem = (dispOrder, updates) => {
|
const updateItem = (dispOrder, updates) => {
|
||||||
setState({
|
setEstimateContextState({
|
||||||
itemList: updateItemInList(state.itemList, dispOrder, updates),
|
itemList: updateItemInList(estimateContextState.itemList, dispOrder, updates),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const addItem = () => {
|
const addItem = () => {
|
||||||
const newItemDispOrder = Math.max(...state.itemList.map((item) => item.dispOrder)) + 1
|
let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder))
|
||||||
setState({
|
newItemDispOrder = (Math.floor(newItemDispOrder / 100) + 1) * 100
|
||||||
|
setEstimateContextState({
|
||||||
itemList: [
|
itemList: [
|
||||||
...state.itemList,
|
...estimateContextState.itemList,
|
||||||
{
|
{
|
||||||
objectNo: objectRecoil.floorPlanObjectNo,
|
objectNo: objectRecoil.floorPlanObjectNo,
|
||||||
planNo: planNo,
|
planNo: planNo,
|
||||||
@ -90,8 +83,8 @@ export const useEstimateController = (planNo) => {
|
|||||||
amount: '', //수량
|
amount: '', //수량
|
||||||
unitPrice: '0',
|
unitPrice: '0',
|
||||||
unit: '', //단위
|
unit: '', //단위
|
||||||
salePrice: '0', //단가
|
salePrice: '', //단가
|
||||||
saleTotPrice: '0', //금액(부가세별도)
|
saleTotPrice: '', //금액(부가세별도)
|
||||||
itemChangeFlg: '1', //추가시 체인지플래그 1로
|
itemChangeFlg: '1', //추가시 체인지플래그 1로
|
||||||
partAdd: '1', //NEW 체인지 플래그
|
partAdd: '1', //NEW 체인지 플래그
|
||||||
delFlg: '0', //삭제 플래그 0 삭제하면 1
|
delFlg: '0', //삭제 플래그 0 삭제하면 1
|
||||||
@ -101,8 +94,8 @@ export const useEstimateController = (planNo) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setEstimateData({ ...state, userId: session.userId, sapSalesStoreCd: session.custCd })
|
setEstimateData({ ...estimateContextState, userId: session.userId, sapSalesStoreCd: session.custCd })
|
||||||
}, [state])
|
}, [estimateContextState])
|
||||||
|
|
||||||
// 첨부파일 다운로드
|
// 첨부파일 다운로드
|
||||||
const handleEstimateFileDownload = async (originFile) => {
|
const handleEstimateFileDownload = async (originFile) => {
|
||||||
@ -133,27 +126,43 @@ export const useEstimateController = (planNo) => {
|
|||||||
const handleEstimateSubmit = async () => {
|
const handleEstimateSubmit = async () => {
|
||||||
//0. 필수체크
|
//0. 필수체크
|
||||||
let flag = true
|
let flag = true
|
||||||
console.log('::담긴 estimateData:::', estimateData)
|
if (estimateData.charger.trim().length === 0) {
|
||||||
|
flag = false
|
||||||
|
return alert(getMessage('estimate.detail.save.requiredCharger'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (estimateData.objectName.trim().length === 0) {
|
||||||
|
flag = false
|
||||||
|
return alert(getMessage('estimate.detail.save.requiredObjectName'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(Date.parse(estimateData.estimateDate))) {
|
||||||
|
flag = false
|
||||||
|
return alert(getMessage('estimate.detail.save.requiredEstimateDate'))
|
||||||
|
}
|
||||||
|
|
||||||
// console.log('첨부파일:::::', estimateData.fileList)
|
// console.log('첨부파일:::::', estimateData.fileList)
|
||||||
//첨부파일을 첨부안했는데
|
//첨부파일을 첨부안했는데
|
||||||
//아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼
|
//아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼
|
||||||
|
let fileFlg = true
|
||||||
if (estimateData.fileList.length < 1) {
|
if (estimateData.fileList.length < 1) {
|
||||||
if (estimateData.itemList.length > 1) {
|
if (estimateData.itemList.length > 1) {
|
||||||
estimateData.itemList.map((row) => {
|
estimateData.itemList.map((row) => {
|
||||||
if (row.fileUploadFlg === '1') {
|
if (row.fileUploadFlg === '1') {
|
||||||
if (estimateData.fileFlg === '0') {
|
if (fileFlg) {
|
||||||
alert(getMessage('estimate.detail.save.requiredMsg'))
|
if (estimateData.fileFlg === '0') {
|
||||||
flag = false
|
fileFlg = false
|
||||||
|
return alert(getMessage('estimate.detail.save.requiredFileUpload'))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (flag && fileFlg) {
|
||||||
//1. 첨부파일 저장
|
//1. 첨부파일 저장시작
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
console.log('첨부파일:!!!', estimateData.fileList)
|
|
||||||
formData.append('file', estimateData.fileList)
|
formData.append('file', estimateData.fileList)
|
||||||
formData.append('objectNo', estimateData.objectNo)
|
formData.append('objectNo', estimateData.objectNo)
|
||||||
formData.append('planNo', estimateData.planNo)
|
formData.append('planNo', estimateData.planNo)
|
||||||
@ -161,36 +170,87 @@ export const useEstimateController = (planNo) => {
|
|||||||
formData.append('userId', estimateData.userId)
|
formData.append('userId', estimateData.userId)
|
||||||
|
|
||||||
await post({ url: '/api/file/fileUpload', data: formData })
|
await post({ url: '/api/file/fileUpload', data: formData })
|
||||||
|
//첨부파일저장끝
|
||||||
|
|
||||||
//2. 상세데이터 저장
|
//제품라인 추가했는데 아이템 안고르고 저장하면itemId=''은 날리고 나머지 저장하기
|
||||||
return
|
estimateData.itemList = estimateData.itemList.filter((item) => item.itemId !== '')
|
||||||
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {
|
|
||||||
if (res) {
|
let delCnt = 0
|
||||||
alert(getMessage('estimate.detail.save.alertMsg'))
|
estimateData.itemList.map((item) => {
|
||||||
|
if (item.delFlg === '1') {
|
||||||
|
delCnt++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if (delCnt === estimateData.itemList.length) {
|
||||||
|
return alert(getMessage('estimate.detail.save.requiredItem'))
|
||||||
|
}
|
||||||
|
|
||||||
// try {
|
estimateData.itemList.map((item) => {
|
||||||
// const result = await promisePost({
|
item.amount = item.amount.replaceAll(',', '')
|
||||||
// url: ESTIMATE_API_ENDPOINT,
|
item.salePrice = parseFloat(item.salePrice.replaceAll(',', '')).toFixed(2)
|
||||||
// data: estimateData,
|
item.saleTotPrice = parseFloat(item.saleTotPrice.replaceAll(',', '')).toFixed(2)
|
||||||
// })
|
})
|
||||||
// alert(getMessage('estimate.detail.save.alertMsg'))
|
console.log('최종 정보::;', estimateData)
|
||||||
// return result
|
|
||||||
// } catch (error) {
|
//2. 상세데이터 저장
|
||||||
// console.error('Failed to submit estimate:', error)
|
// return
|
||||||
// throw error
|
try {
|
||||||
// }
|
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {
|
||||||
|
if (res.status === 201) {
|
||||||
|
alert(getMessage('estimate.detail.save.alertMsg'))
|
||||||
|
//어디로 보낼지
|
||||||
|
fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.log('error::::::::::::', e.response.data.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 견적서 복사버튼
|
||||||
|
* (견적서 번호(estimateData.docNo)가 생성된 이후 버튼 활성화 )
|
||||||
|
* T01관리자 계정 및 1차판매점에게만 제공
|
||||||
|
*/
|
||||||
|
const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId) => {
|
||||||
|
if (saleStoreId === '') {
|
||||||
|
return alert(getMessage('estimate.detail.productFeaturesPopup.requiredStoreId'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copyReceiveUser.trim().length === 0) {
|
||||||
|
return alert(getMessage('estimate.detail.productFeaturesPopup.requiredReceiveUser'))
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
saleStoreId: session.storeId,
|
||||||
|
sapSalesStoreCd: session.custCd,
|
||||||
|
objectNo: objectRecoil.floorPlanObjectNo,
|
||||||
|
planNo: sendPlanNo,
|
||||||
|
copySaleStoreId: otherSaleStoreId ? otherSaleStoreId : saleStoreId,
|
||||||
|
copyReceiveUser: copyReceiveUser,
|
||||||
|
userId: session.userId,
|
||||||
|
}
|
||||||
|
|
||||||
|
// return
|
||||||
|
await promisePost({ url: '/api/estimate/save-estimate-copy', data: params }).then((res) => {
|
||||||
|
if (res.status === 201) {
|
||||||
|
if (isObjectNotEmpty(res.data)) {
|
||||||
|
let newObjectNo = res.data.objectNo
|
||||||
|
alert(getMessage('estimate.detail.estimateCopyPopup.copy.alertMessage'))
|
||||||
|
router.push(`/management/stuff/detail?objectNo=${newObjectNo.toString()}`, { scroll: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
estimateContextState,
|
||||||
setState,
|
setEstimateContextState,
|
||||||
updateItem,
|
updateItem,
|
||||||
addItem,
|
addItem,
|
||||||
handleEstimateSubmit,
|
handleEstimateSubmit,
|
||||||
fetchSetting,
|
fetchSetting,
|
||||||
handleEstimateFileDownload,
|
handleEstimateFileDownload,
|
||||||
|
handleEstimateCopy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
94
src/hooks/main/useMainContentsController.js
Normal file
94
src/hooks/main/useMainContentsController.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useContext, useEffect } from 'react'
|
||||||
|
import { useAxios } from '../useAxios'
|
||||||
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
|
export const useMainContentsController = () => {
|
||||||
|
const { session } = useContext(SessionContext)
|
||||||
|
const { promiseGet } = useAxios()
|
||||||
|
const { setQcastState, setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main search area
|
||||||
|
*/
|
||||||
|
// const [saleStoreId, setSaleStoreId] = useState('')
|
||||||
|
// const [saleStoreName, setSaleStoreName] = useState('')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main contents area
|
||||||
|
*/
|
||||||
|
// const [objectList, setObjectList] = useState([])
|
||||||
|
// const [businessCharger, setBusinessCharger] = useState(null)
|
||||||
|
// const [businessChargerMail, setBusinessChargerMail] = useState(null)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 최근 물건 목록 조회
|
||||||
|
*/
|
||||||
|
const fetchObjectList = async () => {
|
||||||
|
try {
|
||||||
|
const apiUrl = `/api/main-page/object/${session?.storeId}/list`
|
||||||
|
await promiseGet({
|
||||||
|
url: apiUrl,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
// setSaleStoreId(res.data.saleStoreId)
|
||||||
|
// setSaleStoreName(res.data.saleStoreName)
|
||||||
|
|
||||||
|
// setObjectList(res.data.objectList)
|
||||||
|
// setBusinessCharger(res.data.businessCharger)
|
||||||
|
// setBusinessChargerMail(res.data.businessChargerMail)
|
||||||
|
setQcastState({
|
||||||
|
saleStoreId: res.data.saleStoreId,
|
||||||
|
saleStoreName: res.data.saleStoreName,
|
||||||
|
objectList: res.data.objectList,
|
||||||
|
businessCharger: res.data.businessCharger,
|
||||||
|
businessChargerMail: res.data.businessChargerMail,
|
||||||
|
})
|
||||||
|
setIsGlobalLoading(false)
|
||||||
|
} else {
|
||||||
|
// setSaleStoreId('')
|
||||||
|
// setSaleStoreName('')
|
||||||
|
|
||||||
|
// setObjectList([])
|
||||||
|
// setBusinessCharger(null)
|
||||||
|
// setBusinessChargerMail(null)
|
||||||
|
setQcastState({
|
||||||
|
saleStoreId: '',
|
||||||
|
saleStoreName: '',
|
||||||
|
objectList: [],
|
||||||
|
businessCharger: null,
|
||||||
|
businessChargerMail: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('MAIN API fetching error:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initObjectList = () => {
|
||||||
|
setQcastState({
|
||||||
|
saleStoreId: '',
|
||||||
|
saleStoreName: '',
|
||||||
|
objectList: [],
|
||||||
|
businessCharger: null,
|
||||||
|
businessChargerMail: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// saleStoreId,
|
||||||
|
// saleStoreName,
|
||||||
|
// objectList,
|
||||||
|
// businessCharger,
|
||||||
|
// businessChargerMail,
|
||||||
|
fetchObjectList,
|
||||||
|
initObjectList,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ import { useEvent } from '@/hooks/useEvent'
|
|||||||
import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common'
|
import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common'
|
||||||
|
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
|
import next from 'next'
|
||||||
|
|
||||||
export function useModuleBasicSetting() {
|
export function useModuleBasicSetting() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -31,7 +32,7 @@ export function useModuleBasicSetting() {
|
|||||||
setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경
|
setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경
|
||||||
const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset
|
const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset
|
||||||
//모듈설치영역?? 생성
|
//모듈설치영역?? 생성
|
||||||
const setupSurface = new QPolygon(offsetPoints, {
|
let setupSurface = new QPolygon(offsetPoints, {
|
||||||
stroke: 'red',
|
stroke: 'red',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeDashArray: [10, 4],
|
strokeDashArray: [10, 4],
|
||||||
@ -45,8 +46,12 @@ export function useModuleBasicSetting() {
|
|||||||
parentId: roof.id, //가대 폴리곤의 임시 인덱스를 넣어줌
|
parentId: roof.id, //가대 폴리곤의 임시 인덱스를 넣어줌
|
||||||
name: POLYGON_TYPE.MODULE_SETUP_SURFACE,
|
name: POLYGON_TYPE.MODULE_SETUP_SURFACE,
|
||||||
flowDirection: roof.direction,
|
flowDirection: roof.direction,
|
||||||
|
flipX: roof.flipX,
|
||||||
|
flipY: roof.flipY,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setupSurface.setViewLengthText(false)
|
||||||
|
|
||||||
canvas.add(setupSurface)
|
canvas.add(setupSurface)
|
||||||
//지붕면 선택 금지
|
//지붕면 선택 금지
|
||||||
roof.set({
|
roof.set({
|
||||||
@ -62,6 +67,7 @@ export function useModuleBasicSetting() {
|
|||||||
|
|
||||||
//설치 범위 지정 클릭 이벤트
|
//설치 범위 지정 클릭 이벤트
|
||||||
const toggleSelection = (setupSurface) => {
|
const toggleSelection = (setupSurface) => {
|
||||||
|
console.log('setupSurface', setupSurface)
|
||||||
const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
|
const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
|
||||||
//최초 선택일때
|
//최초 선택일때
|
||||||
if (!isExist) {
|
if (!isExist) {
|
||||||
@ -376,9 +382,12 @@ export function useModuleBasicSetting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//자동 모듈 설치(그리드 방식)
|
//자동 모듈 설치(그리드 방식)
|
||||||
const autoModuleSetup = () => {
|
const autoModuleSetup = (placementRef) => {
|
||||||
|
const isChidori = placementRef.isChidori.current
|
||||||
|
|
||||||
initEvent()
|
initEvent()
|
||||||
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
||||||
|
|
||||||
const notSelectedTrestlePolygons = canvas
|
const notSelectedTrestlePolygons = canvas
|
||||||
?.getObjects()
|
?.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것
|
||||||
@ -400,6 +409,9 @@ export function useModuleBasicSetting() {
|
|||||||
|
|
||||||
if (moduleIsSetup.length > 0) {
|
if (moduleIsSetup.length > 0) {
|
||||||
alert('기존 모듈은 제거됩니다.')
|
alert('기존 모듈은 제거됩니다.')
|
||||||
|
moduleIsSetup.forEach((module) => {
|
||||||
|
canvas?.remove(module)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
notSelectedTrestlePolygons.forEach((obj) => {
|
notSelectedTrestlePolygons.forEach((obj) => {
|
||||||
@ -472,8 +484,11 @@ export function useModuleBasicSetting() {
|
|||||||
width = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 172.2 : 113.4
|
width = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 172.2 : 113.4
|
||||||
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
||||||
}
|
}
|
||||||
const cols = Math.floor((bbox[2] - bbox[0]) / width)
|
|
||||||
const rows = Math.floor((bbox[3] - bbox[1]) / height)
|
let cols = Math.floor((bbox[2] - bbox[0]) / width)
|
||||||
|
let rows = Math.floor((bbox[3] - bbox[1]) / height)
|
||||||
|
|
||||||
|
// cols = cols * 2
|
||||||
|
|
||||||
for (let col = 0; col <= cols; col++) {
|
for (let col = 0; col <= cols; col++) {
|
||||||
for (let row = 0; row <= rows; row++) {
|
for (let row = 0; row <= rows; row++) {
|
||||||
@ -481,10 +496,8 @@ export function useModuleBasicSetting() {
|
|||||||
y = 0,
|
y = 0,
|
||||||
square = [],
|
square = [],
|
||||||
margin = 0
|
margin = 0
|
||||||
|
|
||||||
if (moduleSetupSurface.flowDirection !== undefined) {
|
if (moduleSetupSurface.flowDirection !== undefined) {
|
||||||
//배치면 처림 방향이 정해져있는 경우
|
//배치면 처림 방향이 정해져있는 경우
|
||||||
|
|
||||||
if (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north') {
|
if (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north') {
|
||||||
//남,북
|
//남,북
|
||||||
margin = (bbox[2] - bbox[0] - cols * width) / 2 //박스 끝에서 박스 시작값을 빼고 width와 계산된 cols를 곱한값을 뺀뒤 나누기 2 하면 가운데 배치됨
|
margin = (bbox[2] - bbox[0] - cols * width) / 2 //박스 끝에서 박스 시작값을 빼고 width와 계산된 cols를 곱한값을 뺀뒤 나누기 2 하면 가운데 배치됨
|
||||||
@ -514,25 +527,50 @@ export function useModuleBasicSetting() {
|
|||||||
y = bbox[1] + row * height
|
y = bbox[1] + row * height
|
||||||
}
|
}
|
||||||
|
|
||||||
square = [
|
if (isChidori === 'true') {
|
||||||
[x, y],
|
if (row % 2 !== 0) {
|
||||||
[x + width, y],
|
square = [
|
||||||
[x + width, y + height],
|
[x, y],
|
||||||
[x, y + height],
|
[x + width, y],
|
||||||
[x, y],
|
[x + width, y + height],
|
||||||
]
|
[x, y + height],
|
||||||
|
[x, y],
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
square = [
|
||||||
|
[x - width / 2, y],
|
||||||
|
[x - width / 2 + width, y],
|
||||||
|
[x - width / 2 + width, y + height],
|
||||||
|
[x - width / 2, y + height],
|
||||||
|
[x - width / 2, y],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
square = [
|
||||||
|
[x, y],
|
||||||
|
[x + width, y],
|
||||||
|
[x + width, y + height],
|
||||||
|
[x, y + height],
|
||||||
|
[x, y],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// square = [
|
||||||
|
// [x - width / 2, y],
|
||||||
|
// [x - width / 2 + width, y],
|
||||||
|
// [x - width / 2 + width, y + height],
|
||||||
|
// [x - width / 2, y + height],
|
||||||
|
// [x - width / 2, y],
|
||||||
|
// ]
|
||||||
|
|
||||||
const squarePolygon = turf.polygon([square])
|
const squarePolygon = turf.polygon([square])
|
||||||
const disjointFromTrestle =
|
const disjointFromTrestle =
|
||||||
turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||||
|
|
||||||
if (disjointFromTrestle) {
|
if (disjointFromTrestle) {
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
|
|
||||||
if (containsBatchObjects.length > 0) {
|
if (containsBatchObjects.length > 0) {
|
||||||
let convertBatchObject
|
let convertBatchObject
|
||||||
|
|
||||||
//도머가 있으면 적용되는 로직
|
//도머가 있으면 적용되는 로직
|
||||||
const isDisjoint = containsBatchObjects.every((batchObject) => {
|
const isDisjoint = containsBatchObjects.every((batchObject) => {
|
||||||
if (batchObject.type === 'group') {
|
if (batchObject.type === 'group') {
|
||||||
@ -540,12 +578,8 @@ export function useModuleBasicSetting() {
|
|||||||
} else {
|
} else {
|
||||||
convertBatchObject = polygonToTurfPolygon(batchObject)
|
convertBatchObject = polygonToTurfPolygon(batchObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
return turf.booleanDisjoint(squarePolygon, convertBatchObject) //도머가 여러개일수있으므로 겹치는게 있다면...
|
return turf.booleanDisjoint(squarePolygon, convertBatchObject) //도머가 여러개일수있으므로 겹치는게 있다면...
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('isDisjoint', isDisjoint)
|
|
||||||
|
|
||||||
if (isDisjoint) {
|
if (isDisjoint) {
|
||||||
const tempModule = new QPolygon(points, {
|
const tempModule = new QPolygon(points, {
|
||||||
fill: '#BFFD9F',
|
fill: '#BFFD9F',
|
||||||
@ -558,7 +592,11 @@ export function useModuleBasicSetting() {
|
|||||||
lockScalingY: false, // Y 축 크기 조정 잠금
|
lockScalingY: false, // Y 축 크기 조정 잠금
|
||||||
opacity: 0.8,
|
opacity: 0.8,
|
||||||
parentId: moduleSetupSurface.parentId,
|
parentId: moduleSetupSurface.parentId,
|
||||||
|
lineCol: col,
|
||||||
|
lineRow: row,
|
||||||
|
name: 'module',
|
||||||
})
|
})
|
||||||
|
tempModule.setViewLengthText(false)
|
||||||
canvas?.add(tempModule)
|
canvas?.add(tempModule)
|
||||||
moduleSetupArray.push(tempModule)
|
moduleSetupArray.push(tempModule)
|
||||||
}
|
}
|
||||||
@ -577,6 +615,7 @@ export function useModuleBasicSetting() {
|
|||||||
parentId: moduleSetupSurface.parentId,
|
parentId: moduleSetupSurface.parentId,
|
||||||
lineCol: col,
|
lineCol: col,
|
||||||
lineRow: row,
|
lineRow: row,
|
||||||
|
name: 'module',
|
||||||
})
|
})
|
||||||
canvas?.add(tempModule)
|
canvas?.add(tempModule)
|
||||||
moduleSetupArray.push(tempModule)
|
moduleSetupArray.push(tempModule)
|
||||||
@ -584,47 +623,115 @@ export function useModuleBasicSetting() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let drawRoofCells
|
|
||||||
// if (maxLengthLine.flowDirection === 'right' || maxLengthLine.flowDirection === 'left') {
|
|
||||||
// drawRoofCells = trestle.fillCell({ width: 113.4, height: 172.2, padding: 0 })
|
|
||||||
// trestle.flowDirection = 'south'
|
|
||||||
// } else {
|
|
||||||
// drawRoofCells = trestle.fillCell({ width: 172.2, height: 113.4, padding: 0 })
|
|
||||||
// trestle.flowDirection = 'east'
|
|
||||||
// }
|
|
||||||
|
|
||||||
// drawRoofCells.forEach((cell) => {
|
|
||||||
// moduleSetupArray.push(cell)
|
|
||||||
// })
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 추후에 가대까지 완료하면 그룹시켜버림
|
|
||||||
*/
|
|
||||||
// const groupCellObj = canvas
|
|
||||||
// ?.getObjects()
|
|
||||||
// .filter(
|
|
||||||
// (obj) =>
|
|
||||||
// obj?.parentId === trestle.parentId ||
|
|
||||||
// obj?.id === trestle.parentId ||
|
|
||||||
// (obj?.name === 'arrow' && obj?.parent.id === trestle.parentId) ||
|
|
||||||
// (obj?.name === 'flowDirectionText' && obj?.parent.parent.id === trestle.parentId),
|
|
||||||
// )
|
|
||||||
|
|
||||||
// console.log('groupCellObj', groupCellObj)
|
|
||||||
|
|
||||||
// canvas?.add(
|
|
||||||
// new fabric.Group(groupCellObj, {
|
|
||||||
// name: 'cellGroup',
|
|
||||||
// originX: 'center',
|
|
||||||
// originY: 'center',
|
|
||||||
// }),
|
|
||||||
// )
|
|
||||||
|
|
||||||
moduleSetupSurface.set({ modules: moduleSetupArray })
|
moduleSetupSurface.set({ modules: moduleSetupArray })
|
||||||
})
|
})
|
||||||
|
|
||||||
setModuleIsSetup(moduleSetupArray)
|
setModuleIsSetup(moduleSetupArray)
|
||||||
|
|
||||||
|
console.log(calculateForApi(moduleSetupArray))
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateForApi = (moduleSetupArray) => {
|
||||||
|
const centerPoints = []
|
||||||
|
moduleSetupArray.forEach((module, index) => {
|
||||||
|
module.tempIndex = index
|
||||||
|
const { x, y } = module.getCenterPoint()
|
||||||
|
const { width, height } = module
|
||||||
|
centerPoints.push({ x, y, width, height, index })
|
||||||
|
const circle = new fabric.Circle({
|
||||||
|
radius: 5,
|
||||||
|
fill: 'red',
|
||||||
|
name: 'redCircle',
|
||||||
|
left: x - 5,
|
||||||
|
top: y - 5,
|
||||||
|
index: index,
|
||||||
|
selectable: false,
|
||||||
|
})
|
||||||
|
canvas.add(circle)
|
||||||
|
})
|
||||||
|
|
||||||
|
//완전 노출 하면
|
||||||
|
let exposedBottom = 0
|
||||||
|
// 반 노출 하면
|
||||||
|
let exposedHalfBottom = 0
|
||||||
|
// 완전 노출 상면
|
||||||
|
let exposedTop = 0
|
||||||
|
//반 노출 상면
|
||||||
|
let exposedHalfTop = 0
|
||||||
|
// 완전 접면
|
||||||
|
let touchDimension = 0
|
||||||
|
//반접면
|
||||||
|
let halfTouchDimension = 0
|
||||||
|
// 노출하면 체크
|
||||||
|
centerPoints.forEach((centerPoint, index) => {
|
||||||
|
const { x, y, width, height } = centerPoint
|
||||||
|
// centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
|
||||||
|
const bottomCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y + height)) < 2)
|
||||||
|
if (bottomCell.length === 1) {
|
||||||
|
touchDimension++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const bottomLeftPoint = { x: x - width / 2, y: y + height }
|
||||||
|
const bottomRightPoint = { x: x + width / 2, y: y + height }
|
||||||
|
|
||||||
|
// 바로 아래에 셀이 없는 경우 물떼세 배치가 왼쪽 되어있는 셀을 찾는다.
|
||||||
|
const leftBottomCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
const rightBottomCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
if (leftBottomCnt + rightBottomCnt === 2) {
|
||||||
|
touchDimension++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (leftBottomCnt + rightBottomCnt === 1) {
|
||||||
|
halfTouchDimension++
|
||||||
|
exposedHalfBottom++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (leftBottomCnt + rightBottomCnt === 0) {
|
||||||
|
exposedBottom++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 노출상면 체크
|
||||||
|
|
||||||
|
centerPoints.forEach((centerPoint, index) => {
|
||||||
|
const { x, y, width, height } = centerPoint
|
||||||
|
const topCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y - height)) < 2)
|
||||||
|
if (topCell.length === 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
const topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
|
||||||
|
const leftTopCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
const rightTopCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
|
||||||
|
if (leftTopCnt + rightTopCnt === 1) {
|
||||||
|
exposedHalfTop++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (leftTopCnt + rightTopCnt === 0) {
|
||||||
|
exposedTop++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
exposedBottom,
|
||||||
|
exposedHalfBottom,
|
||||||
|
exposedTop,
|
||||||
|
exposedHalfTop,
|
||||||
|
touchDimension,
|
||||||
|
halfTouchDimension,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const coordToTurfPolygon = (points) => {
|
const coordToTurfPolygon = (points) => {
|
||||||
@ -646,7 +753,7 @@ export function useModuleBasicSetting() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function batchObjectGroupToTurfPolygon(group) {
|
const batchObjectGroupToTurfPolygon = (group) => {
|
||||||
const polygons = group.getObjects().filter((obj) => obj.type === 'QPolygon')
|
const polygons = group.getObjects().filter((obj) => obj.type === 'QPolygon')
|
||||||
let allPoints = []
|
let allPoints = []
|
||||||
|
|
||||||
@ -658,6 +765,43 @@ export function useModuleBasicSetting() {
|
|||||||
return hull
|
return hull
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calcMinXByHeightDistance = (nowSurface, index, reverse) => {
|
||||||
|
function calculateSlopeIntercept(x1, y1, x2, y2) {
|
||||||
|
console.log('Intercept', x1, y1, x2, y2)
|
||||||
|
|
||||||
|
const slope = (y2 - y1) / (x2 - x1)
|
||||||
|
const intercept = y1 - slope * x1
|
||||||
|
|
||||||
|
return { slope, intercept }
|
||||||
|
}
|
||||||
|
|
||||||
|
let prevLines = nowSurface.lines[(index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
||||||
|
let nextLines = nowSurface.lines[index]
|
||||||
|
|
||||||
|
// 선분 정보
|
||||||
|
const l1 = prevLines
|
||||||
|
const l2 = nextLines
|
||||||
|
const lineLength = 172.2
|
||||||
|
|
||||||
|
// l1과 l2의 기울기 및 절편
|
||||||
|
let { slope: m1, intercept: b1 } = calculateSlopeIntercept(l1.x1, l1.y1, l1.x2, l1.y2)
|
||||||
|
let { slope: m2, intercept: b2 } = calculateSlopeIntercept(l2.x1, l2.y1, l2.x2, l2.y2)
|
||||||
|
|
||||||
|
console.log(m1, b1, m2, b2)
|
||||||
|
|
||||||
|
// 가로선 x1 계산
|
||||||
|
const x1 = (m2 * lineLength + b2 - b1) / (m1 - m2)
|
||||||
|
const x2 = x1 + lineLength // 끝점 x2
|
||||||
|
|
||||||
|
// 가로선 y값 계산
|
||||||
|
const y0 = m1 * x1 + b1
|
||||||
|
|
||||||
|
// 결과 출력
|
||||||
|
|
||||||
|
console.log({ x1: x1, y1: y0, x2: x2, y2: y0 })
|
||||||
|
return { x1: x1, y1: y0, x2: x2, y2: y0 }
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
makeModuleInstArea,
|
makeModuleInstArea,
|
||||||
manualModuleSetup,
|
manualModuleSetup,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { canvasState } from '@/store/canvasAtom'
|
|||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { compasDegAtom } from '@/store/orientationAtom'
|
import { compasDegAtom } from '@/store/orientationAtom'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
// 모듈,회로 구성 탭 기본설정 > 방위설정 탭
|
// 모듈,회로 구성 탭 기본설정 > 방위설정 탭
|
||||||
export function useOrientation() {
|
export function useOrientation() {
|
||||||
@ -11,6 +12,16 @@ export function useOrientation() {
|
|||||||
|
|
||||||
const { drawDirectionArrow } = usePolygon()
|
const { drawDirectionArrow } = usePolygon()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
roof.set({
|
||||||
|
moduleCompass: null,
|
||||||
|
})
|
||||||
|
drawDirectionArrow(roof)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
const nextStep = () => {
|
const nextStep = () => {
|
||||||
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
roofs.forEach((roof) => {
|
roofs.forEach((roof) => {
|
||||||
@ -277,7 +277,7 @@ export function useCanvasSetting() {
|
|||||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||||
break
|
break
|
||||||
case 'gridDisplay': //그리드 표시
|
case 'gridDisplay': //그리드 표시
|
||||||
optionName = ['lindGrid', 'dotGrid']
|
optionName = ['lindGrid', 'dotGrid', 'tempGrid']
|
||||||
break
|
break
|
||||||
case 'lineDisplay': //지붕선 표시
|
case 'lineDisplay': //지붕선 표시
|
||||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
|
||||||
import { useEffect } from 'react'
|
|
||||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
|
||||||
|
|
||||||
export function useFirstOption() {
|
|
||||||
const canvas = useRecoilValue(canvasState)
|
|
||||||
|
|
||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const option1 = settingModalFirstOptions.option1
|
|
||||||
|
|
||||||
// 'allocDisplay' 할당 표시
|
|
||||||
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
|
||||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
|
||||||
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
|
||||||
// 'wordDisplay' 문자 표시
|
|
||||||
// 'circuitNumDisplay' 회로번호 표시
|
|
||||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
|
||||||
// 'trestleDisplay' 가대 표시
|
|
||||||
// 'totalDisplay' 집계표 표시
|
|
||||||
|
|
||||||
let optionName //옵션명
|
|
||||||
let optionSelected //옵션상태
|
|
||||||
|
|
||||||
for (let i = 0; i < option1.length; i++) {
|
|
||||||
switch (option1[i].column) {
|
|
||||||
case 'allocDisplay': //할당 표시
|
|
||||||
optionName = ['1']
|
|
||||||
break
|
|
||||||
case 'outlineDisplay': //외벽선 표시
|
|
||||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
|
||||||
break
|
|
||||||
case 'gridDisplay': //그리드 표시
|
|
||||||
optionName = ['lineGrid', 'dotGrid', 'adsorptionPoint', 'tempGrid']
|
|
||||||
break
|
|
||||||
case 'lineDisplay': //지붕선 표시
|
|
||||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
|
||||||
break
|
|
||||||
case 'wordDisplay': //문자 표시
|
|
||||||
optionName = ['commonText']
|
|
||||||
break
|
|
||||||
case 'circuitNumDisplay': //회로번호 표시
|
|
||||||
optionName = ['7']
|
|
||||||
break
|
|
||||||
case 'flowDisplay': //흐름방향 표시
|
|
||||||
optionName = ['arrow', 'flowText']
|
|
||||||
break
|
|
||||||
case 'trestleDisplay': //가대 표시
|
|
||||||
optionName = ['8']
|
|
||||||
break
|
|
||||||
case 'totalDisplay': //집계표 표시
|
|
||||||
optionName = ['9']
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// 표시 선택 상태(true/false)
|
|
||||||
optionSelected = option1[i].selected
|
|
||||||
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => optionName.includes(obj.name))
|
|
||||||
//.filter((obj) => obj.name === optionName)
|
|
||||||
.forEach((obj) => {
|
|
||||||
obj.set({ visible: optionSelected })
|
|
||||||
//obj.set({ visible: !obj.visible })
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
// console.log(
|
|
||||||
// 'optionName',
|
|
||||||
// optionName,
|
|
||||||
// canvas.getObjects().filter((obj) => optionName.includes(obj.name)),
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
}, [settingModalFirstOptions])
|
|
||||||
|
|
||||||
return { settingModalFirstOptions, setSettingModalFirstOptions }
|
|
||||||
}
|
|
||||||
@ -15,14 +15,12 @@ import {
|
|||||||
outerLineLength2State,
|
outerLineLength2State,
|
||||||
outerLineTypeState,
|
outerLineTypeState,
|
||||||
} from '@/store/outerLineAtom'
|
} from '@/store/outerLineAtom'
|
||||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine, polygonToTurfPolygon } from '@/util/canvas-util'
|
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine } from '@/util/canvas-util'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { booleanPointInPolygon } from '@turf/turf'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { calculateAngle, isSamePoint } from '@/util/qpolygon-utils'
|
import { calculateAngle, isSamePoint } from '@/util/qpolygon-utils'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
// 보조선 작성
|
// 보조선 작성
|
||||||
@ -122,6 +120,38 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
setOuterLineDiagonalLength(0)
|
setOuterLineDiagonalLength(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const move = (object, x, y) => {
|
||||||
|
const line = copy(object, x, y)
|
||||||
|
canvas.remove(object)
|
||||||
|
canvas.setActiveObject(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
const copy = (object, x, y) => {
|
||||||
|
return addLine([object.x1 + x, object.y1 + y, object.x2 + x, object.y2 + y], {
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
selectable: true,
|
||||||
|
name: 'auxiliaryLine',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addBisectorLine = (target) => {
|
||||||
|
const slope = (target.y2 - target.y1) / (target.x2 - target.x1)
|
||||||
|
const bisectorSlope = -1 / slope
|
||||||
|
const length = target.length
|
||||||
|
const dx = length / Math.sqrt(1 + bisectorSlope * bisectorSlope)
|
||||||
|
const dy = bisectorSlope * dx
|
||||||
|
const endX = (target.x1 + target.x2) / 2
|
||||||
|
const endY = (target.y1 + target.y2) / 2
|
||||||
|
|
||||||
|
addLine([dx, dy, endX, endY], {
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
selectable: true,
|
||||||
|
name: 'auxiliaryLine',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const keydown = {
|
const keydown = {
|
||||||
outerLine: (e) => {
|
outerLine: (e) => {
|
||||||
if (mousePointerArr.current.length === 0) {
|
if (mousePointerArr.current.length === 0) {
|
||||||
@ -130,7 +160,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
if (activeElem !== length1Ref.current) {
|
if (activeElem !== length1Ref.current) {
|
||||||
length1Ref.current.focus()
|
length1Ref?.current?.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = e.key
|
const key = e.key
|
||||||
@ -180,7 +210,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
|
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
if (activeElem !== length1Ref.current && activeElem !== length2Ref.current) {
|
if (activeElem !== length1Ref.current && activeElem !== length2Ref.current) {
|
||||||
length1Ref.current.focus()
|
length1Ref?.current?.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@ -455,9 +485,24 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
name: 'auxiliaryLine',
|
name: 'auxiliaryLine',
|
||||||
})
|
})
|
||||||
|
|
||||||
lineHistory.current.push(line)
|
const historyLines = [...lineHistory.current]
|
||||||
|
|
||||||
|
const hasSameLine = historyLines.some((history) => {
|
||||||
|
return (
|
||||||
|
(isSamePoint(history.startPoint, line.startPoint) && isSamePoint(history.endPoint, line.endPoint)) ||
|
||||||
|
(isSamePoint(history.startPoint, line.endPoint) && isSamePoint(history.endPoint, line.startPoint))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
mousePointerArr.current = []
|
mousePointerArr.current = []
|
||||||
clear()
|
clear()
|
||||||
|
|
||||||
|
if (hasSameLine) {
|
||||||
|
canvas.remove(line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lineHistory.current.push(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mouseDown = (e) => {
|
const mouseDown = (e) => {
|
||||||
@ -856,5 +901,8 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
handleRollback,
|
handleRollback,
|
||||||
buttonAct,
|
buttonAct,
|
||||||
setButtonAct,
|
setButtonAct,
|
||||||
|
move,
|
||||||
|
copy,
|
||||||
|
addBisectorLine,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,6 +125,12 @@ export function usePropertiesSetting(id) {
|
|||||||
}
|
}
|
||||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
const notSetAttributes = lines.filter((line) => !line.attributes?.type)
|
||||||
|
if (notSetAttributes.length > 0) {
|
||||||
|
alert('설정되지 않은 외벽선이 있습니다.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
line.set({
|
line.set({
|
||||||
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
@ -10,6 +10,9 @@ import { POLYGON_TYPE } from '@/common/common'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import ActualSizeSetting from '@/components/floor-plan/modal/roofAllocation/ActualSizeSetting'
|
import ActualSizeSetting from '@/components/floor-plan/modal/roofAllocation/ActualSizeSetting'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
import { menuTypeState } from '@/store/menuAtom'
|
||||||
|
|
||||||
// 지붕면 할당
|
// 지붕면 할당
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
@ -21,6 +24,8 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const currentObject = useRecoilValue(currentObjectState)
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
|
const { setMenuNumber } = useCanvasMenu()
|
||||||
|
const setMenuType = useSetRecoilState(menuTypeState)
|
||||||
const roofMaterials = [
|
const roofMaterials = [
|
||||||
{
|
{
|
||||||
id: 'A',
|
id: 'A',
|
||||||
@ -132,6 +137,9 @@ export function useRoofAllocationSetting(id) {
|
|||||||
setValues(values.filter((value) => value.id !== id))
|
setValues(values.filter((value) => value.id !== id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { handleMenu } = useMenu()
|
||||||
|
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
||||||
|
|
||||||
// 선택한 지붕재로 할당
|
// 선택한 지붕재로 할당
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
||||||
@ -213,6 +221,8 @@ export function useRoofAllocationSetting(id) {
|
|||||||
})
|
})
|
||||||
setEditingLines([])
|
setEditingLines([])
|
||||||
closeAll()
|
closeAll()
|
||||||
|
setMenuNumber(3)
|
||||||
|
setMenuType('surface')
|
||||||
}
|
}
|
||||||
|
|
||||||
const setLineSize = (id, size) => {
|
const setLineSize = (id, size) => {
|
||||||
|
|||||||
@ -377,20 +377,20 @@ export function useRoofShapeSetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 기존 wallLine, roofBase 제거
|
// 기존 wallLine, roofBase 제거
|
||||||
/*canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
.forEach((line) => {
|
.forEach((line) => {
|
||||||
canvas.remove(line)
|
canvas.remove(line)
|
||||||
})*/
|
})
|
||||||
|
|
||||||
/*canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
|
||||||
.forEach((obj) => {
|
.forEach((obj) => {
|
||||||
canvas.remove(...obj.innerLines)
|
canvas.remove(...obj.innerLines)
|
||||||
canvas.remove(obj)
|
canvas.remove(obj)
|
||||||
})*/
|
})
|
||||||
|
|
||||||
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction })
|
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction })
|
||||||
polygon.lines = [...outerLines]
|
polygon.lines = [...outerLines]
|
||||||
|
|||||||
@ -102,6 +102,15 @@ export function useSurfaceShapeBatch() {
|
|||||||
|
|
||||||
canvas?.add(obj)
|
canvas?.add(obj)
|
||||||
|
|
||||||
|
canvas?.renderAll()
|
||||||
|
closePopup(id)
|
||||||
|
})
|
||||||
|
|
||||||
|
addCanvasMouseEventListener('mouse:down', (e) => {
|
||||||
|
isDrawing = false
|
||||||
|
|
||||||
|
canvas?.remove(obj)
|
||||||
|
|
||||||
//각도 추가
|
//각도 추가
|
||||||
let originAngle = 0 //기본 남쪽
|
let originAngle = 0 //기본 남쪽
|
||||||
let direction = 'south'
|
let direction = 'south'
|
||||||
@ -119,21 +128,31 @@ export function useSurfaceShapeBatch() {
|
|||||||
direction = 'north'
|
direction = 'north'
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.set({ direction: direction })
|
//회전, flip등이 먹은 기준으로 새로생성
|
||||||
obj.set({ originAngle: originAngle })
|
const batchSurface = new QPolygon(obj.getCurrentPoints(), {
|
||||||
|
fill: 'transparent',
|
||||||
canvas?.renderAll()
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
strokeDasharray: [10, 4],
|
||||||
|
fontSize: 12,
|
||||||
|
selectable: true,
|
||||||
|
lockMovementX: true, // X 축 이동 잠금
|
||||||
|
lockMovementY: true, // Y 축 이동 잠금
|
||||||
|
lockRotation: true, // 회전 잠금
|
||||||
|
lockScalingX: true, // X 축 크기 조정 잠금
|
||||||
|
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||||
|
name: POLYGON_TYPE.ROOF,
|
||||||
|
originX: 'center',
|
||||||
|
originY: 'center',
|
||||||
|
pitch: globalPitch,
|
||||||
|
surfaceId: surfaceId,
|
||||||
|
direction: direction,
|
||||||
|
})
|
||||||
|
canvas?.add(batchSurface)
|
||||||
|
setSurfaceShapePattern(batchSurface, roofDisplay.column)
|
||||||
|
drawDirectionArrow(batchSurface)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
})
|
|
||||||
|
|
||||||
addCanvasMouseEventListener('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
obj.set('name', POLYGON_TYPE.ROOF)
|
|
||||||
obj.set('surfaceId', surfaceId)
|
|
||||||
initEvent()
|
initEvent()
|
||||||
setSurfaceShapePattern(obj, roofDisplay.column)
|
|
||||||
closePopup(id)
|
|
||||||
drawDirectionArrow(obj)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,8 +438,8 @@ export function useSurfaceShapeBatch() {
|
|||||||
{
|
{
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
stroke: 'black', //black
|
stroke: 'black', //black
|
||||||
strokeWidth: 2,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: false,
|
||||||
fontSize: 0,
|
fontSize: 0,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -429,6 +448,7 @@ export function useSurfaceShapeBatch() {
|
|||||||
const scale = (length1 - length2) / coord.x
|
const scale = (length1 - length2) / coord.x
|
||||||
|
|
||||||
tmpPolygon.set({ scaleX: scale })
|
tmpPolygon.set({ scaleX: scale })
|
||||||
|
tmpPolygon.setViewLengthText(false)
|
||||||
|
|
||||||
pointsArray[0].x = 0
|
pointsArray[0].x = 0
|
||||||
pointsArray[0].y = length3 //바닥면부터 시작하게
|
pointsArray[0].y = length3 //바닥면부터 시작하게
|
||||||
@ -584,18 +604,6 @@ export function useSurfaceShapeBatch() {
|
|||||||
text: '배치면 내용을 전부 삭제하시겠습니까?',
|
text: '배치면 내용을 전부 삭제하시겠습니까?',
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
// canvas?.getObjects().forEach((obj) => {
|
|
||||||
// if (
|
|
||||||
// obj.name === POLYGON_TYPE.ROOF ||
|
|
||||||
// obj.name === BATCH_TYPE.OPENING ||
|
|
||||||
// obj.name === BATCH_TYPE.SHADOW ||
|
|
||||||
// obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
|
|
||||||
// obj.name === BATCH_TYPE.PENTAGON_DORMER ||
|
|
||||||
// obj.name === 'lengthText'
|
|
||||||
// ) {
|
|
||||||
// canvas?.remove(obj)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
canvas.clear()
|
canvas.clear()
|
||||||
swalFire({ text: '삭제 완료 되었습니다.' })
|
swalFire({ text: '삭제 완료 되었습니다.' })
|
||||||
},
|
},
|
||||||
@ -661,34 +669,6 @@ export function useSurfaceShapeBatch() {
|
|||||||
return groupObjectsArray
|
return groupObjectsArray
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllRelatedObjects(id) {
|
|
||||||
const ult = []
|
|
||||||
const map = new Map()
|
|
||||||
|
|
||||||
// Create a map of objects by their id
|
|
||||||
canvas.getObjects().forEach((obj) => {
|
|
||||||
map.set(obj.id, obj)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Helper function to recursively find all related objects
|
|
||||||
function findRelatedObjects(id) {
|
|
||||||
const obj = map.get(id)
|
|
||||||
if (obj) {
|
|
||||||
result.push(obj)
|
|
||||||
canvas.getObjects().forEach((o) => {
|
|
||||||
if (o.parentId === id) {
|
|
||||||
findRelatedObjects(o.id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the search with the given parentId
|
|
||||||
findRelatedObjects(id)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveSurfaceShapeBatch = () => {
|
const moveSurfaceShapeBatch = () => {
|
||||||
const roof = canvas.getActiveObject()
|
const roof = canvas.getActiveObject()
|
||||||
|
|
||||||
@ -919,12 +899,45 @@ export function useSurfaceShapeBatch() {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeSurfaceFlowDirection = (roof, direction, orientation) => {
|
const updateFlippedPoints = (polygon) => {
|
||||||
roof.set({
|
if (!(polygon instanceof fabric.Polygon)) {
|
||||||
direction: direction,
|
console.error('The object is not a Polygon.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { flipX, flipY, width, height, points, left, top, scaleX, scaleY } = polygon
|
||||||
|
|
||||||
|
// 현재 points의 사본 가져오기
|
||||||
|
const newPoints = points.map((point) => {
|
||||||
|
let x = point.x
|
||||||
|
let y = point.y
|
||||||
|
|
||||||
|
// flipX 적용
|
||||||
|
if (flipX) {
|
||||||
|
x = width - x
|
||||||
|
}
|
||||||
|
|
||||||
|
// flipY 적용
|
||||||
|
if (flipY) {
|
||||||
|
y = height - y
|
||||||
|
}
|
||||||
|
|
||||||
|
// 스케일 및 전역 좌표 고려
|
||||||
|
x = (x - width / 2) * scaleX + width / 2
|
||||||
|
y = (y - height / 2) * scaleY + height / 2
|
||||||
|
|
||||||
|
return { x, y }
|
||||||
})
|
})
|
||||||
drawDirectionArrow(roof)
|
|
||||||
canvas?.renderAll()
|
// flipX, flipY를 초기화
|
||||||
|
polygon.flipX = false
|
||||||
|
polygon.flipY = false
|
||||||
|
|
||||||
|
// points 업데이트
|
||||||
|
polygon.set({ points: newPoints })
|
||||||
|
polygon.setCoords()
|
||||||
|
|
||||||
|
return polygon
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
import AuxiliaryMove from '@/components/floor-plan/modal/auxiliary/AuxiliaryMove'
|
|
||||||
import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize'
|
import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
@ -11,7 +10,7 @@ import GridCopy from '@/components/floor-plan/modal/grid/GridCopy'
|
|||||||
import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal'
|
import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal'
|
||||||
import { gridColorState } from '@/store/gridAtom'
|
import { gridColorState } from '@/store/gridAtom'
|
||||||
import { contextPopupPositionState, contextPopupState } from '@/store/popupAtom'
|
import { contextPopupPositionState, contextPopupState } from '@/store/popupAtom'
|
||||||
import AuxiliaryCopy from '@/components/floor-plan/modal/auxiliary/AuxiliaryCopy'
|
import AuxiliaryEdit from '@/components/floor-plan/modal/auxiliary/AuxiliaryEdit'
|
||||||
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
|
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
|
||||||
import RoofMaterialSetting from '@/components/floor-plan/modal/object/RoofMaterialSetting'
|
import RoofMaterialSetting from '@/components/floor-plan/modal/object/RoofMaterialSetting'
|
||||||
import DormerOffset from '@/components/floor-plan/modal/object/DormerOffset'
|
import DormerOffset from '@/components/floor-plan/modal/object/DormerOffset'
|
||||||
@ -34,8 +33,10 @@ import CircuitNumberEdit from '@/components/floor-plan/modal/module/CircuitNumbe
|
|||||||
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
||||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||||
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
||||||
|
import { useLine } from '@/hooks/useLine'
|
||||||
|
|
||||||
export function useContextMenu() {
|
export function useContextMenu() {
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
|
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
|
||||||
const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴
|
const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴
|
||||||
const [contextMenu, setContextMenu] = useRecoilState(contextMenuListState) // 메뉴.object 별 context menu
|
const [contextMenu, setContextMenu] = useRecoilState(contextMenuListState) // 메뉴.object 별 context menu
|
||||||
@ -53,6 +54,7 @@ export function useContextMenu() {
|
|||||||
const { moveObjectBatch } = useObjectBatch({})
|
const { moveObjectBatch } = useObjectBatch({})
|
||||||
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
|
const { addLine, removeLine } = useLine()
|
||||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||||
|
|
||||||
const currentMenuSetting = () => {
|
const currentMenuSetting = () => {
|
||||||
@ -130,22 +132,57 @@ export function useContextMenu() {
|
|||||||
id: 'auxiliaryMove',
|
id: 'auxiliaryMove',
|
||||||
name: `${getMessage('contextmenu.auxiliary.move')}(M)`,
|
name: `${getMessage('contextmenu.auxiliary.move')}(M)`,
|
||||||
shortcut: ['m', 'M'],
|
shortcut: ['m', 'M'],
|
||||||
component: <AuxiliaryMove id={popupId} />,
|
component: <AuxiliaryEdit id={popupId} type={'move'} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'auxiliaryCopy',
|
id: 'auxiliaryCopy',
|
||||||
name: `${getMessage('contextmenu.auxiliary.copy')}(C)`,
|
name: `${getMessage('contextmenu.auxiliary.copy')}(C)`,
|
||||||
shortcut: ['c', 'C'],
|
shortcut: ['c', 'C'],
|
||||||
component: <AuxiliaryCopy id={popupId} />,
|
component: <AuxiliaryEdit id={popupId} type={'copy'} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'auxiliaryRemove',
|
id: 'auxiliaryRemove',
|
||||||
shortcut: ['d', 'D'],
|
shortcut: ['d', 'D'],
|
||||||
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
|
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
|
||||||
|
fn: () => {
|
||||||
|
canvas.remove(currentObject)
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'auxiliaryVerticalBisector',
|
id: 'auxiliaryVerticalBisector',
|
||||||
name: getMessage('contextmenu.auxiliary.vertical.bisector'),
|
name: getMessage('contextmenu.auxiliary.vertical.bisector'),
|
||||||
|
fn: () => {
|
||||||
|
const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1)
|
||||||
|
const length = currentObject.length
|
||||||
|
|
||||||
|
let startX, startY, endX, endY
|
||||||
|
if (slope === 0) {
|
||||||
|
startX = endX = (currentObject.x1 + currentObject.x2) / 2
|
||||||
|
startY = currentObject.y2 - length / 2
|
||||||
|
endY = currentObject.y2 + length / 2
|
||||||
|
} else if (slope === Infinity) {
|
||||||
|
startX = currentObject.x1 - length / 2
|
||||||
|
startY = endY = (currentObject.y1 + currentObject.y2) / 2
|
||||||
|
endX = currentObject.x1 + length / 2
|
||||||
|
} else {
|
||||||
|
const bisectorSlope = -1 / slope
|
||||||
|
const dx = length / 2 / Math.sqrt(1 + bisectorSlope * bisectorSlope)
|
||||||
|
const dy = bisectorSlope * dx
|
||||||
|
|
||||||
|
startX = (currentObject.x1 + currentObject.x2) / 2 + dx
|
||||||
|
startY = (currentObject.y1 + currentObject.y2) / 2 + dy
|
||||||
|
endX = (currentObject.x1 + currentObject.x2) / 2 - dx
|
||||||
|
endY = (currentObject.y1 + currentObject.y2) / 2 - dy
|
||||||
|
}
|
||||||
|
|
||||||
|
addLine([startX, startY, endX, endY], {
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
selectable: true,
|
||||||
|
name: 'auxiliaryLine',
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'auxiliaryCut',
|
id: 'auxiliaryCut',
|
||||||
@ -248,8 +285,6 @@ export function useContextMenu() {
|
|||||||
}, [currentContextMenu])
|
}, [currentContextMenu])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(currentObject)
|
|
||||||
|
|
||||||
if (currentObject?.name) {
|
if (currentObject?.name) {
|
||||||
console.log('object', currentObject)
|
console.log('object', currentObject)
|
||||||
switch (currentObject.name) {
|
switch (currentObject.name) {
|
||||||
@ -446,19 +481,24 @@ export function useContextMenu() {
|
|||||||
])
|
])
|
||||||
break
|
break
|
||||||
case 'lineGrid':
|
case 'lineGrid':
|
||||||
|
case 'dotGrid':
|
||||||
|
case 'tempGrid':
|
||||||
setContextMenu([
|
setContextMenu([
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'gridMove',
|
id: 'gridMove',
|
||||||
name: getMessage('modal.grid.move'),
|
name: getMessage('modal.grid.move'),
|
||||||
|
component: <GridMove id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gridCopy',
|
id: 'gridCopy',
|
||||||
name: getMessage('modal.grid.copy'),
|
name: getMessage('modal.grid.copy'),
|
||||||
|
component: <GridCopy id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('contextmenu.grid.color.edit'),
|
name: getMessage('contextmenu.grid.color.edit'),
|
||||||
|
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
@ -467,6 +507,7 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'removeAll',
|
id: 'removeAll',
|
||||||
name: getMessage('contextmenu.remove.all'),
|
name: getMessage('contextmenu.remove.all'),
|
||||||
|
fn: () => {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
|
|||||||
@ -23,6 +23,9 @@ export function usePlan() {
|
|||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { get, promisePost, promisePut, promiseDel } = useAxios()
|
const { get, promisePost, promisePut, promiseDel } = useAxios()
|
||||||
|
|
||||||
|
const planLabel = 'Plan '
|
||||||
|
const newPlanLabel = 'New Plan '
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 마우스 포인터의 가이드라인을 제거합니다.
|
* 마우스 포인터의 가이드라인을 제거합니다.
|
||||||
*/
|
*/
|
||||||
@ -184,7 +187,7 @@ export function usePlan() {
|
|||||||
return get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) =>
|
return get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) =>
|
||||||
res.map((item) => ({
|
res.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.objectNo + '-' + item.id, // tab button에 표출될 이름 (임시)
|
name: planLabel + item.id,
|
||||||
userId: item.userId,
|
userId: item.userId,
|
||||||
canvasStatus: dbToCanvasFormat(item.canvasStatus),
|
canvasStatus: dbToCanvasFormat(item.canvasStatus),
|
||||||
isCurrent: false,
|
isCurrent: false,
|
||||||
@ -213,7 +216,7 @@ export function usePlan() {
|
|||||||
? {
|
? {
|
||||||
...plan,
|
...plan,
|
||||||
id: res.data,
|
id: res.data,
|
||||||
name: currentCanvasPlan.objectNo + '-' + res.data,
|
name: planLabel + res.data,
|
||||||
canvasStatus: canvasStatus,
|
canvasStatus: canvasStatus,
|
||||||
}
|
}
|
||||||
: plan,
|
: plan,
|
||||||
@ -318,7 +321,7 @@ export function usePlan() {
|
|||||||
const id = uuidv4()
|
const id = uuidv4()
|
||||||
const newPlan = {
|
const newPlan = {
|
||||||
id: id,
|
id: id,
|
||||||
name: `Plan ${planNum + 1}`,
|
name: newPlanLabel + `${planNum + 1}`,
|
||||||
objectNo: objectNo,
|
objectNo: objectNo,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
canvasStatus: canvasStatus,
|
canvasStatus: canvasStatus,
|
||||||
@ -364,14 +367,13 @@ export function usePlan() {
|
|||||||
/**
|
/**
|
||||||
* plan 조회
|
* plan 조회
|
||||||
*/
|
*/
|
||||||
const loadCanvasPlanData = (userId, objectNo) => {
|
const loadCanvasPlanData = (userId, objectNo, pid) => {
|
||||||
getCanvasByObjectNo(userId, objectNo).then((res) => {
|
getCanvasByObjectNo(userId, objectNo).then((res) => {
|
||||||
// console.log('canvas 목록 ', res)
|
// console.log('canvas 목록 ', res)
|
||||||
if (res.length > 0) {
|
if (res.length > 0) {
|
||||||
setInitCanvasPlans(res)
|
setInitCanvasPlans(res)
|
||||||
setPlans(res)
|
setPlans(res)
|
||||||
updateCurrentPlan(res.at(-1).id) // last 데이터에 포커싱
|
updateCurrentPlan(Number(pid)) // last 데이터에 포커싱
|
||||||
setPlanNum(res.length)
|
|
||||||
} else {
|
} else {
|
||||||
addPlan(userId, objectNo)
|
addPlan(userId, objectNo)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
'use server'
|
'use server'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated
|
||||||
|
* 개발후 삭제 예정
|
||||||
|
*/
|
||||||
|
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
const imageSavePath = 'public/cadImages'
|
const imageSavePath = 'public/cadImages'
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
'use server'
|
'use server'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated
|
||||||
|
* 개발후 삭제 예정
|
||||||
|
*/
|
||||||
|
|
||||||
// import { PrismaClient } from '@prisma/client'
|
// import { PrismaClient } from '@prisma/client'
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
|
|||||||
64
src/lib/fileAction.js
Normal file
64
src/lib/fileAction.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
|
const CAD_FILE_PATH = 'public/cad-images'
|
||||||
|
const IMAGE_FILE_PATH = 'public/plan-bg-images'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 변환 & 저장
|
||||||
|
* @param {*} fileName
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const convertDwgToPng = async (fileName, data) => {
|
||||||
|
console.log('fileName', fileName)
|
||||||
|
try {
|
||||||
|
await fs.readdir(CAD_FILE_PATH)
|
||||||
|
} catch {
|
||||||
|
await fs.mkdir(CAD_FILE_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fs.writeFile(`${CAD_FILE_PATH}/${fileName}`, data, 'base64')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 이미지 저장
|
||||||
|
* base64 형식으로 저장
|
||||||
|
* @param {*} title
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const writeImageBase64 = async (title, data) => {
|
||||||
|
// 해당 경로에 Directory 가 없다면 생성
|
||||||
|
try {
|
||||||
|
await fs.readdir(IMAGE_FILE_PATH)
|
||||||
|
} catch {
|
||||||
|
await fs.mkdir(IMAGE_FILE_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.writeFile(`${IMAGE_FILE_PATH}/${title}.png`, data, 'base64')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 이미지 저장
|
||||||
|
* Buffer 형식으로 저장
|
||||||
|
* @param {*} title
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const writeImageBuffer = async (file) => {
|
||||||
|
// 해당 경로에 Directory 가 없다면 생성
|
||||||
|
try {
|
||||||
|
await fs.readdir(IMAGE_FILE_PATH)
|
||||||
|
} catch {
|
||||||
|
await fs.mkdir(IMAGE_FILE_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await fileURLToPath.arrayBuffer()
|
||||||
|
const buffer = new Uint8Array(arrayBuffer)
|
||||||
|
|
||||||
|
return fs.writeFile(`${IMAGE_FILE_PATH}/${file.fileName}`, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { convertDwgToPng, writeImageBase64, writeImageBuffer }
|
||||||
@ -4,6 +4,7 @@
|
|||||||
"header.menus.home": "ホームへv",
|
"header.menus.home": "ホームへv",
|
||||||
"header.menus.management": "物品及び図面管理",
|
"header.menus.management": "物品及び図面管理",
|
||||||
"header.menus.management.newStuff": "新規 物件 登録",
|
"header.menus.management.newStuff": "新規 物件 登録",
|
||||||
|
"header.menus.management.detail": "物件詳細",
|
||||||
"header.menus.management.stuffList": "物件の状況",
|
"header.menus.management.stuffList": "物件の状況",
|
||||||
"header.menus.community": "コミュニティ",
|
"header.menus.community": "コミュニティ",
|
||||||
"header.menus.community.notice": "お知らせ",
|
"header.menus.community.notice": "お知らせ",
|
||||||
@ -160,7 +161,7 @@
|
|||||||
"plan.menu.estimate.docDown": "文書のダウンロード",
|
"plan.menu.estimate.docDown": "文書のダウンロード",
|
||||||
"plan.menu.estimate.save": "保存",
|
"plan.menu.estimate.save": "保存",
|
||||||
"plan.menu.estimate.reset": "初期化",
|
"plan.menu.estimate.reset": "初期化",
|
||||||
"plan.menu.estimate.copy": "コピー",
|
"plan.menu.estimate.copy": "見積書のコピー",
|
||||||
"plan.menu.simulation": "発展シミュレーション",
|
"plan.menu.simulation": "発展シミュレーション",
|
||||||
"plan.menu.simulation.excel": "Excel",
|
"plan.menu.simulation.excel": "Excel",
|
||||||
"plan.menu.simulation.pdf": "PDF",
|
"plan.menu.simulation.pdf": "PDF",
|
||||||
@ -284,7 +285,6 @@
|
|||||||
"modal.panel.batch.statistic.total": "合計",
|
"modal.panel.batch.statistic.total": "合計",
|
||||||
"modal.flow.direction.setting": "流れ方向の設定",
|
"modal.flow.direction.setting": "流れ方向の設定",
|
||||||
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
|
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
|
||||||
"modal.image.size.setting": "画像のサイズ変更",
|
|
||||||
"modal.actual.size.setting": "実測値設定",
|
"modal.actual.size.setting": "実測値設定",
|
||||||
"modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。",
|
"modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。",
|
||||||
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)",
|
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)",
|
||||||
@ -667,6 +667,7 @@
|
|||||||
"stuff.detail.btn.save": "保存",
|
"stuff.detail.btn.save": "保存",
|
||||||
"stuff.detail.btn.tempSave": "一時保存",
|
"stuff.detail.btn.tempSave": "一時保存",
|
||||||
"stuff.detail.save": "保存しました",
|
"stuff.detail.save": "保存しました",
|
||||||
|
"stuff.detail.tempSave": "一時保存されました",
|
||||||
"stuff.detail.noChgData": "変更内容はありません",
|
"stuff.detail.noChgData": "変更内容はありません",
|
||||||
"stuff.detail.save.valierror1": "垂直説説は0より大きい値を入力してください",
|
"stuff.detail.save.valierror1": "垂直説説は0より大きい値を入力してください",
|
||||||
"stuff.detail.save.valierror2": "設置高さ0より大きい値を入力してください",
|
"stuff.detail.save.valierror2": "設置高さ0より大きい値を入力してください",
|
||||||
@ -697,9 +698,9 @@
|
|||||||
"stuff.planReqPopup.error.message1": "設計依頼を選択してください.",
|
"stuff.planReqPopup.error.message1": "設計依頼を選択してください.",
|
||||||
"stuff.planReqPopup.error.message2": "販売店を選択してください.",
|
"stuff.planReqPopup.error.message2": "販売店を選択してください.",
|
||||||
"stuff.search.title": "物件状況",
|
"stuff.search.title": "物件状況",
|
||||||
"stuff.search.btn1": "新規 物件 登録",
|
"stuff.search.btn.register": "新規 物件 登録",
|
||||||
"stuff.search.btn2": "照会",
|
"stuff.search.btn.search": "照会",
|
||||||
"stuff.search.btn3": "初期化",
|
"stuff.search.btn.reset": "初期化",
|
||||||
"stuff.search.schObjectNo": "品番",
|
"stuff.search.schObjectNo": "品番",
|
||||||
"stuff.search.schSaleStoreName": "販売代理店名",
|
"stuff.search.schSaleStoreName": "販売代理店名",
|
||||||
"stuff.search.schAddress": "商品アドレス",
|
"stuff.search.schAddress": "商品アドレス",
|
||||||
@ -823,6 +824,8 @@
|
|||||||
"estimate.detail.objectName": "案件名",
|
"estimate.detail.objectName": "案件名",
|
||||||
"estimate.detail.objectRemarks": "メモ",
|
"estimate.detail.objectRemarks": "メモ",
|
||||||
"estimate.detail.estimateType": "注文分類",
|
"estimate.detail.estimateType": "注文分類",
|
||||||
|
"estimate.detail.estimateType.yjss": "住宅PKG",
|
||||||
|
"estimate.detail.estimateType.yjod": "積上げ( YJOD )",
|
||||||
"estimate.detail.roofCns": "屋根材・仕様施工",
|
"estimate.detail.roofCns": "屋根材・仕様施工",
|
||||||
"estimate.detail.remarks": "備考",
|
"estimate.detail.remarks": "備考",
|
||||||
"estimate.detail.fileFlg": "後日資料提出",
|
"estimate.detail.fileFlg": "後日資料提出",
|
||||||
@ -839,11 +842,10 @@
|
|||||||
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
|
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(モジュール容量 × 数量)÷1000",
|
|
||||||
"estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG単価 (W)×PKG容量(W)",
|
|
||||||
"estimate.detail.header.showPrice": "価格表示",
|
"estimate.detail.header.showPrice": "価格表示",
|
||||||
"estimate.detail.header.unitPrice": "定価",
|
"estimate.detail.header.unitPrice": "定価",
|
||||||
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
||||||
|
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください.",
|
||||||
"estimate.detail.showPrice.description1": "製品価格 OPEN",
|
"estimate.detail.showPrice.description1": "製品価格 OPEN",
|
||||||
"estimate.detail.showPrice.description2": "追加, 変更資材",
|
"estimate.detail.showPrice.description2": "追加, 変更資材",
|
||||||
"estimate.detail.showPrice.description3": "添付必須",
|
"estimate.detail.showPrice.description3": "添付必須",
|
||||||
@ -868,17 +870,31 @@
|
|||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "販売店名",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "販売店名",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "案件名",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "案件名",
|
||||||
"estimate.detail.docPopup.schWeightFlg": "架台重量表を含む",
|
"estimate.detail.docPopup.schWeightFlg": "架台重量表を含む",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "含む",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "含む",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "含まない",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "含まない",
|
||||||
"estimate.detail.docPopup.schDrawingFlg": "図面/シミュレーションファイルを含む",
|
"estimate.detail.docPopup.schDrawingFlg": "図面/シミュレーションファイルを含む",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "含む",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "含む",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "含まない",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "含まない",
|
||||||
"estimate.detail.docPopup.close": "閉じる",
|
"estimate.detail.docPopup.close": "閉じる",
|
||||||
"estimate.detail.docPopup.docDownload": "文書のダウンロード",
|
"estimate.detail.docPopup.docDownload": "文書のダウンロード",
|
||||||
|
"estimate.detail.estimateCopyPopup.title": "見積もり",
|
||||||
|
"estimate.detail.estimateCopyPopup.explane": "見積書をコピーする販売店を設定します。見積もりは定価にコピーされます.",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.saleStoreId": "一次販売店名 / ID",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.otherSaleStoreId": "二次販売店名 / ID",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.receiveUser": "担当者",
|
||||||
|
"estimate.detail.estimateCopyPopup.close": "閉じる",
|
||||||
|
"estimate.detail.estimateCopyPopup.copyBtn": "見積もり",
|
||||||
|
"estimate.detail.estimateCopyPopup.copy.alertMessage": "見積書がコピーされました. コピーした商品情報に移動します.",
|
||||||
"estimate.detail.productFeaturesPopup.title": "製品特異事項",
|
"estimate.detail.productFeaturesPopup.title": "製品特異事項",
|
||||||
"estimate.detail.productFeaturesPopup.close": "閉じる",
|
"estimate.detail.productFeaturesPopup.close": "閉じる",
|
||||||
|
"estimate.detail.productFeaturesPopup.requiredStoreId": "一次販売店は必須です.",
|
||||||
|
"estimate.detail.productFeaturesPopup.requiredReceiveUser": "担当者は必須です.",
|
||||||
"estimate.detail.save.alertMsg": "保存されている見積書で製品を変更した場合、図面や回路には反映されません.",
|
"estimate.detail.save.alertMsg": "保存されている見積書で製品を変更した場合、図面や回路には反映されません.",
|
||||||
"estimate.detail.save.requiredMsg": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください.",
|
"estimate.detail.save.requiredFileUpload": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください.",
|
||||||
|
"estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります.",
|
||||||
|
"estimate.detail.save.requiredCharger": "担当者は必須です.",
|
||||||
|
"estimate.detail.save.requiredObjectName": "案件名は必須です.",
|
||||||
|
"estimate.detail.save.requiredEstimateDate": "見積日は必須です.",
|
||||||
"estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?",
|
"estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?",
|
||||||
"simulator.title.sub1": "物件番号",
|
"simulator.title.sub1": "物件番号",
|
||||||
"simulator.title.sub2": "作成日",
|
"simulator.title.sub2": "作成日",
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"header.menus.home": "Home",
|
"header.menus.home": "Home",
|
||||||
"header.menus.management": "물건 및 도면 관리",
|
"header.menus.management": "물건 및 도면 관리",
|
||||||
"header.menus.management.newStuff": "신규 물건 등록",
|
"header.menus.management.newStuff": "신규 물건 등록",
|
||||||
|
"header.menus.management.detail": "물건 상세",
|
||||||
"header.menus.management.stuffList": "물건 현황",
|
"header.menus.management.stuffList": "물건 현황",
|
||||||
"header.menus.community": "커뮤니티",
|
"header.menus.community": "커뮤니티",
|
||||||
"header.menus.community.notice": "공지",
|
"header.menus.community.notice": "공지",
|
||||||
@ -164,7 +165,7 @@
|
|||||||
"plan.menu.estimate.docDown": "문서 다운로드",
|
"plan.menu.estimate.docDown": "문서 다운로드",
|
||||||
"plan.menu.estimate.save": "저장",
|
"plan.menu.estimate.save": "저장",
|
||||||
"plan.menu.estimate.reset": "초기화",
|
"plan.menu.estimate.reset": "초기화",
|
||||||
"plan.menu.estimate.copy": "복사",
|
"plan.menu.estimate.copy": "견적서 복사",
|
||||||
"plan.menu.simulation": "발전 시뮬레이션",
|
"plan.menu.simulation": "발전 시뮬레이션",
|
||||||
"plan.menu.simulation.excel": "Excel",
|
"plan.menu.simulation.excel": "Excel",
|
||||||
"plan.menu.simulation.pdf": "PDF",
|
"plan.menu.simulation.pdf": "PDF",
|
||||||
@ -289,7 +290,6 @@
|
|||||||
"modal.panel.batch.statistic.total": "합계",
|
"modal.panel.batch.statistic.total": "합계",
|
||||||
"modal.flow.direction.setting": "흐름 방향 설정",
|
"modal.flow.direction.setting": "흐름 방향 설정",
|
||||||
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
|
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
|
||||||
"modal.image.size.setting": "이미지 크기 조절",
|
|
||||||
"modal.actual.size.setting": "실측치 설정",
|
"modal.actual.size.setting": "실측치 설정",
|
||||||
"modal.actual.size.setting.info": "※隅棟・谷・棟의 실제 치수를 입력해주세요.",
|
"modal.actual.size.setting.info": "※隅棟・谷・棟의 실제 치수를 입력해주세요.",
|
||||||
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요",
|
"modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요",
|
||||||
@ -677,6 +677,7 @@
|
|||||||
"stuff.detail.btn.save": "저장",
|
"stuff.detail.btn.save": "저장",
|
||||||
"stuff.detail.btn.tempSave": "임시저장",
|
"stuff.detail.btn.tempSave": "임시저장",
|
||||||
"stuff.detail.save": "저장되었습니다",
|
"stuff.detail.save": "저장되었습니다",
|
||||||
|
"stuff.detail.tempSave": "임시저장 되었습니다",
|
||||||
"stuff.detail.noChgData": "변경된 내용이 없습니다",
|
"stuff.detail.noChgData": "변경된 내용이 없습니다",
|
||||||
"stuff.detail.save.valierror1": "수직적설량은 0보다 큰 값을 입력하세요",
|
"stuff.detail.save.valierror1": "수직적설량은 0보다 큰 값을 입력하세요",
|
||||||
"stuff.detail.save.valierror2": "설치높이는 0보다 큰 값을 입력하세요",
|
"stuff.detail.save.valierror2": "설치높이는 0보다 큰 값을 입력하세요",
|
||||||
@ -707,9 +708,9 @@
|
|||||||
"stuff.planReqPopup.error.message1": "설계의뢰를 선택해주세요.",
|
"stuff.planReqPopup.error.message1": "설계의뢰를 선택해주세요.",
|
||||||
"stuff.planReqPopup.error.message2": "판매점을 선택해주세요.",
|
"stuff.planReqPopup.error.message2": "판매점을 선택해주세요.",
|
||||||
"stuff.search.title": "물건현황",
|
"stuff.search.title": "물건현황",
|
||||||
"stuff.search.btn1": "신규 물건 등록",
|
"stuff.search.btn.register": "신규 물건 등록",
|
||||||
"stuff.search.btn2": "조회",
|
"stuff.search.btn.search": "조회",
|
||||||
"stuff.search.btn3": "초기화",
|
"stuff.search.btn.reset": "초기화",
|
||||||
"stuff.search.schObjectNo": "물건번호",
|
"stuff.search.schObjectNo": "물건번호",
|
||||||
"stuff.search.schSaleStoreName": "판매대리점명",
|
"stuff.search.schSaleStoreName": "판매대리점명",
|
||||||
"stuff.search.schAddress": "물건주소",
|
"stuff.search.schAddress": "물건주소",
|
||||||
@ -833,6 +834,8 @@
|
|||||||
"estimate.detail.objectName": "안건명",
|
"estimate.detail.objectName": "안건명",
|
||||||
"estimate.detail.objectRemarks": "메모",
|
"estimate.detail.objectRemarks": "메모",
|
||||||
"estimate.detail.estimateType": "주문분류",
|
"estimate.detail.estimateType": "주문분류",
|
||||||
|
"estimate.detail.estimateType.yjss": "住宅PKG",
|
||||||
|
"estimate.detail.estimateType.yjod": "積上げ( YJOD )",
|
||||||
"estimate.detail.roofCns": "지붕재・사양시공",
|
"estimate.detail.roofCns": "지붕재・사양시공",
|
||||||
"estimate.detail.remarks": "비고",
|
"estimate.detail.remarks": "비고",
|
||||||
"estimate.detail.fileFlg": "후일자료제출",
|
"estimate.detail.fileFlg": "후일자료제출",
|
||||||
@ -849,11 +852,10 @@
|
|||||||
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
|
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(모듈수량 * 수량)÷100",
|
|
||||||
"estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG단가(W) * PKG용량(W)",
|
|
||||||
"estimate.detail.header.showPrice": "가격표시",
|
"estimate.detail.header.showPrice": "가격표시",
|
||||||
"estimate.detail.header.unitPrice": "정가",
|
"estimate.detail.header.unitPrice": "정가",
|
||||||
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
||||||
|
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.",
|
||||||
"estimate.detail.showPrice.description1": "제품 가격 OPEN",
|
"estimate.detail.showPrice.description1": "제품 가격 OPEN",
|
||||||
"estimate.detail.showPrice.description2": "추가, 변경 자재",
|
"estimate.detail.showPrice.description2": "추가, 변경 자재",
|
||||||
"estimate.detail.showPrice.description3": "첨부필수",
|
"estimate.detail.showPrice.description3": "첨부필수",
|
||||||
@ -878,17 +880,31 @@
|
|||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "판매점명",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "판매점명",
|
||||||
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "안건명",
|
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "안건명",
|
||||||
"estimate.detail.docPopup.schWeightFlg": "가대 중량표 포함",
|
"estimate.detail.docPopup.schWeightFlg": "가대 중량표 포함",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "포함",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "포함",
|
||||||
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "미포함",
|
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "미포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg": "도면/시뮬레이션 파일 포함",
|
"estimate.detail.docPopup.schDrawingFlg": "도면/시뮬레이션 파일 포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "포함",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "포함",
|
||||||
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg1": "미포함",
|
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "미포함",
|
||||||
"estimate.detail.docPopup.close": "닫기",
|
"estimate.detail.docPopup.close": "닫기",
|
||||||
"estimate.detail.docPopup.docDownload": "문서 다운로드",
|
"estimate.detail.docPopup.docDownload": "문서 다운로드",
|
||||||
|
"estimate.detail.estimateCopyPopup.title": "견적복사",
|
||||||
|
"estimate.detail.estimateCopyPopup.explane": "견적서를 복사할 판매점을 설정하십시오. 견적서는 정가로 복사됩니다.",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.saleStoreId": "1차 판매점명 / ID",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.otherSaleStoreId": "2차 판매점명 / ID",
|
||||||
|
"estimate.detail.estimateCopyPopup.label.receiveUser": "담당자",
|
||||||
|
"estimate.detail.estimateCopyPopup.close": "닫기",
|
||||||
|
"estimate.detail.estimateCopyPopup.copyBtn": "견적복사",
|
||||||
|
"estimate.detail.estimateCopyPopup.copy.alertMessage": "견적서가 복사되었습니다. 복사된 물건정보로 이동합니다.",
|
||||||
"estimate.detail.productFeaturesPopup.title": "제품특이사항",
|
"estimate.detail.productFeaturesPopup.title": "제품특이사항",
|
||||||
"estimate.detail.productFeaturesPopup.close": "닫기",
|
"estimate.detail.productFeaturesPopup.close": "닫기",
|
||||||
|
"estimate.detail.productFeaturesPopup.requiredStoreId": "1차 판매점은 필수값 입니다.",
|
||||||
|
"estimate.detail.productFeaturesPopup.requiredReceiveUser": "담당자는 필수값 입니다.",
|
||||||
"estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우, 도면 및 회로에 반영되지 않습니다.",
|
"estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우, 도면 및 회로에 반영되지 않습니다.",
|
||||||
"estimate.detail.save.requiredMsg": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.",
|
"estimate.detail.save.requiredFileUpload": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.",
|
||||||
|
"estimate.detail.save.requiredItem": "제품은 1개이상 등록해야 됩니다.",
|
||||||
|
"estimate.detail.save.requiredCharger": "담당자는 필수값 입니다.",
|
||||||
|
"estimate.detail.save.requiredObjectName": "안건명은 필수값 입니다.",
|
||||||
|
"estimate.detail.save.requiredEstimateDate": "견적일은 필수값 입니다.",
|
||||||
"estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?",
|
"estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?",
|
||||||
"simulator.title.sub1": "물건번호",
|
"simulator.title.sub1": "물건번호",
|
||||||
"simulator.title.sub2": "작성일",
|
"simulator.title.sub2": "작성일",
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { atom } from 'recoil'
|
import { atom } from 'recoil'
|
||||||
import { v1 } from 'uuid'
|
|
||||||
export const floorPlanObjectState = atom({
|
export const floorPlanObjectState = atom({
|
||||||
key: `floorPlanObjectState/${v1()}`,
|
key: 'floorPlanObjectState',
|
||||||
default: {
|
default: {
|
||||||
floorPlanObjectNo: '', //물건번호
|
floorPlanObjectNo: '', //물건번호
|
||||||
},
|
},
|
||||||
@ -9,7 +8,7 @@ export const floorPlanObjectState = atom({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const estimateState = atom({
|
export const estimateState = atom({
|
||||||
key: `estimateState`,
|
key: 'estimateState',
|
||||||
default: {},
|
default: {},
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -217,3 +217,11 @@ export const basicSettingState = atom({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 현재 선택된 물건 번호
|
||||||
|
*/
|
||||||
|
export const correntObjectNoState = atom({
|
||||||
|
key: 'correntObjectNoState',
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
|||||||
8
src/store/simulatorAtom.js
Normal file
8
src/store/simulatorAtom.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { atom } from 'recoil'
|
||||||
|
|
||||||
|
export const pwrGnrSimTypeState = atom({
|
||||||
|
key: 'pwrGnrSimType',
|
||||||
|
default: {
|
||||||
|
type: 'D',
|
||||||
|
},
|
||||||
|
})
|
||||||
@ -19,6 +19,8 @@ export const stuffSearchState = atom({
|
|||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSortType: 'R', //정렬조건 (R:최근등록일 U:최근수정일)
|
schSortType: 'R', //정렬조건 (R:최근등록일 U:최근수정일)
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
},
|
},
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1201,7 +1201,7 @@ export function removeDuplicatePolygons(polygons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const isSamePoint = (a, b) => {
|
export const isSamePoint = (a, b) => {
|
||||||
return Math.abs(Math.round(a.x) - Math.round(b.x)) <= 1 && Math.abs(Math.round(a.y) - Math.round(b.y)) <= 1
|
return Math.abs(Math.round(a.x) - Math.round(b.x)) <= 2 && Math.abs(Math.round(a.y) - Math.round(b.y)) <= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
20
yarn.lock
20
yarn.lock
@ -529,7 +529,7 @@
|
|||||||
|
|
||||||
"@kurkle/color@^0.3.0":
|
"@kurkle/color@^0.3.0":
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
|
resolved "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz"
|
||||||
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
|
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
|
||||||
|
|
||||||
"@mapbox/node-pre-gyp@^1.0.0":
|
"@mapbox/node-pre-gyp@^1.0.0":
|
||||||
@ -4344,7 +4344,7 @@ chalk@^2.4.2:
|
|||||||
|
|
||||||
chart.js@^4.4.6:
|
chart.js@^4.4.6:
|
||||||
version "4.4.6"
|
version "4.4.6"
|
||||||
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.6.tgz#da39b84ca752298270d4c0519675c7659936abec"
|
resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.4.6.tgz"
|
||||||
integrity sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==
|
integrity sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@kurkle/color" "^0.3.0"
|
"@kurkle/color" "^0.3.0"
|
||||||
@ -5846,7 +5846,7 @@ rbush@^3.0.1:
|
|||||||
|
|
||||||
react-chartjs-2@^5.2.0:
|
react-chartjs-2@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz#43c1e3549071c00a1a083ecbd26c1ad34d385f5d"
|
resolved "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz"
|
||||||
integrity sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==
|
integrity sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==
|
||||||
|
|
||||||
react-color-palette@^7.2.2:
|
react-color-palette@^7.2.2:
|
||||||
@ -5954,6 +5954,11 @@ react-select@^5.8.1:
|
|||||||
react-transition-group "^4.3.0"
|
react-transition-group "^4.3.0"
|
||||||
use-isomorphic-layout-effect "^1.1.2"
|
use-isomorphic-layout-effect "^1.1.2"
|
||||||
|
|
||||||
|
react-spinners@^0.14.1:
|
||||||
|
version "0.14.1"
|
||||||
|
resolved "https://registry.npmjs.org/react-spinners/-/react-spinners-0.14.1.tgz"
|
||||||
|
integrity sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag==
|
||||||
|
|
||||||
react-style-singleton@^2.2.1:
|
react-style-singleton@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz"
|
resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz"
|
||||||
@ -6280,14 +6285,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.2.0"
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
|
||||||
dependencies:
|
|
||||||
ansi-regex "^5.0.1"
|
|
||||||
|
|
||||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user