diff --git a/src/components/common/select/QSelectBox.jsx b/src/components/common/select/QSelectBox.jsx
index 12c72b5e..f1041da3 100644
--- a/src/components/common/select/QSelectBox.jsx
+++ b/src/components/common/select/QSelectBox.jsx
@@ -1,6 +1,7 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { useOnClickOutside } from 'usehooks-ts'
+import { useMessage } from '@/hooks/useMessage'
/**
*
@@ -26,13 +27,15 @@ export default function QSelectBox({
showKey = '',
params = {},
}) {
+ const { getMessage } = useMessage()
+
/**
* 초기 상태 처리
* useState 초기 값으로 사용해야 해서 useState 보다 위에 작성
* @returns {string} 초기 상태
*/
const handleInitState = () => {
- if (options.length === 0) return title !== '' ? title : '선택하세요.'
+ if (options.length === 0) return title !== '' ? title : getMessage('selectbox.title')
if (showKey !== '' && !value) {
//value가 없으면 showKey가 있으면 우선 보여준다
// return options[0][showKey]
@@ -44,13 +47,13 @@ export default function QSelectBox({
return option[sourceKey] === value[targetKey]
})
if (!option) {
- return title !== '' ? title : '선택하세요.'
+ return title !== '' ? title : getMessage('selectbox.title')
} else {
return option[showKey]
}
} else {
//일치하는 조건이 없으면 기본값을 보여준다.
- return title !== '' ? title : '선택하세요.'
+ return title !== '' ? title : getMessage('selectbox.title')
}
}
diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx
index a97cb4cb..609ba73e 100644
--- a/src/components/estimate/Estimate.jsx
+++ b/src/components/estimate/Estimate.jsx
@@ -19,10 +19,11 @@ import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from
import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid'
import { correntObjectNoState } from '@/store/settingAtom'
-import { useRouter, useSearchParams } from 'next/navigation'
-import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
+import { useSearchParams } from 'next/navigation'
import { usePlan } from '@/hooks/usePlan'
import { usePopup } from '@/hooks/usePopup'
+import { useSwal } from '@/hooks/useSwal'
+import { QcastContext } from '@/app/QcastProvider'
export default function Estimate({}) {
const [uniqueData, setUniqueData] = useState([])
@@ -33,6 +34,8 @@ export default function Estimate({}) {
const [objectNo, setObjectNo] = useState('') //물건번호
const [planNo, setPlanNo] = useState('') //플랜번호
+ const { swalFire } = useSwal()
+
const [files, setFiles] = useState([]) // 보내는 첨부파일
const [originFiles, setOriginFiles] = useState([]) //기존 첨부파일
@@ -79,6 +82,7 @@ export default function Estimate({}) {
const [specialNoteList, setSpecialNoteList] = useState([])
const [popShowSpecialNoteList, setPopShowSpecialNoteList] = useState([])
+ const { setIsGlobalLoading } = useContext(QcastContext)
const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get, post, promisePost } = useAxios(globalLocaleState)
@@ -347,7 +351,11 @@ export default function Estimate({}) {
setEstimateContextState({
originFiles: originFiles,
})
- alert(getMessage('estimate.detail.alert.delFile'))
+
+ swalFire({
+ text: getMessage('estimate.detail.alert.delFile'),
+ type: 'alert',
+ })
}
//가격표시 option 목록 최초세팅 && 주문분류 변경시
@@ -476,10 +484,15 @@ export default function Estimate({}) {
if (!pass) {
//Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.
- return alert(getMessage('estimate.detail.showPrice.pricingBtn.noItemId'))
+ return swalFire({
+ text: getMessage('estimate.detail.showPrice.pricingBtn.noItemId'),
+ type: 'alert',
+ icon: 'warning',
+ })
}
}
+ setIsGlobalLoading(true)
await promisePost({ url: '/api/estimate/price/item-price-list', data: param }).then((res) => {
let updateList = []
if (res) {
@@ -527,6 +540,7 @@ export default function Estimate({}) {
}
}
}
+ setIsGlobalLoading(false)
})
}
@@ -787,7 +801,11 @@ export default function Estimate({}) {
const removeItem = () => {
const array = [...selection]
if (isEmptyArray(array)) {
- return alert(getMessage('estimate.detail.alert.selectDelItem'))
+ return swalFire({
+ text: getMessage('estimate.detail.alert.selectDelItem'),
+ type: 'alert',
+ icon: 'warning',
+ })
}
let delList = []
estimateContextState.itemList.filter((row) => {
@@ -817,7 +835,11 @@ export default function Estimate({}) {
})
if (delCnt === updateList.length) {
- return alert(getMessage('estimate.detail.save.requiredItem'))
+ return swalFire({
+ text: getMessage('estimate.detail.save.requiredItem'),
+ type: 'alert',
+ icon: 'warning',
+ })
}
setEstimateContextState({
@@ -1188,7 +1210,7 @@ export default function Estimate({}) {
@@ -1206,7 +1228,7 @@ export default function Estimate({}) {
@@ -1297,13 +1319,13 @@ export default function Estimate({}) {
//사양시공
let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('、')
return (
-
+
@@ -1316,7 +1338,6 @@ export default function Estimate({}) {
{getMessage('estimate.detail.remarks')} |
- {/* */}
+ {estimateContextState?.northArrangement === '1' && (
+ {getMessage('estimate.detail.dragFileGuide')}
+ )}
diff --git a/src/components/estimate/popup/DocDownOptionPop.jsx b/src/components/estimate/popup/DocDownOptionPop.jsx
index 50dfd018..13477b63 100644
--- a/src/components/estimate/popup/DocDownOptionPop.jsx
+++ b/src/components/estimate/popup/DocDownOptionPop.jsx
@@ -4,20 +4,21 @@ import { useMessage } from '@/hooks/useMessage'
import { useAxios } from '@/hooks/useAxios'
import { useRecoilValue } from 'recoil'
import { floorPlanObjectState, estimateState } from '@/store/floorPlanObjectAtom'
-import { usePathname } from 'next/navigation'
+import { usePathname, useSearchParams } from 'next/navigation'
export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDownPopLockFlg }) {
const { getMessage } = useMessage()
const { promisePost } = useAxios()
const pathName = usePathname()
+ const searchParams = useSearchParams()
//EXCEL, PDF 구분
const [schDownload, setSchDownload] = useState('EXCEL')
//다운로드 파일 EXCEL
const [schUnitPriceFlg, setSchUnitPriceFlg] = useState('0')
//견적제출서 표시명
- const [schDisplayFlg, setSchSchDisplayFlg] = useState('0')
+ const [schDisplayFlg, setSchDisplayFlg] = useState('0')
//가대 중량표 포함(포함:1 미포함 : 0)
const [schWeightFlg, setSchWeightFlg] = useState('1')
//도면/시뮬레이션 파일 포함
@@ -53,8 +54,9 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDown
defaultSchDrawingFlg = defaultSchDrawingFlg.concat('|', '2', '|', '3')
}
+ //objectRecoil.floorPlanObjectNo가 비워지는 경우가 있어서 없으면 url에서 뺴오도록 추가
const params = {
- objectNo: objectRecoil.floorPlanObjectNo,
+ objectNo: objectRecoil?.floorPlanObjectNo ? objectRecoil.floorPlanObjectNo : searchParams.get('objectNo'),
planNo: planNo,
schDownload: schDownload,
schUnitPriceFlg: sendUnitPriceFlg,
@@ -206,7 +208,7 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDown
value={'0'}
checked={schDisplayFlg === '0'}
onChange={(e) => {
- setSchSchDisplayFlg(e.target.value)
+ setSchDisplayFlg(e.target.value)
}}
/>
@@ -219,7 +221,7 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDown
value={'1'}
checked={schDisplayFlg === '1'}
onChange={(e) => {
- setSchSchDisplayFlg(e.target.value)
+ setSchDisplayFlg(e.target.value)
}}
/>
diff --git a/src/components/estimate/popup/EstimateCopyPop.jsx b/src/components/estimate/popup/EstimateCopyPop.jsx
index 001de6e9..35d8d54b 100644
--- a/src/components/estimate/popup/EstimateCopyPop.jsx
+++ b/src/components/estimate/popup/EstimateCopyPop.jsx
@@ -69,7 +69,7 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) {
get({ url: url }).then((res) => {
if (!isEmptyArray(res)) {
res.map((row) => {
- row.value == row.saleStoreId
+ row.value = row.saleStoreId
row.label = row.saleStoreName
})
otherList = res
diff --git a/src/components/estimate/popup/ProductFeaturesPop.jsx b/src/components/estimate/popup/ProductFeaturesPop.jsx
index f2d98800..b6b02c64 100644
--- a/src/components/estimate/popup/ProductFeaturesPop.jsx
+++ b/src/components/estimate/popup/ProductFeaturesPop.jsx
@@ -7,16 +7,16 @@ export default function ProductFeaturesPop({ popShowSpecialNoteList, showProduct
useEffect(() => {
let pushData = []
- popShowSpecialNoteList.map((row) => {
+ popShowSpecialNoteList.forEach((row) => {
let option = showProductFeatureData.split('、')
- option.map((row2) => {
+ option.forEach((row2) => {
if (row.code === row2) {
pushData.push(row)
}
})
})
setShowSpecialNoteList(pushData)
- }, [popShowSpecialNoteList])
+ }, [popShowSpecialNoteList, showProductFeatureData])
return (
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 26563ad3..22ef408b 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -249,6 +249,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
},
addLengthText() {
+ if ([POLYGON_TYPE.MODULE, 'arrow', POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.OBJECT_SURFACE].includes(this.name)) {
+ return
+ }
this.canvas
?.getObjects()
.filter((obj) => obj.name === 'lengthText' && obj.parentId === this.id)
diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
index 31698b1a..f5ecb10d 100644
--- a/src/components/floor-plan/CanvasFrame.jsx
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -16,7 +16,16 @@ import { totalDisplaySelector } from '@/store/settingAtom'
import { MENU } from '@/common/common'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
import { QcastContext } from '@/app/QcastProvider'
-import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
+import {
+ makersState,
+ modelsState,
+ moduleStatisticsState,
+ pcsCheckState,
+ selectedMakerState,
+ selectedModelsState,
+ seriesState,
+} from '@/store/circuitTrestleAtom'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
export default function CanvasFrame() {
const canvasRef = useRef(null)
@@ -25,33 +34,59 @@ export default function CanvasFrame() {
const currentMenu = useRecoilValue(currentMenuState)
const { floorPlanState } = useContext(FloorPlanContext)
const { contextMenu, handleClick } = useContextMenu()
- const { currentCanvasPlan } = usePlan()
+ const { plans, currentCanvasPlan, resetCanvasStatus } = usePlan()
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
const { setIsGlobalLoading } = useContext(QcastContext)
- const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
- const reset = useResetRecoilState(moduleStatisticsState)
+ const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
+ const resetMakersState = useResetRecoilState(makersState)
+ const resetSelectedMakerState = useResetRecoilState(selectedMakerState)
+ const resetSeriesState = useResetRecoilState(seriesState)
+ const resetModelsState = useResetRecoilState(modelsState)
+ const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
+ const resetPcsCheckState = useResetRecoilState(pcsCheckState)
+ const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
+
const loadCanvas = () => {
- if (canvas) {
- canvas?.clear() // 캔버스를 초기화합니다.
- if (currentCanvasPlan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
- canvas?.loadFromJSON(JSON.parse(currentCanvasPlan.canvasStatus), function () {
+ if (!canvas) return
+
+ canvas?.clear() // 캔버스를 초기화합니다.
+ if (currentCanvasPlan) {
+ const plan = plans.find((plan) => plan.id === currentCanvasPlan.id)
+ if (plan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
+ canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
canvas?.renderAll() // 캔버스를 다시 그립니다.
})
}
- gridInit()
}
+ gridInit()
}
useEffect(() => {
loadCanvas()
- reset()
+ resetRecoilData()
+ Object.keys(currentCanvasPlan).length > 0 && handleModuleSelectionTotal()
}, [currentCanvasPlan, canvas])
useEffect(() => {
setIsGlobalLoading(false)
+
+ return () => {
+ canvas?.clear()
+ resetCanvasStatus()
+ }
}, [])
+ const resetRecoilData = () => {
+ resetModuleStatisticsState()
+ resetMakersState()
+ resetSelectedMakerState()
+ resetSeriesState()
+ resetModelsState()
+ resetSelectedModelsState()
+ resetPcsCheckState()
+ }
+
return (
diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx
index bc1a4007..6a7d5ef0 100644
--- a/src/components/floor-plan/CanvasLayout.jsx
+++ b/src/components/floor-plan/CanvasLayout.jsx
@@ -1,6 +1,7 @@
'use client'
import { useContext, useEffect } from 'react'
+import { usePathname } from 'next/navigation'
import { useRecoilValue } from 'recoil'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
import { SessionContext } from '@/app/SessionProvider'
@@ -12,6 +13,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
export default function CanvasLayout({ children }) {
// const { menuNumber } = props
+ const pathname = usePathname()
const { menuNumber } = useCanvasMenu()
const { session } = useContext(SessionContext)
const { floorPlanState } = useContext(FloorPlanContext)
@@ -37,10 +39,12 @@ export default function CanvasLayout({ children }) {
onClick={() => handleCurrentPlan(plan.id)}
>
{`Plan ${plan.planNo}`}
- {index !== 0 && (
+ {index !== 0 && !pathname.includes('/estimate') && !pathname.includes('/simulator') && (
+ onClick={(e) => {
+ //삭제 아이콘 눌렀는데 handleCurrentPlan실행되서 추가
+ e.stopPropagation()
swalFire({
text: `Plan ${plan.planNo} ` + getMessage('plan.message.confirm.delete'),
type: 'confirm',
@@ -48,13 +52,13 @@ export default function CanvasLayout({ children }) {
handleDeletePlan(e, plan)
},
})
- }
+ }}
>
)}
))}
- {plans.length < 10 && (
+ {plans.length < 10 && !pathname.includes('/estimate') && !pathname.includes('/simulator') && (
{/* 설정 오류시 노출 */}
- ※ 施工方法が選択できません。 基準風速または基準積雪量を確認してください。
>
diff --git a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx
index 706fad9f..75c8dcd9 100644
--- a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx
+++ b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx
@@ -120,7 +120,7 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
value={selectedTrestle}
sourceKey={'trestleMkrCd'}
targetKey={'trestleMkrCd'}
- showKey={'trestleMkrCdNm'}
+ showKey={'trestleMkrCdJp'}
onChange={handleChangeTrestle}
/>
)}
@@ -138,7 +138,7 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
value={selectedConstMthd}
sourceKey={'constMthdCd'}
targetKey={'constMthdCd'}
- showKey={'constMthdCdNm'}
+ showKey={'constMthdCdJp'}
onChange={handleChangeConstMthd}
/>
)}
@@ -156,7 +156,7 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
value={selectedRoofBase}
sourceKey={'roofBaseCd'}
targetKey={'roofBaseCd'}
- showKey={'roofBaseCdNm'}
+ showKey={'roofBaseCdJp'}
onChange={handleChangeRoofBase}
/>
)}
@@ -203,7 +203,7 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
強化施工
-
+
{
}, [compasDeg])
const checkDegree = (e) => {
- if (numberCheck(Number(e)) && Number(e) >= -180 && Number(e) <= 180) {
- setCompasDeg(Number(e))
+ if (e === '-0' || e === '-') {
+ setCompasDeg('-')
+ return
+ }
+ if (e === '0-') {
+ setCompasDeg('-0')
+ return
+ }
+ if (Number(e) >= -180 && Number(e) <= 180) {
+ if (numberCheck(Number(e))) {
+ setCompasDeg(Number(e))
+ }
} else {
setCompasDeg(compasDeg)
}
@@ -46,8 +56,14 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
{Array.from({ length: 180 / 15 }).map((dot, index) => (
setCompasDeg(15 * (12 + index))}
+ className={`circle ${getDegreeInOrientation(compasDeg) === -1 * (-15 * index + 180) || (index === 0 && compasDeg >= 172 && index === 0 && compasDeg <= 180) || (compasDeg === -180 && index === 0) ? 'act' : ''}`}
+ onClick={() => {
+ if (index === 0) {
+ setCompasDeg(180)
+ return
+ }
+ setCompasDeg(-1 * (-15 * index + 180))
+ }}
>
{index === 0 && 180°}
{index === 6 && -90°}
@@ -56,7 +72,7 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
{Array.from({ length: 180 / 15 }).map((dot, index) => (
setCompasDeg(15 * index)}
>
{index === 0 && 0°}
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx
index eff568cd..4eeeab0a 100644
--- a/src/components/floor-plan/modal/basic/step/Placement.jsx
+++ b/src/components/floor-plan/modal/basic/step/Placement.jsx
@@ -2,25 +2,24 @@ import { forwardRef, useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { checkedModuleState, currentCanvasPlanState } from '@/store/canvasAtom'
-import { useRecoilValue, useSetRecoilState } from 'recoil'
-import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
-import { useModulePlace } from '@/hooks/module/useModulePlace'
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
+import { isObjectNotEmpty } from '@/util/common-utils'
const Placement = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [isChidori, setIsChidori] = useState(false)
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
- const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
- const [setupLocation, setSetupLocation] = useState('center')
+ const [setupLocation, setSetupLocation] = useState('eaves')
const [isMaxSetup, setIsMaxSetup] = useState('false')
const [selectedItems, setSelectedItems] = useState({})
- const { makeModuleInstArea } = useModuleBasicSetting()
- const { selectedModules } = useModulePlace()
+ const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState)
const setCheckedModules = useSetRecoilState(checkedModuleState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
+ const { makeModuleInitArea } = useModuleBasicSetting(3)
//모듈 배치면 생성
useEffect(() => {
@@ -30,17 +29,39 @@ const Placement = forwardRef((props, refs) => {
if (isChidroriValue) {
setIsChidoriNotAble(true)
}
+ makeModuleInitArea(moduleSelectionData)
}
}, [])
+ //최초 지입시 체크
+ useEffect(() => {
+ if (isObjectNotEmpty(moduleSelectionData)) {
+ //두번째 선택한 데이터가를 기반으로 세번째 선택을 체크한다
+ if (moduleSelectionData.roofConstructions.length > 0 && moduleSelectionData.module.itemList.length > 0) {
+ let initCheckedModule = {}
+ moduleSelectionData.module.itemList.forEach((obj, index) => {
+ if (index === 0) {
+ initCheckedModule = { [obj.itemId]: true }
+ } else {
+ initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
+ }
+ })
+ setSelectedItems(initCheckedModule)
+ setSelectedModules(moduleSelectionData.module)
+ }
+ }
+ }, [moduleSelectionData])
+
//체크된 모듈 데이터
useEffect(() => {
- const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
- const moduleArray = selectedModules.itemList.filter((item) => {
- return checkedModuleIds.includes(item.itemId)
- })
- setCheckedModules(moduleArray)
- }, [selectedItems])
+ if (isObjectNotEmpty(selectedItems) && isObjectNotEmpty(selectedModules)) {
+ const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
+ const moduleArray = selectedModules.itemList.filter((item) => {
+ return checkedModuleIds.includes(item.itemId)
+ })
+ setCheckedModules(moduleArray)
+ }
+ }, [selectedItems, selectedModules])
const moduleData = {
header: [
@@ -77,20 +98,6 @@ const Placement = forwardRef((props, refs) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
}
- useEffect(() => {
- if (moduleSelectionData && moduleSelectionData.module.itemList.length > 0) {
- let initCheckedModule = {}
- moduleSelectionData.module.itemList.forEach((obj, index) => {
- if (index === 0) {
- initCheckedModule = { [obj.itemId]: true }
- } else {
- initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
- }
- })
- setSelectedItems(initCheckedModule)
- }
- }, [])
-
return (
<>
@@ -117,29 +124,27 @@ const Placement = forwardRef((props, refs) => {
{selectedModules.itemList &&
selectedModules.itemList.map((item, index) => (
- <>
-
- |
-
-
-
-
- |
-
-
-
- {item.itemNm}
-
- |
- {item.wpOut} |
-
- >
+
+ |
+
+
+
+
+ |
+
+
+
+ {item.itemNm}
+
+ |
+ {item.wpOut} |
+
))}
@@ -215,10 +220,10 @@ const Placement = forwardRef((props, refs) => {
-
+ {/*
-
+ */}
diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx
index 255833a8..39d0ee19 100644
--- a/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx
+++ b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx
@@ -1,12 +1,22 @@
+import { useState, useEffect } from 'react'
+import { useRecoilState } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import QSelectBox from '@/components/common/select/QSelectBox'
+import { useMasterController } from '@/hooks/common/useMasterController'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
+import { isObjectNotEmpty } from '@/util/common-utils'
export default function PitchModule({}) {
const { getMessage } = useMessage()
- const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }]
+ const { getModuleTypeItemList } = useMasterController()
+ const [moduleList, setModuleList] = useState([])
+ const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
+ const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
+
const moduleData = {
header: [
- { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
+ { name: getMessage('module'), width: 250, prop: 'module', type: 'color-box' },
{
name: `${getMessage('높이')} (mm)`,
prop: 'height',
@@ -14,24 +24,45 @@ export default function PitchModule({}) {
{ name: `${getMessage('width')} (mm)`, prop: 'width' },
{ name: `${getMessage('output')} (W)`, prop: 'output' },
],
- rows: [
- {
- module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
- height: { name: '1134' },
- width: { name: '1722' },
- output: { name: '440' },
- },
- {
- module: {
- name: 'Re.RISE MS-G3 290',
- color: '#67A2AA',
- },
- height: { name: '1134' },
- width: { name: '1722' },
- output: { name: '240' },
- },
- ],
}
+
+ const getModuleData = async (roofsIds) => {
+ const list = await getModuleTypeItemList(roofsIds)
+ if (list.data.length > 0) {
+ //selectbox에 이름을 넣는다
+ list.data.forEach((item) => {
+ item.name = item.itemNm
+ })
+ //셀렉트박스 데이터 초기화
+ setModuleList(list.data)
+ }
+ }
+
+ useEffect(() => {
+ getModuleData(['FLAT_ROOF'])
+ }, [])
+
+ const handleChangeModule = (option) => {
+ //선택된 모듈
+ setSelectedModules(option) //선택값 저장
+ setModuleSelectionData({
+ ...moduleSelectionData,
+ flatModule: option,
+ })
+ moduleSelectedDataTrigger({
+ ...moduleSelectionData,
+ flatModule: option,
+ })
+ }
+
+ useEffect(() => {
+ if (isObjectNotEmpty(moduleSelectionData.flatModule) && moduleList.length > 0) {
+ handleChangeModule(moduleSelectionData.flatModule)
+ }
+ }, [moduleList])
+
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+
return (
<>
@@ -39,7 +70,17 @@ export default function PitchModule({}) {
{getMessage('modal.module.basic.setting.module.setting')}
-
+ {moduleList && (
+
+ )}
@@ -54,33 +95,21 @@ export default function PitchModule({}) {
- {moduleData.rows.map((row) => (
- <>
-
- {moduleData.header.map((header) => (
- <>
- {header.type === 'color-box' && (
- |
-
-
- {row[header.prop].name}
-
- |
- )}
- {!header.type && header.type !== 'color-box' && {row[header.prop].name} | }
- >
- ))}
+ {selectedModules &&
+ selectedModules.itemList &&
+ selectedModules.itemList.map((row, index) => (
+
+ |
+
+
+ {row.itemNm}
+
+ |
+ {Number(row.shortAxis).toFixed(0)} |
+ {Number(row.longAxis).toFixed(0)} |
+ {Number(row.wpOut).toFixed(0)} |
- >
- ))}
- {Array.from({ length: 3 - moduleData.rows.length }).map((_, i) => (
-
- |
- |
- |
- |
-
- ))}
+ ))}
diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx
index a292ed2d..660d3717 100644
--- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx
+++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx
@@ -1,49 +1,48 @@
import { forwardRef, useState, useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
-import { canvasState } from '@/store/canvasAtom'
-import { useRecoilValue } from 'recoil'
+import { canvasState, checkedModuleState } from '@/store/canvasAtom'
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { POLYGON_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent'
+import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
const PitchPlacement = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [setupLocation, setSetupLocation] = useState('south')
- const { makeModuleInstArea } = useModuleBasicSetting()
const canvas = useRecoilValue(canvasState)
const { initEvent } = useEvent()
- useEffect(() => {
- makeModuleInstArea()
- }, [])
+ const { selectedModules } = useModuleBasicSetting(3)
+ const setCheckedModules = useSetRecoilState(checkedModuleState)
+ const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
+ const [selectedItems, setSelectedItems] = useState({})
useEffect(() => {
handleChangeSetupLocation()
}, [setupLocation])
+ const handleSelectedItem = (e) => {
+ setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
+ }
+
const moduleData = {
header: [
{ type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
],
- rows: [
- {
- check: false,
- module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
- output: { name: '440' },
- },
- {
- check: false,
- module: {
- name: 'Re.RISE MS-G3 290',
- color: '#67A2AA',
- },
- output: { name: '240' },
- },
- ],
}
+ //체크된 모듈 데이터
+ useEffect(() => {
+ const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
+ const moduleArray = selectedModules.itemList.filter((item) => {
+ return checkedModuleIds.includes(item.itemId)
+ })
+ setCheckedModules(moduleArray)
+ }, [selectedItems])
+
const handleSetupLocation = (e) => {
initEvent()
refs.setupLocation.current = e.target
@@ -81,6 +80,20 @@ const PitchPlacement = forwardRef((props, refs) => {
}
}
+ useEffect(() => {
+ if (moduleSelectionData && moduleSelectionData.flatModule.itemList.length > 0) {
+ let initCheckedModule = {}
+ moduleSelectionData.flatModule.itemList.forEach((obj, index) => {
+ if (index === 0) {
+ initCheckedModule = { [obj.itemId]: true }
+ } else {
+ initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
+ }
+ })
+ setSelectedItems(initCheckedModule)
+ }
+ }, [])
+
return (
<>
@@ -150,8 +160,7 @@ const PitchPlacement = forwardRef((props, refs) => {
name="radio01"
id="ra01"
value={'south'}
- checked={setupLocation === 'south'}
- defaultChecked
+ defaultChecked={setupLocation === 'south'}
onClick={handleSetupLocation}
/>
@@ -162,7 +171,7 @@ const PitchPlacement = forwardRef((props, refs) => {
name="radio01"
id="ra02"
value={'excreta'}
- checked={setupLocation === 'excreta'}
+ defaultChecked={setupLocation === 'excreta'}
onClick={handleSetupLocation}
/>
diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
index 3783e033..1e989963 100644
--- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
@@ -1,7 +1,6 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState, useEffect, useContext } from 'react'
import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect'
-import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation'
import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
@@ -20,7 +19,11 @@ import { useTrestle } from '@/hooks/module/useTrestle'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { v4 as uuidv4 } from 'uuid'
-import { stepUpListDataState } from '@/store/circuitTrestleAtom'
+import { useEstimate } from '@/hooks/useEstimate'
+import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
+import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
+import { usePlan } from '@/hooks/usePlan'
const ALLOCATION_TYPE = {
AUTO: 'auto',
@@ -29,52 +32,73 @@ const ALLOCATION_TYPE = {
export default function CircuitTrestleSetting({ id }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
- const { apply } = useTrestle()
+ const { apply, setViewCircuitNumberTexts } = useTrestle()
const { swalFire } = useSwal()
+ const { saveEstimate } = useEstimate()
const canvas = useRecoilValue(canvasState)
- const [makers, setMakers] = useRecoilState(makersState)
- const [selectedMaker, setSelectedMaker] = useRecoilState(selectedMakerState)
- const [series, setSeries] = useRecoilState(seriesState)
- const [models, setModels] = useRecoilState(modelsState)
- const [selectedModels, setSelectedModels] = useRecoilState(selectedModelsState)
- const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
-
const [tabNum, setTabNum] = useState(1)
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
const [circuitAllocationType, setCircuitAllocationType] = useState(1)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState)
- const { getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()
+ const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList } = useMasterController()
// 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가
const [selectedStepUpValues, setSelectedStepUpValues] = useState({})
const [getStepUpSelections, setGetStepUpSelections] = useState(null)
+ // const { trigger: setCircuitData } = useCanvasPopupStatusController(4)
+ // const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState)
+ const [stepUpListData, setStepUpListData] = useState([])
+ const [seletedOption, setSeletedOption] = useState(null)
+ const { setModuleStatisticsData } = useCircuitTrestle()
- const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState)
+ const { handleCanvasToPng } = useImgLoader()
+ const { saveCanvas } = usePlan()
+ const {
+ makers,
+ setMakers,
+ selectedMaker,
+ setSelectedMaker,
+ series,
+ setSeries,
+ models,
+ setModels,
+ selectedModels,
+ setSelectedModels,
+ pcsCheck,
+ setPcsCheck,
+ getOptYn,
+ getPcsItemList,
+ getSelectedPcsItemList,
+ getUseModuleItemList,
+ getRoofSurfaceList,
+ getModuleList,
+ removeNotAllocationModules,
+ } = useCircuitTrestle()
+ // const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
useEffect(() => {
if (!managementState) {
setManagementState(managementStateLoaded)
}
+ // setCircuitData({
+ // makers,
+ // selectedMaker,
+ // series,
+ // models,
+ // selectedModels,
+ // pcsCheck,
+ // })
}, [])
- useEffect(() => {
- if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) {
- const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
- canvas.remove(...notAllocationModules)
- canvas.renderAll()
- }
- }, [tabNum])
-
- useEffect(() => {
- console.log('stepUpListData >>> ', stepUpListData)
- }, [stepUpListData])
+ // 수동할당 시 모듈 삭제
+ // 시리즈중 자동으로 추천 PCS 정보 조회
const onAutoRecommend = () => {
if (series.filter((s) => s.selected).length === 0) {
swalFire({
- title: '시리즈를 선택해 주세요.',
+ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02'),
type: 'alert',
})
return
@@ -87,27 +111,45 @@ export default function CircuitTrestleSetting({ id }) {
pcsItemList: getPcsItemList(),
}
+ // 파워컨디셔너 추천 목록 조회
if (selectedModels.length === 0) {
+ // 시리즈중 자동으로 추천 PCS 정보 조회
getPcsAutoRecommendList(params).then((res) => {
if (res.data?.pcsItemList) {
- const itemList = models.filter((model) => {
- return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
+ let pcsItemList = []
+ let pcsObj = {}
+
+ models.forEach((model) => {
+ pcsObj[model.itemId] = model
})
- const selectedModels = itemList.map((model) => {
- return {
- ...model,
- id: uuidv4(),
+ res.data?.pcsItemList.forEach((item) => {
+ if (pcsObj[item.itemId]) {
+ pcsItemList.push({
+ ...pcsObj[item.itemId],
+ isUsed: false,
+ id: uuidv4(),
+ })
}
})
+ // 회로 구성 가능 여부 체크 요청 파라미터
const pcsVoltageChkParams = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(),
- pcsItemList: getPcsItemList(),
+ pcsItemList: pcsItemList,
}
- setSelectedModels(selectedModels)
+ // 추천 목록 선택
+ setSelectedModels(pcsItemList)
+ // 회로 구성 가능 여부 체크
getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
- setTabNum(2)
+ if (res.resultCode === 'S') {
+ setTabNum(2)
+ } else {
+ swalFire({
+ title: res.resultMsg,
+ type: 'alert',
+ })
+ }
})
} else {
// 데이터가 없는 경우 오류 메시지 확인 필요
@@ -125,144 +167,37 @@ export default function CircuitTrestleSetting({ id }) {
}
})
} else {
- getPcsVoltageChk(params).then((res) => {
- setTabNum(2)
- })
- }
- }
-
- const getOptYn = () => {
- return {
- maxConnYn: pcsCheck.max ? 'Y' : 'N',
- smpCirYn: pcsCheck.division ? 'Y' : 'N',
- coldZoneYn: managementState?.coldRegionFlg === '1' ? 'Y' : 'N',
- }
- }
-
- const getPcsItemList = () => {
- return models.map((model) => {
- return {
- itemId: model.itemId,
- pcsMkrCd: model.pcsMkrCd,
- pcsSerCd: model.pcsSerCd,
- }
- })
- }
-
- const getUseModuleItemList = () => {
- return selectedModules.itemList.map((m) => {
- return {
- itemId: m.itemId,
- mixMatlNo: m.mixMatlNo,
- }
- })
- }
-
- const getRoofSurfaceList = () => {
- return canvas
- .getObjects()
- .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
- .map((obj) => {
- return {
- roofSurfaceId: obj.id,
- roofSurface: canvas
- .getObjects()
- .filter((o) => o.id === obj.parentId)[0]
- .directionText.replace(/[0-9]/g, ''),
- roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
- moduleList: getModuleList(obj).map((module) => {
- return {
- itemId: module.moduleInfo.itemId,
- circuit: module.circuitNumber ? module.circuitNumber : null,
- pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
- uniqueId: module.id ? module.id : null,
- }
- }),
+ // 회로 구성 가능 여부 체크
+ getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
+ if (res.resultCode === 'S') {
+ // 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
+ getPcsVoltageStepUpList({
+ ...params,
+ pcsItemList: getSelectedPcsItemList(),
+ }).then((res) => {
+ setTabNum(2)
+ })
+ } else {
+ swalFire({
+ title: res.resultMsg,
+ type: 'alert',
+ })
}
})
- }
-
- const getModuleList = (surface) => {
- let moduleList = []
- let [xObj, yObj] = [{}, {}]
- let [xPoints, yPoints] = [[], []]
- surface.modules.forEach((module) => {
- if (!xObj[module.left]) {
- xObj[module.left] = module.left
- xPoints.push(module.left)
- }
- if (!yObj[module.top]) {
- yObj[module.top] = module.top
- yPoints.push(module.top)
- }
- })
- switch (surface.direction) {
- case 'south':
- xPoints.sort((a, b) => a - b)
- yPoints.sort((a, b) => b - a)
- yPoints.forEach((y, index) => {
- let temp = surface.modules.filter((m) => m.top === y)
- if (index % 2 === 0) {
- temp.sort((a, b) => a.left - b.left)
- } else {
- temp.sort((a, b) => b.left - a.left)
- }
- moduleList = [...moduleList, ...temp]
- })
- break
- case 'north':
- xPoints.sort((a, b) => b - a)
- yPoints.sort((a, b) => a - b)
- yPoints.forEach((y, index) => {
- let temp = surface.modules.filter((m) => m.top === y)
- if (index % 2 === 0) {
- temp.sort((a, b) => b.left - a.left)
- } else {
- temp.sort((a, b) => a.left - b.left)
- }
- moduleList = [...moduleList, ...temp]
- })
- break
- case 'west':
- xPoints.sort((a, b) => a - b)
- yPoints.sort((a, b) => a - b)
- xPoints.forEach((x, index) => {
- let temp = surface.modules.filter((m) => m.left === x)
- if (index % 2 === 0) {
- temp.sort((a, b) => a.top - b.top)
- } else {
- temp.sort((a, b) => b.top - a.top)
- }
- moduleList = [...moduleList, ...temp]
- })
- break
- case 'east':
- xPoints.sort((a, b) => b - a)
- yPoints.sort((a, b) => b - a)
- xPoints.forEach((x, index) => {
- let temp = surface.modules.filter((m) => m.left === x)
- if (index % 2 === 0) {
- temp.sort((a, b) => b.top - a.top)
- } else {
- temp.sort((a, b) => a.top - b.top)
- }
- moduleList = [...moduleList, ...temp]
- })
- break
- default:
- return []
}
- return moduleList
}
+ // 자동할당 버튼 클릭 시
const onAutoAllocation = () => {
let moduleStdQty = 0
let moduleMaxQty = 0
const selectedModels = models.filter((m) => m.selected)
+ // 시리즈중 자동으로 추천 PCS 정보 조회
if (selectedModels.length === 0) {
onAutoRecommend()
} else {
+ // 모듈 최소 매수
moduleStdQty = selectedModels.reduce((acc, model) => {
return acc + parseInt(model.moduleStdQty)
}, 0)
@@ -285,42 +220,71 @@ export default function CircuitTrestleSetting({ id }) {
// setTabNum(2)
}
+ // 수동할당 버튼 클릭 시
const onPassivityAllocation = () => {
if (selectedModels.length === 0) {
const params = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
- roofSurfaceList: getRoofSurfaceList(),
+ roofSurfaceList: getRoofSurfaceList().map((surface) => {
+ return {
+ ...surface,
+ moduleList: surface.moduleList.map((module) => {
+ return {
+ itemId: module.itemId,
+ uniqueId: module.uniqueId,
+ }
+ }),
+ }
+ }),
pcsItemList: getPcsItemList(),
}
+ // 파워컨디셔너 추천 목록 조회
getPcsAutoRecommendList(params).then((res) => {
if (res.data?.pcsItemList) {
- const itemList = models.filter((model) => {
- return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
+ let pcsItemList = []
+ let pcsObj = {}
+ models.forEach((model) => {
+ pcsObj[model.itemId] = model
})
- const selectedModels = itemList.map((model) => {
- return {
- ...model,
- id: uuidv4(),
+ res.data?.pcsItemList.forEach((item) => {
+ if (pcsObj[item.itemId]) {
+ pcsItemList.push({
+ ...pcsObj[item.itemId],
+ isUsed: false,
+ id: uuidv4(),
+ })
}
})
- const PcsVoltageChkParams = {
+ const pcsVoltageChkParams = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(),
- pcsItemList: getPcsItemList(),
+ pcsItemList: pcsItemList.map((item) => {
+ return {
+ itemId: item.itemId,
+ pcsMkrCd: item.pcsMkrCd,
+ pcsSerCd: item.pcsSerCd,
+ }
+ }),
}
- setSelectedModels(selectedModels)
- getPcsVoltageChk(PcsVoltageChkParams).then((res) => {})
+ setSelectedModels(pcsItemList)
+ getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
+ setAllocationType(ALLOCATION_TYPE.PASSIVITY)
+ })
} else {
swalFire({
- title: '파워컨디셔너를 추가해 주세요.',
+ title: res.result.resultMsg,
type: 'alert',
+ confirmFn: () => {
+ return
+ },
})
+ return
}
})
- } else if (pcsCheck.max) {
+ } else {
const moduleStdQty = selectedModels.reduce((acc, model) => {
return acc + parseInt(model.moduleStdQty)
}, 0)
@@ -333,14 +297,14 @@ export default function CircuitTrestleSetting({ id }) {
if (placementModules.length > target) {
swalFire({
- title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.',
+ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error01'),
type: 'alert',
})
return
}
- }
- setAllocationType(ALLOCATION_TYPE.PASSIVITY)
+ setAllocationType(ALLOCATION_TYPE.PASSIVITY)
+ }
}
// StepUp에서 선택된 값들을 처리하는 함수 수정
@@ -358,83 +322,59 @@ export default function CircuitTrestleSetting({ id }) {
setGetStepUpSelections(() => getCurrentSelections)
}
- // apply 함수 수정
- const onApply = () => {
- // 현재 선택된 값들 가져오기
- const currentSelections = getStepUpSelections ? getStepUpSelections() : {}
-
- console.log('currentSelections >>> ', currentSelections)
-
- // 실제 선택된 값이 있는지 더 정확하게 확인
- const hasSelections = Object.values(currentSelections).some((stepUpConfig) => Object.values(stepUpConfig).length > 0)
-
- console.log('hasSelections >>> ', hasSelections)
-
- if (!hasSelections) {
- swalFire({
- title: '승압 설정값을 선택해주세요.1',
- type: 'alert',
- })
- return
- }
-
- // 선택된 값들 로그
- console.log('Applying StepUp configurations:', currentSelections)
-
- // StepUp 컴포넌트로부터 stepUpListData 받아오기
- //const stepUpData = getStepUpSelections().stepUpListData
- //console.log('stepUpData >>> ', stepUpData)
- // stepUpListData를 Recoil state에 저장
- // setStepUpListData(stepUpData)
-
- // 선택된 값들을 배열로 변환하여 처리
- const configurations = Object.values(currentSelections)
- .map((stepUpConfig) => {
- const firstConfig = Object.values(stepUpConfig)[0] // 첫 번째 설정만 사용
- return {
- pcsInfo: firstConfig.pcsInfo,
- allocation: firstConfig.allocation,
- }
- })
- .filter((config) => config.pcsInfo && config.allocation) // 유효한 설정만 필터링
-
- console.log('Processed configurations:', configurations)
-
- // stepUpListData를 Recoil state에 저장
- setStepUpListData(configurations)
-
- // 기존 apply 로직 실행 전에 필요한 데이터가 모두 있는지 확인
- if (configurations.length > 0) {
- apply()
- } else {
- swalFire({
- title: '승압 설정값을 선택해주세요.2',
- type: 'alert',
+ // 회로할당(승압설정) 저장 버튼 클릭 시
+ const onApply = async () => {
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ .map((obj) => {
+ obj.pcses = getStepUpListData()
})
+
+ setViewCircuitNumberTexts(false)
+
+ handleCanvasToPng(1)
+
+ const result = await apply()
+ if (result) {
+ handleCanvasToPng(2)
+ setViewCircuitNumberTexts(true)
+ // 캔버스 저장
+ await saveCanvas(false)
+ // 견적서 저장
+ await saveEstimate(result)
}
+ // removeNotAllocationModules()
}
+ // 이전 버튼 클릭 시
const onClickPrev = () => {
- setAllocationType(ALLOCATION_TYPE.AUTO)
+ // setAllocationType(ALLOCATION_TYPE.AUTO)
swalFire({
- text: '할당한 회로 번호가 초기화됩니다.',
+ text: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset.info'),
type: 'alert',
icon: 'warning',
confirmFn: () => {
- const circuitModules = canvas
- .getObjects()
- .filter((obj) => obj.name === 'module' && selectedModels.map((model) => model.id).includes(obj.circuit?.circuitInfo?.id))
+ const circuitModules = canvas.getObjects().filter((obj) => obj.name === 'module')
canvas.remove(...circuitModules.map((module) => module.circuit))
circuitModules.forEach((obj) => {
obj.circuit = null
obj.pcsItemId = null
})
- setAllocationType(ALLOCATION_TYPE.AUTO)
+
+ if (allocationType === ALLOCATION_TYPE.PASSIVITY) {
+ setAllocationType(ALLOCATION_TYPE.AUTO)
+ } else {
+ setTabNum(1)
+ }
+
canvas.renderAll()
+ setModuleStatisticsData()
},
})
}
+ // 파워컨디셔너 컴포넌트 속성
const powerConditionalSelectProps = {
tabNum,
setTabNum,
@@ -449,8 +389,10 @@ export default function CircuitTrestleSetting({ id }) {
selectedModels,
setSelectedModels,
managementState,
+ getUseModuleItemList,
}
+ // 수동할당 컴포넌트 속성
const passivityProps = {
tabNum,
setTabNum,
@@ -462,18 +404,86 @@ export default function CircuitTrestleSetting({ id }) {
getRoofSurfaceList,
}
+ // 승압설정 컴포넌트 속성
const stepUpProps = {
tabNum,
setTabNum,
models,
setModels,
+ allocationType,
circuitAllocationType,
setCircuitAllocationType,
+ selectedModels,
+ setSelectedModels,
+ getSelectedPcsItemList,
getOptYn, // 옵션 Y/N
getUseModuleItemList, // 사용된 모듈아이템 List
getRoofSurfaceList, // 지붕면 목록
getPcsItemList, // PCS 아이템 목록
onValuesSelected: handleStepUpValuesSelected, // 선택된 값들을 처리하는 함수
+ stepUpListData,
+ setStepUpListData,
+ seletedOption,
+ setSeletedOption,
+ getModuleList,
+ }
+
+ // 승압설정 목록 조회
+ const getStepUpListData = () => {
+ return stepUpListData[0].pcsItemList.map((item) => {
+ return item.serQtyList
+ .filter((serQty) => serQty.selected)
+ .map((serQty) => {
+ return {
+ pcsMkrCd: item.pcsMkrCd,
+ pcsSerCd: item.pcsSerCd,
+ pcsItemId: item.itemId,
+ pscOptCd: seletedOption.code,
+ paralQty: serQty.paralQty,
+ connections: item.connList?.length
+ ? [
+ {
+ connItemId: item.connList[0].itemId,
+ },
+ ]
+ : [],
+ }
+ })[0]
+ })
+ }
+
+ const handleStepUp = () => {
+ const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
+ if (notAllocationModules.length > 0) {
+ swalFire({
+ title: getMessage('not.allocation.exist.module'),
+ type: 'alert',
+ confirmFn: () => {},
+ })
+ return
+ // canvas.remove(...notAllocationModules)
+ // canvas.renderAll()
+ }
+ setTabNum(2)
+ }
+
+ // 닫기 버튼 클릭 시 처리하는 함수 추가
+ const handleClose = () => {
+ // // 회로 번호 텍스트 제거
+ const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
+ canvas.remove(...circuitTexts)
+ // 모듈의 회로 정보 초기화
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+ .forEach((obj) => {
+ obj.circuit = null
+ obj.pcsItemId = null
+ obj.circuitNumber = null
+ })
+
+ canvas.renderAll()
+ closePopup(id)
}
return (
@@ -481,7 +491,8 @@ export default function CircuitTrestleSetting({ id }) {
{getMessage('modal.circuit.trestle.setting')}
- closePopup(id)}>
+ {/* closePopup(id)}> */}
+
닫기
@@ -498,7 +509,7 @@ export default function CircuitTrestleSetting({ id }) {
{tabNum === 2 && }
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
- onAutoAllocation()}>
+ onAutoRecommend()}>
{getMessage('modal.circuit.trestle.setting.circuit.allocation.auto')}
onPassivityAllocation()}>
@@ -508,17 +519,17 @@ export default function CircuitTrestleSetting({ id }) {
)}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
- onClickPrev()}>
+ onClickPrev()}>
{getMessage('modal.common.prev')}
- setTabNum(2)}>
+ handleStepUp()}>
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
)}
{tabNum === 2 && (
- setTabNum(1)}>
+ onClickPrev()}>
{getMessage('modal.common.prev')}
{/* apply()}> */}
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx
deleted file mode 100644
index b980eeb4..00000000
--- a/src/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation.jsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import AutoCircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation'
-import PassivityCircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation'
-import { useMessage } from '@/hooks/useMessage'
-
-export default function CircuitAllocation(props) {
- const { getMessage } = useMessage()
- const { circuitAllocationType, setCircuitAllocationType } = props
- return (
- <>
-
- setCircuitAllocationType(1)}>
- {getMessage('modal.circuit.trestle.setting.circuit.allocation.auto')}
-
- setCircuitAllocationType(2)}>
- {getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}
-
-
-
- {getMessage('modal.circuit.trestle.setting.circuit.allocation')}
- {circuitAllocationType === 1 && }
- {circuitAllocationType === 2 && }
-
- >
- )
-}
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
index 407c5e34..5ab5b70c 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
@@ -1,11 +1,12 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import QSelectBox from '@/components/common/select/QSelectBox'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
import { pcsCheckState } from '@/store/circuitTrestleAtom'
import { globalLocaleStore } from '@/store/localeAtom'
-import { selectedModuleState } from '@/store/selectedModuleOptions'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isNullOrUndefined } from '@/util/common-utils'
import { useContext, useEffect, useState } from 'react'
import { useRecoilState } from 'recoil'
@@ -27,6 +28,7 @@ export default function PowerConditionalSelect(props) {
selectedModels,
setSelectedModels,
managementState,
+ getUseModuleItemList,
} = props
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
@@ -36,9 +38,11 @@ export default function PowerConditionalSelect(props) {
const { getPcsMakerList, getPcsModelList } = useMasterController()
const selectedModules = useRecoilValue(selectedModuleState)
const { swalFire } = useSwal()
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+ const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const modelHeader = [
- { name: getMessage('시리즈'), width: '15%', prop: 'pcsSerNm', type: 'color-box' },
- { name: getMessage('명칭'), width: '15%', prop: 'itemNm', type: 'color-box' },
+ { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.series'), width: '15%', prop: 'pcsSerNm', type: 'color-box' },
+ { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.name'), width: '15%', prop: 'goodsNo', type: 'color-box' },
{
name: `${getMessage('modal.circuit.trestle.setting.power.conditional.select.rated.output')} (kW)`,
width: '10%',
@@ -64,60 +68,54 @@ export default function PowerConditionalSelect(props) {
useEffect(() => {
if (makers.length === 0) {
getPcsMakerList().then((res) => {
- console.log('getPcsMakerList', res.data)
setMakers(res.data)
})
}
}, [])
- const checkValidation = () => {
- const checkedSeries = series.filter((s) => s.selected)
- if (checkedSeries.length === 0) {
- swalFire({
- title: 'PCS 시리즈를 선택해 주세요.',
- icon: 'warning',
- })
- return false
- } else if (checkedSeries.length === 1) {
- if (checkedSeries[0].pcsMkrMultiType === 'SINGLE-P' && checkedSeries[0].pcsSerParallelYn === 'Y') {
- swalFire({
- title: '병설은 단독으로 안 됨',
- icon: 'warning',
- })
- }
- return false
- }
- return true
- }
-
const onCheckSeries = (data) => {
- console.log('data', data)
- const copySeries = series.map((s) => {
- return {
- ...s,
- selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : s.selected,
- }
- })
+ let copySeries = []
+ if (data.pcsMkrMultiType === 'MULTI') {
+ copySeries = series.map((s) => {
+ return {
+ ...s,
+ selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : s.selected,
+ }
+ })
+ } else if (data.pcsMkrMultiType === 'SINGLE-P') {
+ copySeries = series.map((s) => {
+ return {
+ ...s,
+ selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : s.pcsMkrMultiType === 'MULTI' ? s.selected : false,
+ }
+ })
+ } else {
+ copySeries = series.map((s) => {
+ return {
+ ...s,
+ selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : false,
+ }
+ })
+ }
setSeries(copySeries)
- console.log('copySeries', copySeries)
handleSetmodels(copySeries.filter((s) => s.selected))
}
const handleSetmodels = (selectedSeries) => {
- console.log('series', selectedSeries)
if (selectedSeries.length === 0) {
setModels([])
setSelectedModels([])
return
}
+ console.log('moduleSelectionData', moduleSelectionData)
const pcsMkrCd = selectedSeries[0]?.pcsMkrCd
const pcsSerList = selectedSeries.map((series) => {
return { pcsSerCd: series.pcsSerCd }
})
- const moduleItemList = selectedModules.itemList?.map((module) => {
+ const moduleItemList = moduleSelectionData.module.itemList.map((item) => {
return {
- itemId: module.itemId,
- mixMatlNo: module.mixMatlNo,
+ itemId: item.itemId,
+ mixMatlNo: item.mixMatlNo,
}
})
getPcsModelList({ pcsMkrCd, pcsSerList, moduleItemList }).then((res) => {
@@ -143,13 +141,17 @@ export default function PowerConditionalSelect(props) {
if (selectedRow === null) return
if (selectedModels.length === 3) {
swalFire({
- title: '최대 3개까지 선택할 수 있습니다.',
+ title: getMessage('max.select', [3]),
icon: 'warning',
})
return
}
- setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4() }])
+ if (selectedMaker.pcsMkrMultiType === 'MULTI') {
+ setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }])
+ } else if (!selectedModels.find((m) => m.itemId === selectedRow.itemId)) {
+ setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }])
+ }
setSelectedRow(null)
}
@@ -160,10 +162,14 @@ export default function PowerConditionalSelect(props) {
const onChangeMaker = (option) => {
if (option) {
setModels([])
+ setSelectedModels([])
setSelectedMaker(option)
+ const param = {
+ pcsMkrCd: option.pcsMkrCd,
+ mixMatlNo: moduleSelectionData.module.mixMatlNo,
+ }
- getPcsMakerList(option).then((res) => {
- console.log('getPcsMakerList(series)', res.data)
+ getPcsMakerList(param).then((res) => {
setSeries(
res.data.map((series) => {
return { ...series, selected: false }
@@ -198,7 +204,7 @@ export default function PowerConditionalSelect(props) {
{series?.map((series, index) => (
-
+
onCheckSeries(series)} checked={series.selected} />
@@ -238,9 +244,9 @@ export default function PowerConditionalSelect(props) {
- {selectedModels?.map((model) => (
-
- {model.itemNm} onRemoveSelectedModel(model)}>
+ {selectedModels?.map((model, index) => (
+
+ {model.goodsNo} onRemoveSelectedModel(model)}>
))}
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx
index 71dd3e30..e0bd7592 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx
@@ -9,19 +9,36 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom'
import { useMasterController } from '@/hooks/common/useMasterController'
+import { v4 as uuidv4 } from 'uuid'
+import { globalLocaleStore } from '@/store/localeAtom'
+import { POLYGON_TYPE } from '@/common/common'
+import { useSwal } from '@/hooks/useSwal'
+import { circuitNumDisplaySelector } from '@/store/settingAtom'
export default function StepUp(props) {
+ const {
+ models,
+ allocationType,
+ stepUpListData,
+ setStepUpListData,
+ seletedOption,
+ setSeletedOption,
+ selectedModels,
+ setSelectedModels,
+ getSelectedPcsItemList,
+ getModuleList,
+ } = props
const { getMessage } = useMessage()
+ const { swalFire } = useSwal()
+ const globalLocale = useRecoilValue(globalLocaleStore)
const [moduleTab, setModuleTab] = useState(1)
const [moduleTabs, setModuleTabs] = useState({})
const [arrayLength, setArrayLength] = useState(3) //module-table-inner의 반복 개수
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
- const { models } = props
- const { getPcsVoltageStepUpList, getPcsAutoRecommendList } = useMasterController()
+ const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk, getPcsConnOptionItemList } = useMasterController()
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const canvas = useRecoilValue(canvasState)
const selectedModules = useRecoilValue(selectedModuleState)
- const [stepUpListData, setStepUpListData] = useState([])
const [optCodes, setOptCodes] = useState([])
const [selectedRows, setSelectedRows] = useState({})
@@ -29,7 +46,7 @@ export default function StepUp(props) {
// 선택된 값들을 저장할 상태 추가
const [selectedValues, setSelectedValues] = useState({})
-
+ const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
// useCanvasPopupStatusController(6)
// const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore)
// if (Object.keys(canvasPopupStatusState[6]).length !== 0) {
@@ -37,34 +54,176 @@ export default function StepUp(props) {
// }
useEffect(() => {
- // PCS 승압설정 정보 조회
- fetchStepUpData()
+ console.log(allocationType)
+
+ if (allocationType === 'auto') {
+ // PCS 자동 승압설정 정보 조회
+ fetchAutoStepUpData()
+ } else {
+ // PCS 수동 승압설정 정보 조회
+ fetchPassiStepUpData()
+ }
}, [])
- // PCS 승압설정 정보 조회
- const fetchStepUpData = async () => {
+ // PCS 자동 승압설정 정보 조회
+ const fetchAutoStepUpData = async () => {
try {
const params = {
- useYn: props.getOptYn(), // 옵션 Y/N
+ ...props.getOptYn(), // 옵션 Y/N
useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List
roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록
- pcsItemList: props.getPcsItemList(), // PCS 아이템 목록
+ pcsItemList: props.getSelectedPcsItemList(), // PCS 아이템 목록
}
- // PCS 승압설정 정보 조회
- const res = await getPcsVoltageStepUpList(params)
+ // 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
+ getPcsVoltageStepUpList(params).then((res) => {
+ if (res.result.resultCode === 'S') {
+ if (res?.result.code === 200 && res?.data) {
+ const dataArray = Array.isArray(res.data) ? res.data : [res.data]
+ const stepUpListData = formatStepUpListData(dataArray)
- if (res?.result.code === 200 && res?.data) {
- const dataArray = Array.isArray(res.data) ? res.data : [res.data]
- const stepUpListData = formatStepUpListData(dataArray)
+ // PCS 승압설정 정보 SET
+ setStepUpListData(stepUpListData)
- // PCS 승압설정 정보 SET
- setStepUpListData(stepUpListData)
+ // PCS 옵션 조회
+ const formattedOptCodes = formatOptionCodes(res.data.optionList)
+ setOptCodes(formattedOptCodes)
+ setSeletedOption(formattedOptCodes[0])
- // PCS 옵션 조회
- const formattedOptCodes = formatOptionCodes(res.data.optionList)
- setOptCodes(formattedOptCodes)
+ // 캔버스에 회로 정보 적용
+ //stepUpListData[0].pcsItemList.forEach((pcsItem) => {
+ stepUpListData[0].pcsItemList.forEach((pcsItem) => {
+ const selectedSerQty = pcsItem.serQtyList.find((serQty) => serQty.selected)
+ if (selectedSerQty) {
+ selectedSerQty.roofSurfaceList.forEach((roofSurface) => {
+ const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0]
+ const moduleIds = targetSurface.modules.map((module) => module.id)
+
+ // 기존 모듈 텍스트 삭제
+ canvas
+ .getObjects()
+ .filter((obj) => moduleIds.includes(obj.parentId))
+ .forEach((text) => canvas.remove(text))
+
+ // 새로운 모듈 회로 정보 추가
+ roofSurface.moduleList.forEach((module) => {
+ const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0]
+ const moduleCircuitText = new fabric.Text(module.circuit, {
+ left: targetModule.left + targetModule.width / 2,
+ top: targetModule.top + targetModule.height / 2,
+ fill: 'black',
+ fontSize: 20,
+ width: targetModule.width,
+ height: targetModule.height,
+ textAlign: 'center',
+ originX: 'center',
+ originY: 'center',
+ name: 'circuitNumber',
+ parentId: targetModule.id,
+ circuitInfo: module.pcsItemId,
+ selectable: false,
+ visible: isDisplayCircuitNumber,
+ })
+ targetModule.circuit = moduleCircuitText
+ targetModule.pcsItemId = module.pcsItemId
+ targetModule.circuitNumber = module.circuit
+ canvas.add(moduleCircuitText)
+ })
+ })
+ }
+ })
+
+ canvas.renderAll()
+ } else {
+ swalFire({
+ title: res.result.resultMsg,
+ type: 'alert',
+ })
+ }
+ }
+ })
+ } catch (error) {
+ console.error('Error fetching step up data:', error)
+ }
+ }
+
+ // PCS 수동 승압설정 정보 조회
+ const fetchPassiStepUpData = async () => {
+ try {
+ // 1-1 2-2
+ // canvas
+ // .getObjects()
+ // .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
+ // .map((module) => module.circuitNumber)
+
+ // 모듈 데이터 가져오기
+ const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+
+ // PCS별 회로 정보를 저장할 객체
+ const pcsSummary = {}
+
+ // 각 모듈을 순회하며 PCS별 회로 정보 수집
+ modules.forEach((module) => {
+ if (!module.circuit || !module.pcsItemId) return
+
+ if (!pcsSummary[module.pcsItemId]) {
+ pcsSummary[module.pcsItemId] = {
+ circuits: {},
+ totalModules: 0,
+ }
+ }
+
+ const circuitNumber = module.circuitNumber
+ if (!pcsSummary[module.pcsItemId].circuits[circuitNumber]) {
+ pcsSummary[module.pcsItemId].circuits[circuitNumber] = 0
+ }
+ pcsSummary[module.pcsItemId].circuits[circuitNumber]++
+ pcsSummary[module.pcsItemId].totalModules++
+ })
+
+ const params = {
+ useModuleItemList: props.getUseModuleItemList(),
+ pcsItemList: getSelectedPcsItemList(),
}
+
+ // PCS 접속함 및 옵션 목록 조회
+ getPcsConnOptionItemList(params).then((res) => {
+ if (res?.result.code === 200 && res?.data) {
+ // PCS 아이템 리스트에 serQtyList 추가
+ const pcsItemListWithSerQty = res.data.pcsItemList.map((pcsItem) => {
+ const pcsData = pcsSummary[pcsItem.itemId] || { circuits: {}, totalModules: 0 }
+ const circuitCounts = Object.values(pcsData.circuits)
+ return {
+ ...pcsItem,
+ serQtyList: [
+ {
+ // 한 회로당 최대 모듈 수
+ serQty: circuitCounts.length > 0 ? Math.max(...circuitCounts) : 0,
+ // 회로 개수
+ paralQty: Object.keys(pcsData.circuits).length || 0,
+ rmdYn: 'Y',
+ usePossYn: 'Y',
+ roofSurfaceList: props.getRoofSurfaceList(),
+ },
+ ],
+ }
+ })
+
+ // Update res.data with modified pcsItemList
+ res.data.pcsItemList = pcsItemListWithSerQty
+
+ const dataArray = Array.isArray(res.data) ? res.data : [res.data]
+ const stepUpListData = formatStepUpListData(dataArray)
+
+ // PCS 승압설정 정보 SET
+ setStepUpListData(stepUpListData)
+
+ // PCS 옵션 조회
+ const formattedOptCodes = formatOptionCodes(res.data.optionList)
+ setOptCodes(formattedOptCodes)
+ setSeletedOption(formattedOptCodes[0])
+ }
+ })
} catch (error) {
console.error('Error fetching step up data:', error)
}
@@ -79,16 +238,6 @@ export default function StepUp(props) {
}))
}
- // // PCS 승압설정 정보 포맷
- // const formatStepUpListData = (dataArray = []) => {
- // return dataArray?.map((stepUps) => ({
- // ...stepUps,
- // optionList: formatOptionList(stepUps.optionList),
- // pcsItemList: formatPcsItemList(stepUps.pcsItemList),
- // selectedPcsItem: formatPcsItemList(stepUps.pcsItemList),
- // }))
- // }
-
// PCS 승압설정 정보 포맷 후 추천 값 저장
const formatStepUpListData = (dataArray = []) => {
const formattedData = dataArray?.map((stepUps) => ({
@@ -98,39 +247,6 @@ export default function StepUp(props) {
selectedPcsItem: formatPcsItemList(stepUps.pcsItemList),
}))
- // 초기 추천 값들을 selectedValues에 저장
- const initialSelectedValues = {}
- formattedData.forEach((stepUp) => {
- stepUp.pcsItemList.forEach((pcsItem, pcsIdx) => {
- const pcsKey = `${stepUp.id}_${pcsIdx}`
-
- // 추천 값(rmdYn === 'Y') 찾기
- const recommendedRow = pcsItem.serQtyList.find((item) => item.rmdYn === 'Y')
- if (recommendedRow) {
- const selectionData = {
- stepUpId: pcsItem.goodsNo,
- pcsInfo: {
- itemId: pcsItem.itemId,
- goodsNo: pcsItem.goodsNo,
- pcsMkrCd: pcsItem.pcsMkrCd,
- pcsSerCd: pcsItem.pcsSerCd,
- },
- allocation: {
- serQty: recommendedRow.serQty,
- paralQty: recommendedRow.paralQty,
- },
- }
-
- initialSelectedValues[stepUp.id] = {
- ...initialSelectedValues[stepUp.id],
- [pcsKey]: selectionData,
- }
- }
- })
- })
-
- setSelectedValues(initialSelectedValues)
-
return formattedData
}
@@ -145,12 +261,13 @@ export default function StepUp(props) {
// PCS 아이템 포맷
const formatPcsItemList = (pcsItemList = []) => {
- return pcsItemList?.map((item) => ({
+ return pcsItemList?.map((item, index) => ({
goodsNo: item.goodsNo ? item.goodsNo : '',
itemId: item.itemId ? item.itemId : '',
itemNm: item.itemNm ? item.itemNm : '',
pcsMkrCd: item.pcsMkrCd ? item.pcsMkrCd : '',
pcsSerCd: item.pcsSerCd ? item.pcsSerCd : '',
+ uniqueIndex: `${item.itemId}_${index}`, // 고유 식별자 추가(동일한 PCS를 구분)
connList: formatConnList(item.connList),
serQtyList: formatSerQtyList(item.serQtyList),
}))
@@ -173,11 +290,13 @@ export default function StepUp(props) {
// PCS 시리즈 포맷
const formatSerQtyList = (serQtyList = []) => {
return serQtyList?.map((qty) => ({
+ code: uuidv4(),
serQty: qty.serQty ? qty.serQty : 0,
paralQty: qty.paralQty ? qty.paralQty : 0,
rmdYn: qty.rmdYn ? qty.rmdYn : 'N',
usePossYn: qty.usePossYn ? qty.usePossYn : 'Y',
roofSurfaceList: formatRoofSurfaceList(qty.roofSurfaceList),
+ selected: qty.rmdYn === 'Y',
}))
}
@@ -209,79 +328,139 @@ export default function StepUp(props) {
}
// 행 선택 핸들러 함수 추가
- const handleRowClick = (goodsNo, pcsIdx, serQtyIdx, serQty, paralQty) => {
- const rowKey = `${goodsNo}_${pcsIdx}_${serQtyIdx}`
- const pcsKey = `${goodsNo}_${pcsIdx}`
+ const handleRowClick = (mainIdx, subIdx) => {
+ // 자동 승압 설정인 경우만 실행
+ if (allocationType !== 'auto') return
- console.log('goodsNo >> ', goodsNo, serQty, paralQty)
+ let tempStepUpListData = [...stepUpListData]
+ let selectedData = {}
- // 현재 선택된 PCS 아이템 정보 가져오기
- const pcsItem = stepUpListData.find((stepUp) => stepUp.pcsItemList.find((item) => item.goodsNo === goodsNo))?.pcsItemList[pcsIdx]
+ tempStepUpListData[0].pcsItemList[mainIdx].serQtyList.forEach((item, index) => {
+ if (index === subIdx) {
+ selectedData = item
+ }
+ item.selected = index === subIdx
+ })
+ // 선택된 행 정보 저장
+ setStepUpListData(tempStepUpListData)
- if (!pcsItem) {
- console.error('PCS item not found:', { goodsNo, pcsIdx })
- return
- }
+ // console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData)
+ // console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData)
- // 선택된 값들 업데이트 - 더 자세한 정보 포함
- const selectionData = {
- goodsNo: goodsNo,
- pcsInfo: {
- itemId: pcsItem?.itemId,
- goodsNo: pcsItem?.goodsNo,
- pcsMkrCd: pcsItem?.pcsMkrCd,
- pcsSerCd: pcsItem?.pcsSerCd,
- },
- allocation: {
- serQty: serQty,
- paralQty: paralQty,
- },
- }
+ // PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행
+ if (stepUpListData[0].pcsItemList.length > 1 && mainIdx === 0) {
+ // 파워컨디셔너 옵션 조회 요청 파라미터
+ const params = {
+ ...props.getOptYn(), // 옵션 Y/N
+ useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List
+ roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록
+ pcsItemList: props.getSelectedPcsItemList().map((pcsItem, index) => {
+ // PCS 아이템 목록
+ // tempStepUpListData에서 해당 PCS 아이템 찾기
+ // uniqueIndex를 사용하여 매칭
+ const matchingPcsItem = tempStepUpListData[0].pcsItemList.find((item) => item.uniqueIndex === `${pcsItem.itemId}_${index}`)
- // 선택된 값들 업데이트
- setSelectedValues((prev) => ({
- ...prev,
- [goodsNo]: {
- ...prev[goodsNo],
- [pcsKey]: selectionData,
- },
- }))
+ // 선택된 serQty 찾기
+ const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0
- // 부모 컴포넌트에 선택된 값들 전달
- if (props.onValuesSelected) {
- props.onValuesSelected(selectionData)
- }
-
- setSelectedRows((prev) => {
- // 현재 stepUpId에 대한 선택 상태가 없으면 빈 객체로 초기화
- const currentStepUpSelections = prev[goodsNo] || {}
-
- // 이미 선택된 행을 다시 클릭하는 경우, 선택을 해제하지 않음
- if (currentStepUpSelections[pcsKey] === rowKey) {
- return prev
+ return {
+ ...pcsItem,
+ applySerQty: selectedSerQty,
+ }
+ }),
}
- return {
- ...prev,
- [goodsNo]: {
- ...currentStepUpSelections,
- [pcsKey]: rowKey,
- },
+ // PCS가 1개 이고 2번째 또는 3번째 PCS serQty가 0인 경우는 추천 API 실행하지 않음
+ if (params.pcsItemList.length !== 1 && (params.pcsItemList[1]?.applySerQty !== 0 || params.pcsItemList[2]?.applySerQty) !== 0) {
+ // PCS 승압설정 정보 조회
+ //const res = await getPcsVoltageStepUpList(params)
+ //getPcsManualConfChk(params).then((res) => {
+ getPcsVoltageStepUpList(params).then((res) => {
+ if (res?.result.code === 200 && res?.data) {
+ const dataArray = Array.isArray(res.data) ? res.data : [res.data]
+ const stepUpListData = formatStepUpListData(dataArray)
+
+ // PCS 승압설정 정보 SET
+ setStepUpListData(stepUpListData)
+
+ // PCS 옵션 조회
+ const formattedOptCodes = formatOptionCodes(res.data.optionList)
+ setOptCodes(formattedOptCodes)
+ setSeletedOption(formattedOptCodes[0])
+ }
+ })
}
+ }
+
+ selectedData.roofSurfaceList.forEach((roofSurface) => {
+ const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0]
+ const moduleIds = targetSurface.modules.map((module) => {
+ return module.id
+ })
+
+ targetSurface.modules.map((module) => {
+ module.circuit = null
+ module.circuitNumber = null
+ module.pcsItemId = null
+ })
+
+ // 모듈 목록 삭제
+ canvas
+ .getObjects()
+ .filter((obj) => moduleIds.includes(obj.parentId))
+ .map((text) => {
+ canvas.remove(text)
+ })
+
+ // 모듈 목록 추가
+ canvas.renderAll()
+
+ roofSurface.moduleList.forEach((module) => {
+ const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0]
+ if (module.circuit === '') return
+ const moduleCircuitText = new fabric.Text(module.circuit, {
+ left: targetModule.left + targetModule.width / 2,
+ top: targetModule.top + targetModule.height / 2,
+ fill: 'black',
+ fontSize: 20,
+ width: targetModule.width,
+ height: targetModule.height,
+ textAlign: 'center',
+ originX: 'center',
+ originY: 'center',
+ name: 'circuitNumber',
+ parentId: targetModule.id,
+ circuitInfo: module.pcsItemId,
+ visible: isDisplayCircuitNumber,
+ })
+ targetModule.circuit = moduleCircuitText
+ targetModule.pcsItemId = module.pcsItemId
+ targetModule.circuitNumber = module.circuit
+ canvas.add(moduleCircuitText)
+ })
})
- // 수동 선택 상태를 업데이트하되, 기존 추천 선택은 유지
- setIsManualSelection((prev) => ({
- ...prev,
- [goodsNo]: {
- ...prev[goodsNo],
- [pcsKey]: true,
- },
- }))
+ canvas.renderAll()
}
// 현재 선택된 값들을 가져오는 함수 추가
const getCurrentSelections = () => {
+ const selectedValues = stepUpListData[0].pcsItemList.forEach((item) => {
+ item.serQtyList.filter((serQty) => serQty.selected)
+ return item.serQtyList.map((serQty) => {
+ return {
+ pcsMkrCd: serQty.pcsMkrCd,
+ pcsSerCd: serQty.pcsSerCd,
+ pcsItemId: serQty.itemId,
+ pcsOptCd: seletedOption,
+ paralQty: serQty.paralQty,
+ connections: {
+ connItemId: item.connList[0].itemId,
+ },
+ }
+ })
+ })
+
return selectedValues
}
@@ -310,7 +489,7 @@ export default function StepUp(props) {
{/* 3개일때 className = by-max */}
{stepUpListData.map((stepUp, index) => (
- {stepUp?.pcsItemList.map((_, idx) => (
+ {stepUp?.pcsItemList.map((pcsItem, idx) => (
{stepUp.pcsItemList[idx].goodsNo}
@@ -323,20 +502,13 @@ export default function StepUp(props) {
- {stepUp.pcsItemList[idx].serQtyList.map((item, serQtyIdx) => {
- const rowKey = `${stepUp.pcsItemList[idx].goodsNo}_${idx}_${serQtyIdx}`
- const pcsKey = `${stepUp.pcsItemList[idx].goodsNo}_${idx}`
+ {pcsItem.serQtyList.map((item, serQtyIdx) => {
return (
handleRowClick(stepUp.pcsItemList[idx].goodsNo, idx, serQtyIdx, item.serQty, item.paralQty)}
- style={{ cursor: 'pointer' }}
+ key={`row-${serQtyIdx}`}
+ className={`${item.selected ? 'on' : ''}`}
+ onClick={() => handleRowClick(idx, serQtyIdx)}
+ style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
>
| {item.serQty} |
{item.paralQty} |
@@ -428,7 +600,18 @@ export default function StepUp(props) {
{optCodes.length > 0 && (
{/* */}
-
+ {
+ return { ...roof, name: globalLocale === 'ko' ? roof.name : roof.nameJp }
+ })}
+ title={globalLocale === 'ko' ? optCodes[0].name : optCodes[0].nameJp}
+ value={seletedOption}
+ sourceKey="code"
+ targetKey="code"
+ showKey="name"
+ onChange={(e) => setSeletedOption(e)}
+ />
)}
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx
deleted file mode 100644
index 026bbaee..00000000
--- a/src/components/floor-plan/modal/circuitTrestle/step/type/AutoCircuitAllocation.jsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useMessage } from '@/hooks/useMessage'
-
-export default function AutoCircuitAllocation() {
- const { getMessage } = useMessage()
- return (
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
index 32b15236..e77c2b66 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
@@ -1,46 +1,40 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { POLYGON_TYPE } from '@/common/common'
import { useMasterController } from '@/hooks/common/useMasterController'
+import { useModule } from '@/hooks/module/useModule'
+import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
import { selectedModuleState } from '@/store/selectedModuleOptions'
+import { circuitNumDisplaySelector } from '@/store/settingAtom'
import { useContext, useEffect, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
export default function PassivityCircuitAllocation(props) {
const {
- tabNum,
- setTabNum,
selectedModels,
+ setSelectedModels,
getOptYn: getApiProps,
getUseModuleItemList: getSelectedModuleList,
getSelectModelList: getSelectModelList,
- getRoofSurfaceList,
- getModelList,
} = props
const { swalFire } = useSwal()
const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState)
- const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
- // const [totalWpout, setTotalWpout] = useState(0)
const [selectedPcs, setSelectedPcs] = useState(selectedModels[0])
- // const { header, rows: row } = moduleStatistics
- const [header, setHeader] = useState(moduleStatistics.header)
- const [rows, setRows] = useState(moduleStatistics.rows)
- const [footer, setFooter] = useState(['합계'])
+ const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const [circuitNumber, setCircuitNumber] = useState(1)
const [targetModules, setTargetModules] = useState([])
const { getPcsManualConfChk } = useMasterController()
+ const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
+ const { setModuleStatisticsData } = useCircuitTrestle()
useEffect(() => {
- console.log('header, rows', header, rows)
- console.log('selectedModels', selectedModels)
- // setSurfaceInfo()
- setTableData()
+ setModuleStatisticsData()
if (!managementState) {
setManagementState(managementStateLoaded)
}
@@ -82,82 +76,15 @@ export default function PassivityCircuitAllocation(props) {
canvas.renderAll()
}
- const setSurfaceInfo = () => {
- const surfaces = canvas.getObjects().filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name)
- // setHeaders([header[0], { name: '회로', prop: 'circuit' }, ...header.slice(1)])
- setRows(
- rows.map((row) => {
- return {
- ...row,
- circuit: '',
- }
- }),
- )
- let totals = {}
-
- rows.forEach((row) => {
- if (header.length === 4) {
- if (!totals[header[2].prop]) totals[header[2].prop] = 0
- totals[header[2].prop] += +row[header[2].prop]
- } else if (header.length === 5) {
- if (!totals[header[2].prop]) totals[header[2].prop] = 0
- totals[header[2].prop] += +row[header[2].prop]
- if (!totals[header[3].prop]) totals[header[3].prop] = 0
- totals[header[3]] += +row[header[3]]
- }
- })
- setFooter([
- ...['합계', ''],
- ...Object.keys(totals).map((key) => {
- return totals[key]
- }),
- Object.keys(totals).reduce((acc, key) => {
- return acc + totals[key]
- }, 0),
- ])
- // let totalWpout = 0
- // const rows = surfaces.map((surface) => {
- // let wpOut = 0
- // let moduleInfo = {}
- // surface.modules.forEach((module) => {
- // wpOut += +module.moduleInfo.wpOut
- // if (!moduleInfo[module.moduleInfo.itemId]) moduleInfo[module.moduleInfo.itemId] = 0
- // moduleInfo[module.moduleInfo.itemId]++
- // })
- // totalWpout += wpOut
- // console.log('🚀 ~ moduleData.rows=surfaces.map ~ module:', module)
- // return {
- // roofShape: DIRECTION[surface.direction],
- // powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }),
- // ...moduleInfo,
- // }
- // })
-
- // setTotalWpout(totalWpout)
- // 지붕면 리스트 -> 지붕면에 있는 모듈 리스트 -> 발전량 총합 계산
- // wpOut
-
- // setModuleData({
- // header: [
- // { name: getMessage('modal.panel.batch.statistic.roof.shape'), prop: 'roofShape' },
- // { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
- // ...selectedModules.itemList.map((module) => {
- // return {
- // name: module.itemNm,
- // prop: module.itemId,
- // }
- // }),
- // {
- // name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`,
- // prop: 'powerGeneration',
- // },
- // ],
- // rows: rows,
- // })
- }
-
const handleCircuitNumberFix = () => {
- let uniqueCircuitNumbers = null
+ let uniqueCircuitNumbers = [
+ ...new Set(
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber)
+ .map((obj) => obj.circuitNumber),
+ ),
+ ]
if (!circuitNumber || circuitNumber === 0) {
swalFire({
text: '회로번호를 1 이상입력해주세요.',
@@ -173,16 +100,8 @@ export default function PassivityCircuitAllocation(props) {
})
return
} else if (selectedModels.length > 1) {
- uniqueCircuitNumbers = [
- ...new Set(
- canvas
- .getObjects()
- .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber)
- .map((obj) => obj.circuitNumber),
- ),
- ]
-
let result = false
+
uniqueCircuitNumbers.forEach((number) => {
if (
number.split('-')[1] === circuitNumber + ')' &&
@@ -201,11 +120,15 @@ export default function PassivityCircuitAllocation(props) {
}
}
+ let tempSelectedPcs = { ...selectedPcs }
canvas.discardActiveObject()
canvas
.getObjects()
.filter((obj) => targetModules.includes(obj.id))
.forEach((obj) => {
+ if (obj.circuit) {
+ canvas.remove(obj.circuit)
+ }
const moduleCircuitText = new fabric.Text(getCircuitNumber(), {
left: obj.left + obj.width / 2,
top: obj.top + obj.height / 2,
@@ -217,21 +140,33 @@ export default function PassivityCircuitAllocation(props) {
originX: 'center',
originY: 'center',
name: 'circuitNumber',
+ selectable: false,
parentId: obj.id,
circuitInfo: selectedPcs,
+ visible: isDisplayCircuitNumber,
})
obj.set({
strokeWidth: 0.3,
})
obj.pcsItemId = selectedPcs.itemId
+ obj.pcsItemCode = selectedPcs.id
obj.circuit = moduleCircuitText
obj.circuitNumber = getCircuitNumber()
+ tempSelectedPcs.used = true
+ setSelectedPcs(tempSelectedPcs)
canvas.add(moduleCircuitText)
})
+ let pcsList = JSON.parse(JSON.stringify(selectedModels)).map((model) => {
+ if (model.id === selectedPcs.id) {
+ model.isUsed = true
+ }
+ return model
+ })
+
const roofSurfaceList = canvas
.getObjects()
- .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name)
+ .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0)
.map((surface) => {
return {
roofSurfaceId: surface.id,
@@ -247,7 +182,8 @@ export default function PassivityCircuitAllocation(props) {
}
})
- const pcsItemList = selectedModels.map((model) => {
+ const usedPcses = pcsList.filter((model) => model.isUsed)
+ const pcsItemList = usedPcses.map((model, index) => {
return {
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
@@ -257,7 +193,7 @@ export default function PassivityCircuitAllocation(props) {
serQtyList: [
{
serQty: targetModules.length,
- paralQty: 0,
+ paralQty: uniqueCircuitNumbers.length,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: roofSurfaceList,
@@ -273,7 +209,7 @@ export default function PassivityCircuitAllocation(props) {
}
getPcsManualConfChk(params).then((res) => {
- if (res.resultCode === 'E') {
+ if (res?.resultCode === 'E') {
swalFire({
text: res.resultMsg,
type: 'alert',
@@ -292,13 +228,16 @@ export default function PassivityCircuitAllocation(props) {
canvas.renderAll()
},
})
-
+ setSelectedPcs({ ...selectedPcs, used: false })
+ setTargetModules([])
return
}
+ setSelectedModels(pcsList)
+
setTargetModules([])
setCircuitNumber(+circuitNumber + 1)
- setTableData()
+ setModuleStatisticsData()
})
}
@@ -310,116 +249,29 @@ export default function PassivityCircuitAllocation(props) {
}
}
- const setTableData = () => {
- const tempHeader = [
- { name: getMessage('simulator.table.sub1'), prop: 'name' },
- { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
- ...selectedModules.itemList.map((module) => {
- return {
- name: module.itemNm,
- prop: module.itemId,
- }
- }),
- { name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
- ]
-
- const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
- const surfaceIds = surfaces.map((surface) => surface.parentId)
- const surfaceObjects = {}
- const rows = surfaces.map((surface) => {
- const moduleObject = {}
- surfaceObjects[surface.id] = {
- roofSurface: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText,
- circuit: '-',
- amount: 0,
- wpOut: 0,
- circuits: {},
- }
-
- surface.modules.forEach((module) => {
- if (!surfaceObjects[surface.id][module.moduleInfo.itemId]) {
- // 지붕면에 모듈 존재 여부
- surfaceObjects[surface.id][module.moduleInfo.itemId] = 0 // 모듈 초기화
- }
-
- surfaceObjects[surface.id][module.moduleInfo.itemId]++
- surfaceObjects[surface.id].wpOut += +module.moduleInfo.wpOut
- if (module.circuit) {
- if (!surfaceObjects[surface.id].circuits[module.circuitNumber]) {
- surfaceObjects[surface.id].circuits[module.circuitNumber] = {
- circuit: module.circuitNumber,
- wpOut: 0,
- circuits: { wpOut: 0 },
- }
-
- if (!surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]) {
- surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId] = 0
- }
- }
- surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]++
- surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut += +module.moduleInfo.wpOut
- surfaceObjects[surface.id].wpOut -= +module.moduleInfo.wpOut
- surfaceObjects[surface.id][module.moduleInfo.itemId]--
- }
- })
- })
- console.log('rows', rows)
- console.log('surfaceObjects', surfaceObjects)
- let tempRows = []
- Object.keys(surfaceObjects).forEach((key) => {
- let tempRow = {
- name: surfaceObjects[key].roofSurface,
- circuit: surfaceObjects[key].circuit,
- wpOut: surfaceObjects[key].wpOut,
- }
- selectedModules.itemList.forEach((module) => {
- tempRow[module.itemId] = surfaceObjects[key][module.itemId]
- })
- tempRows.push(tempRow)
-
- Object.keys(surfaceObjects[key].circuits).forEach((circuit) => {
- let row = {
- name: surfaceObjects[key].roofSurface,
- circuit: surfaceObjects[key].circuits[circuit].circuit,
- wpOut: surfaceObjects[key].circuits[circuit].circuits.wpOut,
- }
- selectedModules.itemList.forEach((module) => {
- row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
- })
- tempRows.push(row)
- })
- })
- const tempFooter = {
- name: '총합',
- circuit: '-',
- wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0),
- }
- selectedModules.itemList.forEach((module) => {
- tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0)
- })
-
- setHeader(tempHeader)
- setRows(tempRows.filter((row) => row.wpOut !== 0))
- setFooter(tempFooter)
- setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
- }
-
const initSelectedPcsCircuitNumber = () => {
swalFire({
- title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'),
+ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset.info'),
type: 'confirm',
icon: 'warning',
confirmFn: () => {
const circuitModules = canvas.getObjects().filter((obj) => obj.name === 'module' && obj.circuit?.circuitInfo?.id === selectedPcs.id)
+ const circuitNumbers = circuitModules.map((obj) => {
+ const circuitNumber = obj.circuitNumber.replace(/[()]/g, '').split('-')
+ return parseInt(circuitNumber[circuitNumber.length - 1])
+ })
+ const minCircuitNumber = Math.min(...circuitNumbers)
canvas.remove(...circuitModules.map((module) => module.circuit))
circuitModules.forEach((obj) => {
obj.circuit = null
obj.pcsItemId = null
})
+ setCircuitNumber(minCircuitNumber)
setTargetModules([])
canvas.renderAll()
canvas.discardActiveObject()
+ setModuleStatisticsData()
},
})
}
@@ -427,7 +279,7 @@ export default function PassivityCircuitAllocation(props) {
const initAllPcsCircuitNumber = () => {
canvas.discardActiveObject()
swalFire({
- title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.setting.info'),
+ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset.info'),
type: 'confirm',
icon: 'warning',
confirmFn: () => {
@@ -439,9 +291,9 @@ export default function PassivityCircuitAllocation(props) {
obj.circuit = null
obj.pcsItemId = null
})
- setTargetModules([])
-
canvas.renderAll()
+ setTargetModules([])
+ setModuleStatisticsData()
},
})
}
@@ -479,9 +331,7 @@ export default function PassivityCircuitAllocation(props) {
{header.map((header, i) => (
|
- {typeof footer[header.prop] === 'number'
- ? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 })
- : footer[header.prop]}
+ {footer[header.prop]}
|
))}
@@ -509,7 +359,7 @@ export default function PassivityCircuitAllocation(props) {
onChange={() => setSelectedPcs(model)}
/>
))}
- {/*
-
-
-
-
-
-
-
-
-
-
- */}
diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx
index 8e1f9fac..bfff66a2 100644
--- a/src/components/floor-plan/modal/module/PanelEdit.jsx
+++ b/src/components/floor-plan/modal/module/PanelEdit.jsx
@@ -36,7 +36,7 @@ export default function PanelEdit(props) {
const { moduleMove, moduleCopy, moduleMultiMove, moduleMultiCopy, moduleMoveAll, moduleCopyAll } = useModule()
useEffect(() => {
- if (canvas) {
+ if (!canvas) {
const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module') // selectedObj에 없는 객체만 필터링
isSetupModules.forEach((obj) => obj.set({ lockMovementX: false, lockMovementY: false }))
}
@@ -52,18 +52,30 @@ export default function PanelEdit(props) {
})
return
}
+ debugger
+ const completeSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.isComplete)
+
+ if (completeSurfaces.length > 0) {
+ swalFire({
+ title: getMessage('modal.module.can.not.edit'),
+ type: 'alert',
+ icon: 'error',
+ })
+ return
+ }
+
switch (type) {
case PANEL_EDIT_TYPE.MOVE:
moduleMove(length, direction)
break
case PANEL_EDIT_TYPE.MOVE_ALL:
- moduleMoveAll(length, direction)
+ moduleMoveAll(length, direction, props.arrayData)
break
case PANEL_EDIT_TYPE.COPY:
moduleCopy(length, direction)
break
case PANEL_EDIT_TYPE.COPY_ALL:
- moduleCopyAll(length, direction)
+ moduleCopyAll(length, direction, props.arrayData)
break
case PANEL_EDIT_TYPE.COLUMN_MOVE:
moduleMultiMove('column', length, direction)
diff --git a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
index 4b41b72e..8cd0de0e 100644
--- a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
+++ b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
@@ -1,10 +1,16 @@
'use client'
-import { useState } from 'react'
+import { useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
-import { useRecoilValue, useResetRecoilState } from 'recoil'
+import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
+import { useModule } from '@/hooks/module/useModule'
+import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit'
+import { canvasState } from '@/store/canvasAtom'
+import { POLYGON_TYPE } from '@/common/common'
+import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
+import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
export default function PanelBatchStatistics() {
const { getMessage } = useMessage()
@@ -13,7 +19,14 @@ export default function PanelBatchStatistics() {
x: 0,
y: 30,
})
+ const canvas = useRecoilValue(canvasState)
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
+ const { setModuleStatisticsData } = useCircuitTrestle()
+ const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState)
+
+ useEffect(() => {
+ if (moduleSelectionDataStore && moduleSelectionDataStore.module) setModuleStatisticsData()
+ }, [])
return (
@@ -33,9 +46,7 @@ export default function PanelBatchStatistics() {
{rows.map((row, index) => (
{header.map((item, i) => (
- |
- {typeof row[item.prop] === 'number' ? row[item.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 }) : row[item.prop]}
- |
+ {row[item.prop] ?? 0} |
))}
))}
diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx
index 1a5ea92a..5439b303 100644
--- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx
+++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx
@@ -258,7 +258,11 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
{
diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
index 5bfad3e4..2374c582 100644
--- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
+++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
@@ -31,6 +31,7 @@ export default function ContextRoofAllocationSetting(props) {
handleSaveContext,
currentRoofList,
handleChangeInput,
+ handleChangePitch,
} = useRoofAllocationSetting(id)
const { findCommonCode } = useCommonCode()
@@ -45,114 +46,82 @@ export default function ContextRoofAllocationSetting(props) {
return (
-
- {getMessage('plan.menu.estimate.roof.alloc')}
- closePopup(id)}>
- 닫기
-
-
-
- {getMessage('modal.roof.alloc.info')}
-
- {getMessage('modal.roof.alloc.select.roof.material')}
-
- {
- // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
- setCurrentRoofMaterial(e)
- }}
- showKey={'roofMatlNm'}
- sourceKey={'roofMatlCd'}
- targetKey={'roofMatlCd'}
- />
+ {currentRoofList && (
+ <>
+
+ {getMessage('plan.menu.estimate.roof.alloc')}
+ closePopup(id)}>
+ 닫기
+
- {
- onAddRoofMaterial()
- }}
- >
-
- {getMessage('modal.common.add')}
-
-
-
- {currentRoofList.length > 0 &&
- currentRoofList.map((roof, index) => {
- return (
-
-
-
-
-
-
-
-
-
- handleChangeRoofMaterial(e, index)}
- />
-
- {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}}
- {index !== 0 && onDeleteRoofMaterial(index)}>}
+
+ {getMessage('modal.roof.alloc.info')}
+
+ {getMessage('modal.roof.alloc.select.roof.material')}
+
+ {
+ // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
+ setCurrentRoofMaterial(e)
+ }}
+ showKey={'roofMatlNm'}
+ sourceKey={'roofMatlCd'}
+ targetKey={'roofMatlCd'}
+ />
+
+ {
+ onAddRoofMaterial()
+ }}
+ >
+
+ {getMessage('modal.common.add')}
+
+
+
+
+ {currentRoofList.map((roof, index) => {
+ return (
+
+
+
+
-
-
-
- {getMessage('slope')}
-
- {
- handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
- }}
- defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
- />
-
- {pitchText}
-
-
- {(roof.widAuth || roof.lenAuth) && (
-
- {roof.widAuth && (
+
+
- W
-
-
+
+ handleChangeRoofMaterial(e, index)}
+ />
+ {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}}
+ {index !== 0 && (
+
+ onDeleteRoofMaterial(index)}>
+
+ )}
- )}
- {roof.lenAuth && (
-
- )}
-
- )}
- {(roof.raftAuth || roof.roofPchAuth) && (
-
+
{roof.raftAuth && (
{getMessage('modal.placement.initial.setting.rafter')}
{raftCodes.length > 0 && (
-
+
)}
+
+ {(roof.widAuth || roof.lenAuth) && (
+ <>
+ {roof.widAuth && (
+
+
+ W
+
+ {
+ handleChangeInput(e, 'width', index)
+ }}
+ />
+
+
+
+ )}
+ {roof.lenAuth && (
+
+
+ L
+
+ {
+ handleChangeInput(e, 'length', index)
+ }}
+ />
+
+
+
+ )}
+ >
+ )}
{roof.roofPchAuth && (
{getMessage('hajebichi')}
-
)}
-
- )}
-
-
- {
- handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index)
- }}
- >
- {getMessage('modal.roof.alloc.select.parallel')}
-
-
- {
- handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index)
- }}
- >
- {getMessage('modal.roof.alloc.select.stairs')}
-
+
+
+ {getMessage('slope')}
+
+ {
+ // handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
+ handleChangePitch(e, index)
+ }}
+ value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
+ defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
+ />
+
+ {pitchText}
+
+
+
+
+ {
+ handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index)
+ }}
+ >
+ {getMessage('modal.roof.alloc.select.parallel')}
+
+
+ {
+ handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index)
+ }}
+ >
+ {getMessage('modal.roof.alloc.select.stairs')}
+
+
+
-
-
- )
- })}
-
-
-
- {getMessage('modal.roof.alloc.apply')}
-
-
-
+ )
+ })}
+
+
+
+
+ {getMessage('modal.roof.alloc.apply')}
+
+
+
+ >
+ )}
diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
index 0142a329..acd2291c 100644
--- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
+++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
@@ -33,6 +33,7 @@ export default function RoofAllocationSetting(props) {
handleChangeLayout,
currentRoofList,
handleChangeInput,
+ handleChangePitch,
} = useRoofAllocationSetting(id)
const pitchText = useRecoilValue(pitchTextSelector)
const { findCommonCode } = useCommonCode()
@@ -99,7 +100,7 @@ export default function RoofAllocationSetting(props) {
-
+
handleChangeRoofMaterial(e, index)}
/>
- {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}}
- {index !== 0 && onDeleteRoofMaterial(index)}>}
+ {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}}
+ {index !== 0 && (
+
+ onDeleteRoofMaterial(index)}>
+
+ )}
-
-
- {getMessage('slope')}
-
- {
- handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
- }}
- defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
- />
-
- {pitchText}
-
-
- {(roof.widAuth || roof.lenAuth) && (
+
+ {roof.raftAuth && (
- {roof.widAuth && (
-
- W
-
- handleChangeInput(e, 'width', index)}
- readOnly={roof.widAuth === 'R'}
+
+ {getMessage('modal.placement.initial.setting.rafter')}
+ {raftCodes.length > 0 && (
+
+ handleChangeRaft(e, index)}
/>
-
- )}
- {roof.lenAuth && (
-
- L
-
- handleChangeInput(e, 'length', index)}
- readOnly={roof.lenAuth === 'R'}
- />
-
-
- )}
+ )}
+
)}
- {(roof.raftAuth || roof.roofPchAuth) && (
-
- {roof.raftAuth && (
+
+ {(roof.widAuth || roof.lenAuth) && (
+ <>
+ {roof.widAuth && (
- {getMessage('modal.placement.initial.setting.rafter')}
- {raftCodes.length > 0 && (
-
- handleChangeRaft(e, index)}
- />
-
- )}
-
-
- )}
- {roof.roofPchAuth && (
-
-
- {getMessage('hajebichi')}
-
+ W
+
handleChangeInput(e, 'hajebichi', index)}
- value={parseInt(roof.hajebichi)}
- readOnly={roof.roofPchAuth === 'R'}
+ defaultValue={roof.width}
+ onChange={(e) => handleChangeInput(e, 'width', index)}
+ readOnly={roof.widAuth === 'R'}
/>
)}
+ {roof.lenAuth && (
+
+
+ L
+
+ handleChangeInput(e, 'length', index)}
+ readOnly={roof.lenAuth === 'R'}
+ />
+
+
+
+ )}
+ >
+ )}
+ {roof.roofPchAuth && (
+
+
+ {getMessage('hajebichi')}
+
+ handleChangeInput(e, 'hajebichi', index)}
+ value={parseInt(roof.hajebichi)}
+ readOnly={roof.roofPchAuth === 'R'}
+ />
+
+
)}
+
+
+ {getMessage('slope')}
+
+ {
+ handleChangePitch(e, index)
+ }}
+ value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
+ defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
+ />
+
+ {pitchText}
+
+
- {hasSleeve}
diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx
index cfd9eea4..51a52cdb 100644
--- a/src/components/floor-plan/modal/setting01/FirstOption.jsx
+++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx
@@ -44,7 +44,7 @@ export default function FirstOption(props) {
const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
polygons.forEach((polygon) => {
- setSurfaceShapePattern(polygon, item.column)
+ setSurfaceShapePattern(polygon, item.column, false, polygon.roofMaterial, true, true)
})
//디스플레이 설정 표시(단 건 선택)
} else {
diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx
index 941c2d3e..f264edb2 100644
--- a/src/components/floor-plan/modal/setting01/SecondOption.jsx
+++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx
@@ -21,6 +21,7 @@ export default function SecondOption(props) {
const flowFont = useRecoilValue(fontSelector('flowText'))
const lengthFont = useRecoilValue(fontSelector('lengthText'))
const circuitNumberTextFont = useRecoilValue(fontSelector('circuitNumberText'))
+ const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText'))
const [dimensionId, setDimensionId] = useState(uuidv4())
const [fontId, setFontId] = useState(uuidv4())
const [planSizeId, setPlanSizeId] = useState(uuidv4())
@@ -103,12 +104,7 @@ export default function SecondOption(props) {
//치수선 설정
if (!showDimensionLineSettingModal) {
setShowDimensionLineSettingModal(true)
- fontProps.font = {
- fontFamily: '',
- fontWeight: '',
- fontSize: '',
- fontColor: '',
- }
+ fontProps.font = dimensionLineTextFont
addPopup(dimensionId, 2, , true)
} else {
setShowDimensionLineSettingModal(false)
diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx
index 323b332d..b0d99d2c 100644
--- a/src/components/main/ChangePasswordPop.jsx
+++ b/src/components/main/ChangePasswordPop.jsx
@@ -6,9 +6,12 @@ import { useRecoilValue, useRecoilState } from 'recoil'
import { useAxios } from '@/hooks/useAxios'
import { globalLocaleStore } from '@/store/localeAtom'
import { logout, setSession, login } from '@/lib/authActions'
+import { useSwal } from '@/hooks/useSwal'
+
export default function ChangePasswordPop(props) {
const globalLocaleState = useRecoilValue(globalLocaleStore)
+ const { swalFire } = useSwal()
const { patch } = useAxios(globalLocaleState)
const { getMessage } = useMessage()
const [sessionState, setSessionState] = useRecoilState(sessionStore)
@@ -22,7 +25,7 @@ export default function ChangePasswordPop(props) {
const form = { register, setValue, getValues, handleSubmit, resetField, control, watch }
- //자리수체크
+ //자리수체크 반각 10자리 입력하면 10 리턴
const checkLength = (pwd1) => {
let str = new String(pwd1)
let _byte = 0
@@ -55,22 +58,38 @@ export default function ChangePasswordPop(props) {
//비밀번호 미입력시
if (_password1.trim() === '') {
- alert(getMessage('main.popup.login.validate3'))
+ swalFire({
+ text: getMessage('main.popup.login.validate3'),
+ type: 'alert',
+ icon: 'error',
+ })
return false
}
if (_password2.trim() === '') {
- alert(getMessage('main.popup.login.validate3'))
+ swalFire({
+ text: getMessage('main.popup.login.validate3'),
+ type: 'alert',
+ icon: 'error',
+ })
return false
}
if (_password1 !== _password2) {
- alert(getMessage('main.popup.login.validate1'))
+ swalFire({
+ text: getMessage('main.popup.login.validate1'),
+ type: 'alert',
+ icon: 'error',
+ })
return false
}
- //패스워드 길이수 체크
+ //패스워드 길이수 체크 반각10
if (checkLength(_password1) > 10) {
- return alert(getMessage('main.popup.login.validate2'))
+ swalFire({
+ text: getMessage('main.popup.login.validate2'),
+ type: 'alert',
+ icon: 'error',
+ })
}
const param = {
@@ -83,12 +102,17 @@ export default function ChangePasswordPop(props) {
.then((res) => {
if (res?.result?.code === 200) {
if (res?.result?.resultCode === 'S') {
- alert(getMessage('main.popup.login.success'))
- const result = { ...sessionState, pwdInitYn: 'Y' }
- setSession(result)
- setSessionState(result)
- props.setChagePasswordPopOpen(false)
- login()
+ swalFire({
+ text: getMessage('main.popup.login.success'),
+ type: 'alert',
+ confirmFn: async () => {
+ const result = { ...sessionState, pwdInitYn: 'Y' }
+ setSession(result)
+ setSessionState(result)
+ props.setChagePasswordPopOpen(false)
+ await login()
+ },
+ })
} else {
alert(res?.result?.resultMsg)
}
@@ -130,6 +154,7 @@ export default function ChangePasswordPop(props) {
autoComplete="off"
onChange={checkValue}
onKeyUp={checkValue}
+ maxLength={10}
/>
@@ -150,6 +175,7 @@ export default function ChangePasswordPop(props) {
autoComplete="off"
onChange={checkValue}
onKeyUp={checkValue}
+ maxLength={10}
/>
diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx
index 3c1e184b..2985484e 100644
--- a/src/components/main/MainContents.jsx
+++ b/src/components/main/MainContents.jsx
@@ -14,10 +14,9 @@ import { useMainContentsController } from '@/hooks/main/useMainContentsControlle
import { QcastContext } from '@/app/QcastProvider'
import { useSwal } from '@/hooks/useSwal'
-import BoardDetailModal from '../community/modal/BoardDetailModal'
import { handleFileDown } from '@/util/board-utils'
-export default function MainContents() {
+export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) {
const { swalFire } = useSwal()
const { getMessage } = useMessage()
@@ -116,10 +115,6 @@ export default function MainContents() {
}
}
- // FAQ 팝업 관련
- const [open, setOpen] = useState(false)
- const [modalNoticeNo, setModalNoticeNo] = useState('')
-
return (
@@ -178,7 +173,6 @@ export default function MainContents() {
- {open && }
{recentFaqList.length > 0 ? (
@@ -192,8 +186,8 @@ export default function MainContents() {
className="faq-title pre"
style={{ cursor: 'pointer' }}
onClick={() => {
- setOpen(true)
- setModalNoticeNo(row.noticeNo)
+ setFaqOpen(true)
+ setFaqModalNoticeNo(row.noticeNo)
}}
>
{row.title}
diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx
index 2155331c..51154e92 100644
--- a/src/components/management/Stuff.jsx
+++ b/src/components/management/Stuff.jsx
@@ -149,7 +149,22 @@ export default function Stuff() {
cellStyle: { textAlign: 'left' },
},
{ field: 'saleStoreName', minWidth: 300, headerName: getMessage('stuff.gridHeader.saleStoreName'), cellStyle: { textAlign: 'left' } },
- { field: 'address', headerName: getMessage('stuff.gridHeader.address'), cellStyle: { textAlign: 'left' } },
+ {
+ field: 'address',
+ headerName: getMessage('stuff.gridHeader.address'),
+ cellStyle: { textAlign: 'left' },
+ cellRenderer: (params) => {
+ let prefName = params?.data?.prefName
+ let address = params?.data?.address
+ let showAddress
+ if (params?.data?.prefName && params?.data?.address) {
+ showAddress = prefName + ' ' + address
+ } else {
+ showAddress = null
+ }
+ return showAddress
+ },
+ },
{ field: 'dispCompanyName', headerName: getMessage('stuff.gridHeader.dispCompanyName'), cellStyle: { textAlign: 'left' } },
{ field: 'receiveUser', headerName: getMessage('stuff.gridHeader.receiveUser'), cellStyle: { textAlign: 'left' } },
{
@@ -215,8 +230,6 @@ export default function Stuff() {
startRow: (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1,
endRow: stuffSearchParams?.endRow,
schSaleStoreId: stuffSearchParams?.schMyDataCheck ? stuffSearchParams.schSaleStoreId : '',
- // schSelSaleStoreId: stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : '',
- // schOtherSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : '',
schSelSaleStoreId: stuffSearchParams?.schMyDataCheck ? '' : stuffSearchParams.schSelSaleStoreId,
schOtherSelSaleStoreId: stuffSearchParams?.schMyDataCheck ? '' : stuffSearchParams.schOtherSelSaleStoreId,
schSortType: stuffSearchParams.schSortType,
@@ -288,11 +301,6 @@ export default function Stuff() {
stuffSearchParams.schSaleStoreId = session.storeId
stuffSearchParams.schOtherSelSaleStoreId = ''
stuffSearchParams.schSelSaleStoreId = ''
- // if (session.storeLvl === '1') {
- // stuffSearchParams.schSaleStoreId = session.storeId
- // stuffSearchParams.schOtherSelSaleStoreId = ''
- // stuffSearchParams.schSelSaleStoreId = ''
- // }
}
async function fetchData() {
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx
index e4ef732c..e200da48 100644
--- a/src/components/management/StuffDetail.jsx
+++ b/src/components/management/StuffDetail.jsx
@@ -282,23 +282,26 @@ export default function StuffDetail() {
autoHeight: true,
cellStyle: { justifyContent: 'center' },
cellRenderer: (params) => {
- let buttonStyle
+ let buttonStyle = ''
+ let buttonStyle2 = ''
if (params.value == null) {
- buttonStyle = {
- display: 'none',
+ buttonStyle = 'none'
+ buttonStyle2 = 'none'
+ } else {
+ if (params?.data?.createSaleStoreId === 'T01') {
+ if (session?.storeId !== 'T01') {
+ buttonStyle = 'none'
+ }
}
- }
- if (managementState?.createUser === 'T01') {
- if (session.userId !== 'T01') {
- // #474
- buttonStyle = { display: 'none' }
+ if (params?.data?.tempFlg === '1') {
+ buttonStyle2 = 'none'
}
}
return (
<>
{
@@ -312,7 +315,7 @@ export default function StuffDetail() {
{getMessage('stuff.detail.planGrid.btn1')}
{
@@ -347,11 +350,8 @@ export default function StuffDetail() {
}
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
if (res.status === 200) {
- if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
- //createUser가 T01인데 로그인사용자가 T01이 아니면 버튼숨기기
- setShowButton('none')
- } else {
- if (session.userId !== res?.data?.createUser) {
+ if (res?.data?.createSaleStoreId === 'T01') {
+ if (session?.storeId !== 'T01') {
setShowButton('none')
}
}
@@ -362,8 +362,9 @@ export default function StuffDetail() {
} else if (res.data.surfaceType === 'Ⅱ') {
surfaceTypeValue = '2'
}
- setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue, firstFlag: 'Y' })
+ setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
} else {
+ setIsGlobalLoading(false)
setManagementState({})
swalFire({
text: getMessage('stuff.detail.header.notExistObjectNo'),
@@ -379,9 +380,9 @@ export default function StuffDetail() {
setPlanGridProps({ ...planGridProps, planGridData: [] })
}
} else {
+ setIsGlobalLoading(false)
setManagementState({})
setPlanGridProps({ ...planGridProps, planGridData: [] })
-
swalFire({
text: getMessage('stuff.detail.header.notExistObjectNo'),
type: 'alert',
@@ -409,11 +410,7 @@ export default function StuffDetail() {
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 {
- url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
- }
+ url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
}
get({ url: url }).then((res) => {
@@ -521,11 +518,7 @@ export default function StuffDetail() {
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 {
- url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
- }
+ url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
}
get({ url: url }).then((res) => {
if (!isEmptyArray(res)) {
@@ -1393,7 +1386,7 @@ export default function StuffDetail() {
//상세화면으로 전환
if (res.status === 201) {
setIsGlobalLoading(false)
- setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
+ setFloorPlanObjectNo({ floorPlanObjectNo: res?.data?.objectNo })
swalFire({
text: getMessage('stuff.detail.save'),
type: 'alert',
@@ -1420,7 +1413,14 @@ export default function StuffDetail() {
text: getMessage('stuff.detail.save'),
type: 'alert',
confirmFn: () => {
- callDetailApi(objectNo)
+ let surfaceTypeValue
+ if (res.data.surfaceType === 'Ⅲ・Ⅳ') {
+ surfaceTypeValue = '3'
+ } else if (res.data.surfaceType === 'Ⅱ') {
+ surfaceTypeValue = '2'
+ }
+ setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
+ router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
},
})
}
@@ -1432,25 +1432,6 @@ export default function StuffDetail() {
}
}
- const callDetailApi = async (objectNo) => {
- await promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
- if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
- setShowButton('none')
- } else {
- if (session.userId !== res?.data?.createUser) {
- setShowButton('none')
- }
- }
- let surfaceTypeValue
- if (res.data.surfaceType === 'Ⅲ・Ⅳ') {
- surfaceTypeValue = '3'
- } else {
- surfaceTypeValue = '2'
- }
- setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
- })
- }
-
// 임시저장
const onTempSave = async () => {
const formData = form.getValues()
@@ -1637,9 +1618,8 @@ export default function StuffDetail() {
// 그리드 더블 클릭 해당플랜의 도면작성 화면으로 이동
const getCellDoubleClicked = (params) => {
- //#474정책
- if (managementState.createUser === 'T01') {
- if (session.userId !== 'T01') {
+ if (managementState?.createSaleStoreId === 'T01') {
+ if (session?.storeId !== 'T01') {
return false
}
}
diff --git a/src/components/management/StuffHeader.jsx b/src/components/management/StuffHeader.jsx
index 5fd12414..d669ad7a 100644
--- a/src/components/management/StuffHeader.jsx
+++ b/src/components/management/StuffHeader.jsx
@@ -68,7 +68,7 @@ export default function StuffHeader() {
{getMessage('stuff.detail.header.specificationConfirmDate')}
- {managementState?.specificationConfirmDate ? `${dayjs(managementState.specificationConfirmDate).format('YYYY.MM.DD HH:mm:ss')}` : ''}
+ {managementState?.specificationConfirmDate ? `${dayjs(managementState.specificationConfirmDate).format('YYYY.MM.DD')}` : ''}
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx
index 19c26521..c5862641 100644
--- a/src/components/management/StuffSearchCondition.jsx
+++ b/src/components/management/StuffSearchCondition.jsx
@@ -56,7 +56,7 @@ export default function StuffSearchCondition() {
const [objectNo, setObjectNo] = useState('') //물건번호
const [saleStoreName, setSaleStoreName] = useState('') //판매대리점명
const [address, setAddress] = useState('') //물건주소
- const [objectName, setobjectName] = useState('') //물건명
+ const [objectName, setObjectName] = useState('') //물건명
const [dispCompanyName, setDispCompanyName] = useState('') //견적처
const [schSelSaleStoreId, setSchSelSaleStoreId] = useState('') //판매대리점 선택
const [receiveUser, setReceiveUser] = useState('') //담당자
@@ -96,8 +96,6 @@ export default function StuffSearchCondition() {
schAddress: address ? address.trim() : '',
schObjectName: objectName ? objectName.trim() : '',
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
- // schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
- // schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
schSaleStoreId: stuffSearch?.schMyDataCheck ? stuffSearch?.schSaleStoreId : '',
schSelSaleStoreId: stuffSearch?.schMyDataCheck ? '' : stuffSearch.schSelSaleStoreId,
schOtherSelSaleStoreId: stuffSearch?.schMyDataCheck ? '' : stuffSearch.schOtherSelSaleStoreId,
@@ -122,8 +120,8 @@ export default function StuffSearchCondition() {
schAddress: address ? address.trim() : '',
schObjectName: objectName ? objectName.trim() : '',
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
- schSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? '' : stuffSearch.schSelSaleStoreId,
- schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
+ schSelSaleStoreId: '',
+ schOtherSelSaleStoreId: otherSaleStoreId ? otherSaleStoreId : stuffSearch.schOtherSelSaleStoreId,
schReceiveUser: receiveUser ? receiveUser.trim() : '',
schDateType: dateType,
schTempFlg: tempFlg, //임시저장물건
@@ -144,8 +142,8 @@ export default function StuffSearchCondition() {
schAddress: address ? address.trim() : '',
schObjectName: objectName ? objectName.trim() : '',
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
- schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
- schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
+ schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : stuffSearch.schSelSaleStoreId,
+ schOtherSelSaleStoreId: otherSaleStoreId ? otherSaleStoreId : stuffSearch.schOtherSelSaleStoreId,
schReceiveUser: receiveUser ? receiveUser.trim() : '',
schDateType: dateType,
schTempFlg: tempFlg, //임시저장물건
@@ -183,28 +181,6 @@ export default function StuffSearchCondition() {
})
} else if (stuffSearch.code === 'E') {
if (session.storeId !== 'T01' && session.storeLvl === '1') {
- setStuffSearch({
- schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
- schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
- schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
- schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
- schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
- schSelSaleStoreId: myDataCheck ? schSelSaleStoreId : otherSaleStoreId ? schSelSaleStoreId : '',
- schOtherSelSaleStoreId: myDataCheck ? '' : otherSaleStoreId,
- schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
- schDateType: dateType,
- schTempFlg: tempFlg, //임시저장물건
- schMyDataCheck: myDataCheck,
- 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 : 'U',
- pageNo: stuffSearch?.pageNo,
- pageSize: stuffSearch?.pageSize,
- })
- } else if (session.storeId === 'T01') {
if (stuffSearch.pageNo !== 1) {
setStuffSearch({
schObjectNo: objectNo ? objectNo.trim() : stuffSearch.schObjectNo.trim(),
@@ -212,8 +188,8 @@ export default function StuffSearchCondition() {
schAddress: address ? address.trim() : '',
schObjectName: objectName ? objectName.trim() : '',
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
- schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
- schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
+ schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : stuffSearch.schSelSaleStoreId,
+ schOtherSelSaleStoreId: otherSaleStoreId ? otherSaleStoreId : stuffSearch.schOtherSelSaleStoreId,
schReceiveUser: receiveUser ? receiveUser.trim() : '',
schDateType: dateType,
schTempFlg: tempFlg, //임시저장물건
@@ -229,14 +205,60 @@ export default function StuffSearchCondition() {
})
} else {
setStuffSearch({
- schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
- schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
- schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
- schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
- schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
+ schObjectNo: objectNo ? objectNo.trim() : '',
+ schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
+ schAddress: address ? address.trim() : '',
+ schObjectName: objectName ? objectName.trim() : '',
+ schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
+ schSelSaleStoreId: myDataCheck ? '' : otherSaleStoreId ? '' : '',
+ schOtherSelSaleStoreId: myDataCheck ? '' : otherSaleStoreId,
+ schReceiveUser: receiveUser ? receiveUser.trim() : '',
+ schDateType: dateType,
+ schTempFlg: tempFlg, //임시저장물건
+ schMyDataCheck: myDataCheck,
+ 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 : 'U',
+ pageNo: stuffSearch?.pageNo,
+ pageSize: stuffSearch?.pageSize,
+ })
+ }
+ } else if (session.storeId === 'T01') {
+ if (stuffSearch.pageNo !== 1) {
+ setStuffSearch({
+ schObjectNo: objectNo ? objectNo.trim() : stuffSearch.schObjectNo.trim(),
+ schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
+ schAddress: address ? address.trim() : '',
+ schObjectName: objectName ? objectName.trim() : '',
+ schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
+ schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : stuffSearch.schSelSaleStoreId,
+ schOtherSelSaleStoreId: otherSaleStoreId ? otherSaleStoreId : stuffSearch.schOtherSelSaleStoreId,
+ schReceiveUser: receiveUser ? receiveUser.trim() : '',
+ schDateType: dateType,
+ schTempFlg: tempFlg, //임시저장물건
+ schMyDataCheck: myDataCheck,
+ 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: 'U',
+ pageNo: 1,
+ pageSize: stuffSearch?.pageSize,
+ })
+ } else {
+ setStuffSearch({
+ schObjectNo: objectNo ? objectNo.trim() : '',
+ schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
+ schAddress: address ? address.trim() : '',
+ schObjectName: objectName ? objectName.trim() : '',
+ schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
schSelSaleStoreId: schSelSaleStoreId,
schOtherSelSaleStoreId: otherSaleStoreId,
- schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
+ schReceiveUser: receiveUser ? receiveUser.trim() : '',
schDateType: dateType,
schTempFlg: tempFlg, //임시저장물건
schMyDataCheck: myDataCheck,
@@ -252,14 +274,15 @@ export default function StuffSearchCondition() {
}
} else {
setStuffSearch({
- schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
- schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
- schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
- schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
- schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
+ schObjectNo: objectNo ? objectNo.trim() : '',
+ schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
+ schAddress: address ? address.trim() : '',
+ schObjectName: objectName ? objectName.trim() : '',
+ schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
schSelSaleStoreId: schSelSaleStoreId,
schOtherSelSaleStoreId: otherSaleStoreId,
- schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
+ schReceiveUser: receiveUser ? receiveUser.trim() : '',
+
schDateType: dateType,
schTempFlg: tempFlg, //임시저장물건
schMyDataCheck: myDataCheck,
@@ -314,7 +337,7 @@ export default function StuffSearchCondition() {
stuffSearch.schSaleStoreId = ''
setObjectNo('')
setAddress('')
- setobjectName('')
+ setObjectName('')
setSaleStoreName('')
setReceiveUser('')
setDispCompanyName('')
@@ -452,12 +475,7 @@ export default function StuffSearchCondition() {
//T01일떄
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
} else {
- if (session.storeLvl === '1') {
- //T01아닌 1차점일때
- url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
- } else {
- url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
- }
+ url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
}
get({ url: url }).then((res) => {
@@ -600,7 +618,7 @@ export default function StuffSearchCondition() {
if (isObjectNotEmpty(key)) {
setOtherSaleStoreId('')
setSchSelSaleStoreId(key.saleStoreId)
- stuffSearch.schSelSaleStoreId = key.saleStoreId
+ // stuffSearch.schSelSaleStoreId = key.saleStoreId
//고른 1차점의 saleStoreId로 2차점 API호출하기
let url = `/api/object/saleStore/${key.saleStoreId}/list?firstFlg=0&userId=${session?.userId}`
let otherList
@@ -645,11 +663,11 @@ export default function StuffSearchCondition() {
stuffSearch.schMyDataCheck = false
if (isObjectNotEmpty(key)) {
setOtherSaleStoreId(key.saleStoreId)
- stuffSearch.schOtherSelSaleStoreId = key.saleStoreId
+ // stuffSearch.schOtherSelSaleStoreId = key.saleStoreId
//2차점 골랐을때 1차점 값
if (session.storeId === 'T01') {
- stuffSearch.schSelSaleStoreId = schSelSaleStoreId
+ // stuffSearch.schSelSaleStoreId = schSelSaleStoreId
} else {
stuffSearch.schSelSaleStoreId = ''
}
@@ -682,7 +700,7 @@ export default function StuffSearchCondition() {
setObjectNo('')
setSaleStoreName('')
setAddress('')
- setobjectName('')
+ setObjectName('')
setDispCompanyName('')
setReceiveUser('')
objectNoRef.current.value = ''
@@ -717,7 +735,7 @@ export default function StuffSearchCondition() {
setObjectNo('')
setSaleStoreName('')
setAddress('')
- setobjectName('')
+ setObjectName('')
setDispCompanyName('')
setReceiveUser('')
objectNoRef.current.value = ''
@@ -748,15 +766,6 @@ export default function StuffSearchCondition() {
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)
setTempFlg(stuffSearch.schTempFlg ? stuffSearch.schTempFlg : tempFlg)
setMyDataCheck(stuffSearch.schMyDataCheck)
}
@@ -775,7 +784,7 @@ export default function StuffSearchCondition() {
setObjectNo('')
setSaleStoreName('')
setAddress('')
- setobjectName('')
+ setObjectName('')
setDispCompanyName('')
setReceiveUser('')
objectNoRef.current.value = ''
@@ -806,7 +815,7 @@ export default function StuffSearchCondition() {
setObjectNo(stuffSearch.schObjectNo ? stuffSearch.schObjectNo : objectNo)
setSaleStoreName(stuffSearch.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName)
setAddress(stuffSearch.schAddress ? stuffSearch.schAddress : address)
- setobjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
+ setObjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName)
setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName)
setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser)
setDateType(stuffSearch.schDateType ? stuffSearch.schDateType : dateType)
@@ -987,7 +996,7 @@ export default function StuffSearchCondition() {
className="input-light"
defaultValue={stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo}
onChange={() => {
- stuffSearch.schObjectNo = objectNoRef.current.value
+ // stuffSearch.schObjectNo = objectNoRef.current.value
setObjectNo(objectNoRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
@@ -1003,7 +1012,7 @@ export default function StuffSearchCondition() {
className="input-light"
defaultValue={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
onChange={() => {
- stuffSearch.schSaleStoreName = saleStoreNameRef.current.value
+ // stuffSearch.schSaleStoreName = saleStoreNameRef.current.value
setSaleStoreName(saleStoreNameRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
@@ -1020,7 +1029,7 @@ export default function StuffSearchCondition() {
className="input-light"
defaultValue={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
onChange={() => {
- stuffSearch.schDispCompanyName = dispCompanyNameRef.current.value
+ // stuffSearch.schDispCompanyName = dispCompanyNameRef.current.value
setDispCompanyName(dispCompanyNameRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
@@ -1038,8 +1047,8 @@ export default function StuffSearchCondition() {
className="input-light"
defaultValue={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
onChange={() => {
- stuffSearch.schObjectName = objectNameRef.current.value
- setobjectName(objectNameRef.current.value)
+ // stuffSearch.schObjectName = objectNameRef.current.value
+ setObjectName(objectNameRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
/>
@@ -1054,7 +1063,7 @@ export default function StuffSearchCondition() {
ref={receiveUserRef}
defaultValue={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser}
onChange={() => {
- stuffSearch.schReceiveUser = receiveUserRef.current.value
+ // stuffSearch.schReceiveUser = receiveUserRef.current.value
setReceiveUser(receiveUserRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
@@ -1070,7 +1079,7 @@ export default function StuffSearchCondition() {
className="input-light"
defaultValue={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
onChange={() => {
- stuffSearch.schAddress = addressRef.current.value
+ // stuffSearch.schAddress = addressRef.current.value
setAddress(addressRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
@@ -1092,7 +1101,7 @@ export default function StuffSearchCondition() {
value={'U'}
onChange={(e) => {
setDateType(e.target.value)
- stuffSearch.schDateType = e.target.value
+ // stuffSearch.schDateType = e.target.value
}}
/>
@@ -1106,7 +1115,7 @@ export default function StuffSearchCondition() {
value={'R'}
onChange={(e) => {
setDateType(e.target.value)
- stuffSearch.schDateType = e.target.value
+ // stuffSearch.schDateType = e.target.value
}}
/>
@@ -1288,7 +1297,10 @@ export default function StuffSearchCondition() {
onChange={onSelectionChange2}
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
- isDisabled={otherSaleStoreList != null && otherSaleStoreList.length === 1 ? true : false}
+ // isDisabled={otherSaleStoreList != null && otherSaleStoreList.length === 1 ? true : false}
+ isDisabled={
+ session?.storeLvl === '1' ? (otherSaleStoreList.length > 0 ? false : true) : otherSaleStoreList.length === 1 ? true : false
+ }
isClearable={true}
value={otherSaleStoreList.filter(function (option) {
return option.saleStoreId === otherSaleStoreId
diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx
index 8e61e259..bb6f48b9 100644
--- a/src/components/management/StuffSubHeader.jsx
+++ b/src/components/management/StuffSubHeader.jsx
@@ -38,9 +38,8 @@ export default function StuffSubHeader({ type }) {
useEffect(() => {
if (isObjectNotEmpty(managementState)) {
- if (managementState.createUser === 'T01') {
- if (session.userId !== 'T01') {
- //도면 작성은 이동 할 수 있도록 변경 #457 다시 못하도록 변경#474
+ if (managementState?.createSaleStoreId === 'T01') {
+ if (session?.storeId !== 'T01') {
setButtonStyle('none')
}
}
diff --git a/src/components/simulator/Simulator.jsx b/src/components/simulator/Simulator.jsx
index 306b5365..f7f09969 100644
--- a/src/components/simulator/Simulator.jsx
+++ b/src/components/simulator/Simulator.jsx
@@ -176,7 +176,6 @@ export default function Simulator() {
const [content, setContent] = useState('')
const fetchSimulatorNotice = async () => {
- setIsGlobalLoading(true)
get({ url: '/api/pwrGnrSimulation/guideInfo' }).then((res) => {
if (res.data) {
setContent(res.data.replaceAll('\n', ' '))
@@ -184,7 +183,6 @@ export default function Simulator() {
setContent(getMessage('common.message.no.data'))
}
})
- setIsGlobalLoading(false)
}
// 차트 데이터 변경 시, list type 셋팅
diff --git a/src/hooks/common/useCanvasConfigInitialize.js b/src/hooks/common/useCanvasConfigInitialize.js
index c178bf75..089aeea9 100644
--- a/src/hooks/common/useCanvasConfigInitialize.js
+++ b/src/hooks/common/useCanvasConfigInitialize.js
@@ -25,24 +25,17 @@ export function useCanvasConfigInitialize() {
const {} = useRoof()
const { drawDirectionArrow } = usePolygon()
- useEffect(() => {
- if (!canvas) return
- canvas
- .getObjects()
- .filter((polygon) => polygon.name === 'roof')
- .forEach((polygon) => {
- setSurfaceShapePattern(polygon, roofDisplay.column)
- })
- canvas.renderAll()
- }, [roofDisplay])
-
useEffect(() => {
if (!canvas) return
const offsetTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
const flowTexts = canvas.getObjects().filter((obj) => obj.name === 'flowText')
if (basicSetting.roofAngleSet === 'slope') {
offsetTexts.forEach((obj) => {
- obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${angleUnit}` })
+ let text = `${!obj.originText ? '' : obj.originText}`
+ if (!obj.onlyOffset) {
+ text = text + `-∠${obj.pitch}${angleUnit}`
+ }
+ obj.set({ text: text })
})
flowTexts.forEach((obj) => {
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${obj.pitch}${pitchText}` })
@@ -51,7 +44,11 @@ export function useCanvasConfigInitialize() {
if (basicSetting.roofAngleSet === 'flat') {
offsetTexts.forEach((obj) => {
- obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${angleUnit}` })
+ let text = `${!obj.originText ? '' : obj.originText}`
+ if (!obj.onlyOffset) {
+ text = text + `-∠${getDegreeByChon(obj.pitch)}${angleUnit}`
+ }
+ obj.set({ text: text })
})
flowTexts.forEach((obj) => {
obj.set({ text: `${!obj.originText ? '' : obj.originText + '-'}∠${getDegreeByChon(obj.pitch)}${pitchText}` })
@@ -204,8 +201,8 @@ export function useCanvasConfigInitialize() {
.forEach((obj) => {
obj.set({
selectable: true,
- lockMovementX: false,
- lockMovementY: false,
+ lockMovementX: true,
+ lockMovementY: true,
})
obj.setViewLengthText(false)
})
diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js
index e4b2cc46..4757fbc0 100644
--- a/src/hooks/common/useCanvasPopupStatusController.js
+++ b/src/hooks/common/useCanvasPopupStatusController.js
@@ -1,78 +1,117 @@
'use client'
-import { useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import useSWR from 'swr'
import useSWRMutation from 'swr/mutation'
import { useAxios } from '../useAxios'
import { unescapeString } from '@/util/common-utils'
-import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
+import { moduleSelectionDataState, moduleSelectionTotalState } from '@/store/selectedModuleOptions'
import { compasDegAtom } from '@/store/orientationAtom'
-import { currentCanvasPlanState } from '@/store/canvasAtom'
+import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom'
+import { POLYGON_TYPE } from '@/common/common'
export function useCanvasPopupStatusController(param = 1) {
const popupType = parseInt(param)
const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom)
const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState)
- const { getFetcher, postFetcher } = useAxios()
-
+ const { get, getFetcher, postFetcher } = useAxios()
+ const canvas = useRecoilValue(canvasState)
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
// console.log('🚀 ~ Orientation ~ currentCanvasPlan:', currentCanvasPlan)
- const {
- data: popupStatus,
- error,
- isLoading,
- } = useSWR(
- popupType ? `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupType}` : null,
- getFetcher,
- )
+ /**
+ * 팝업 상태 조회
+ * @param {number} popupTypeParam
+ * @returns
+ */
+ const getModuleSelection = async (popupTypeParam) => {
+ // const {
+ // data: popupStatus,
+ // error,
+ // isLoading,
+ // } = useSWR(
+ // `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupTypeParam}`,
+ // getFetcher,
+ // )
- useEffect(() => {
- // console.log('🚀 ~ useEffect ~ popupStatus:', popupStatus)
- if (popupStatus) {
- switch (parseInt(popupStatus?.popupType)) {
- case 1:
- setCompasDeg(popupStatus.popupStatus)
- break
- case 2:
- setModuleSelectionDataStore(JSON.parse(unescapeString(popupStatus.popupStatus)))
- break
- case 3:
- break
- case 4:
- break
- case 5:
- break
- case 6:
- break
- default:
- }
- } else {
- switch (popupType) {
- case 1:
- setCompasDeg(0)
- break
- case 2:
- setModuleSelectionDataStore({
- common: {},
- roofConstructions: [],
- })
- break
- case 3:
- break
- case 4:
- break
- case 5:
- break
- case 6:
- break
- default:
+ const res = await get({
+ url: `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupTypeParam}`,
+ })
+
+ return res
+ }
+
+ /**
+ * 전체 팝업 상태 조회
+ * 조회 후 전체 데이터 recoil에 저장
+ */
+ const handleModuleSelectionTotal = async () => {
+ for (let i = 1; i < 3; i++) {
+ const result = await getModuleSelection(i)
+ // setModuleSelectionTotal((prev) => ({ ...prev, [i]: JSON.parse(unescapeString(result.popupStatus)) }))
+ if(!result) return
+ if (i === 1) {
+ setCompasDeg(result.popupStatus)
+ } else if (i === 2) {
+ const data = JSON.parse(unescapeString(result.popupStatus))
+ setModuleSelectionDataStore(data)
+
+ const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+ roofSurfaceList.forEach((surface) => {
+ surface.modules = modules.filter((module) => module.surfaceId === surface.id)
+ })
}
}
- }, [popupStatus])
+ }
+ // useEffect(() => {
+ // if (popupStatus) {
+ // switch (parseInt(popupStatus?.popupType)) {
+ // case 1:
+ // setCompasDeg(popupStatus.popupStatus)
+ // break
+ // case 2:
+ // setModuleSelectionDataStore(JSON.parse(unescapeString(popupStatus.popupStatus)))
+ // break
+ // case 3:
+ // break
+ // case 4:
+ // break
+ // case 5:
+ // break
+ // case 6:
+ // break
+ // default:
+ // }
+ // } else {
+ // switch (popupType) {
+ // case 1:
+ // setCompasDeg(0)
+ // break
+ // case 2:
+ // setModuleSelectionDataStore({
+ // common: {},
+ // roofConstructions: [],
+ // })
+ // break
+ // case 3:
+ // break
+ // case 4:
+ // break
+ // case 5:
+ // break
+ // case 6:
+ // break
+ // default:
+ // }
+ // }
+ // }, [popupStatus])
+
+ /**
+ * 팝업 상태 저장
+ */
const { trigger, isMutating } = useSWRMutation(
`/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupType}`,
(url, { arg }) => {
@@ -86,5 +125,5 @@ export function useCanvasPopupStatusController(param = 1) {
},
)
- return { trigger }
+ return { handleModuleSelectionTotal, trigger }
}
diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js
index 22694c4d..baaa7dfe 100644
--- a/src/hooks/common/useCommonUtils.js
+++ b/src/hooks/common/useCommonUtils.js
@@ -9,6 +9,7 @@ import { canvasState } from '@/store/canvasAtom'
import { v4 as uuidv4 } from 'uuid'
import { usePopup } from '@/hooks/usePopup'
import Distance from '@/components/floor-plan/modal/distance/Distance'
+import { usePolygon } from '@/hooks/usePolygon'
export function useCommonUtils() {
const canvas = useRecoilValue(canvasState)
@@ -20,6 +21,7 @@ export function useCommonUtils() {
const commonTextFont = useRecoilValue(fontSelector('commonText'))
const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState)
const { addPopup } = usePopup()
+ const { drawDirectionArrow, addLengthText } = usePolygon()
useEffect(() => {
// initEvent()
@@ -608,6 +610,16 @@ export function useCommonUtils() {
//객체가 그룹일 경우에는 그룹 아이디를 따로 넣어준다
if (clonedObj.type === 'group') clonedObj.set({ groupId: uuidv4() })
+ //배치면일 경우
+ if (obj.name === 'roof') {
+ clonedObj.setCoords()
+ clonedObj.fire('polygonMoved')
+ clonedObj.set({ direction: obj.direction, directionText: obj.directionText })
+ canvas.renderAll()
+ addLengthText(clonedObj) //수치 추가
+ drawDirectionArrow(clonedObj) //방향 화살표 추가
+ }
+
initEvent()
})
}
diff --git a/src/hooks/common/useGrid.js b/src/hooks/common/useGrid.js
index abd2a6e0..29a5edea 100644
--- a/src/hooks/common/useGrid.js
+++ b/src/hooks/common/useGrid.js
@@ -71,10 +71,10 @@ export function useGrid() {
const backgroundPolygon = new fabric.Polygon(
[
- { x: 0, y: 0 },
- { x: canvas.width, y: 0 },
- { x: canvas.width, y: canvas.height },
- { x: 0, y: canvas.height },
+ { x: -1500, y: -1500 },
+ { x: 2500, y: -1500 },
+ { x: 2500, y: 2500 },
+ { x: -1500, y: 2500 },
],
{
fill: pattern,
@@ -90,9 +90,14 @@ export function useGrid() {
}
if (patternData.lineGridDisplay) {
- for (let i = 0; i < canvas.height / patternData.gridVertical + 1; i++) {
+ for (let i = 0; i < 5000 / patternData.gridVertical + 1; i++) {
const horizontalLine = new fabric.Line(
- [0, i * patternData.gridVertical - patternData.gridVertical / 2, canvas.width, i * patternData.gridVertical - patternData.gridVertical / 2],
+ [
+ -1500,
+ -1500 + i * patternData.gridVertical - patternData.gridVertical / 2,
+ 3000,
+ -1500 + i * patternData.gridVertical - patternData.gridVertical / 2,
+ ],
{
stroke: gridColor,
strokeWidth: 1,
@@ -113,9 +118,14 @@ export function useGrid() {
canvas.add(horizontalLine)
}
- for (let i = 0; i < canvas.width / patternData.gridHorizon + 1; i++) {
+ for (let i = 0; i < 5000 / patternData.gridHorizon + 1; i++) {
const verticalLine = new fabric.Line(
- [i * patternData.gridHorizon - patternData.gridHorizon / 2, 0, i * patternData.gridHorizon - patternData.gridHorizon / 2, canvas.height],
+ [
+ -1500 + i * patternData.gridHorizon - patternData.gridHorizon / 2,
+ -1500,
+ -1500 + i * patternData.gridHorizon - patternData.gridHorizon / 2,
+ 3000,
+ ],
{
stroke: gridColor,
strokeWidth: 1,
diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js
index b090df81..e1c37915 100644
--- a/src/hooks/common/useMasterController.js
+++ b/src/hooks/common/useMasterController.js
@@ -137,16 +137,6 @@ export function useMasterController() {
* @returns
*/
const getPcsModelList = async (params = null) => {
- const test = {
- pcsMkrCd: 'MKR003',
- pcsSerList: [{ pcsSerCd: 'SER007' }, { pcsSerCd: 'SER009' }, { pcsSerCd: 'SER010' }],
- moduleItemList: [
- { itemId: '107015', mixMatlNo: null },
- { itemId: '107077', mixMatlNo: null },
- { itemId: '107015', mixMatlNo: null },
- ],
- }
-
return await post({ url: '/api/v1/master/getPcsSeriesItemList', data: params }).then((res) => {
return res
})
@@ -201,13 +191,22 @@ export function useMasterController() {
* @returns
*/
const getPcsVoltageStepUpList = async (params2 = null) => {
+ // roofSurfaceList의 moduleList에서 circuit 속성을 제외
+ const modifiedRoofSurfaceList = params2.roofSurfaceList.map((surface) => ({
+ ...surface,
+ moduleList: surface.moduleList.map((module) => ({
+ itemId: module.itemId,
+ uniqueId: module.uniqueId,
+ })),
+ }))
+
const params = {
...params2,
- maxConnYn: params2.useYn.maxConnYn,
- smpCirYn: params2.useYn.smpCirYn,
- coldZoneYn: params2.useYn.coldZoneYn,
+ maxConnYn: params2.maxConnYn,
+ smpCirYn: params2.smpCirYn,
+ coldZoneYn: params2.coldZoneYn,
useModuleItemList: params2.useModuleItemList,
- roofSurfaceList: params2.roofSurfaceList,
+ roofSurfaceList: modifiedRoofSurfaceList,
pcsItemList: params2.pcsItemList,
}
@@ -229,8 +228,18 @@ export function useMasterController() {
* @returns
*/
const updateObjectDate = async (params = null) => {
- return await put({ url: '/api/object/update-object-date', data: params }).then((res) => {
- console.log('updateObjectDate', res)
+ return await put({ url: '/api/object/update-object-date', data: params })
+ }
+
+ /**
+ * PCS 접속함 및 옵션 목록 조회
+ * @param {사용된 모듈 아이템 목록} useModuleItemList
+ * @param {PCS 제품 목록} pcsItemList
+ * @returns
+ */
+ const getPcsConnOptionItemList = async (params = null) => {
+ return await post({ url: '/api/v1/master/getPcsConnOptionItemList', data: params }).then((res) => {
+ return res
})
}
@@ -248,5 +257,6 @@ export function useMasterController() {
getPcsVoltageStepUpList,
updateObjectDate,
getQuotationItem,
+ getPcsConnOptionItemList,
}
}
diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js
index c0a4e1d5..5eadcf18 100644
--- a/src/hooks/common/useMenu.js
+++ b/src/hooks/common/useMenu.js
@@ -19,6 +19,7 @@ import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { useRecoilValue } from 'recoil'
import { currentMenuState } from '@/store/canvasAtom'
import { MENU } from '@/common/common'
+import { useTrestle } from '@/hooks/module/useTrestle'
export default function useMenu() {
const menus = []
@@ -26,6 +27,7 @@ export default function useMenu() {
const [popupId, setPopupId] = useState(uuidv4())
const { addPopup } = usePopup()
const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({})
+ const { clear: trestleClear } = useTrestle()
const handleMenu = (type) => {
if (type === 'outline') {
switch (currentMenu) {
@@ -79,6 +81,7 @@ export default function useMenu() {
if (type === 'module') {
switch (currentMenu) {
case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING:
+ trestleClear()
addPopup(popupId, 1, )
break
case MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING:
diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js
index bb079bc7..106154fe 100644
--- a/src/hooks/common/useRefFiles.js
+++ b/src/hooks/common/useRefFiles.js
@@ -15,8 +15,8 @@ export function useRefFiles() {
const [currentBgImage, setCurrentBgImage] = useState(null)
const queryRef = useRef(null)
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
- const canvas = useRecoilValue(canvasState)
- const { handleBackImageLoadToCanvas } = useCanvas()
+ // const canvas = useRecoilValue(canvasState)
+ const { canvas, handleBackImageLoadToCanvas } = useCanvas()
const { swalFire } = useSwal()
const { get, post, promisePost } = useAxios()
@@ -66,15 +66,20 @@ export function useRefFiles() {
}
const refFileSetting = (file) => {
- if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
- // setRefImage(file)
- file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file)
+ console.log('🚀 ~ refFileSetting ~ file:', file)
+ if (file.name.split('.').pop() === 'dwg') {
+ handleUploadConvertRefFile(file)
} else {
- swalFire({
- text: '이미지가 아닙니다.',
- type: 'alert',
- icon: 'error',
- })
+ if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
+ // file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file)
+ handleUploadImageRefFile(file)
+ } else {
+ swalFire({
+ text: '이미지가 아닙니다.',
+ type: 'alert',
+ icon: 'error',
+ })
+ }
}
}
/**
@@ -121,23 +126,30 @@ export function useRefFiles() {
}
const res = await get({
- url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
+ url: `${process.env.NEXT_PUBLIC_HOST_URL}/map/convert?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
})
console.log('🚀 ~ handleMapImageDown ~ res:', res)
- const file = await readImage(res.fileNm)
- console.log('🚀 ~ handleMapImageDown ~ file:', file)
- setCurrentBgImage(file)
- // handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`)
- // setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value }))
+ // const file = await readImage(res.fileNm)
+ // console.log('🚀 ~ handleMapImageDown ~ file:', file)
+ // setCurrentBgImage(file)
+ setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
}
+ /**
+ * 배경 이미지 로드를 위한 세팅
+ */
useEffect(() => {
if (!currentBgImage) {
return
}
console.log('🚀 ~ useEffect ~ currentBgImage:', currentBgImage)
- handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`)
- setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: refImage?.name ?? null, mapPositionAddress: queryRef.current.value }))
+ // handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`)
+ handleBackImageLoadToCanvas(currentBgImage)
+ setCurrentCanvasPlan((prev) => ({
+ ...prev,
+ bgImageName: refImage?.name ?? null,
+ mapPositionAddress: queryRef.current.value,
+ }))
}, [currentBgImage])
/**
@@ -147,15 +159,17 @@ export function useRefFiles() {
const handleUploadImageRefFile = async (file) => {
const formData = new FormData()
formData.append('file', file)
- formData.append('fileName', currentCanvasPlan.id)
+ // formData.append('fileName', currentCanvasPlan.id)
// const res = await post({ url: `${process.env.NEXT_PUBLIC_API_SERVER_PATH}/api/image-upload`, data: formData })
- const res = await post({ url: `http://localhost:3000/api/image-upload`, data: formData })
+ const res = await post({
+ url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/upload`,
+ data: formData,
+ })
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
- const image = await readImage(res.fileNm)
- console.log('🚀 ~ handleUploadImageRefFile ~ file:', image)
-
- setCurrentBgImage(image)
+ // const image = await readImage(res.filePath)
+ // console.log('🚀 ~ handleUploadImageRefFile ~ file:', image)
+ setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
setRefImage(file)
}
@@ -167,15 +181,24 @@ export function useRefFiles() {
const formData = new FormData()
formData.append('file', file)
- await promisePost({ url: converterUrl, data: formData })
- .then((res) => {
- convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData)
- swalFire({ text: '파일 변환 성공' })
- setRefImage(res.data.Files[0].FileData)
- })
- .catch((err) => {
- swalFire({ text: '파일 변환 실패', icon: 'error' })
- })
+ const res = await post({ url: converterUrl, data: formData })
+ console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
+ const result = await post({
+ url: `${process.env.NEXT_PUBLIC_HOST_URL}/cad/convert`,
+ data: res,
+ })
+ console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
+ setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${result.filePath}`)
+ setRefImage(res.Files[0].FileData)
+ // await promisePost({ url: converterUrl, data: formData })
+ // .then((res) => {
+ // convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData)
+ // swalFire({ text: '파일 변환 성공' })
+ // setRefImage(res.data.Files[0].FileData)
+ // })
+ // .catch((err) => {
+ // swalFire({ text: '파일 변환 실패', icon: 'error' })
+ // })
}
/**
diff --git a/src/hooks/common/useRoof.js b/src/hooks/common/useRoof.js
index 0b5e5a6b..14407aa9 100644
--- a/src/hooks/common/useRoof.js
+++ b/src/hooks/common/useRoof.js
@@ -16,7 +16,9 @@ export function useRoof() {
.filter((polygon) => polygon.name === 'roof')
.forEach((polygon) => {
if (allocDisplay) {
- setSurfaceShapePattern(polygon, roofDisplay.column)
+ if (polygon.roofMaterial) {
+ setSurfaceShapePattern(polygon, roofDisplay.column, false, polygon.roofMaterial, true)
+ }
} else {
polygon.set('fill', null)
}
diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js
index eaaebf0c..54ebaecb 100644
--- a/src/hooks/common/useRoofFn.js
+++ b/src/hooks/common/useRoofFn.js
@@ -1,10 +1,11 @@
-import { useRecoilValue } from 'recoil'
+import { useRecoilValue, useResetRecoilState } from 'recoil'
import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
import { POLYGON_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent'
import { useLine } from '@/hooks/useLine'
+import { outerLinePointsState } from '@/store/outerLineAtom'
const ROOF_COLOR = {
0: 'rgb(199,240,213)',
@@ -17,22 +18,27 @@ export function useRoofFn() {
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
const currentObject = useRecoilValue(currentObjectState)
const { addCanvasMouseEventListener, initEvent } = useEvent()
+ const resetPoints = useResetRecoilState(outerLinePointsState)
const { addPitchText } = useLine()
//면형상 선택 클릭시 지붕 패턴 입히기
- function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial, isForceChange = false) {
+ function setSurfaceShapePattern(
+ polygon,
+ mode = 'onlyBorder',
+ trestleMode = false,
+ roofMaterial = selectedRoofMaterial,
+ isForceChange = false,
+ isDisplay = false,
+ ) {
if (!polygon) {
return
}
- if (isForceChange) {
- if (polygon.roofMaterial) {
+ if (isForceChange && !isDisplay) {
+ /*if (polygon.roofMaterial) {
polygon.roofMaterial = null
- }
+ }*/
}
- if (polygon.roofMaterial) {
- return
- }
const ratio = window.devicePixelRatio || 1
const layout = roofMaterial.layout
@@ -303,5 +309,33 @@ export function useRoofFn() {
return area.points.map((p) => fabric.util.transformPoint({ x: p.x - area.pathOffset.x, y: p.y - area.pathOffset.y }, area.calcTransformMatrix()))
}
- return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial }
+ const removeOuterLines = (currentMousePos) => {
+ const roofBase = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+ .filter((roof) => roof.inPolygon(currentMousePos))
+
+ if (roofBase.length === 0) {
+ return
+ }
+
+ const roof = roofBase[0]
+ const wall = roof.wall
+
+ canvas.remove(roof)
+ canvas.remove(wall)
+
+ const allRoofObject = canvas
+ .getObjects()
+ .filter((obj) => /*obj !== roof && obj !== wall &&*/ obj.attributes?.roofId === roof.id || obj.parentId === roof.id || obj.parentId === wall.id)
+
+ allRoofObject.forEach((obj) => {
+ canvas.remove(obj)
+ })
+
+ canvas.renderAll()
+ resetPoints()
+ }
+
+ return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines }
}
diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js
index ebd1ad88..c87e77de 100644
--- a/src/hooks/floorPlan/estimate/useEstimateController.js
+++ b/src/hooks/floorPlan/estimate/useEstimateController.js
@@ -80,7 +80,6 @@ export const useEstimateController = (planNo) => {
res.data.pkgAsp = roundedNumber.toString()
}
-
setEstimateContextState(res.data)
}
}
@@ -155,7 +154,7 @@ export const useEstimateController = (planNo) => {
})
.catch((error) => {
console.log('::FileDownLoad Error::', error)
- alert('File does not exist.')
+ return swalFire({ text: getMessage('File does not exist'), type: 'alert' })
})
}
@@ -169,19 +168,19 @@ export const useEstimateController = (planNo) => {
if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) {
flag = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredCharger'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert' })
}
if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) {
flag = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredObjectName'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert' })
}
if (isNaN(Date.parse(estimateData.estimateDate))) {
flag = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredEstimateDate'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert' })
}
if (estimateData.estimateType === 'YJSS') {
@@ -189,7 +188,7 @@ export const useEstimateController = (planNo) => {
if (pkgAsp === '0') {
flag = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredPkgAsp'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert' })
}
}
@@ -209,6 +208,16 @@ export const useEstimateController = (planNo) => {
//기존에 첨부된 파일이 없으면
if (isEmptyArray(estimateData.newFileList)) {
//새로 첨부한 파일이 없으면
+
+ //북면 먼저 체크
+ if (estimateData.fileFlg === '0') {
+ if (estimateData?.northArrangement === '1') {
+ fileFlg = false
+ setIsGlobalLoading(false)
+ return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert' })
+ }
+ }
+
if (estimateData.itemList.length > 1) {
estimateData.itemList.map((row) => {
if (row.delFlg === '0') {
@@ -217,7 +226,7 @@ export const useEstimateController = (planNo) => {
if (estimateData.fileFlg === '0') {
fileFlg = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredFileUpload'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert' })
}
}
}
@@ -235,7 +244,7 @@ export const useEstimateController = (planNo) => {
if (item.itemId === '') {
itemFlg = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredItemId'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert' })
}
}
@@ -251,7 +260,7 @@ export const useEstimateController = (planNo) => {
if (item.amount < 1) {
itemFlg = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredAmount'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert' })
}
if (estimateData.estimateType !== 'YJSS') {
@@ -263,7 +272,7 @@ export const useEstimateController = (planNo) => {
if (item.salePrice < 1) {
itemFlg = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredSalePrice'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
}
}
@@ -274,7 +283,7 @@ export const useEstimateController = (planNo) => {
if (isNaN(item.salePrice)) {
itemFlg = false
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredSalePrice'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
}
}
}
@@ -292,7 +301,7 @@ export const useEstimateController = (planNo) => {
})
if (delCnt === estimateData.itemList.length) {
setIsGlobalLoading(false)
- return alert(getMessage('estimate.detail.save.requiredItem'))
+ return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert' })
}
}
@@ -401,11 +410,19 @@ export const useEstimateController = (planNo) => {
*/
const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId) => {
if (saleStoreId === '') {
- return alert(getMessage('estimate.detail.productFeaturesPopup.requiredStoreId'))
+ return swalFire({
+ text: getMessage('estimate.detail.productFeaturesPopup.requiredStoreId'),
+ type: 'alert',
+ icon: 'warning',
+ })
}
if (copyReceiveUser.trim().length === 0) {
- return alert(getMessage('estimate.detail.productFeaturesPopup.requiredReceiveUser'))
+ return swalFire({
+ text: getMessage('estimate.detail.productFeaturesPopup.requiredReceiveUser'),
+ type: 'alert',
+ icon: 'warning',
+ })
}
const params = {
saleStoreId: session.storeId,
diff --git a/src/hooks/floorPlan/useImgLoader.js b/src/hooks/floorPlan/useImgLoader.js
new file mode 100644
index 00000000..ceced3be
--- /dev/null
+++ b/src/hooks/floorPlan/useImgLoader.js
@@ -0,0 +1,80 @@
+import { useRecoilValue } from 'recoil'
+import { canvasState } from '@/store/canvasAtom'
+import { useCanvas } from '../useCanvas'
+import { useAxios } from '../useAxios'
+import { usePlan } from '../usePlan'
+import { POLYGON_TYPE } from '@/common/common'
+
+/**
+ * 이미지 로더 hook
+ * @returns {function} handleCanvasToPng
+ */
+export function useImgLoader() {
+ const canvas = useRecoilValue(canvasState)
+ const { currentCanvasPlan } = usePlan()
+ const { post } = useAxios()
+
+ /**
+ * 이미지 저장 시 왼쪽 위, 오른쪽 아래 좌표
+ * return [start, end]
+ */
+ const getImageCoordinates = () => {
+ const margin = 20
+
+ const objects = canvas.getObjects().filter((obj) => [POLYGON_TYPE.ROOF, 'lengthText', 'arrow'].includes(obj.name))
+
+ const minX = objects.reduce((acc, cur) => (cur.left < acc ? cur.left : acc), objects[0].left)
+ const minY = objects.reduce((acc, cur) => (cur.top < acc ? cur.top : acc), objects[0].top)
+
+ const maxX = objects.reduce((acc, cur) => (cur.left + cur.width > acc ? cur.left + cur.width : acc), 0)
+ const maxY = objects.reduce((acc, cur) => (cur.top + cur.height > acc ? cur.top + cur.height : acc), 0)
+ return [
+ { x: minX - margin, y: minY - margin },
+ { x: maxX + margin, y: maxY + margin },
+ ]
+ }
+
+ /**
+ * 캔버스를 이미지로 저장
+ * @param {integer} type 1: 모듈만 있는 상태, 2: 가대까지 올린 상태
+ */
+ const handleCanvasToPng = async (type) => {
+ removeMouseLines()
+
+ canvas.getObjects('image').forEach((obj) => {
+ if (obj.getSrc) {
+ const img = new Image()
+ img.crossOrigin = 'anonymous'
+ img.src = obj.getSrc()
+ obj.setElement(img)
+ }
+ })
+
+ canvas.renderAll()
+
+ const res = await post({
+ url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`,
+ data: {
+ objectNo: currentCanvasPlan.objectNo,
+ planNo: currentCanvasPlan.planNo,
+ type,
+ canvasToPng: canvas.toDataURL('image/png').replace('data:image/png;base64,', ''),
+ coordinates: getImageCoordinates(),
+ },
+ })
+ console.log('🚀 ~ handleCanvasToPng ~ res:', res)
+ }
+
+ /**
+ * 마우스 포인터의 가이드라인을 제거합니다.
+ */
+ const removeMouseLines = () => {
+ if (canvas?._objects.length > 0) {
+ const mouseLines = canvas?._objects.filter((obj) => obj.name === 'mouseLine')
+ mouseLines.forEach((item) => canvas?.remove(item))
+ }
+ canvas?.renderAll()
+ }
+
+ return { handleCanvasToPng }
+}
diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js
index de64c404..bd462b5e 100644
--- a/src/hooks/module/useModule.js
+++ b/src/hooks/module/useModule.js
@@ -1,12 +1,15 @@
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
import { canvasState } from '@/store/canvasAtom'
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
-import { useRecoilValue } from 'recoil'
+import { useRecoilValue, useSetRecoilState } from 'recoil'
import { v4 as uuidv4 } from 'uuid'
import * as turf from '@turf/turf'
import { useSwal } from '../useSwal'
import { useModuleBasicSetting } from './useModuleBasicSetting'
import { useMessage } from '../useMessage'
+import { selectedModuleState } from '@/store/selectedModuleOptions'
+import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
+import { useCircuitTrestle } from '../useCirCuitTrestle'
export const MODULE_REMOVE_TYPE = {
LEFT: 'left',
@@ -35,6 +38,8 @@ export function useModule() {
const { swalFire } = useSwal()
const { getMessage } = useMessage()
const { checkModuleDisjointObjects } = useModuleBasicSetting()
+ const selectedModules = useRecoilValue(selectedModuleState)
+ const { setModuleStatisticsData } = useCircuitTrestle()
const moduleMove = (length, direction) => {
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
@@ -42,6 +47,7 @@ export function useModule() {
canvas.discardActiveObject() //선택해제
+ debugger
const isSetupModules = getOtherModules(selectedObj)
const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
const setupSurface = canvas
@@ -141,104 +147,113 @@ export function useModule() {
}
}
- const moduleMoveAll = (length, direction) => {
- const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
- const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
- const objects = getObjects()
+ const moduleMoveAll = (length, direction, surfaceArray) => {
+ surfaceArray.forEach((surface) => {
+ const modules = canvas
+ .getObjects()
+ .filter((module) => module.name === POLYGON_TYPE.MODULE)
+ .filter((module) => module.surfaceId === surface.id)
+ const objects = getObjects()
- let isWarning = false
+ let isWarning = false
- modules.forEach((module) => {
- const { top, left } = getPosotion(module, direction, length, false)
- module.originPos = {
- top: module.top,
- left: module.left,
- fill: module.fill,
- }
+ modules.forEach((module) => {
+ const { top, left } = getPosotion(module, direction, length, false)
+ module.originPos = {
+ top: module.top,
+ left: module.left,
+ fill: module.fill,
+ }
+
+ module.set({ top, left })
+ module.setCoords()
+ canvas.renderAll()
+
+ if (isOverlapObjects(module, objects) || isOutsideSurface(module, surface)) {
+ isWarning = true
+ module.set({ fill: 'red' })
+ }
+ })
- module.set({ top, left })
- module.setCoords()
canvas.renderAll()
-
- if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
- isWarning = true
- module.set({ fill: 'red' })
+ if (isWarning) {
+ swalFire({
+ title: getMessage('can.not.move.module'),
+ icon: 'error',
+ type: 'alert',
+ confirmFn: () => {
+ modules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
+ module.setCoords()
+ })
+ canvas.renderAll()
+ },
+ })
}
})
-
- canvas.renderAll()
- if (isWarning) {
- swalFire({
- title: getMessage('can.not.move.module'),
- icon: 'error',
- type: 'alert',
- confirmFn: () => {
- modules.forEach((module) => {
- module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
- module.setCoords()
- })
- canvas.renderAll()
- },
- })
- }
}
- const moduleCopyAll = (length, direction) => {
- const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
- const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
- const objects = getObjects()
- const copyModules = []
- let copyModule = null
- let isWarning = false
- let moduleLength = 0
- if (['up', 'down'].includes(direction)) {
- modules.sort((a, b) => a.top - b.top)
- moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
- } else if (['left', 'right'].includes(direction)) {
- modules.sort((a, b) => a.left - b.left)
- moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
- }
+ const moduleCopyAll = (length, direction, surfaceArray) => {
+ surfaceArray.forEach((surface) => {
+ const modules = canvas
+ .getObjects()
+ .filter((module) => module.name === POLYGON_TYPE.MODULE)
+ .filter((module) => module.surfaceId === surface.id)
+ const objects = getObjects()
+ const copyModules = []
- modules.forEach((module) => {
- const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
- module.clone((obj) => {
- obj.set({
- parentId: module.parentId,
- initOptions: module.initOptions,
- direction: module.direction,
- arrow: module.arrow,
- name: module.name,
- type: module.type,
- length: module.length,
- points: module.points,
- surfaceId: module.surfaceId,
- left,
- top,
- id: uuidv4(),
- })
- copyModule = obj
- canvas.add(obj)
- copyModules.push(obj)
- obj.setCoords()
- })
- if (isOverlapObjects(copyModule, objects) || isOutsideSurface(copyModule, moduleSetupSurface)) {
- isWarning = true
- copyModule.set({ fill: 'red' })
+ let copyModule = null
+ let isWarning = false
+ let moduleLength = 0
+ if (['up', 'down'].includes(direction)) {
+ modules.sort((a, b) => a.top - b.top)
+ moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
+ } else if (['left', 'right'].includes(direction)) {
+ modules.sort((a, b) => a.left - b.left)
+ moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
}
- canvas.renderAll()
- })
- if (isWarning) {
- swalFire({
- title: getMessage('can.not.copy.module'),
- icon: 'error',
- type: 'alert',
- confirmFn: () => {
- canvas.remove(...copyModules)
- canvas.renderAll()
- },
+ modules.forEach((module) => {
+ const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
+ module.clone((obj) => {
+ obj.set({
+ parentId: module.parentId,
+ initOptions: module.initOptions,
+ direction: module.direction,
+ arrow: module.arrow,
+ name: module.name,
+ type: module.type,
+ length: module.length,
+ points: module.points,
+ surfaceId: module.surfaceId,
+ left,
+ top,
+ id: uuidv4(),
+ })
+ copyModule = obj
+ canvas.add(obj)
+ copyModules.push(obj)
+ obj.setCoords()
+ })
+ if (isOverlapObjects(copyModule, objects) || isOutsideSurface(copyModule, surface)) {
+ isWarning = true
+ copyModule.set({ fill: 'red' })
+ }
+ canvas.renderAll()
})
- }
+
+ if (isWarning) {
+ swalFire({
+ title: getMessage('can.not.copy.module'),
+ icon: 'error',
+ type: 'alert',
+ confirmFn: () => {
+ canvas.remove(...copyModules)
+ canvas.renderAll()
+ },
+ })
+ }
+ })
}
const moduleCopy = (length, direction) => {
@@ -298,7 +313,10 @@ export function useModule() {
canvas.renderAll()
},
})
+ } else {
+ moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
}
+ setModuleStatisticsData()
}
const moduleMultiCopy = (type, length, direction) => {
@@ -372,6 +390,9 @@ export function useModule() {
canvas.renderAll()
},
})
+ } else {
+ moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
+ setModuleStatisticsData()
}
}
@@ -487,6 +508,7 @@ export function useModule() {
},
})
}
+ setModuleStatisticsData()
}
const moduleRowRemove = (type) => {
@@ -602,6 +624,7 @@ export function useModule() {
},
})
}
+ setModuleStatisticsData()
}
const moduleColumnInsert = (type) => {
@@ -697,6 +720,7 @@ export function useModule() {
},
})
}
+ setModuleStatisticsData()
}
const muduleRowInsert = (type) => {
@@ -794,66 +818,80 @@ export function useModule() {
},
})
}
+ setModuleStatisticsData()
}
- const alignModule = (type) => {
- const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
- const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
- const objects = getObjects()
- let [top, bottom, left, right] = [0, 0, 0, 0]
+ const alignModule = (type, surfaceArray) => {
+ surfaceArray.forEach((surface) => {
+ const modules = canvas
+ .getObjects()
+ .filter((module) => module.name === POLYGON_TYPE.MODULE)
+ .filter((module) => module.surfaceId === surface.id)
- top = Math.min(...modules.map((module) => module.top))
- bottom = Math.max(...modules.map((module) => module.top + module.height))
- left = Math.min(...modules.map((module) => module.left))
- right = Math.max(...modules.map((module) => module.left + module.width))
- const moduleSurfacePos = {
- top: Math.min(...moduleSetupSurface.points.map((point) => point.y)),
- left: Math.min(...moduleSetupSurface.points.map((point) => point.x)),
- }
- const [height, width] = [bottom - top, right - left]
- const verticalCenterLength = moduleSurfacePos.top + moduleSetupSurface.height / 2 - (top + height / 2)
- const horizontalCenterLength = moduleSurfacePos.left + moduleSetupSurface.width / 2 - (left + width / 2)
- let isWarning = false
+ const objects = getObjects()
+ let [top, bottom, left, right] = [0, 0, 0, 0]
- canvas.discardActiveObject()
- modules.forEach((module) => {
- module.originPos = {
- left: module.left,
- top: module.top,
- fill: module.fill,
- }
- if (type === MODULE_ALIGN_TYPE.VERTICAL) {
- module.set({ top: module.top + verticalCenterLength })
- } else if (type === MODULE_ALIGN_TYPE.HORIZONTAL) {
- module.set({ left: module.left + horizontalCenterLength })
+ top = Math.min(...modules.map((module) => module.top))
+ bottom = Math.max(...modules.map((module) => module.top + module.height))
+ left = Math.min(...modules.map((module) => module.left))
+ right = Math.max(...modules.map((module) => module.left + module.width))
+ const moduleSurfacePos = {
+ top: Math.min(...surface.points.map((point) => point.y)),
+ left: Math.min(...surface.points.map((point) => point.x)),
}
+ const [height, width] = [bottom - top, right - left]
+ const verticalCenterLength = moduleSurfacePos.top + surface.height / 2 - (top + height / 2)
+ const horizontalCenterLength = moduleSurfacePos.left + surface.width / 2 - (left + width / 2)
+ let isWarning = false
+ canvas.discardActiveObject()
+ modules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ fill: module.fill,
+ }
+ if (type === MODULE_ALIGN_TYPE.VERTICAL) {
+ module.set({ top: module.top + verticalCenterLength })
+ } else if (type === MODULE_ALIGN_TYPE.HORIZONTAL) {
+ module.set({ left: module.left + horizontalCenterLength })
+ }
+
+ canvas.renderAll()
+ module.setCoords()
+ if (isOverlapObjects(module, objects) || isOutsideSurface(module, surface)) {
+ isWarning = true
+ module.set({ fill: 'red' })
+ }
+ })
canvas.renderAll()
- module.setCoords()
- if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
- isWarning = true
- module.set({ fill: 'red' })
+ if (isWarning) {
+ swalFire({
+ title: getMessage('can.not.align.module'),
+ icon: 'error',
+ type: 'alert',
+ confirmFn: () => {
+ modules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
+ module.setCoords()
+ })
+ canvas.renderAll()
+ },
+ })
}
})
- canvas.renderAll()
- if (isWarning) {
- swalFire({
- title: getMessage('can.not.align.module'),
- icon: 'error',
- type: 'alert',
- confirmFn: () => {
- modules.forEach((module) => {
- module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
- module.setCoords()
- })
- canvas.renderAll()
- },
- })
- }
}
const modulesRemove = () => {
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ if (activeModule.circuit) {
+ swalFire({
+ title: getMessage('can.not.remove.module'),
+ icon: 'error',
+ type: 'alert',
+ })
+ return
+ }
const modules = canvas
.getObjects()
.filter((obj) => obj.surfaceId === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE && activeModule.id !== obj.id)
@@ -861,6 +899,20 @@ export function useModule() {
surface.set({ modules: modules })
canvas.remove(activeModule)
canvas.renderAll()
+ setModuleStatisticsData()
+ }
+
+ const moduleRoofRemove = (surfaceArray) => {
+ surfaceArray.forEach((surface) => {
+ surface.modules = []
+ canvas
+ .getObjects()
+ .filter((module) => module.name === POLYGON_TYPE.MODULE && module.surfaceId === surface.id)
+ .forEach((module) => {
+ canvas.remove(module)
+ })
+ })
+ setModuleStatisticsData()
}
const isOverlapOtherModules = (module, otherModules) => {
@@ -941,6 +993,7 @@ export function useModule() {
moduleColumnInsert,
muduleRowInsert,
modulesRemove,
+ moduleRoofRemove,
alignModule,
}
}
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js
index f003982c..3197f5ad 100644
--- a/src/hooks/module/useModuleBasicSetting.js
+++ b/src/hooks/module/useModuleBasicSetting.js
@@ -1,7 +1,8 @@
+import { useState } from 'react'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
-import { canvasSettingState, canvasState, checkedModuleState, isManualModuleSetupState, selectedModuleState } from '@/store/canvasAtom'
+import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom'
import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon } from '@/util/canvas-util'
-import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom'
+import { addedRoofsState, basicSettingState, roofDisplaySelector } from '@/store/settingAtom'
import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils'
import { QPolygon } from '@/components/fabric/QPolygon'
import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom'
@@ -15,14 +16,21 @@ import { useRoofFn } from '@/hooks/common/useRoofFn'
import { useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
+import { useMasterController } from '@/hooks/common/useMasterController'
+import { v4 as uuidv4 } from 'uuid'
+// import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
+import { isObjectNotEmpty } from '@/util/common-utils'
+import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
-export function useModuleBasicSetting() {
+export function useModuleBasicSetting(tabNum) {
const canvas = useRecoilValue(canvasState)
const { getMessage } = useMessage()
const roofDisplay = useRecoilValue(roofDisplaySelector)
const [moduleSetupSurface, setModuleSetupSurface] = useRecoilState(moduleSetupSurfaceState)
const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState)
- const { addCanvasMouseEventListener, initEvent, removeMouseEvent } = useEvent()
+ const { addCanvasMouseEventListener, initEvent, removeMouseEvent, addTargetMouseEventListener } = useEvent()
+ // const { setModuleStatisticsData } = useCircuitTrestle()
const { swalFire } = useSwal()
const compasDeg = useRecoilValue(compasDegAtom)
@@ -34,19 +42,314 @@ export function useModuleBasicSetting() {
const canvasSetting = useRecoilValue(canvasSettingState)
+ const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
+ const [trestleDetailParams, setTrestleDetailParams] = useState([])
+ const [trestleDetailList, setTrestleDetailList] = useState([])
+ const selectedModules = useRecoilValue(selectedModuleState)
+ const { getTrestleDetailList } = useMasterController()
+ const [saleStoreNorthFlg, setSaleStoreNorthFlg] = useState(false)
+
+ const [currentObject, setCurrentObject] = useRecoilState(currentObjectState)
+ const { setModuleStatisticsData } = useCircuitTrestle()
+
useEffect(() => {
// console.log('basicSetting', basicSetting)
+
if (canvas) {
- canvas.selection = true
- canvas.selectionFullyContained = true
- // canvas.on('selection:created', (e) => {
- // console.log('selection:created', e.selected)
- // })
+ //드래그 여부
+ // canvas.selection = true
+ // canvas.selectionFullyContained = true
}
}, [])
// const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext)
+ //모듈 선택에서 선택된 값들 넘어옴
+ const makeModuleInitArea = () => {
+ if (isObjectNotEmpty(moduleSelectionData) && tabNum === 3) {
+ if (canvasSetting.roofSizeSet !== '3') {
+ const common = moduleSelectionData.common
+ const roofConstructions = moduleSelectionData.roofConstructions
+
+ // console.log('roofConstructions', roofConstructions)
+
+ if (roofConstructions && roofConstructions.length > 0) {
+ const listParams = roofConstructions.map((item) => {
+ return {
+ ...common,
+ // moduleTpCd: selectedModules.itemTp,
+ roofMatlCd: item.trestle.roofMatlCd,
+ trestleMkrCd: item.trestle.trestleMkrCd,
+ constMthdCd: item.trestle.constMthdCd,
+ roofBaseCd: item.trestle.roofBaseCd,
+ constTp: item.construction.constTp,
+ mixMatlNo: selectedModules.mixMatlNo,
+ roofPitch: item.addRoof.hajebichi ? item.addRoof.hajebichi : 0,
+ inclCd: String(item.addRoof.pitch),
+ roofIndex: item.addRoof.index,
+ workingWidth: item.addRoof.lenBase,
+ raftBaseCd: item.trestle.raftBaseCd,
+ }
+ })
+ setTrestleDetailParams(listParams)
+
+ //북면 설치 가능 판매점
+ if (moduleSelectionData.common.saleStoreNorthFlg === '1') {
+ setSaleStoreNorthFlg(true)
+ }
+ }
+ } else {
+ //육지붕 일경우에는 바로 배치면 설치LL
+ canvas
+ .getObjects()
+ .filter((roof) => roof.name === 'roof')
+ .forEach((roof) => {
+ makeModuleInstArea(roof, null)
+ })
+ }
+ }
+ }
+ // console.log('moduleSelectionData', moduleSelectionData)
+
+ // console.log('canvasSetting.roofSizeSet', canvasSetting.roofSizeSet)
+
+ //가대 상세 데이터 조회
+ const getTrestleDetailListData = async () => {
+ const trestleDetailList = await getTrestleDetailList(trestleDetailParams)
+ if (trestleDetailList.length > 0) {
+ setTrestleDetailList(trestleDetailList)
+ }
+ }
+
+ //가대 상세 데이터 파라메터 담기면 실행
+ useEffect(() => {
+ if (trestleDetailParams.length > 0) {
+ getTrestleDetailListData(trestleDetailParams)
+ }
+ }, [trestleDetailParams])
+
+ //가대 상세 데이터 들어오면 실행
+ useEffect(() => {
+ if (trestleDetailList.length > 0) {
+ //지붕을 가져옴
+ canvas
+ .getObjects()
+ .filter((roof) => roof.name === 'roof')
+ .forEach((roof) => {
+ if (!roof.roofMaterial) return
+ const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번
+ trestleDetailList.forEach((detail) => {
+ if (detail.data !== null) {
+ if (Number(detail.data.roofIndex) === roofIndex) {
+ //roof에 상세 데이터 추가
+ roof.set({ trestleDetail: detail.data })
+ //배치면 설치 영역
+ makeModuleInstArea(roof, detail.data)
+ //surface에 상세 데이터 추가
+ }
+ }
+ })
+ })
+ }
+ }, [trestleDetailList])
+
+ //선택 배치면 배열`
+ let selectedModuleInstSurfaceArray = []
+
+ //가대 상세 데이터 기준으로 모듈 설치 배치면 생성
+ const makeModuleInstArea = (roof, trestleDetail) => {
+ //지붕 객체 반환
+
+ if (tabNum == 3) {
+ if (!roof) {
+ return
+ }
+
+ //도머등 오브젝트 객체가 있으면 아웃라인 낸다
+ const batchObjects = canvas
+ ?.getObjects()
+ .filter(
+ (obj) =>
+ obj.name === BATCH_TYPE.OPENING ||
+ obj.name === BATCH_TYPE.SHADOW ||
+ obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
+ obj.name === BATCH_TYPE.PENTAGON_DORMER,
+ ) //도머s 객체
+
+ //도머도 외곽을 따야한다
+ const batchObjectOptions = {
+ stroke: 'red',
+ fill: 'transparent',
+ strokeDashArray: [10, 4],
+ strokeWidth: 1,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ selectable: true,
+ name: POLYGON_TYPE.OBJECT_SURFACE,
+ originX: 'center',
+ originY: 'center',
+ }
+
+ //도머등 오브젝트 객체가 있으면 아웃라인 낸다
+ batchObjects.forEach((obj) => {
+ //도머일때
+ if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) {
+ const groupPoints = obj.groupPoints
+ const offsetObjects = offsetPolygon(groupPoints, 10)
+ const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions)
+ dormerOffset.setViewLengthText(false)
+ canvas.add(dormerOffset) //모듈설치면 만들기
+ } else {
+ //개구, 그림자일때
+ const points = obj.points
+ const offsetObjects = offsetPolygon(points, 10)
+ const offset = new QPolygon(offsetObjects, batchObjectOptions)
+ offset.setViewLengthText(false)
+ canvas.add(offset) //모듈설치면 만들기
+ }
+ })
+
+ const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id)
+ if (isExistSurface) {
+ addTargetMouseEventListener('mousedown', isExistSurface, function () {
+ toggleSelection(isExistSurface)
+ })
+ } else {
+ let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1
+ setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경
+ const offsetPoints = offsetPolygon(roof.points, offsetLength) //안쪽 offset
+ //모듈설치영역?? 생성
+
+ const surfaceId = uuidv4()
+ let isNorth = false
+
+ if (canvasSetting.roofSizeSet !== '3') {
+ //북면이 있지만
+ if (roof.directionText && roof.directionText.indexOf('北') > -1) {
+ //북쪽일때 해당 서북서, 동북동은 제외한다고 한다
+ if (!(roof.directionText.indexOf('西北西') > -1 || roof.directionText.indexOf('東北東') > -1)) {
+ isNorth = true
+ }
+ }
+ }
+ //모듈설치면 생성
+ let setupSurface = new QPolygon(offsetPoints, {
+ stroke: 'red',
+ fill: 'rgba(255,255,255,0.1)',
+ strokeDashArray: [10, 4],
+ strokeWidth: 1,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ selectable: true,
+ parentId: roof.id, //가대 폴리곤의 임시 인덱스를 넣어줌
+ name: POLYGON_TYPE.MODULE_SETUP_SURFACE,
+ flowDirection: roof.direction,
+ direction: roof.direction,
+ flipX: roof.flipX,
+ flipY: roof.flipY,
+ surfaceId: surfaceId,
+ originX: 'center',
+ originY: 'center',
+ modules: [],
+ roofMaterial: roof.roofMaterial,
+ trestleDetail: trestleDetail,
+ isNorth: isNorth,
+ perPixelTargetFind: true,
+ // angle: -compasDeg,
+ })
+
+ setupSurface.setViewLengthText(false)
+ canvas.add(setupSurface) //모듈설치면 만들기
+
+ //지붕면 선택 금지
+ roof.set({
+ selectable: false, //선택 금지
+ // evented: false, //클릭 이벤트도 금지
+ })
+
+ canvas.renderAll()
+
+ //바로 들어올때
+ const setupModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+ const eaveBars = canvas.getObjects().filter((obj) => obj.name === 'eaveBar' || obj.name === 'halfEaveBar')
+ const racks = canvas.getObjects().filter((obj) => obj.name === 'rack' || obj.name === 'smartRack')
+ const brackets = canvas.getObjects().filter((obj) => obj.name === 'brackets')
+ setupModules.forEach((obj) => {
+ canvas.bringToFront(obj)
+ })
+
+ eaveBars.forEach((obj) => {
+ canvas.bringToFront(obj)
+ })
+ racks.forEach((obj) => {
+ canvas.bringToFront(obj)
+ })
+ brackets.forEach((obj) => {
+ canvas.bringToFront(obj)
+ })
+
+ //모듈설치면 클릭이벤트
+ addTargetMouseEventListener('mousedown', setupSurface, function () {
+ toggleSelection(setupSurface)
+ })
+ }
+ }
+
+ //설치 범위 지정 클릭 이벤트
+ const toggleSelection = (setupSurface) => {
+ const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
+ //최초 선택일때
+ if (!isExist) {
+ //설치면이 북면이고 북면설치 허용점이 아니면
+ if (setupSurface.isNorth && !saleStoreNorthFlg) {
+ swalFire({ text: getMessage('module.not.batch.north'), icon: 'warning' })
+ return
+ }
+
+ //기본 선택이랑 스트로크 굵기가 같으면 선택 안됨으로 봄
+ setupSurface.set({
+ ...setupSurface,
+ strokeWidth: 3,
+ strokeDashArray: [0],
+ fill: 'rgba(255,255,255,0.1)',
+ })
+ canvas.discardActiveObject() // 객체의 활성 상태 해제
+ //중복으로 들어가는걸 방지하기 위한 코드
+
+ canvas?.renderAll()
+ selectedModuleInstSurfaceArray.push(setupSurface)
+
+ // console.log('selectedModuleInstSurfaceArray', selectedModuleInstSurfaceArray)
+
+ setCurrentObject({ name: 'moduleSetupSurface', arrayData: [...selectedModuleInstSurfaceArray] })
+ } else {
+ //선택후 재선택하면 선택안됨으로 변경
+ setupSurface.set({
+ ...setupSurface,
+ fill: 'rgba(255,255,255,0.1)',
+ strokeDashArray: [10, 4],
+ strokeWidth: 1,
+ })
+ canvas.discardActiveObject() // 객체의 활성 상태 해제
+
+ //폴리곤에 커스텀 인덱스를 가지고 해당 배열 인덱스를 찾아 삭제함
+ const removeIndex = setupSurface.parentId
+ const removeArrayIndex = selectedModuleInstSurfaceArray.findIndex((obj) => obj.parentId === removeIndex)
+ selectedModuleInstSurfaceArray.splice(removeArrayIndex, 1)
+ setCurrentObject({ name: 'moduleSetupSurface', arrayData: [...selectedModuleInstSurfaceArray] })
+ }
+
+ canvas?.renderAll()
+ setModuleSetupSurface([...selectedModuleInstSurfaceArray])
+ }
+ }
+
//모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화
const restoreModuleInstArea = () => {
//설치면 삭제
@@ -70,12 +373,21 @@ export function useModuleBasicSetting() {
})
}
+ useEffect(() => {
+ if (canvasSetting.roofSizeSet !== '3') {
+ if (isObjectNotEmpty(moduleSelectionData) && moduleSelectionData.common.saleStoreNorthFlg === '1') {
+ setSaleStoreNorthFlg(true)
+ }
+ }
+ }, [isManualModuleSetup])
+
/**
* trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 로 진입여부를 확인
* 확인 후 셀을 이동시킴
*/
const manualModuleSetup = () => {
// console.log('isManualModuleSetup', isManualModuleSetup)
+ const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
if (isManualModuleSetup) {
if (checkedModule.length === 0) {
@@ -90,8 +402,14 @@ export function useModuleBasicSetting() {
return
}
- const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체
+ //수동모드 모듈 설치면 선택 잠금
+ moduleSetupSurfaces.forEach((obj) => {
+ obj.set({
+ selectable: false,
+ evented: false,
+ })
+ })
const moduleOptions = {
fill: checkedModule[0].color,
@@ -103,7 +421,7 @@ export function useModuleBasicSetting() {
lockRotation: true, // 회전 잠금
lockScalingX: true, // X 축 크기 조정 잠금
lockScalingY: true, // Y 축 크기 조정 잠금
- name: 'module',
+ name: POLYGON_TYPE.MODULE,
}
if (moduleSetupSurfaces.length !== 0) {
@@ -128,12 +446,11 @@ export function useModuleBasicSetting() {
const moduleHeight = Number(checkedModule[0].shortAxis) / 10
let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight
let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
- let { width, height } = calculateVisibleModuleHeight(
- tmpWidth,
- tmpHeight,
- getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch),
- flowDirection,
- ) //각도 적용
+
+ let { width, height } =
+ canvasSetting.roofSizeSet === '1'
+ ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection)
+ : { width: tmpWidth, height: tmpHeight }
const points = [
{ x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
@@ -168,7 +485,12 @@ export function useModuleBasicSetting() {
parentId: moduleSetupSurfaces[i].parentId,
})
- canvas?.add(tempModule) //움직여가면서 추가됨
+ //북면이고 북면설치상점이 아니면 그냥 return
+ if (trestlePolygon.isNorth && !saleStoreNorthFlg) {
+ return
+ } else {
+ canvas?.add(tempModule) //움직여가면서 추가됨
+ }
/**
* 스냅기능
@@ -178,12 +500,12 @@ export function useModuleBasicSetting() {
let intvHor =
flowDirection === 'south' || flowDirection === 'north'
- ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor
- : moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer
+ ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10
+ : moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10
let intvVer =
flowDirection === 'south' || flowDirection === 'north'
- ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer
- : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor
+ ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10
+ : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10
const trestleLeft = moduleSetupSurfaces[i].left
const trestleTop = moduleSetupSurfaces[i].top
@@ -361,6 +683,7 @@ export function useModuleBasicSetting() {
const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인
if (!isOverlap) {
canvas?.remove(tempModule)
+
//안겹치면 넣는다
// tempModule.setCoords()
moduleOptions.surfaceId = trestlePolygon.id
@@ -368,6 +691,7 @@ export function useModuleBasicSetting() {
let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: checkedModule[0] })
canvas?.add(manualModule)
manualDrawModules.push(manualModule)
+ setModuleStatisticsData()
getModuleStatistics()
} else {
swalFire({ text: getMessage('module.place.overlab') })
@@ -379,6 +703,16 @@ export function useModuleBasicSetting() {
})
}
} else {
+ if (moduleSetupSurfaces) {
+ //수동모드 해제시 모듈 설치면 선택 잠금
+ moduleSetupSurfaces.forEach((obj) => {
+ obj.set({
+ selectable: true,
+ evented: true,
+ })
+ })
+ }
+
removeMouseEvent('mouse:up')
removeMouseEvent('mouse:move')
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임
@@ -394,8 +728,6 @@ export function useModuleBasicSetting() {
return
}
- console.log('placementRef', placementRef)
-
const isChidori = placementRef.isChidori.current === 'true' ? true : false
const setupLocation = placementRef.setupLocation.current
const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false
@@ -507,52 +839,6 @@ export function useModuleBasicSetting() {
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
}
- /**
- * 모듈의 너비와 높이를 계산하는 함수
- * @param {object} maxLengthLine 최대 길이 라인
- * @param {object} moduleSetupSurface 모듈 설치면
- * @param {object} module 모듈
- * @returns {object} 모듈의 너비와 높이
- */
- const getModuleWidthHeight = (maxLengthLine, moduleSetupSurface, module) => {
- let tmpWidth =
- (maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.longAxis) : Number(module.shortAxis)) / 10
- let tmpHeight =
- (maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.shortAxis) : Number(module.longAxis)) / 10
-
- //배치면때는 방향쪽으로 패널이 넓게 누워져야함
- if (moduleSetupSurface.flowDirection !== undefined) {
- tmpWidth =
- (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
- ? Number(module.longAxis)
- : Number(module.shortAxis)) / 10
- tmpHeight =
- (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
- ? Number(module.shortAxis)
- : Number(module.longAxis)) / 10
- }
-
- return calculateVisibleModuleHeight(
- tmpWidth,
- tmpHeight,
- getDegreeByChon(moduleSetupSurface.roofMaterial.pitch),
- moduleSetupSurface.flowDirection,
- ) //각도 적
- }
-
- const getFlowLines = (moduleSetupSurface, module) => {
- let flowLines = {}
- if (canvasSetting.roofSizeSet !== 3) {
- flowLines = {
- bottom: bottomTopFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'bottom'),
- top: bottomTopFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'top'),
- left: leftRightFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'left'),
- right: leftRightFlowLine(moduleSetupSurface, module).find((obj) => obj.target === 'right'),
- }
- }
- return flowLines
- }
-
const downFlowSetupModule = (
surfaceMaxLines,
maxLengthLine,
@@ -568,8 +854,10 @@ export function useModuleBasicSetting() {
checkedModule.forEach((module, index) => {
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
- const flowLines = getFlowLines(moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, height)
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
+ // let startPoint = flowLines.bottom
+
let startPoint = flowLines.bottom
const moduleArray = []
@@ -589,15 +877,10 @@ export function useModuleBasicSetting() {
}
}
}
- // else {
- // //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치
- // if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') {
- // //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치
- // const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다
- // const halfModuleWidthLength = width / 2
- // startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength }
- // }
- // }
+ //밑에가 평면이면 좌측으로 붙여서 배치
+ if (flowLines.bottom.type === 'flat' && flowLines.left.type === 'curve') {
+ startPoint = flowLines.left
+ }
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
@@ -647,6 +930,7 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
})
} else {
@@ -655,12 +939,17 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
} else {
- tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
+ //디버깅용
+ // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
+ // canvas?.add(tempModule)
+ // canvas.renderAll()
}
}
}
+
setupModule.push(moduleArray)
})
}
@@ -679,7 +968,7 @@ export function useModuleBasicSetting() {
checkedModule.forEach((module, index) => {
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
- const flowLines = getFlowLines(moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, width)
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
let startPoint = flowLines.left
const moduleArray = []
@@ -700,6 +989,12 @@ export function useModuleBasicSetting() {
}
}
+ console.log('flowLines.top', flowLines.top)
+
+ if (flowLines.left.type === 'flat') {
+ startPoint = flowLines.top
+ }
+
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
@@ -748,6 +1043,7 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
})
} else {
@@ -756,7 +1052,13 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
+ } else {
+ //디버깅용
+ // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
+ // canvas?.add(tempModule)
+ // canvas.renderAll()
}
}
}
@@ -778,7 +1080,7 @@ export function useModuleBasicSetting() {
checkedModule.forEach((module, index) => {
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
- const flowLines = getFlowLines(moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, height)
let startPoint = flowLines.top
const moduleArray = []
@@ -860,6 +1162,7 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
})
} else {
@@ -868,7 +1171,13 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
+ } else {
+ //디버깅용
+ // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
+ // canvas?.add(tempModule)
+ // canvas.renderAll()
}
}
}
@@ -890,7 +1199,7 @@ export function useModuleBasicSetting() {
checkedModule.forEach((module, index) => {
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
- const flowLines = getFlowLines(moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, width)
let startPoint = flowLines.right
const moduleArray = []
@@ -959,6 +1268,7 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
})
} else {
@@ -967,7 +1277,13 @@ export function useModuleBasicSetting() {
canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
moduleArray.push(tempModule)
+ canvas.renderAll()
}
+ } else {
+ //디버깅용
+ // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
+ // canvas?.add(tempModule)
+ // canvas.renderAll()
}
}
}
@@ -989,16 +1305,14 @@ export function useModuleBasicSetting() {
const flowDirection = moduleSetupSurface.flowDirection
- console.log('moduleSetupSurface', moduleSetupSurface)
-
let intvHor =
flowDirection === 'south' || flowDirection === 'north'
- ? moduleSetupSurface.trestleDetail.moduleIntvlHor
- : moduleSetupSurface.trestleDetail.moduleIntvlVer
+ ? moduleSetupSurface.trestleDetail.moduleIntvlHor / 10
+ : moduleSetupSurface.trestleDetail.moduleIntvlVer / 10
let intvVer =
flowDirection === 'south' || flowDirection === 'north'
- ? moduleSetupSurface.trestleDetail.moduleIntvlVer
- : moduleSetupSurface.trestleDetail.moduleIntvlHor
+ ? moduleSetupSurface.trestleDetail.moduleIntvlVer / 10
+ : moduleSetupSurface.trestleDetail.moduleIntvlHor / 10
//처마면 배치
if (setupLocation === 'eaves') {
@@ -1106,7 +1420,7 @@ export function useModuleBasicSetting() {
return hull
}
- const bottomTopFlowLine = (surface, module) => {
+ const bottomTopFlowLine = (surface, length) => {
const flowArray = []
const bottomFlow = surface.lines.reduce(
@@ -1165,7 +1479,7 @@ export function useModuleBasicSetting() {
const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000)
const angle3 = 180 - (angle1 + angle2)
- const charlie = Number(module.longAxis) / 10 + 3 // 평행선길이 약간 여유를 줌
+ const charlie = Number(length) + 3 // 평행선길이 약간 여유를 줌
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이
@@ -1177,13 +1491,16 @@ export function useModuleBasicSetting() {
const pointX2 = coords[2].x + ((coords[2].y - top) / (coords[2].y - coords[1].y)) * (coords[1].x - coords[2].x)
const pointY2 = top
- // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
- // stroke: 'red',
- // strokeWidth: 1,
- // selectable: true,
- // })
- // canvas?.add(finalLine)
- // canvas?.renderAll()
+ const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: true,
+ })
+
+ console.log(`index ${index} : finalLine`, pointX1, pointY1, pointX2, pointY2)
+
+ canvas?.add(finalLine)
+ canvas?.renderAll()
let rtnObj
//평평하면
@@ -1224,7 +1541,7 @@ export function useModuleBasicSetting() {
return rtnObjArray
}
- const leftRightFlowLine = (surface, module) => {
+ const leftRightFlowLine = (surface, length) => {
const flowArray = []
const leftFlow = surface.lines.reduce(
(acc, line, index) => {
@@ -1280,7 +1597,7 @@ export function useModuleBasicSetting() {
const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000)
const angle3 = 180 - (angle1 + angle2)
- const charlie = Number(module.shortAxis) / 10 + 3 // 평행선길이 약간 여유를 줌
+ const charlie = Number(length) + 3 // 평행선길이 약간 여유를 줌
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
@@ -1300,13 +1617,13 @@ export function useModuleBasicSetting() {
const pointX2 = top
const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y)
- // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
- // stroke: 'red',
- // strokeWidth: 1,
- // selectable: true,
- // })
- // canvas?.add(finalLine)
- // canvas?.renderAll()
+ const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: true,
+ })
+ canvas?.add(finalLine)
+ canvas?.renderAll()
let rtnObj
//평평하면
@@ -1398,322 +1715,361 @@ export function useModuleBasicSetting() {
const manualFlatroofModuleSetup = (placementFlatRef) => {
let moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
- let flatBatchType = placementFlatRef.setupLocation.current.value
-
- const batchObjects = canvas
- ?.getObjects()
- .filter(
- (obj) =>
- obj.name === BATCH_TYPE.OPENING ||
- obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
- obj.name === BATCH_TYPE.PENTAGON_DORMER ||
- obj.name === BATCH_TYPE.SHADOW,
- ) //도머s 객체
-
- const moduleOptions = {
- fill: '#BFFD9F',
- stroke: 'black',
- strokeWidth: 0.1,
- selectable: true, // 선택 가능하게 설정
- lockMovementX: true, // X 축 이동 잠금
- lockMovementY: true, // Y 축 이동 잠금
- lockRotation: true, // 회전 잠금
- lockScalingX: true, // X 축 크기 조정 잠금
- lockScalingY: true, // Y 축 크기 조정 잠금
- parentId: moduleSetupSurface.parentId,
- surfaceId: moduleSetupSurface.id,
- name: 'module',
- }
-
- if (moduleSetupSurfaces.length !== 0) {
- let tempModule
- let manualDrawModules = []
- let inside = false
- let turfPolygon
- let flowDirection
- let trestlePolygon
-
- //남쪽 선택
- if (flatBatchType === 'excreta') {
- //변별로 선택
- const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine')
- excretaLines.forEach((obj) => {
- if (obj.isSelected === true) {
- const points1 = { x: obj.x1, y: obj.y1 }
- const points2 = { x: obj.x2, y: obj.y2 }
- const angle = calculateAngle(points1, points2)
-
- //변별로 선택으로 되어있을때 모듈면을 회전시키기
- const targetdSurface = moduleSetupSurfaces.filter((surface) => surface.surfaceId === obj.surfaceId)[0]
- targetdSurface.angle = -angle
- //변별로 선택되어있는 지붕도 회전시키기
- const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === targetdSurface.parentId)[0]
- targetRoof.angle = -angle
-
- targetRoof.fire('modified')
- targetdSurface.fire('modified')
- }
- canvas.remove(obj)
- })
- } else {
- moduleSetupSurfaces.forEach((surface) => {
- const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === surface.parentId)[0]
- if (targetRoof) targetRoof.angle = -compasDeg
- surface.angle = -compasDeg
- })
+ if (isManualModuleSetup) {
+ if (checkedModule.length === 0) {
+ swalFire({ text: getMessage('module.place.select.module') })
+ setIsManualModuleSetup(!isManualModuleSetup)
+ return
}
- canvas.renderAll()
- addCanvasMouseEventListener('mouse:move', (e) => {
- //마우스 이벤트 삭제 후 재추가
- const mousePoint = canvas.getPointer(e.e)
+ if (checkedModule.length > 1) {
+ swalFire({ text: getMessage('module.place.select.one.module') })
+ setIsManualModuleSetup(!isManualModuleSetup)
+ return
+ }
- for (let i = 0; i < moduleSetupSurfaces.length; i++) {
- turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i], true)
- trestlePolygon = moduleSetupSurfaces[i]
- manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨
- flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향
- let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113
- let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172
+ let flatBatchType = placementFlatRef.setupLocation.current.value
- const points = [
- { x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
- { x: mousePoint.x + width / 2, y: mousePoint.y - height / 2 },
- { x: mousePoint.x + width / 2, y: mousePoint.y + height / 2 },
- { x: mousePoint.x - width / 2, y: mousePoint.y + height / 2 },
- ]
+ const batchObjects = canvas
+ ?.getObjects()
+ .filter(
+ (obj) =>
+ obj.name === BATCH_TYPE.OPENING ||
+ obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
+ obj.name === BATCH_TYPE.PENTAGON_DORMER ||
+ obj.name === BATCH_TYPE.SHADOW,
+ ) //도머s 객체
- const turfPoints = coordToTurfPolygon(points)
+ let moduleOptions = {
+ fill: '#BFFD9F',
+ stroke: 'black',
+ strokeWidth: 0.1,
+ selectable: true, // 선택 가능하게 설정
+ lockMovementX: true, // X 축 이동 잠금
+ lockMovementY: true, // Y 축 이동 잠금
+ lockRotation: true, // 회전 잠금
+ lockScalingX: true, // X 축 크기 조정 잠금
+ lockScalingY: true, // Y 축 크기 조정 잠금
+ parentId: moduleSetupSurface.parentId,
+ surfaceId: moduleSetupSurface.id,
+ name: POLYGON_TYPE.MODULE,
+ }
- if (turf.booleanWithin(turfPoints, turfPolygon)) {
- let isDrawing = false
+ if (moduleSetupSurfaces.length !== 0) {
+ let tempModule
+ let manualDrawModules = []
+ let inside = false
+ let turfPolygon
+ let flowDirection
+ let trestlePolygon
- if (isDrawing) return
- canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임
+ //남쪽 선택
+ if (flatBatchType === 'excreta') {
+ //변별로 선택
+ const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine')
+ excretaLines.forEach((obj) => {
+ if (obj.isSelected === true) {
+ const points1 = { x: obj.x1, y: obj.y1 }
+ const points2 = { x: obj.x2, y: obj.y2 }
+ const angle = calculateAngle(points1, points2)
- tempModule = new fabric.Rect({
- fill: 'white',
- stroke: 'black',
- strokeWidth: 0.3,
- width: width,
- height: height,
- left: mousePoint.x - width / 2,
- top: mousePoint.y - height / 2,
- selectable: false,
- lockMovementX: true,
- lockMovementY: true,
- lockRotation: true,
- lockScalingX: true,
- lockScalingY: true,
- name: 'tempModule',
- parentId: moduleSetupSurfaces[i].parentId,
- })
+ //변별로 선택으로 되어있을때 모듈면을 회전시키기
+ const targetdSurface = moduleSetupSurfaces.filter((surface) => surface.surfaceId === obj.surfaceId)[0]
+ targetdSurface.angle = -angle
+ //변별로 선택되어있는 지붕도 회전시키기
+ const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === targetdSurface.parentId)[0]
+ targetRoof.angle = -angle
- canvas?.add(tempModule) //움직여가면서 추가됨
+ targetRoof.fire('modified')
+ targetdSurface.fire('modified')
+ }
+ canvas.remove(obj)
+ })
+ } else {
+ moduleSetupSurfaces.forEach((surface) => {
+ const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === surface.parentId)[0]
+ if (targetRoof) targetRoof.angle = -compasDeg
+ surface.angle = -compasDeg
+ })
+ }
+ canvas.renderAll()
- /**
- * 스냅기능
- */
- let snapDistance = 10
- let cellSnapDistance = 20
+ addCanvasMouseEventListener('mouse:move', (e) => {
+ //마우스 이벤트 삭제 후 재추가
+ const mousePoint = canvas.getPointer(e.e)
- const trestleLeft = moduleSetupSurfaces[i].left
- const trestleTop = moduleSetupSurfaces[i].top
- const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX
- const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY
- const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2
+ for (let i = 0; i < moduleSetupSurfaces.length; i++) {
+ turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i], true)
+ trestlePolygon = moduleSetupSurfaces[i]
+ manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨
+ flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향
- // 작은 폴리곤의 경계 좌표 계산
- const smallLeft = tempModule.left
- const smallTop = tempModule.top
- const smallRight = smallLeft + tempModule.width * tempModule.scaleX
- const smallBottom = smallTop + tempModule.height * tempModule.scaleY
- const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2
- const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2
+ const moduleWidth = Number(checkedModule[0].longAxis) / 10
+ const moduleHeight = Number(checkedModule[0].shortAxis) / 10
- /**
- * 미리 깔아놓은 셀이 있을때 셀에 흡착됨
- */
- if (manualDrawModules) {
- manualDrawModules.forEach((cell) => {
- const holdCellLeft = cell.left
- const holdCellTop = cell.top
- const holdCellRight = holdCellLeft + cell.width * cell.scaleX
- const holdCellBottom = holdCellTop + cell.height * cell.scaleY
- const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2
- const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2
+ let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight
+ let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
- //설치된 셀에 좌측에 스냅
- if (Math.abs(smallRight - holdCellLeft) < snapDistance) {
- tempModule.left = holdCellLeft - width - 1
+ let { width, height } =
+ canvasSetting.roofSizeSet === '1'
+ ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection)
+ : { width: tmpWidth, height: tmpHeight }
+
+ const points = [
+ { x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
+ { x: mousePoint.x + width / 2, y: mousePoint.y - height / 2 },
+ { x: mousePoint.x + width / 2, y: mousePoint.y + height / 2 },
+ { x: mousePoint.x - width / 2, y: mousePoint.y + height / 2 },
+ ]
+
+ const turfPoints = coordToTurfPolygon(points)
+
+ if (turf.booleanWithin(turfPoints, turfPolygon)) {
+ let isDrawing = false
+
+ if (isDrawing) return
+ canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임
+
+ tempModule = new fabric.Rect({
+ fill: 'white',
+ stroke: 'black',
+ strokeWidth: 0.3,
+ width: width,
+ height: height,
+ left: mousePoint.x - width / 2,
+ top: mousePoint.y - height / 2,
+ selectable: false,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ name: 'tempModule',
+ parentId: moduleSetupSurfaces[i].parentId,
+ })
+
+ canvas?.add(tempModule) //움직여가면서 추가됨
+
+ /**
+ * 스냅기능
+ */
+ let snapDistance = 10
+ let cellSnapDistance = 20
+
+ let intvHor = flowDirection === 'south' || flowDirection === 'north' ? 1 : 3
+ let intvVer = flowDirection === 'south' || flowDirection === 'north' ? 3 : 1
+
+ const trestleLeft = moduleSetupSurfaces[i].left
+ const trestleTop = moduleSetupSurfaces[i].top
+ const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX
+ const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY
+ const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2
+
+ // 작은 폴리곤의 경계 좌표 계산
+ const smallLeft = tempModule.left
+ const smallTop = tempModule.top
+ const smallRight = smallLeft + tempModule.width * tempModule.scaleX
+ const smallBottom = smallTop + tempModule.height * tempModule.scaleY
+ const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2
+ const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2
+
+ /**
+ * 미리 깔아놓은 셀이 있을때 셀에 흡착됨
+ */
+ if (manualDrawModules) {
+ manualDrawModules.forEach((cell) => {
+ const holdCellLeft = cell.left
+ const holdCellTop = cell.top
+ const holdCellRight = holdCellLeft + cell.width * cell.scaleX
+ const holdCellBottom = holdCellTop + cell.height * cell.scaleY
+ const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2
+ const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2
+
+ //설치된 셀에 좌측에 스냅
+ if (Math.abs(smallRight - holdCellLeft) < snapDistance) {
+ tempModule.left = holdCellLeft - width - intvHor
+ }
+
+ //설치된 셀에 우측에 스냅
+ if (Math.abs(smallLeft - holdCellRight) < snapDistance) {
+ tempModule.left = holdCellRight + intvHor
+ }
+
+ //설치된 셀에 위쪽에 스냅
+ if (Math.abs(smallBottom - holdCellTop) < snapDistance) {
+ tempModule.top = holdCellTop - height - intvVer
+ }
+
+ //설치된 셀에 밑쪽에 스냅
+ if (Math.abs(smallTop - holdCellBottom) < snapDistance) {
+ tempModule.top = holdCellBottom + intvVer
+ }
+ //가운데 -> 가운데
+ if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) {
+ tempModule.left = holdCellCenterX - width / 2
+ }
+ //왼쪽 -> 가운데
+ if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) {
+ tempModule.left = holdCellCenterX
+ }
+ // 오른쪽 -> 가운데
+ if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) {
+ tempModule.left = holdCellCenterX - width
+ }
+ //세로 가운데 -> 가운데
+ if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) {
+ tempModule.top = holdCellCenterY - height / 2
+ }
+ // //위쪽 -> 가운데
+ // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) {
+ // tempModule.top = holdCellCenterY
+ // }
+ // //아랫쪽 -> 가운데
+ // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) {
+ // tempModule.top = holdCellCenterY - height
+ // }
+ })
+ }
+
+ // 위쪽 변에 스냅
+ if (Math.abs(smallTop - trestleTop) < snapDistance) {
+ tempModule.top = trestleTop
+ }
+
+ // 아래쪽 변에 스냅
+ if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) {
+ tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY
+ }
+
+ // 왼쪽변에 스냅
+ if (Math.abs(smallLeft - trestleLeft) < snapDistance) {
+ tempModule.left = trestleLeft
+ }
+ //오른쪽 변에 스냅
+ if (Math.abs(smallRight - trestleRight) < snapDistance) {
+ tempModule.left = trestleRight - tempModule.width * tempModule.scaleX
+ }
+
+ if (flowDirection === 'south' || flowDirection === 'north') {
+ // 모듈왼쪽이 세로중앙선에 붙게 스냅
+ if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
+ tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2
}
- //설치된 셀에 우측에 스냅
- if (Math.abs(smallLeft - holdCellRight) < snapDistance) {
- tempModule.left = holdCellRight + 1
+ // 모듈이 가운데가 세로중앙선에 붙게 스냅
+ if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
+ tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2
}
- //설치된 셀에 위쪽에 스냅
- if (Math.abs(smallBottom - holdCellTop) < snapDistance) {
- tempModule.top = holdCellTop - height - 1
+ // 모듈오른쪽이 세로중앙선에 붙게 스냅
+ if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
+ tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX
+ }
+ } else {
+ // 모듈이 가로중앙선에 스냅
+ if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) {
+ tempModule.top = bigCenterY - tempModule.height / 2
}
- //설치된 셀에 밑쪽에 스냅
- if (Math.abs(smallTop - holdCellBottom) < snapDistance) {
- tempModule.top = holdCellBottom + 1
+ if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
+ tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2
}
- //가운데 -> 가운데
- if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) {
- tempModule.left = holdCellCenterX - width / 2
+ // 모듈 밑면이 가로중앙선에 스냅
+ if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
+ tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY
}
- //왼쪽 -> 가운데
- if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) {
- tempModule.left = holdCellCenterX
+ }
+
+ tempModule.setCoords()
+ canvas?.renderAll()
+ inside = true
+ break
+ } else {
+ inside = false
+ }
+ }
+
+ if (!inside) {
+ // tempModule.set({ fill: 'red' })
+ canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule'))
+ canvas?.renderAll()
+ }
+ })
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ let isIntersection = true
+ if (!inside) return
+ if (tempModule) {
+ const rectPoints = [
+ { x: tempModule.left, y: tempModule.top },
+ { x: tempModule.left + tempModule.width * tempModule.scaleX, y: tempModule.top },
+ {
+ x: tempModule.left + tempModule.width * tempModule.scaleX,
+ y: tempModule.top + tempModule.height * tempModule.scaleY,
+ },
+ { x: tempModule.left, y: tempModule.top + tempModule.height * tempModule.scaleY },
+ ]
+
+ tempModule.set({ points: rectPoints })
+ const tempTurfModule = polygonToTurfPolygon(tempModule)
+
+ //도머 객체를 가져옴
+ if (batchObjects) {
+ batchObjects.forEach((object) => {
+ let dormerTurfPolygon
+
+ if (object.type === 'group') {
+ //도머는 그룹형태임
+ dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
+ } else {
+ //개구, 그림자
+ dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object))
}
- // 오른쪽 -> 가운데
- if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) {
- tempModule.left = holdCellCenterX - width
+
+ const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
+ //겹치면 안됨
+ if (intersection) {
+ swalFire({ text: getMessage('module.place.overobject') })
+ isIntersection = false
}
- //세로 가운데 -> 가운데
- if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) {
- tempModule.top = holdCellCenterY - height / 2
- }
- // //위쪽 -> 가운데
- // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) {
- // tempModule.top = holdCellCenterY
- // }
- // //아랫쪽 -> 가운데
- // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) {
- // tempModule.top = holdCellCenterY - height
- // }
})
}
- // 위쪽 변에 스냅
- if (Math.abs(smallTop - trestleTop) < snapDistance) {
- tempModule.top = trestleTop
- }
+ if (!isIntersection) return
- // 아래쪽 변에 스냅
- if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) {
- tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY
- }
-
- // 왼쪽변에 스냅
- if (Math.abs(smallLeft - trestleLeft) < snapDistance) {
- tempModule.left = trestleLeft
- }
- //오른쪽 변에 스냅
- if (Math.abs(smallRight - trestleRight) < snapDistance) {
- tempModule.left = trestleRight - tempModule.width * tempModule.scaleX
- }
-
- if (flowDirection === 'south' || flowDirection === 'north') {
- // 모듈왼쪽이 세로중앙선에 붙게 스냅
- if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
- tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2
- }
-
- // 모듈이 가운데가 세로중앙선에 붙게 스냅
- if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
- tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2
- }
-
- // 모듈오른쪽이 세로중앙선에 붙게 스냅
- if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
- tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX
- }
- } else {
- // 모듈이 가로중앙선에 스냅
- if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) {
- tempModule.top = bigCenterY - tempModule.height / 2
- }
-
- if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
- tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2
- }
- // 모듈 밑면이 가로중앙선에 스냅
- if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
- tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY
- }
- }
-
- tempModule.setCoords()
- canvas?.renderAll()
- inside = true
- break
- } else {
- inside = false
- }
- }
-
- if (!inside) {
- // tempModule.set({ fill: 'red' })
- canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule'))
- canvas?.renderAll()
- }
- })
-
- addCanvasMouseEventListener('mouse:up', (e) => {
- let isIntersection = true
- if (!inside) return
- if (tempModule) {
- const rectPoints = [
- { x: tempModule.left, y: tempModule.top },
- { x: tempModule.left + tempModule.width * tempModule.scaleX, y: tempModule.top },
- {
- x: tempModule.left + tempModule.width * tempModule.scaleX,
- y: tempModule.top + tempModule.height * tempModule.scaleY,
- },
- { x: tempModule.left, y: tempModule.top + tempModule.height * tempModule.scaleY },
- ]
-
- tempModule.set({ points: rectPoints })
- const tempTurfModule = polygonToTurfPolygon(tempModule)
-
- //도머 객체를 가져옴
- if (batchObjects) {
- batchObjects.forEach((object) => {
- let dormerTurfPolygon
-
- if (object.type === 'group') {
- //도머는 그룹형태임
- dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
+ if (turf.booleanWithin(tempTurfModule, turfPolygon)) {
+ //마우스 클릭시 set으로 해당 위치에 셀을 넣음
+ const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인
+ if (!isOverlap) {
+ moduleOptions.surfaceId = trestlePolygon.id
+ let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: checkedModule[0] })
+ canvas?.add(manualModule)
+ manualDrawModules.push(tempModule)
} else {
- //개구, 그림자
- dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object))
+ swalFire({ text: getMessage('module.place.overlab') })
}
-
- const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
- //겹치면 안됨
- if (intersection) {
- swalFire({ text: getMessage('module.place.overobject') })
- isIntersection = false
- }
- })
- }
-
- if (!isIntersection) return
-
- if (turf.booleanWithin(tempTurfModule, turfPolygon)) {
- //마우스 클릭시 set으로 해당 위치에 셀을 넣음
- const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인
- if (!isOverlap) {
- moduleOptions.surfaceId = trestlePolygon.id
- let manualModule = new QPolygon(tempModule.points, { ...moduleOptions })
- canvas?.add(manualModule)
- manualDrawModules.push(tempModule)
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.out') })
}
- } else {
- swalFire({ text: getMessage('module.place.out') })
}
- }
- })
- }
+ })
+ }
+ getModuleStatistics()
+ } else {
+ if (moduleSetupSurfaces) {
+ //수동모드 해제시 모듈 설치면 선택 잠금
+ moduleSetupSurfaces.forEach((obj) => {
+ obj.set({
+ selectable: true,
+ evented: true,
+ })
+ })
+ }
- getModuleStatistics()
+ removeMouseEvent('mouse:up')
+ removeMouseEvent('mouse:move')
+ canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임
+ }
}
const autoFlatroofModuleSetup = (placementFlatRef) => {
@@ -1809,17 +2165,17 @@ export function useModuleBasicSetting() {
targetLine.y2 = lines[index].y2
})
- const flowLines = {
- bottom: bottomTopFlowLine(surface).find((obj) => obj.target === 'bottom'),
- top: bottomTopFlowLine(surface).find((obj) => obj.target === 'top'),
- left: leftRightFlowLine(surface).find((obj) => obj.target === 'left'),
- right: leftRightFlowLine(surface).find((obj) => obj.target === 'right'),
- }
+ // const flowLines = {
+ // bottom: bottomTopFlowLine(surface).find((obj) => obj.target === 'bottom'),
+ // top: bottomTopFlowLine(surface).find((obj) => obj.target === 'top'),
+ // left: leftRightFlowLine(surface).find((obj) => obj.target === 'left'),
+ // right: leftRightFlowLine(surface).find((obj) => obj.target === 'right'),
+ // }
- surface.set({ flowLines: flowLines })
+ // surface.set({ flowLines: flowLines })
})
- const moduleOptions = {
+ let moduleOptions = {
fill: '#BFFD9F',
stroke: 'black',
strokeWidth: 0.1,
@@ -1831,7 +2187,7 @@ export function useModuleBasicSetting() {
lockScalingY: true, // Y 축 크기 조정 잠금
parentId: moduleSetupSurface.parentId,
surfaceId: moduleSetupSurface.id,
- name: 'module',
+ name: POLYGON_TYPE.MODULE,
}
let leftMargin, bottomMargin, square
@@ -1871,169 +2227,188 @@ export function useModuleBasicSetting() {
let moduleGroup = []
- const flatRoofDownFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
- let startPoint = moduleSetupSurface.flowLines.bottom
+ const flatRoofDownFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
+ checkedModule.forEach((module, index) => {
+ const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
- const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
- const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
- const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
+ const flowLines = getFlowLines(moduleSetupSurface, height)
- let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
- let totalTopEndPoint = maxTopEndPoint - startPoint.y1
- let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
- let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
- let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
- let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
- let tempMaxWidth = width //최대배치인지 확인하려고 넣음
+ let startPoint = flowLines.bottom
+
+ const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
+ const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
+ const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
+
+ let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
+ let totalTopEndPoint = maxTopEndPoint - startPoint.y1
+ let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
+ let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
+ let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
+ let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
+ let tempMaxWidth = width //최대배치인지 확인하려고 넣음
+
+ for (let j = 0; j < diffTopEndPoint; j++) {
+ bottomMargin = marginHeight * j
+ for (let i = 0; i <= totalWidth; i++) {
+ leftMargin = marginWidth * i
+
+ square = [
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
+ [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - bottomMargin],
+ [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
+ ]
+
+ let squarePolygon = turf.polygon([square])
+ let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
+ let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
+
+ moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
+ let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
+ canvas?.add(tempModule)
+ moduleSetupArray.push(tempModule)
+ moduleGroup.push(tempModule)
+ }
+ }
+ })
+ }
+
+ const flatRoofLeftFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
+ checkedModule.forEach((module, index) => {
+ const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, width)
+ let startPoint = flowLines.left
+
+ const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
+ const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
+ const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
+
+ let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
+ let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
+ let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
+ let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width
+ let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint)
+ let tempMaxHeight = height //최대배치인지 확인하려고 넣음
- for (let j = 0; j < diffTopEndPoint; j++) {
- bottomMargin = marginHeight * j
for (let i = 0; i <= totalWidth; i++) {
- leftMargin = marginWidth * i
+ bottomMargin = marginHeight * i
+ for (let j = 0; j < totalHeight; j++) {
+ leftMargin = marginWidth * j
- square = [
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
- [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - bottomMargin],
- [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
- ]
+ square = [
+ [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
+ [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
+ [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ ]
- let squarePolygon = turf.polygon([square])
- let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
- let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
+ let squarePolygon = turf.polygon([square])
+ let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
+ let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
- moduleOptions.surfaceId = moduleSetupSurface.id
- let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
- canvas?.add(tempModule)
- moduleSetupArray.push(tempModule)
- moduleGroup.push(tempModule)
+ // if (disjointFromTrestle && isDisjoint) {
+ moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
+ let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
+ canvas?.add(tempModule)
+ moduleSetupArray.push(tempModule)
+ moduleGroup.push(tempModule)
+ }
}
- }
+ })
}
- const flatRoofLeftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
- let startPoint = moduleSetupSurface.flowLines.left
- const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
- const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
- const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
+ const flatRoofTopFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
+ checkedModule.forEach((module, index) => {
+ const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, height)
+ let startPoint = flowLines.top
- let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
- let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
- let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
- let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width
- let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint)
- let tempMaxHeight = height //최대배치인지 확인하려고 넣음
+ const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
+ const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
+ const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
- for (let i = 0; i <= totalWidth; i++) {
- bottomMargin = marginHeight * i
- for (let j = 0; j < totalHeight; j++) {
- leftMargin = marginWidth * j
+ let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
+ let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint
+ let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1
+ let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
+ let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width))
+ let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height))
+ let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
+ let tempMaxWidth = width //최대배치인지 확인하려고 넣음
- square = [
- [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
- [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
- [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- ]
+ for (let j = 0; j < diffBottomEndPoint; j++) {
+ bottomMargin = marginHeight * j
+ for (let i = 0; i < diffRightEndPoint; i++) {
+ leftMargin = marginWidth * i
- let squarePolygon = turf.polygon([square])
- let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
- let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
+ square = [
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
+ [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
+ [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + bottomMargin],
+ [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
+ ]
- // if (disjointFromTrestle && isDisjoint) {
- moduleOptions.surfaceId = moduleSetupSurface.id
- let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
- canvas?.add(tempModule)
- moduleSetupArray.push(tempModule)
- moduleGroup.push(tempModule)
+ let squarePolygon = turf.polygon([square])
+ let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
+ let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
+
+ // if (disjointFromTrestle && isDisjoint) {
+ moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
+ let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
+ canvas?.add(tempModule)
+ moduleSetupArray.push(tempModule)
+ moduleGroup.push(tempModule)
+ }
}
- }
+ })
}
- const flatRoofTopFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
- let startPoint = moduleSetupSurface.flowLines.top
+ const flatRoofRightFlowSetupModule = (surfaceMaxLines, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
+ checkedModule.forEach((module, index) => {
+ const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
+ const flowLines = getFlowLines(moduleSetupSurface, width)
+ let startPoint = flowLines.right
- const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
- const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
- const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
+ const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
+ const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
+ const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
- let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
- let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint
- let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1
- let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
- let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width))
- let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height))
- let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
- let tempMaxWidth = width //최대배치인지 확인하려고 넣음
+ let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
+ let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
+ let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
+ let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width
+ let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정
+ let tempMaxHeight = height //최대배치인지 확인하려고 넣음
- for (let j = 0; j < diffBottomEndPoint; j++) {
- bottomMargin = marginHeight * j
- for (let i = 0; i < diffRightEndPoint; i++) {
- leftMargin = marginWidth * i
+ for (let i = 0; i <= totalWidth; i++) {
+ bottomMargin = marginHeight * i
+ for (let j = 0; j < totalHeight; j++) {
+ leftMargin = marginWidth * j
- square = [
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
- [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
- [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + bottomMargin],
- [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
- ]
+ square = [
+ [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
+ [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
+ [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
+ ]
- let squarePolygon = turf.polygon([square])
- let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
- let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
+ let squarePolygon = turf.polygon([square])
+ let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
+ let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
- // if (disjointFromTrestle && isDisjoint) {
- moduleOptions.surfaceId = moduleSetupSurface.id
- let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
- canvas?.add(tempModule)
- moduleSetupArray.push(tempModule)
- moduleGroup.push(tempModule)
+ // if (disjointFromTrestle && isDisjoint) {
+ moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
+ let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
+ canvas?.add(tempModule)
+ moduleSetupArray.push(tempModule)
+ moduleGroup.push(tempModule)
+ }
}
- }
- }
-
- const flatRoofRightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
- let startPoint = moduleSetupSurface.flowLines.right
-
- const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
- const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
- const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
-
- let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
- let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
- let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
- let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width
- let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정
- let tempMaxHeight = height //최대배치인지 확인하려고 넣음
-
- for (let i = 0; i <= totalWidth; i++) {
- bottomMargin = marginHeight * i
- for (let j = 0; j < totalHeight; j++) {
- leftMargin = marginWidth * j
-
- square = [
- [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
- [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
- [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
- ]
-
- let squarePolygon = turf.polygon([square])
- let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
- let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
-
- // if (disjointFromTrestle && isDisjoint) {
- moduleOptions.surfaceId = moduleSetupSurface.id
- let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
- canvas?.add(tempModule)
- moduleSetupArray.push(tempModule)
- moduleGroup.push(tempModule)
- }
- }
+ })
}
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
@@ -2047,29 +2422,20 @@ export function useModuleBasicSetting() {
const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface, true) //폴리곤을 turf 객체로 변환
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
- let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4
- let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2
-
- //배치면때는 방향쪽으로 패널이 넓게 누워져야함
- if (moduleSetupSurface.flowDirection !== undefined) {
- width = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 172.2 : 113.4
- height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
- }
-
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
const marginWidth = 1
- const marginHeight = 1
+ const marginHeight = 3
canvas.renderAll()
if (compasDeg >= 0 && compasDeg < 90) {
- flatRoofDownFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
+ flatRoofDownFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
} else if (compasDeg >= 90 && compasDeg < 180) {
- flatRoofLeftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
+ flatRoofLeftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
} else if (compasDeg >= 180 && compasDeg < 270) {
- flatRoofRightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
+ flatRoofRightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
} else {
- flatRoofTopFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
+ flatRoofTopFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
}
const setupedModules = moduleSetupArray.filter((module, index) => {
@@ -2154,7 +2520,7 @@ export function useModuleBasicSetting() {
const getModuleStatistics = () => {
const surfaces = canvas.getObjects().filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name)
- console.log('🚀 ~ getModuleStatistics ~ surfaces:', surfaces)
+ // console.log('🚀 ~ getModuleStatistics ~ surfaces:', surfaces)
let totalWpout = 0
let moduleInfo = {}
const rows = surfaces.map((surface) => {
@@ -2169,7 +2535,7 @@ export function useModuleBasicSetting() {
moduleInfo[module.moduleInfo.itemId].amount++
})
totalWpout += wpOut
- console.log('🚀 ~ moduleData.rows=surfaces.map ~ module:', module)
+ // console.log('🚀 ~ moduleData.rows=surfaces.map ~ module:', module)
const rowObject = {}
Object.keys(moduleInfo).forEach((key) => {
rowObject[key] = moduleInfo[key].amount
@@ -2179,12 +2545,12 @@ export function useModuleBasicSetting() {
...surface,
name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면
// powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }),
- wpOut: wpOut,
+ wpOut: (wpOut / 1000).toFixed(3),
}
})
- console.log('🚀 ~ getModuleStatistics ~ rows:', rows)
- console.log('🚀 ~ getModuleStatistics ~ moduleInfo:', moduleInfo)
+ // console.log('🚀 ~ getModuleStatistics ~ rows:', rows)
+ // console.log('🚀 ~ getModuleStatistics ~ moduleInfo:', moduleInfo)
const header = [
{ name: getMessage('modal.panel.batch.statistic.roof.shape'), prop: 'name' },
...Object.keys(moduleInfo).map((key) => {
@@ -2192,7 +2558,7 @@ export function useModuleBasicSetting() {
}),
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
]
- let footer = ['합계']
+ let footer = [getMessage('modal.panel.batch.statistic.total')]
let footerData = {}
rows.forEach((row) => {
Object.keys(moduleInfo).map((key) => {
@@ -2203,17 +2569,62 @@ export function useModuleBasicSetting() {
Object.keys(footerData).forEach((key) => {
footer.push(footerData[key])
})
- footer.push(totalWpout)
- console.log({ header: header, rows, footer: footer })
+ footer.push((totalWpout / 1000).toFixed(3))
+ // console.log({ header: header, rows, footer: footer })
setModuleStatistics({ header: header, rows, footer: footer })
}
+ /**
+ * 모듈의 너비와 높이를 계산하는 함수
+ * @param {object} maxLengthLine 최대 길이 라인
+ * @param {object} moduleSetupSurface 모듈 설치면
+ * @param {object} module 모듈
+ * @returns {object} 모듈의 너비와 높이
+ */
+ const getModuleWidthHeight = (maxLengthLine, moduleSetupSurface, module) => {
+ let tmpWidth =
+ (maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.longAxis) : Number(module.shortAxis)) / 10
+ let tmpHeight =
+ (maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? Number(module.shortAxis) : Number(module.longAxis)) / 10
+
+ //배치면때는 방향쪽으로 패널이 넓게 누워져야함
+ if (moduleSetupSurface.flowDirection !== undefined) {
+ tmpWidth =
+ (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
+ ? Number(module.longAxis)
+ : Number(module.shortAxis)) / 10
+ tmpHeight =
+ (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north'
+ ? Number(module.shortAxis)
+ : Number(module.longAxis)) / 10
+ }
+
+ return canvasSetting.roofSizeSet === '1'
+ ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurface.roofMaterial.pitch), moduleSetupSurface.flowDirection)
+ : { width: tmpWidth, height: tmpHeight }
+ }
+
+ const getFlowLines = (moduleSetupSurface, length) => {
+ let flowLines = {}
+
+ flowLines = {
+ bottom: bottomTopFlowLine(moduleSetupSurface, length).find((obj) => obj.target === 'bottom'),
+ top: bottomTopFlowLine(moduleSetupSurface, length).find((obj) => obj.target === 'top'),
+ left: leftRightFlowLine(moduleSetupSurface, length).find((obj) => obj.target === 'left'),
+ right: leftRightFlowLine(moduleSetupSurface, length).find((obj) => obj.target === 'right'),
+ }
+ return flowLines
+ }
+
return {
+ selectedModules,
+ makeModuleInstArea,
manualModuleSetup,
autoModuleSetup,
restoreModuleInstArea,
manualFlatroofModuleSetup,
autoFlatroofModuleSetup,
checkModuleDisjointObjects,
+ makeModuleInitArea,
}
}
diff --git a/src/hooks/module/useModulePlace.js b/src/hooks/module/useModulePlace.js
index 8b1940f9..38e628a0 100644
--- a/src/hooks/module/useModulePlace.js
+++ b/src/hooks/module/useModulePlace.js
@@ -10,6 +10,8 @@ import offsetPolygon from '@/util/qpolygon-utils'
import { v4 as uuidv4 } from 'uuid'
import { QPolygon } from '@/components/fabric/QPolygon'
import { useEvent } from '@/hooks/useEvent'
+import { useSwal } from '@/hooks/useSwal'
+import { useMessage } from '@/hooks/useMessage'
export function useModulePlace() {
const canvas = useRecoilValue(canvasState)
@@ -23,211 +25,9 @@ export function useModulePlace() {
const roofDisplay = useRecoilValue(roofDisplaySelector)
const { addTargetMouseEventListener } = useEvent()
const setModuleSetupSurface = useSetRecoilState(moduleSetupSurfaceState)
-
- useEffect(() => {
- if (moduleSelectionData) {
- const common = moduleSelectionData.common
- const roofConstructions = moduleSelectionData.roofConstructions
-
- const listParams = roofConstructions.map((item) => {
- return {
- ...common,
- moduleTpCd: selectedModules.itemTp,
- roofMatlCd: item.trestle.roofMatlCd,
- trestleMkrCd: item.trestle.trestleMkrCd,
- constMthdCd: item.trestle.constMthdCd,
- roofBaseCd: item.trestle.roofBaseCd,
- constTp: item.construction.constTp,
- mixMatlNo: selectedModules.mixMatlNo,
- roofPitch: item.addRoof.roofPchBase ? item.addRoof.roofPchBase : null,
- inclCd: String(item.addRoof.pitch),
- roofIndex: item.addRoof.index,
- workingWidth: item.addRoof.lenBase,
- }
- })
- setTrestleDetailParams(listParams)
- }
- }, [moduleSelectionData])
-
- const getTrestleDetailListData = async () => {
- const trestleDetailList = await getTrestleDetailList(trestleDetailParams)
- if (trestleDetailList.length > 0) {
- setTrestleDetailList(trestleDetailList)
- }
- }
-
- useEffect(() => {
- if (trestleDetailParams.length > 0) {
- getTrestleDetailListData(trestleDetailParams)
- }
- }, [trestleDetailParams])
-
- useEffect(() => {
- if (trestleDetailList.length > 0) {
- //지붕을 가져옴
- canvas
- .getObjects()
- .filter((roof) => roof.name === 'roof')
- .forEach((roof) => {
- const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번
- trestleDetailList.forEach((detail) => {
- if (detail.data !== null) {
- if (Number(detail.data.roofIndex) === roofIndex) {
- //roof에 상세 데이터 추가
- roof.set({ trestleDetail: detail.data })
- //배치면 설치 영역
- makeModuleInstArea(roof, detail.data)
- //surface에 상세 데이터 추가
- } else {
- console.log('가대 데이터가 없네요...')
- }
- }
- })
- })
- }
- }, [trestleDetailList])
-
- const makeModuleInstArea = (roof, trestleDetail) => {
- //지붕 객체 반환
-
- if (!roof) {
- return
- }
-
- const batchObjects = canvas
- ?.getObjects()
- .filter(
- (obj) =>
- obj.name === BATCH_TYPE.OPENING ||
- obj.name === BATCH_TYPE.SHADOW ||
- obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
- obj.name === BATCH_TYPE.PENTAGON_DORMER,
- ) //도머s 객체
-
- //도머도 외곽을 따야한다
-
- const batchObjectOptions = {
- stroke: 'red',
- fill: 'transparent',
- strokeDashArray: [10, 4],
- strokeWidth: 1,
- lockMovementX: true,
- lockMovementY: true,
- lockRotation: true,
- lockScalingX: true,
- lockScalingY: true,
- selectable: true,
- name: POLYGON_TYPE.OBJECT_SURFACE,
- originX: 'center',
- originY: 'center',
- }
-
- batchObjects.forEach((obj) => {
- if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) {
- const groupPoints = obj.groupPoints
- const offsetObjects = offsetPolygon(groupPoints, 10)
- const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions)
- dormerOffset.setViewLengthText(false)
- canvas.add(dormerOffset) //모듈설치면 만들기
- } else {
- const points = obj.points
- const offsetObjects = offsetPolygon(points, 10)
- const offset = new QPolygon(offsetObjects, batchObjectOptions)
- offset.setViewLengthText(false)
- canvas.add(offset) //모듈설치면 만들기
- }
- })
-
- const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id)
- if (isExistSurface) {
- return
- }
-
- let offsetLength = canvasSetting.roofSizeSet === 3 ? -90 : (trestleDetail.eaveIntvl / 10) * -1
- setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경
- const offsetPoints = offsetPolygon(roof.points, offsetLength) //안쪽 offset
- //모듈설치영역?? 생성
-
- const surfaceId = uuidv4()
-
- let setupSurface = new QPolygon(offsetPoints, {
- stroke: 'red',
- fill: 'transparent',
- strokeDashArray: [10, 4],
- strokeWidth: 1,
- lockMovementX: true,
- lockMovementY: true,
- lockRotation: true,
- lockScalingX: true,
- lockScalingY: true,
- selectable: true,
- parentId: roof.id, //가대 폴리곤의 임시 인덱스를 넣어줌
- name: POLYGON_TYPE.MODULE_SETUP_SURFACE,
- flowDirection: roof.direction,
- direction: roof.direction,
- flipX: roof.flipX,
- flipY: roof.flipY,
- surfaceId: surfaceId,
- originX: 'center',
- originY: 'center',
- modules: [],
- roofMaterial: roof.roofMaterial,
- trestleDetail: trestleDetail,
- // angle: -compasDeg,
- })
-
- setupSurface.setViewLengthText(false)
- canvas.add(setupSurface) //모듈설치면 만들기
-
- //지붕면 선택 금지
- roof.set({
- selectable: false,
- })
-
- //모듈설치면 클릭이벤트
- addTargetMouseEventListener('mousedown', setupSurface, function () {
- toggleSelection(setupSurface)
- })
- }
-
- let selectedModuleInstSurfaceArray = []
-
- //설치 범위 지정 클릭 이벤트
- const toggleSelection = (setupSurface) => {
- const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
- //최초 선택일때
- if (!isExist) {
- //기본 선택이랑 스트로크 굵기가 같으면 선택 안됨으로 봄
- setupSurface.set({
- ...setupSurface,
- strokeWidth: 3,
- strokeDashArray: [0],
- fill: 'transparent',
- })
- canvas.discardActiveObject() // 객체의 활성 상태 해제
- //중복으로 들어가는걸 방지하기 위한 코드
-
- canvas?.renderAll()
- selectedModuleInstSurfaceArray.push(setupSurface)
- } else {
- //선택후 재선택하면 선택안됨으로 변경
- setupSurface.set({
- ...setupSurface,
- fill: 'transparent',
- strokeDashArray: [10, 4],
- strokeWidth: 1,
- })
- canvas.discardActiveObject() // 객체의 활성 상태 해제
-
- //폴리곤에 커스텀 인덱스를 가지고 해당 배열 인덱스를 찾아 삭제함
- const removeIndex = setupSurface.parentId
- const removeArrayIndex = selectedModuleInstSurfaceArray.findIndex((obj) => obj.parentId === removeIndex)
- selectedModuleInstSurfaceArray.splice(removeArrayIndex, 1)
- }
-
- canvas?.renderAll()
- setModuleSetupSurface([...selectedModuleInstSurfaceArray])
- }
+ const [saleStoreNorthFlg, setSaleStoreNorthFlg] = useState(false)
+ const { swalFire } = useSwal()
+ const { getMessage } = useMessage()
return {
selectedModules,
diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js
index 0321abaa..0f609eeb 100644
--- a/src/hooks/module/useModuleSelection.js
+++ b/src/hooks/module/useModuleSelection.js
@@ -5,8 +5,11 @@ import { useMasterController } from '@/hooks/common/useMasterController'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { selectedModuleState, moduleSelectionInitParamsState, moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils'
+import { canvasState } from '@/store/canvasAtom'
+import { POLYGON_TYPE } from '@/common/common'
export function useModuleSelection(props) {
+ const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록
@@ -41,6 +44,7 @@ export function useModuleSelection(props) {
instHt: managementState?.installHeight, //설치높이
stdWindSpeed: managementState?.standardWindSpeedId, //기준풍속
stdSnowLd: managementState?.verticalSnowCover, //기준적설량
+ saleStoreNorthFlg: managementState?.saleStoreNorthFlg, //북쪽 설치 여부
}
if (selectedModules) {
@@ -62,6 +66,7 @@ export function useModuleSelection(props) {
// 202000 풍속
const windCodeList = findCommonCode('202000')
+
windCodeList.forEach((obj) => {
obj.name = obj.clCodeNm
obj.id = obj.clCode
@@ -83,6 +88,17 @@ export function useModuleSelection(props) {
}
getModuleData(roofsIds)
+
+ //해당 메뉴 이동시 배치면 삭제
+ const moduleSurfacesArray = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE)
+ if (moduleSurfacesArray.length > 0) {
+ moduleSurfacesArray.forEach((moduleSurface) => {
+ canvas.remove(moduleSurface)
+ })
+ canvas.renderAll()
+ }
}, [])
const getModuleData = async (roofsIds) => {
@@ -98,7 +114,9 @@ export function useModuleSelection(props) {
}
//데이터가 있으면 모듈 자동 선택
+ //1번 모듈 리스트 조회
useEffect(() => {
+ //모듈리스트의 데이터가 변경 되면 모듈 선택으로 이벤트
if (moduleList.length > 0 && isObjectNotEmpty(moduleSelectionData.module)) {
handleChangeModule(moduleSelectionData.module)
}
diff --git a/src/hooks/module/useModuleTabContents.js b/src/hooks/module/useModuleTabContents.js
index f15e643f..43e3845e 100644
--- a/src/hooks/module/useModuleTabContents.js
+++ b/src/hooks/module/useModuleTabContents.js
@@ -5,10 +5,8 @@ import { useMasterController } from '@/hooks/common/useMasterController'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { moduleSelectionDataState, moduleSelectionInitParamsState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty, isEqualObjects } from '@/util/common-utils'
-import { addedRoofsState } from '@/store/settingAtom'
export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) {
- const addRoofsArray = useRecoilValue(addedRoofsState)
const globalPitchText = useRecoilValue(pitchTextSelector) //피치 텍스트
const { findCommonCode } = useCommonCode()
@@ -31,7 +29,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
const [roofBaseParams, setRoofBaseParams] = useState({}) //지붕밑바탕 관련 api호출 파라메터
const moduleSelectionInitParams = useRecoilValue(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등
- const moduleSelectionInitOriginData = useRef(moduleSelectionInitParams)
+ const moduleSelectionInitOriginData = useRef({})
const { getTrestleList, getConstructionList } = useMasterController()
@@ -55,6 +53,8 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
const hajebichiRef = useRef()
const lengthRef = useRef()
+ const [isChangeInitData, setIsChangeInitData] = useState(false)
+
//서까래간격 변경
const handleChangeRaftBase = (option) => {
setSelectedRaftBase(option)
@@ -62,7 +62,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
// setConstMthdList([]) //공법 초기화
// setRoofBaseList([]) //지붕밑바탕 초기화
// setConstructionList([]) //공법 초기화
- resetSelected()
+ resetSelected(1)
}
//처마력바 체크
@@ -109,11 +109,13 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//리코일에 데이터가 담기는 시점에 시작
useEffect(() => {
if (
+ isObjectNotEmpty(moduleSelectionData) &&
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex]) &&
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex].trestle) &&
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex].construction)
) {
- setModuleConstructionSelectionData(moduleSelectionData.roofConstructions[tabIndex])
+ const roofConstructions = moduleSelectionData.roofConstructions.filter((item) => item.roofIndex === tabIndex)[0]
+ setModuleConstructionSelectionData(roofConstructions)
}
}, [moduleSelectionData])
@@ -123,18 +125,30 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
}
}, [moduleConstructionSelectionData])
- // useEffect(() => {
- // if (isExistData) {
- // setConstructionListParams({
- // ...moduleSelectionInitParams,
- // ...roofBaseParams,
- // roofBaseCd: selectedRoofBase.roofBaseCd,
- // inclCd: addRoof.pitch,
- // roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
- // raftBaseCd: selectedRaftBase.raftBaseCd ? selectedRaftBase.raftBaseCd : '',
- // })
- // }
- // }, [selectedRoofBase])
+ useEffect(() => {
+ //되돌아왔을때 재호출 하여 선택한다
+ if (isExistData) {
+ setTrestleParams({
+ moduleTpCd: selectedModules.itemTp,
+ roofMatlCd: addRoof.roofMatlCd,
+ raftBaseCd: selectedRaftBase.raftBaseCd ? selectedRaftBase.raftBaseCd : '',
+ workingWidth: lengthBase,
+ })
+ }
+ }, [isExistData])
+
+ useEffect(() => {
+ if (isExistData) {
+ setConstructionListParams({
+ ...moduleSelectionInitParams,
+ ...roofBaseParams,
+ roofBaseCd: selectedRoofBase.roofBaseCd,
+ inclCd: addRoof.pitch,
+ roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
+ raftBaseCd: selectedRaftBase.raftBaseCd ? selectedRaftBase.raftBaseCd : '',
+ })
+ }
+ }, [selectedRoofBase])
useEffect(() => {
if (
@@ -154,7 +168,9 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//모듈 변경
useEffect(() => {
//lengbase는 무조건 있다고 가정 하고 최초에 실행 방지
+
if (selectedModules) {
+ //여기서부터 시작
//가대메이커 파라메터 만들기
setTrestleParams({
moduleTpCd: selectedModules.itemTp,
@@ -174,8 +190,11 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//가대메이커 변경 함수
const handleChangeTrestle = (option) => {
- setSelectedTrestle(option) //선택값 저장
- setConstructionParams({ ...trestleParams, trestleMkrCd: option.trestleMkrCd, constMthdCd: '', roofBaseCd: '' })
+ if (isObjectNotEmpty(option)) {
+ option.raftBaseCd = selectedRaftBase.raftBaseCd
+ setSelectedTrestle(option) //선택값 저장
+ setConstructionParams({ ...trestleParams, trestleMkrCd: option.trestleMkrCd, constMthdCd: '', roofBaseCd: '' })
+ }
}
useEffect(() => {
@@ -186,13 +205,15 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//공법 변경
const handleChangeConstMthd = (option) => {
- setSelectedConstMthd(option) //선택된값 저장
- setRoofBaseParams({
- ...trestleParams,
- trestleMkrCd: selectedTrestle.trestleMkrCd,
- constMthdCd: option.constMthdCd,
- roofBaseCd: '',
- })
+ if (isObjectNotEmpty(option)) {
+ setSelectedConstMthd(option) //선택된값 저장
+ setRoofBaseParams({
+ ...trestleParams,
+ trestleMkrCd: selectedTrestle.trestleMkrCd,
+ constMthdCd: option.constMthdCd,
+ roofBaseCd: '',
+ })
+ }
}
useEffect(() => {
@@ -202,17 +223,19 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
}, [roofBaseParams])
const handleChangeRoofBase = (option) => {
- setConstructionListParams({
- ...moduleSelectionInitParams,
- trestleMkrCd: selectedTrestle.trestleMkrCd,
- constMthdCd: selectedConstMthd.constMthdCd,
- roofBaseCd: option.roofBaseCd,
- inclCd: addRoof.pitch,
- roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
- raftBaseCd: selectedRaftBase.clCode ? selectedRaftBase.clCode : '',
- roofMatlCd: addRoof.roofMatlCd,
- })
- setSelectedRoofBase(option)
+ if (isObjectNotEmpty(option)) {
+ setConstructionListParams({
+ ...moduleSelectionInitParams,
+ trestleMkrCd: selectedTrestle.trestleMkrCd,
+ constMthdCd: selectedConstMthd.constMthdCd,
+ roofBaseCd: option.roofBaseCd,
+ inclCd: addRoof.pitch,
+ roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
+ raftBaseCd: selectedRaftBase.clCode ? selectedRaftBase.clCode : '',
+ roofMatlCd: addRoof.roofMatlCd,
+ })
+ setSelectedRoofBase(option)
+ }
}
//공법 리스트 변경 함수
@@ -266,32 +289,30 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//공법 선택시 이후 프로세스
useEffect(() => {
if (isObjectNotEmpty(selectedRoofBase) && isObjectNotEmpty(selectedConstruction)) {
- if (tabIndex === roofTab) {
- const common = { ...moduleSelectionInitParams }
- const module = { ...selectedModules }
- const newRoofConstructions = {
- roofIndex: tabIndex,
- addRoof: addRoof,
- trestle: selectedRoofBase,
- construction: selectedConstruction,
- }
+ const common = { ...moduleSelectionInitParams }
+ const module = { ...selectedModules }
+ const newRoofConstructions = {
+ roofIndex: tabIndex,
+ addRoof: addRoof,
+ trestle: selectedRoofBase,
+ construction: selectedConstruction,
+ }
- const index = tempModuleSelectionData.roofConstructions.findIndex((obj) => obj.roofIndex === tabIndex)
+ const index = moduleSelectionData.roofConstructions.findIndex((obj) => obj.roofIndex === tabIndex)
- if (index > -1) {
- const newArray = [
- ...tempModuleSelectionData.roofConstructions.slice(0, index),
- newRoofConstructions,
- ...tempModuleSelectionData.roofConstructions.slice(index + 1),
- ]
- setTempModuleSelectionData({ common: common, module: module, roofConstructions: newArray })
- } else {
- setTempModuleSelectionData({
- common: common,
- module: module,
- roofConstructions: [...tempModuleSelectionData.roofConstructions, { ...newRoofConstructions }],
- })
- }
+ if (index > -1) {
+ const newArray = [
+ ...tempModuleSelectionData.roofConstructions.slice(0, index),
+ newRoofConstructions,
+ ...tempModuleSelectionData.roofConstructions.slice(index + 1),
+ ]
+ setTempModuleSelectionData({ common: common, module: module, roofConstructions: newArray })
+ } else {
+ setTempModuleSelectionData({
+ common: common,
+ module: module,
+ roofConstructions: [...tempModuleSelectionData.roofConstructions, { ...newRoofConstructions }],
+ })
}
}
}, [selectedConstruction])
@@ -299,12 +320,11 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
//거대메이커, 공법, 지붕밑바탕 api 조회
const getModuleOptionsListData = async (params, type) => {
const optionsList = await getTrestleList(params)
-
if (optionsList.data.length > 0) {
if (type === 'trestle') {
//가대 메이커일때
setTrestleList(optionsList.data) //가대 목록
- if (isExistData) {
+ if (isExistData && isObjectNotEmpty(moduleConstructionSelectionData?.trestle)) {
//데이터가 있으면 선택된 가대 메이커를 선택한다
handleChangeTrestle(moduleConstructionSelectionData?.trestle)
} else {
@@ -314,7 +334,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
} else if (type === 'construction') {
//공법일때
setConstMthdList(optionsList.data) //공법 목록
- if (isExistData) {
+ if (isExistData && isObjectNotEmpty(moduleConstructionSelectionData?.construction)) {
//데이터가 있으면 선택된 공법을 선택한다
handleChangeConstMthd(moduleConstructionSelectionData?.trestle)
} else {
@@ -323,7 +343,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
} else if (type === 'roofBase') {
//지붕밑바탕일때
setRoofBaseList(optionsList.data) //지붕밑바탕 목록
- if (isExistData) {
+ if (isExistData && isObjectNotEmpty(moduleConstructionSelectionData?.trestle)) {
//데이터가 있으면 선택된 지붕밑바탕을 선택한다
handleChangeRoofBase(moduleConstructionSelectionData?.trestle) //선택된 지붕밑바탕을 선택한다
}
@@ -333,24 +353,40 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
useEffect(() => {
//모듈이 선택되어있을때
- if (moduleSelectionInitOriginData.current.moduleItemId && moduleSelectionInitOriginData.current.moduleTpCd) {
- //초기에 들어온 데이터가 수정된 데이터가 값이 다르다면`
- if (!isEqualObjects(moduleSelectionInitOriginData.current, moduleSelectionInitParams)) {
- resetSelected()
+ //초기 데이터가 모두 들어있을 경우에 초기 데이터를 저장한다
+ if (
+ moduleSelectionInitParams.illuminationTp &&
+ moduleSelectionInitParams.illuminationTpNm &&
+ moduleSelectionInitParams.instHt &&
+ moduleSelectionInitParams.moduleItemId &&
+ moduleSelectionInitParams.moduleTpCd &&
+ moduleSelectionInitParams.saleStoreNorthFlg &&
+ moduleSelectionInitParams.stdSnowLd &&
+ moduleSelectionInitParams.stdWindSpeed
+ ) {
+ if (!isObjectNotEmpty(moduleSelectionInitOriginData.current)) {
+ moduleSelectionInitOriginData.current = moduleSelectionInitParams
}
}
+
+ if (
+ isObjectNotEmpty(moduleSelectionInitOriginData.current) &&
+ !isEqualObjects(moduleSelectionInitOriginData.current, moduleSelectionInitParams)
+ ) {
+ resetSelected(2)
+ }
}, [moduleSelectionInitParams])
const handleHajebichiAndLength = (e, type) => {
if (type === 'length') {
- setLengthBase(e.target.value)
+ setLengthBase(Number(e.target.value))
} else {
- setHajebichi(e.target.value)
+ setHajebichi(Number(e.target.value))
}
- resetSelected()
+ resetSelected(3)
}
- const resetSelected = () => {
+ const resetSelected = (num) => {
//가대 선택 초기화
setSelectedTrestle({})
diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js
index b64fc171..36b4e640 100644
--- a/src/hooks/module/useOrientation.js
+++ b/src/hooks/module/useOrientation.js
@@ -23,10 +23,13 @@ export function useOrientation() {
}, [])
const nextStep = () => {
+ if (isNaN(compasDeg)) {
+ setCompasDeg(0)
+ }
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
roofs.forEach((roof) => {
roof.set({
- moduleCompass: compasDeg,
+ moduleCompass: isNaN(compasDeg) ? 0 : compasDeg,
})
drawDirectionArrow(roof)
})
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js
index 2fd95ba2..20e8b4ac 100644
--- a/src/hooks/module/useTrestle.js
+++ b/src/hooks/module/useTrestle.js
@@ -1,461 +1,742 @@
import { useRecoilValue } from 'recoil'
-import { canvasState } from '@/store/canvasAtom'
+import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom'
import { POLYGON_TYPE } from '@/common/common'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
-import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util'
+import { getDegreeByChon } from '@/util/canvas-util'
import { v4 as uuidv4 } from 'uuid'
import { useMasterController } from '@/hooks/common/useMasterController'
+import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom'
+import { useSwal } from '@/hooks/useSwal'
// 회로 및 가대설정
export const useTrestle = () => {
const canvas = useRecoilValue(canvasState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
const { getQuotationItem } = useMasterController()
-
+ const currentAngleType = useRecoilValue(currentAngleTypeSelector)
+ const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
+ const isTrestleDisplay = useRecoilValue(trestleDisplaySelector)
+ const { swalFire } = useSwal()
const apply = () => {
- //처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함.
- // exposedBottomPoints는 노출 최하면 들의 centerPoint 배열.
+ const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
+ if (notAllocationModules.length > 0) {
+ swalFire({ text: '回路番号が設定されていないモジュールがあります。 番号を設定しなおすか、 パネルを削除してください。', icon: 'error' })
+ return null
+ }
+ try {
+ //처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함.
+ // exposedBottomPoints는 노출 최하면 들의 centerPoint 배열.
- const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
- // 기존 eaveBar를 삭제
- canvas.getObjects().forEach((obj) => {
- if (obj.name === 'eaveBar' || obj.name === 'rack' || obj.name === 'halfEaveBar' || obj.name === 'smartRack') {
- canvas.remove(obj)
- }
- })
- canvas.getObjects().forEach((obj) => {
- if (obj.name === 'bracket') {
- canvas.remove(obj)
- }
- })
- surfaces.forEach((surface) => {
- const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
- const roofMaterialIndex = parent.roofMaterial.index
- const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction
- if (!construction) {
- alert('앞에서 셋팅 안됨')
- return
- }
-
- let moduleRowsTotCnt = 0
- let isEaveBar = construction.setupCover
- let isSnowGuard = construction.setupSnowCover
- const direction = parent.direction
- const rack = surface.trestleDetail.rack
- let { rackQty, rackIntvlPct, rackYn, cvrPlvrYn } = surface.trestleDetail
-
- if (!rack) {
- //25/01/16 기준 랙이 없는 경우는 그냥 안그려준다.
- return
- }
-
- const rackInfos = Object.keys(rack).map((key) => {
- return { key, value: rack[key] }
- })
-
- const result = calculateForApi(surface)
- const centerPoints = result.centerPoints
-
- const exposedBottomModules = [] // 아래 두면이 모두 노출 되어있는 경우
- const leftExposedHalfBottomModules = [] // 왼쪽 면만 노출되어있는 경우
- const rightExposedHalfBottomPoints = [] // 오른쪽 면만 노출되어 있는 경우
- const leftExposedHalfTopModules = [] // 왼쪽 면만 노출되어 있는 경우
- const rightExposedHalfTopPoints = [] // 오른쪽 면만 노출되어 있는 경우
- const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
-
- modules.forEach((module) => {
- const { x, y } = module.getCenterPoint()
- const isExposedBottom = result.exposedBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
- const isLeftExposedHalfBottom = result.leftExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
- const isRightExposedHalfBottom = result.rightExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
- const isRightExposedHalfTop = result.rightExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
- const isLeftExposedHalfTop = result.leftExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
- if (isExposedBottom) {
- exposedBottomModules.push(module)
- }
- if (isLeftExposedHalfBottom) {
- leftExposedHalfBottomModules.push(module)
- }
- if (isRightExposedHalfBottom) {
- rightExposedHalfBottomPoints.push(module)
- }
- if (isRightExposedHalfTop) {
- leftExposedHalfTopModules.push(module)
- }
- if (isLeftExposedHalfTop) {
- rightExposedHalfTopPoints.push(module)
- }
- })
-
- // 4개중 한개라도 있는 경우 치조배치로 간주한다.
- const isChidory =
- leftExposedHalfBottomModules.length > 0 ||
- rightExposedHalfBottomPoints.length > 0 ||
- leftExposedHalfTopModules.length > 0 ||
- rightExposedHalfTopPoints.length > 0
-
- surface.set({ isChidory: isChidory })
-
- canvas
- .getObjects()
- .filter((obj) => ['eaveBar', 'halfEaveBar'].includes(obj.name) && obj.parentId === surface.id)
- .forEach((obj) => {
+ const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ // 기존 eaveBar를 삭제
+ canvas.getObjects().forEach((obj) => {
+ if (obj.name === 'eaveBar' || obj.name === 'rack' || obj.name === 'halfEaveBar' || obj.name === 'smartRack') {
canvas.remove(obj)
- })
+ }
+ })
+ canvas.getObjects().forEach((obj) => {
+ if (obj.name === 'bracket') {
+ canvas.remove(obj)
+ }
+ })
+ surfaces.forEach((surface) => {
+ const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
+ const roofMaterialIndex = parent.roofMaterial.index
+ const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction
+ if (!construction) {
+ alert('앞에서 셋팅 안됨')
+ return
+ }
- if (isEaveBar) {
- // 처마력바설치 true인 경우 설치
- exposedBottomModules.forEach((module) => {
- //TODO : 방향별로 처마력바 설치해야함
- const bottomPoints = findTopTwoPoints([...module.points], direction)
- if (!bottomPoints) return
- const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], {
- parent: surface,
- name: 'eaveBar',
- stroke: 'blue',
- strokeWidth: 4,
- selectable: false,
- surfaceId: surface.id,
- parentId: module.id,
+ const plvrYn = construction.plvrYn
+ let moduleRowsTotCnt = 0
+ let isEaveBar = construction.setupCover
+ let isSnowGuard = construction.setupSnowCover
+ const direction = parent.direction
+ const rack = surface.trestleDetail.rack
+ let { rackQty, rackIntvlPct, rackYn, cvrPlvrYn, lessSupFitIntvlPct, lessSupFitQty } = surface.trestleDetail
+
+ if (!rack && lessSupFitIntvlPct === 0 && lessSupFitQty === 0) {
+ //25/02/06 가대없음의 경우 랙정보가 없음
+ return
+ }
+
+ let rackInfos = []
+
+ if (rack) {
+ rackInfos = Object.keys(rack).map((key) => {
+ return { key, value: rack[key] }
})
- canvas.add(eaveBar)
- canvas.renderAll()
+ }
+
+ const result = calculateForApi(surface)
+
+ if (!result) {
+ return
+ }
+ const centerPoints = result.centerPoints
+
+ const exposedBottomModules = [] // 아래 두면이 모두 노출 되어있는 경우
+ const leftExposedHalfBottomModules = [] // 왼쪽 면만 노출되어있는 경우
+ const rightExposedHalfBottomPoints = [] // 오른쪽 면만 노출되어 있는 경우
+ const leftExposedHalfTopModules = [] // 왼쪽 면만 노출되어 있는 경우
+ const rightExposedHalfTopPoints = [] // 오른쪽 면만 노출되어 있는 경우
+ const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+
+ modules.forEach((module) => {
+ const { x, y } = module.getCenterPoint()
+ const isExposedBottom = result.exposedBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
+ const isLeftExposedHalfBottom = result.leftExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
+ const isRightExposedHalfBottom = result.rightExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
+ const isRightExposedHalfTop = result.rightExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
+ const isLeftExposedHalfTop = result.leftExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
+ if (isExposedBottom) {
+ exposedBottomModules.push(module)
+ }
+ if (isLeftExposedHalfBottom) {
+ leftExposedHalfBottomModules.push(module)
+ }
+ if (isRightExposedHalfBottom) {
+ rightExposedHalfBottomPoints.push(module)
+ }
+ if (isRightExposedHalfTop) {
+ leftExposedHalfTopModules.push(module)
+ }
+ if (isLeftExposedHalfTop) {
+ rightExposedHalfTopPoints.push(module)
+ }
})
- if (isChidory && cvrPlvrYn === 'Y') {
- leftExposedHalfBottomModules.forEach((module) => {
- const bottomPoints = findTopTwoPoints([...module.points], direction)
- let barPoints = []
- //설치해야할 반처마커버 포인트를 방향에 따라 설정
+ // 4개중 한개라도 있는 경우 치조배치로 간주한다.
+ const isChidory =
+ leftExposedHalfBottomModules.length > 0 ||
+ rightExposedHalfBottomPoints.length > 0 ||
+ leftExposedHalfTopModules.length > 0 ||
+ rightExposedHalfTopPoints.length > 0
- if (direction === 'south') {
- barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x - module.width / 2, bottomPoints[1].y]
- } else if (direction === 'north') {
- barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y]
- } else if (direction === 'east') {
- barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[0].y - module.height / 2]
- } else if (direction === 'west') {
- barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y - module.height / 2]
- }
+ if (plvrYn === 'N' && isChidory) {
+ alert('치조불가공법입니다.')
+ clear()
+ throw new Error('치조불가공법입니다.')
+ }
+ surface.set({ isChidory: isChidory })
+
+ canvas
+ .getObjects()
+ .filter((obj) => ['eaveBar', 'halfEaveBar'].includes(obj.name) && obj.parentId === surface.id)
+ .forEach((obj) => {
+ canvas.remove(obj)
+ })
+
+ if (isEaveBar) {
+ // 처마력바설치 true인 경우 설치
+ exposedBottomModules.forEach((module) => {
+ //TODO : 방향별로 처마력바 설치해야함
+ const bottomPoints = findTopTwoPoints([...module.getCurrentPoints()], direction)
if (!bottomPoints) return
- const halfEaveBar = new fabric.Line(barPoints, {
+ const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], {
parent: surface,
- name: 'halfEaveBar',
+ name: 'eaveBar',
stroke: 'blue',
strokeWidth: 4,
selectable: false,
surfaceId: surface.id,
parentId: module.id,
+ visible: isTrestleDisplay,
})
- canvas.add(halfEaveBar)
+ canvas.add(eaveBar)
canvas.renderAll()
})
- rightExposedHalfBottomPoints.forEach((module) => {
- const bottomPoints = findTopTwoPoints([...module.points], direction)
- let barPoints = []
- //설치해야할 반처마커버 포인트를 방향에 따라 설정
+ if (isChidory && cvrPlvrYn === 'Y') {
+ leftExposedHalfBottomModules.forEach((module) => {
+ const bottomPoints = findTopTwoPoints([...module.getCurrentPoints()], direction)
+ let barPoints = []
+ //설치해야할 반처마커버 포인트를 방향에 따라 설정
- if (direction === 'south') {
- barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y]
- } else if (direction === 'north') {
- barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[0].x + module.width / 2, bottomPoints[1].y]
- } else if (direction === 'east') {
- barPoints = [bottomPoints[0].x, bottomPoints[1].y + module.height / 2, bottomPoints[1].x, bottomPoints[1].y]
- } else if (direction === 'west') {
- barPoints = [bottomPoints[0].x, bottomPoints[1].y - module.height / 2, bottomPoints[1].x, bottomPoints[1].y]
- }
+ if (direction === 'south') {
+ barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x - module.width / 2, bottomPoints[1].y]
+ } else if (direction === 'north') {
+ barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y]
+ } else if (direction === 'east') {
+ barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[0].y - module.height / 2]
+ } else if (direction === 'west') {
+ barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y - module.height / 2]
+ }
- if (!bottomPoints) return
- const halfEaveBar = new fabric.Line(barPoints, {
- parent: surface,
- name: 'halfEaveBar',
- stroke: 'blue',
- strokeWidth: 4,
- selectable: false,
- parentId: module.id,
+ if (!bottomPoints) return
+ const halfEaveBar = new fabric.Line(barPoints, {
+ parent: surface,
+ name: 'halfEaveBar',
+ stroke: 'blue',
+ strokeWidth: 4,
+ selectable: false,
+ surfaceId: surface.id,
+ parentId: module.id,
+ visible: isTrestleDisplay,
+ })
+ canvas.add(halfEaveBar)
+ canvas.renderAll()
})
- canvas.add(halfEaveBar)
- canvas.renderAll()
- })
+
+ rightExposedHalfBottomPoints.forEach((module) => {
+ const bottomPoints = findTopTwoPoints([...module.points], direction)
+ let barPoints = []
+ //설치해야할 반처마커버 포인트를 방향에 따라 설정
+
+ if (direction === 'south') {
+ barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y]
+ } else if (direction === 'north') {
+ barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[0].x + module.width / 2, bottomPoints[1].y]
+ } else if (direction === 'east') {
+ barPoints = [bottomPoints[0].x, bottomPoints[1].y + module.height / 2, bottomPoints[1].x, bottomPoints[1].y]
+ } else if (direction === 'west') {
+ barPoints = [bottomPoints[0].x, bottomPoints[1].y - module.height / 2, bottomPoints[1].x, bottomPoints[1].y]
+ }
+
+ if (!bottomPoints) return
+ const halfEaveBar = new fabric.Line(barPoints, {
+ parent: surface,
+ name: 'halfEaveBar',
+ stroke: 'blue',
+ strokeWidth: 4,
+ selectable: false,
+ parentId: module.id,
+ visible: isTrestleDisplay,
+ })
+ canvas.add(halfEaveBar)
+ canvas.renderAll()
+ })
+ }
}
- }
- const horizontal = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlHor : surface.trestleDetail.moduleIntvlVer
+ const horizontal = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlHor : surface.trestleDetail.moduleIntvlVer
- const vertical = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlVer : surface.trestleDetail.moduleIntvlHor
+ const vertical = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlVer : surface.trestleDetail.moduleIntvlHor
- let mostRowsModule = 0 // 모듈 최대 단 수
- // 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산
- // 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈
- exposedBottomModules.forEach((module) => {
- let { width, height } = { ...module }
- width = Math.floor(width)
- height = Math.floor(height)
- let { x: startX, y: startY } = { ...module.getCenterPoint() }
- let { x, y } = { ...module.getCenterPoint() }
- //TODO : 방향별로 가대 설치해야함
+ let mostRowsModule = 0 // 모듈 최대 단 수
+ // 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산
+ // 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈
+ exposedBottomModules.forEach((module) => {
+ let { width, height } = { ...module }
+ width = Math.floor(width)
+ height = Math.floor(height)
+ let { x: startX, y: startY } = { ...module.getCenterPoint() }
+ let { x, y } = { ...module.getCenterPoint() }
- let leftRows = 1
- let rightRows = 1
- let centerRows = 1
- let hasNextModule = true
- let findLeft = true
- let findRight = true
+ let leftRows = 1
+ let rightRows = 1
+ let centerRows = 1
+ let hasNextModule = true
+ let findLeft = true
+ let findRight = true
- //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
- while (hasNextModule) {
- //바로 위에 있는지 확인한다.
- let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ let leftFindModuleList = [module]
+ let rightFindModuleList = [module]
+ let centerFindModuleList = [module]
- if (nextModule) {
- // 바로 위 모듈을 찾는다.
- leftRows++
- x = nextModule.x
- y = nextModule.y
- } else {
- // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
- if (findLeft) {
- nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findLeft = false
- } else {
- nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findLeft = true
- }
+ //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
+ while (hasNextModule) {
+ //바로 위에 있는지 확인한다.
+ let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
if (nextModule) {
// 바로 위 모듈을 찾는다.
leftRows++
+ leftFindModuleList.push(nextModule)
x = nextModule.x
y = nextModule.y
} else {
- hasNextModule = false
+ // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
+ if (findLeft) {
+ nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findLeft = false
+ } else {
+ nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findLeft = true
+ }
+
+ if (nextModule) {
+ // 바로 위 모듈을 찾는다.
+ leftRows++
+ leftFindModuleList.push(nextModule)
+ x = nextModule.x
+ y = nextModule.y
+ } else {
+ hasNextModule = false
+ }
}
}
- }
- hasNextModule = true
- x = startX
- y = startY
+ hasNextModule = true
+ x = startX
+ y = startY
- // 오른쪽 찾는다.
- while (hasNextModule) {
- //바로 위에 있는지 확인한다.
- let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
-
- if (nextModule) {
- // 바로 위 모듈을 찾는다.
- rightRows++
- x = nextModule.x
- y = nextModule.y
- } else {
- // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
- if (findRight) {
- nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findRight = false
- } else {
- nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findRight = true
- }
+ // 오른쪽 찾는다.
+ while (hasNextModule) {
+ //바로 위에 있는지 확인한다.
+ let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
if (nextModule) {
// 바로 위 모듈을 찾는다.
rightRows++
+ rightFindModuleList.push(nextModule)
+ x = nextModule.x
+ y = nextModule.y
+ } else {
+ // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
+ if (findRight) {
+ nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findRight = false
+ } else {
+ nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findRight = true
+ }
+
+ if (nextModule) {
+ // 바로 위 모듈을 찾는다.
+ rightRows++
+ rightFindModuleList.push(nextModule)
+ x = nextModule.x
+ y = nextModule.y
+ } else {
+ hasNextModule = false
+ }
+ }
+ }
+
+ hasNextModule = true
+ x = startX
+ y = startY
+
+ // 센터 찾는다.
+ while (hasNextModule) {
+ //바로 위에 있는지 확인한다.
+ let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+
+ if (nextModule) {
+ // 바로 위 모듈을 찾는다.
+ centerFindModuleList.push(nextModule)
+ centerRows++
x = nextModule.x
y = nextModule.y
} else {
hasNextModule = false
}
}
- }
- hasNextModule = true
- x = startX
- y = startY
-
- // 센터 찾는다.
- while (hasNextModule) {
- //바로 위에 있는지 확인한다.
- let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
-
- if (nextModule) {
- // 바로 위 모듈을 찾는다.
- centerRows++
- x = nextModule.x
- y = nextModule.y
- } else {
- hasNextModule = false
- }
- }
-
- // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
- const leftRacks = rackInfos.find((rack) => {
- return rack.value.moduleRows === leftRows
- })?.value.racks
-
- // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
- const rightRacks = rackInfos.find((rack) => {
- return rack.value.moduleRows === rightRows
- })?.value.racks
- // 해당 rack으로 그려준다.
-
- const centerRacks = rackInfos.find((rack) => {
- return rack.value.moduleRows === centerRows
- })?.value.racks
-
- mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule)
-
- if (rackYn === 'Y') {
- drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
- drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
-
- if (rackQty === 3) {
- //rack 갯수가 3개인 경우는 중간렉도 추가해줘야함
- drawRacks(centerRacks, rackQty, rackIntvlPct, module, direction, 'C', rackYn)
- } else if (rackQty === 4) {
- drawRacks(leftRacks, rackQty, rackIntvlPct / 3, module, direction, 'L', rackYn)
- drawRacks(rightRacks, rackQty, rackIntvlPct / 3, module, direction, 'R', rackYn)
- }
- }
- module.set({ leftRows, rightRows, centerRows })
- })
- // 왼쪽아래에 모듈이 없는 모듈들
- leftExposedHalfBottomModules.forEach((module) => {
- const { width, height } = module
- let { x: startX, y: startY } = { ...module.getCenterPoint() }
- let { x, y } = { ...module.getCenterPoint() }
- //TODO : 방향별로 가대 설치해야함
-
- let leftRows = 1
- let hasNextModule = true
- let findLeft = true
-
- //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
- while (hasNextModule) {
- //바로 위에 있는지 확인한다.
- let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
-
- if (nextModule) {
- // 바로 위 모듈을 찾는다.
- leftRows++
- x = nextModule.x
- y = nextModule.y
- } else {
- // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
- if (findLeft) {
- nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findLeft = false
- } else {
- nextModule = nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findLeft = true
+ const leftModuleInfos = leftFindModuleList.map((module) => {
+ return {
+ moduleTpCd: module.moduleInfo.moduleTpCd,
}
+ })
+
+ const rightModuleInfos = rightFindModuleList.map((module) => {
+ return {
+ moduleTpCd: module.moduleInfo.moduleTpCd,
+ }
+ })
+
+ const centerModuleInfos = centerFindModuleList.map((module) => {
+ return {
+ moduleTpCd: module.moduleInfo.moduleTpCd,
+ }
+ })
+
+ const leftRowsInfo = moduleTransformData(leftModuleInfos)
+ const rightRowsInfo = moduleTransformData(rightModuleInfos)
+ const centerRowsInfo = moduleTransformData(centerModuleInfos)
+
+ // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
+ const leftRacks = rackInfos.find((rack) => {
+ if (leftRowsInfo.rowsInfo.length === 1) {
+ return (
+ rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
+ )
+ } else {
+ return (
+ rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
+ rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count &&
+ rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count
+ )
+ }
+ })?.value.racks
+
+ // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
+ const rightRacks = rackInfos.find((rack) => {
+ if (rightRowsInfo.rowsInfo.length === 1) {
+ return (
+ rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
+ )
+ } else {
+ return (
+ rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
+ rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count &&
+ rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count
+ )
+ }
+ })?.value.racks
+ // 해당 rack으로 그려준다.
+
+ const centerRacks = rackInfos.find((rack) => {
+ if (centerRowsInfo.rowsInfo.length === 1) {
+ return (
+ rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
+ )
+ } else {
+ return (
+ rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
+ rack.value.moduleTpRows1 === centerRowsInfo.rowsInfo[0].count &&
+ rack.value.moduleTpRows2 === centerRowsInfo.rowsInfo[1].count
+ )
+ }
+ })?.value.racks
+
+ mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule)
+
+ if (rackYn === 'Y') {
+ drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
+ drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
+
+ if (rackQty === 3) {
+ //rack 갯수가 3개인 경우는 중간렉도 추가해줘야함
+ drawRacks(centerRacks, rackQty, rackIntvlPct, module, direction, 'C', rackYn)
+ } else if (rackQty === 4) {
+ drawRacks(leftRacks, rackQty, rackIntvlPct / 3, module, direction, 'L', rackYn)
+ drawRacks(rightRacks, rackQty, rackIntvlPct / 3, module, direction, 'R', rackYn)
+ }
+ }
+ module.set({ leftRows, rightRows, centerRows })
+ })
+ // 왼쪽아래에 모듈이 없는 모듈들
+ leftExposedHalfBottomModules.forEach((module) => {
+ const { width, height } = module
+ let { x: startX, y: startY } = { ...module.getCenterPoint() }
+ let { x, y } = { ...module.getCenterPoint() }
+ //TODO : 방향별로 가대 설치해야함
+
+ let leftRows = 1
+ let hasNextModule = true
+ let findLeft = true
+ let findModuleList = [module]
+
+ //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
+ while (hasNextModule) {
+ //바로 위에 있는지 확인한다.
+ let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
if (nextModule) {
// 바로 위 모듈을 찾는다.
leftRows++
+ findModuleList.push(nextModule)
x = nextModule.x
y = nextModule.y
} else {
- hasNextModule = false
+ // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
+ if (findLeft) {
+ nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findLeft = false
+ } else {
+ nextModule = nextModule = findNextRightModule(
+ {
+ x,
+ y,
+ width,
+ height,
+ horizontal,
+ vertical,
+ },
+ centerPoints,
+ direction,
+ )
+ findLeft = true
+ }
+
+ if (nextModule) {
+ // 바로 위 모듈을 찾는다.
+ leftRows++
+ findModuleList.push(nextModule)
+ x = nextModule.x
+ y = nextModule.y
+ } else {
+ hasNextModule = false
+ }
}
}
- }
- // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
- const leftRacks = rackInfos.find((rack) => {
- return rack.value.moduleRows === leftRows
- })?.value.racks
- mostRowsModule = Math.max(leftRows, mostRowsModule)
- if (rackYn === 'Y') {
- drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
- }
-
- module.set({ leftRows })
- })
- // 오른쪽 아래에 모듈이 없는 모듈들
- rightExposedHalfBottomPoints.forEach((module) => {
- const { width, height } = module
- let { x: startX, y: startY } = { ...module.getCenterPoint() }
- let { x, y } = { ...module.getCenterPoint() }
- //TODO : 방향별로 가대 설치해야함
-
- let rightRows = 1
- let hasNextModule = true
- let findRight = true
-
- // 오른쪽 찾는다.
- while (hasNextModule) {
- //바로 위에 있는지 확인한다.
- let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
-
- if (nextModule) {
- // 바로 위 모듈을 찾는다.
- rightRows++
- x = nextModule.x
- y = nextModule.y
- } else {
- // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
- if (findRight) {
- nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findRight = false
- } else {
- nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
- findRight = true
+ const leftModuleInfos = findModuleList.map((module) => {
+ return {
+ moduleTpCd: module.moduleInfo.moduleTpCd,
}
+ })
+ const leftRowsInfo = moduleTransformData(leftModuleInfos)
+
+ // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
+ const leftRacks = rackInfos.find((rack) => {
+ if (leftRowsInfo.rowsInfo.length === 1) {
+ return (
+ rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
+ )
+ } else {
+ return (
+ rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
+ rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count &&
+ rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count
+ )
+ }
+ })?.value.racks
+
+ mostRowsModule = Math.max(leftRows, mostRowsModule)
+ if (rackYn === 'Y') {
+ drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
+ }
+
+ module.set({ leftRows })
+ })
+ // 오른쪽 아래에 모듈이 없는 모듈들
+ rightExposedHalfBottomPoints.forEach((module) => {
+ const { width, height } = module
+ let { x: startX, y: startY } = { ...module.getCenterPoint() }
+ let { x, y } = { ...module.getCenterPoint() }
+ //TODO : 방향별로 가대 설치해야함
+
+ let rightRows = 1
+ let hasNextModule = true
+ let findRight = true
+ let findModuleList = [module]
+
+ // 오른쪽 찾는다.
+ while (hasNextModule) {
+ //바로 위에 있는지 확인한다.
+ let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
if (nextModule) {
// 바로 위 모듈을 찾는다.
rightRows++
+ findModuleList.push(nextModule)
x = nextModule.x
y = nextModule.y
} else {
- hasNextModule = false
+ // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
+ if (findRight) {
+ nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findRight = false
+ } else {
+ nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction)
+ findRight = true
+ }
+
+ if (nextModule) {
+ // 바로 위 모듈을 찾는다.
+ rightRows++
+ findModuleList.push(nextModule)
+ x = nextModule.x
+ y = nextModule.y
+ } else {
+ hasNextModule = false
+ }
}
}
+
+ const rightRowsInfos = findModuleList.map((module) => {
+ return {
+ moduleTpCd: module.moduleInfo.moduleTpCd,
+ }
+ })
+
+ const rightRowsInfo = moduleTransformData(rightRowsInfos)
+
+ // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
+ const rightRacks = rackInfos.find((rack) => {
+ if (rightRowsInfo.rowsInfo.length === 1) {
+ return (
+ rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
+ )
+ } else {
+ return (
+ rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
+ rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
+ rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count &&
+ rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count
+ )
+ }
+ })?.value.racks
+ mostRowsModule = Math.max(rightRows, mostRowsModule)
+ // 해당 rack으로 그려준다.
+ if (rackYn === 'Y') {
+ drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
+ }
+
+ module.set({ rightRows })
+ })
+
+ surface.set({ moduleRowsTotCnt: mostRowsModule })
+
+ if (rackYn === 'N') {
+ // rack이 없을경우
+ installBracketWithOutRack(surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory)
+ } else if (rackYn === 'Y') {
+ installBracket(surface)
}
- // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
- const rightRacks = rackInfos.find((rack) => {
- return rack.value.moduleRows === rightRows
- })?.value.racks
+ const quotationParam = getTrestleParams(surface)
- mostRowsModule = Math.max(rightRows, mostRowsModule)
- // 해당 rack으로 그려준다.
- if (rackYn === 'Y') {
- drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
- }
-
- module.set({ rightRows })
+ surface.set({ quotationParam, isComplete: true })
})
- surface.set({ moduleRowsTotCnt: mostRowsModule })
-
- if (rackYn === 'N') {
- // rack이 없을경우
- installBracketWithOutRack(surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory)
- } else if (rackYn === 'Y') {
- installBracket(surface)
- }
-
- const quotationParam = getTrestleParams(surface)
-
- surface.set({ quotationParam })
- getQuoationItems()
- })
+ return setEstimateData()
+ } catch (e) {
+ // 에러 발생시 가대 초기화
+ console.error(e)
+ clear()
+ setViewCircuitNumberTexts(true)
+ return null
+ }
}
- const getQuoationItems = () => {
- const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
- const params = { trestles: surfaces.map((surface) => surface.quotationParam), pcses: [] }
- getQuotationItem(params).then((res) => {
- console.log(res)
+ //module Rack 정보를 얻기위한 데이터 가공
+ function moduleTransformData(arr) {
+ let counts = {}
+
+ arr.forEach((item) => {
+ counts[item.moduleTpCd] = (counts[item.moduleTpCd] || 0) + 1
})
+
+ let moduleTotalTp = Object.keys(counts).join('')
+ let rowsInfo = Object.entries(counts).map(([moduleTpCd, count]) => ({ moduleTpCd, count }))
+
+ return { moduleTotalTp, rowsInfo }
+ }
+
+ // itemList 조회 후 estimateParam에 저장
+ const setEstimateData = async () => {
+ const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ //surfaces.pcses들을 배열로 묶는다
+ const pcses = surfaces[0].pcses.filter((pcs) => pcs !== null && pcs !== undefined)
+
+ surfaces.forEach((surface, index) => {
+ if (index !== 0) {
+ if (surface.pcses) {
+ pcses.concat(surface.pcses)
+ }
+ }
+ })
+
+ const allModules = surfaces.map((surface) => surface.modules).flat()
+ // 모듈 파라미터 생성
+ const modules = getModulesParam(allModules)
+ const trestles = []
+ //가대 파라미터 생성
+ surfaces.forEach((surface) => {
+ if (surface.quotationParam) {
+ trestles.push(surface.quotationParam)
+ }
+ })
+
+ // trestles 배열에서 null인 경우 제거
+ const params = { trestles, pcses, modules }
+
+ //견적서 itemList 조회
+ const { data: itemList, data2, result } = await getQuotationItem(params)
+
+ if (result.resultCode === 'E') {
+ swalFire({ text: result.resultMsg, icon: 'error' })
+ return null
+ }
+
+ //northArrangement 북면 설치 여부
+ const northArrangement = getNorthArrangement()
+ // circuitItemList의 경우는 moduleList에서 circuitId만 groupBy한다.
+ let circuitItemList = []
+
+ // roofSurfaceList 생성
+ const roofSurfaceList = surfaces.map((surface) => {
+ const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
+ const { directionText, roofMaterial, pitch: slope, moduleCompass, surfaceCompass } = parent
+ const roofMaterialIndex = parent.roofMaterial.index
+ const { nameJp: roofMaterialIdMulti } = roofMaterial
+ const moduleSelection = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex)
+ const { constTp: constructSpecification, constTpJp: constructSpecificationMulti } = moduleSelection.construction
+ const {
+ trestleMkrCd,
+ constMthdCd: supportMethodId,
+ roofBaseCd,
+ trestleMkrCdJp: supportMeaker,
+ constMthdCdJp: supportMethodIdMulti,
+ } = moduleSelection.trestle
+
+ const modules = surface.modules
+ const moduleList = modules.map((module) => {
+ circuitItemList.push(module.pcsItemId)
+ return {
+ itemId: module.moduleInfo.itemId,
+ circuit: module.circuitNumber,
+ pcItemId: module.pcsItemId,
+ }
+ })
+
+ return {
+ roofSurfaceId: surface.id,
+ roofSurface: directionText.replace(/[^0-9]/g, ''),
+ roofMaterialId: roofMaterial.roofMatlCd,
+ supportMethodId,
+ constructSpecification,
+ constructSpecificationMulti,
+ roofMaterialIdMulti,
+ supportMethodIdMulti,
+ supportMeaker,
+ slope,
+ classType: currentAngleType === 'slope' ? '0' : '1',
+ angle: getDegreeByChon(slope),
+ azimuth: surfaceCompass ?? moduleCompass ?? 0,
+ moduleList,
+ }
+ })
+
+ // circuitItemList 중복제거
+ circuitItemList = circuitItemList.filter((item, index) => circuitItemList.indexOf(item) === index)
+ circuitItemList = circuitItemList.map((circuitId) => {
+ return {
+ itemId: circuitId,
+ }
+ })
+
+ return { itemList, northArrangement, roofSurfaceList, circuitItemList }
+ }
+
+ const getNorthArrangement = () => {
+ const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ let northArrangement = '0'
+
+ surfaces.forEach((surface) => {
+ const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
+ const directionText = parent.directionText
+ // ['西北西','東北東'] 의 경우를 제외하고는 北이 들어간 경우 전부 북면으로 간주
+ if (directionText.includes('北') && !directionText.includes('西北西') && !directionText.includes('東北東')) {
+ if (surface.modules.length > 0) {
+ northArrangement = '1'
+ }
+ }
+ })
+
+ return northArrangement
}
const findNextModule = (currentPoint, centerPoints, direction) => {
- let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
- width = width + horizontal
- height = height + vertical
+ let { x, y, horizontal, vertical } = { ...currentPoint }
+ let { widthArr, heightArr } = centerPoints[0]
+
+ let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
+ let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
let maxX = 2 + horizontal * 3
let maxY = 2 + vertical * 3
@@ -484,7 +765,11 @@ export const useTrestle = () => {
}
const findNextLeftModule = (currentPoint, centerPoints, direction) => {
- let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
+ let { x, y, horizontal, vertical } = { ...currentPoint }
+ let { widthArr, heightArr } = centerPoints[0]
+
+ let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
+ let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
let result
let topLeftPoint
@@ -519,9 +804,11 @@ export const useTrestle = () => {
return result
}
const findNextRightModule = (currentPoint, centerPoints, direction) => {
- let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
- width = width + horizontal
- height = height + vertical
+ let { x, y, horizontal, vertical } = { ...currentPoint }
+ let { widthArr, heightArr } = centerPoints[0]
+
+ let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
+ let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
let result
let topRightPoint
@@ -553,6 +840,9 @@ export const useTrestle = () => {
}
const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => {
+ if (!rackInfos) {
+ return
+ }
const { width, height, left, top, lastX, lastY, surfaceId } = module
const surface = canvas.getObjects().find((obj) => obj.id === surfaceId)
const roof = canvas.getObjects().find((obj) => obj.id === surface.parentId)
@@ -650,29 +940,30 @@ export const useTrestle = () => {
name: 'smartRack',
stroke: 'red',
strokeWidth: 4,
- selectable: false,
+ selectable: true,
shadow: {
color: 'black', // Outline color
blur: 10,
offsetX: 0,
offsetY: 0,
},
-
+ visible: isTrestleDisplay,
parentId: module.id,
surfaceId: surface.id,
supFitQty,
supFitIntvlPct,
- rackLen,
+ rackLen: rackLength,
rackRowsCd,
seq,
smartRackId,
rackId: itemId,
direction: 'top',
})
+ startPointY -= rackLength + 8
canvas.add(rack)
canvas.renderAll()
} else if (setRackTpCd === 'INTVL') {
- startPointY -= rackLength + 8
+ startPointY -= rackLength
}
})
} else {
@@ -690,6 +981,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@@ -730,15 +1022,17 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
- rackLen,
+ rackLen: rackLength,
rackRowsCd,
seq,
smartRackId,
rackId: itemId,
direction: 'left',
})
+ startPointX -= rackLength + 8
canvas.add(rack)
canvas.renderAll()
} else if (setRackTpCd === 'INTVL') {
@@ -759,6 +1053,7 @@ export const useTrestle = () => {
surfaceId: surface.id,
strokeWidth: 4,
selectable: false,
+ visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@@ -799,19 +1094,21 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
- rackLen,
+ rackLen: rackLength,
rackRowsCd,
seq,
smartRackId,
rackId: itemId,
direction: 'right',
})
+ startPointX += rackLength + 8
canvas.add(rack)
canvas.renderAll()
} else if (setRackTpCd === 'INTVL') {
- startPointX += rackLength + 8
+ startPointX += rackLength
}
})
} else {
@@ -826,6 +1123,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
strokeWidth: 4,
selectable: false,
supFitQty,
@@ -866,6 +1164,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@@ -877,8 +1176,9 @@ export const useTrestle = () => {
})
canvas.add(rack)
canvas.renderAll()
- } else if (setRackTpCd === 'INTVL') {
startPointY += rackLength + 8
+ } else if (setRackTpCd === 'INTVL') {
+ startPointY += rackLength
}
})
} else {
@@ -893,6 +1193,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
+ visible: isTrestleDisplay,
strokeWidth: 4,
selectable: false,
supFitQty,
@@ -931,20 +1232,20 @@ export const useTrestle = () => {
canvas.renderAll()
racks.forEach((rack) => {
- const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen } = rack
+ const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen, name } = rack
const bracketLength = 10
if (direction === 'top') {
const result = getBracketPoints(supFitQty, supFitIntvlPct)
-
result.forEach((percent) => {
const bracket = new fabric.Rect({
left: x2 - bracketLength / 3,
- top: y2 + (rackLen / 10) * percent,
+ top: name === 'smartRack' ? y2 + rackLen * percent : y2 + (rackLen / 10) * percent,
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
+ visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@@ -959,11 +1260,12 @@ export const useTrestle = () => {
result.forEach((percent) => {
const bracket = new fabric.Rect({
- left: x2 + (rackLen / 10) * percent,
+ left: name === 'smartRack' ? x2 + rackLen * percent : x2 + (rackLen / 10) * percent,
top: y2 - bracketLength / 3,
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
+ visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@@ -978,10 +1280,11 @@ export const useTrestle = () => {
result.forEach((percent) => {
const bracket = new fabric.Rect({
- left: x2 - (rackLen / 10) * percent,
+ left: name === 'smartRack' ? x2 - rackLen * percent : x2 - (rackLen / 10) * percent,
top: y2 - bracketLength / 3,
fill: 'green',
parentId: rack.parentId,
+ visible: isTrestleDisplay,
surfaceId: surface.id,
name: 'bracket',
width: bracketLength,
@@ -998,10 +1301,11 @@ export const useTrestle = () => {
result.forEach((percent) => {
const bracket = new fabric.Rect({
left: x2 - bracketLength / 3,
- top: y2 - (rackLen / 10) * percent,
+ top: name === 'smartRack' ? y2 - rackLen * percent : y2 - (rackLen / 10) * percent,
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
+ visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@@ -1018,9 +1322,9 @@ export const useTrestle = () => {
//랙 없음 인 경우 지지금구 설치
const installBracketWithOutRack = (surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory) => {
let { rackQty, rackIntvlPct, moduleIntvlHor, moduleIntvlVer, lessSupFitQty, lessSupFitIntvlPct } = surface.trestleDetail
+ rackQty = lessSupFitQty
+ rackIntvlPct = lessSupFitIntvlPct
const direction = surface.direction
- rackQty = 3
- rackIntvlPct = 10
canvas.renderAll()
exposedBottomModules.forEach((module) => {
@@ -1167,17 +1471,18 @@ export const useTrestle = () => {
width: 10,
height: 10,
selectable: false,
+ visible: isTrestleDisplay,
})
canvas.add(bracket)
canvas.renderAll()
if (direction === 'south') {
- startPointY -= height + moduleIntvlVer
+ startPointY -= height
} else if (direction === 'north') {
- startPointY += height + moduleIntvlVer
+ startPointY += height
} else if (direction === 'east') {
- startPointX -= width + moduleIntvlHor
+ startPointX -= width
} else if (direction === 'west') {
- startPointX += width + moduleIntvlHor
+ startPointX += width
}
}
}
@@ -1225,8 +1530,49 @@ export const useTrestle = () => {
return points.slice(0, 2)
}
- const calculateForApi = (moduleSurface) => {
+ const getCenterPoints = (moduleSurface) => {
const centerPoints = []
+ let widthArr = []
+ let heightArr = []
+ const modules = moduleSurface.modules
+ modules.forEach((module, index) => {
+ module.tempIndex = index
+ const { x, y } = module.getCenterPoint()
+ const { width, height } = { ...module }
+ widthArr.push(width)
+ heightArr.push(height)
+ centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index, moduleInfo: module.moduleInfo })
+ })
+
+ //widthArr 중복 제거 1이상 차이가 나지 않으면 같은 너비로 간주
+ widthArr = removeCloseValues(Array.from(new Set(widthArr)))
+ heightArr = removeCloseValues(Array.from(new Set(heightArr)))
+
+ centerPoints.forEach((centerPoint, index) => {
+ centerPoint.widthArr = [...widthArr]
+
+ centerPoint.heightArr = [...heightArr]
+ })
+
+ function removeCloseValues(arr, threshold = 1) {
+ arr.sort((a, b) => a - b) // 배열을 정렬
+
+ let result = []
+
+ for (let i = 0; i < arr.length; i++) {
+ if (i === 0 || Math.abs(arr[i] - arr[i - 1]) >= threshold) {
+ result.push(arr[i])
+ }
+ }
+
+ return result
+ }
+
+ return centerPoints
+ }
+
+ const calculateForApi = (moduleSurface) => {
+ const centerPoints = getCenterPoints(moduleSurface)
const direction = moduleSurface.direction
const modules = moduleSurface.modules
@@ -1238,12 +1584,6 @@ export const useTrestle = () => {
const maxX = 2 + horizontal * 3
const maxY = 2 + vertical * 3
- modules.forEach((module, index) => {
- module.tempIndex = index
- const { x, y } = module.getCenterPoint()
- const { width, height } = { ...module }
- centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index })
- })
if (centerPoints.length === 0) return
@@ -1270,7 +1610,7 @@ export const useTrestle = () => {
let rightExposedHalfTopPoints = []
centerPoints.forEach((centerPoint, index) => {
- let { x, y, width, height } = { ...centerPoint }
+ let { x, y, width, height, widthArr, heightArr } = { ...centerPoint }
// centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
let bottomCell
let bottomLeftPoint
@@ -1280,28 +1620,29 @@ export const useTrestle = () => {
switch (direction) {
case 'south':
- width = width + horizontal
- height = height + vertical
+ //widthArr의 값을 전부 더한 후 widthArr의 길이로 나누어 평균값을 구한다.
+ width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
+ height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY)
bottomLeftPoint = { x: x - width / 2, y: y + height }
bottomRightPoint = { x: x + width / 2, y: y + height }
break
case 'north':
- width = width + horizontal
- height = height + vertical
+ width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
+ height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY)
bottomLeftPoint = { x: x + width / 2, y: y - height }
bottomRightPoint = { x: x - width / 2, y: y - height }
break
case 'east':
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
- width = width + horizontal
+ width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
bottomLeftPoint = { x: x + width, y: y + height / 2 }
bottomRightPoint = { x: x + width, y: y - height / 2 }
break
case 'west':
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
- width = width + horizontal
+ width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
bottomLeftPoint = { x: x - width, y: y - height / 2 }
bottomRightPoint = { x: x - width, y: y + height / 2 }
break
@@ -1492,6 +1833,16 @@ export const useTrestle = () => {
return groups
}
+ // 각도에 따른 길이 반환
+ function getTrestleLength(length, degree) {
+ if (roofSizeSet !== 1) {
+ // 복시도 입력이 아닌경우 그냥 길이 return
+ return length
+ }
+ const radians = (degree * Math.PI) / 180
+ return length * Math.cos(radians)
+ }
+
// 견적서 아이템 조회 api parameter 생성
const getTrestleParams = (surface) => {
const result = calculateForApi(surface)
@@ -1552,12 +1903,12 @@ export const useTrestle = () => {
rackYn,
racks: rackParams,
rackTotCnt: rackList.length ?? 0 + smartRackGroup.length ?? 0,
- rackFittingCnt: bracketList.length,
+ rackFittingTotCnt: bracketList.length,
moduleRows: getMostLeftModules(surface),
cvrYn: moduleSelection.construction.setupCover ? 'Y' : 'N',
snowGdYn: moduleSelection.construction.setupSnowCover ? 'Y' : 'N',
plvrYn: cvrPlvrYn,
- modules: getModules(surface),
+ // modules: getModules(surface), // 2025-02-06 api 수정
trestleMkrCd,
constMthdCd,
roofBaseCd,
@@ -1569,10 +1920,9 @@ export const useTrestle = () => {
}
}
- const getModules = (surface) => {
- const { modules } = surface
-
- const params = modules.map((module, index) => {
+ // 전체 모듈 파라미터 생성
+ const getModulesParam = (allModules) => {
+ const params = allModules.map((module, index) => {
return {
moduleTpCd: module.moduleInfo.itemTp,
moduleItemId: module.moduleInfo.itemId,
@@ -1758,16 +2108,16 @@ export const useTrestle = () => {
const { direction, modules } = surface
let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail
- const centerPoints = modules.map((module) => {
- return module.getCenterPoint()
- })
+ const centerPoints = getCenterPoints(surface)
const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer
const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor
const maxX = 2 + horizontal * 3
const maxY = 2 + vertical * 3
- let { width, height } = { ...module }
+ let { widthArr, heightArr } = centerPoints[0]
+ let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length
+ let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length
let { x, y } = { ...module.getCenterPoint() }
let halfBottomLeftPoint
@@ -1882,5 +2232,30 @@ export const useTrestle = () => {
}
}
- return { apply, getTrestleParams }
+ const clear = () => {
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ .forEach((obj) => {
+ obj.isComplete = false
+ })
+
+ canvas.getObjects().forEach((obj) => {
+ if (obj.name === 'eaveBar' || obj.name === 'rack' || obj.name === 'halfEaveBar' || obj.name === 'smartRack' || obj.name === 'bracket') {
+ canvas.remove(obj)
+ }
+ })
+ }
+
+ // 전모듈 의 회로번호 visible false 처리
+ // 가대 설치 전 필요
+ const setViewCircuitNumberTexts = (visible) => {
+ const circuitNumberTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
+ circuitNumberTexts.forEach((text) => {
+ text.visible = visible
+ })
+ canvas.renderAll()
+ }
+
+ return { apply, getTrestleParams, clear, setViewCircuitNumberTexts }
}
diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js
index 44ede007..311708d2 100644
--- a/src/hooks/object/useObjectBatch.js
+++ b/src/hooks/object/useObjectBatch.js
@@ -26,7 +26,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
useEffect(() => {
if (canvas) {
- dbClickEvent()
+ // dbClickEvent()
}
return () => {
diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js
index 29287689..c5ce450c 100644
--- a/src/hooks/option/useCanvasSetting.js
+++ b/src/hooks/option/useCanvasSetting.js
@@ -36,6 +36,9 @@ import { useCanvasMenu } from '../common/useCanvasMenu'
import { menuTypeState } from '@/store/menuAtom'
import { usePopup } from '../usePopup'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
+import { useCommonCode } from '@/hooks/common/useCommonCode'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
const defaultDotLineGridSetting = {
INTERVAL: {
@@ -114,6 +117,16 @@ export function useCanvasSetting() {
const [fetchRoofMaterials, setFetchRoofMaterials] = useRecoilState(fetchRoofMaterialsState)
const [type, setType] = useRecoilState(menuTypeState)
const setCurrentMenu = useSetRecoilState(currentMenuState)
+
+ const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
+ const resetSelectedModules = useResetRecoilState(selectedModuleState) //선택된 모듈
+
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+
+ const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보
+ const { findCommonCode } = useCommonCode()
+ const [currentRoof, setCurrentRoof] = useState(null) // 현재 선택된 지붕재 정보
+
const SelectOptions = [
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
{ id: 2, name: '1/2', value: 1 / 2 },
@@ -128,10 +141,11 @@ export function useCanvasSetting() {
const { closeAll } = usePopup()
useEffect(() => {
- console.log('correntObjectNo', correntObjectNo)
+ const tempFetchRoofMaterials = !fetchRoofMaterials
- setFetchRoofMaterials(!fetchRoofMaterials)
- if (fetchRoofMaterials) {
+ //최초 1회만 실행하도록 처리
+ setFetchRoofMaterials(tempFetchRoofMaterials)
+ if (tempFetchRoofMaterials) {
addRoofMaterials()
}
}, [])
@@ -192,6 +206,16 @@ export function useCanvasSetting() {
}
}, [roofMaterials, correntObjectNo])
+ //배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가
+ useEffect(() => {
+ if (addedRoofs.length > 0) {
+ const raftCodeList = findCommonCode('203800')
+ setRaftCodes(raftCodeList)
+
+ setCurrentRoof({ ...addedRoofs[0] })
+ }
+ }, [addedRoofs])
+
useEffect(() => {
if (!canvas) {
return
@@ -350,6 +374,8 @@ export function useCanvasSetting() {
roofAngle: 21.8,
},
]
+
+ setMenuNumber(1)
}
// 데이터 설정
@@ -368,6 +394,7 @@ export function useCanvasSetting() {
layout: roofsArray[i].roofLayout,
roofSizeSet: roofsRow[i].roofSizeSet,
roofAngleSet: roofsRow[i].roofAngleSet,
+ roofDbData: roofsRow[i].roofDbData,
pitch: roofsArray[i].roofPitch,
angle: roofsArray[i].roofAngle,
})
@@ -446,6 +473,15 @@ export function useCanvasSetting() {
setType('outline')
setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE)
}
+
+ //모듈 선택 데이터 초기화
+ resetModuleSelectionData()
+ moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] })
+
+ const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE)
+ if (!isModuleExist) {
+ resetSelectedModules()
+ }
} catch (error) {
swalFire({ text: error.message, icon: 'error' })
}
@@ -727,7 +763,7 @@ export function useCanvasSetting() {
for (let i = 0; i < option1.length; i++) {
switch (option1[i].column) {
case 'allocDisplay': //할당 표시
- optionName = ['1']
+ optionName = []
break
case 'outlineDisplay': //외벽선 표시
optionName = ['outerLine', POLYGON_TYPE.WALL]
@@ -742,19 +778,20 @@ export function useCanvasSetting() {
optionName = ['commonText']
break
case 'circuitNumDisplay': //회로번호 표시
- optionName = ['7']
+ optionName = ['circuitNumber']
break
case 'flowDisplay': //흐름방향 표시
optionName = ['arrow', 'flowText']
break
case 'trestleDisplay': //가대 표시
- optionName = ['8']
+ optionName = ['rack', 'smartRack', 'bracket', 'eaveBar', 'halfEaveBar']
break
case 'imageDisplay': //이미지 표시
optionName = ['9']
break
case 'totalDisplay': //집계표 표시
- optionName = ['10']
+ // 작업할 필요 없음
+ optionName = []
break
}
// 표시 선택 상태(true/false)
diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js
index 4997bdf8..7cacdd03 100644
--- a/src/hooks/roofcover/useAuxiliaryDrawing.js
+++ b/src/hooks/roofcover/useAuxiliaryDrawing.js
@@ -24,7 +24,7 @@ import { calculateAngle, isSamePoint } from '@/util/qpolygon-utils'
import { POLYGON_TYPE } from '@/common/common'
// 보조선 작성
-export function useAuxiliaryDrawing(id) {
+export function useAuxiliaryDrawing(id, isUseEffect = true) {
const canvas = useRecoilValue(canvasState)
const { addCanvasMouseEventListener, addDocumentEventListener, removeMouseLine, initEvent } = useEvent()
// const { addCanvasMouseEventListener, addDocumentEventListener, removeMouseLine, initEvent } = useContext(EventContext)
@@ -654,6 +654,8 @@ export function useAuxiliaryDrawing(id) {
selectable: true,
name: 'auxiliaryLine',
isFixed: true,
+ attributes: { ...line1.attributes },
+ parentId: line1.parentId,
},
)
lineHistory.current.push(newLine)
@@ -674,6 +676,8 @@ export function useAuxiliaryDrawing(id) {
selectable: false,
name: 'auxiliaryLine',
isFixed: true,
+ attributes: { ...line1.attributes },
+ parentId: line1.parentId,
})
lineHistory.current.push(newLine)
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
@@ -685,6 +689,8 @@ export function useAuxiliaryDrawing(id) {
selectable: false,
name: 'auxiliaryLine',
isFixed: true,
+ attributes: { ...line1.attributes },
+ parentId: line1.parentId,
})
lineHistory.current.push(newLine)
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
@@ -724,6 +730,8 @@ export function useAuxiliaryDrawing(id) {
selectable: true,
name: 'auxiliaryLine',
isFixed: true,
+ attributes: { ...line1.attributes },
+ parentId: line1.parentId,
intersectionPoint,
})
} else {
@@ -733,6 +741,8 @@ export function useAuxiliaryDrawing(id) {
selectable: true,
name: 'auxiliaryLine',
isFixed: true,
+ attributes: { ...line1.attributes },
+ parentId: line1.parentId,
intersectionPoint,
})
}
@@ -825,7 +835,7 @@ export function useAuxiliaryDrawing(id) {
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
// 겹치는 선 하나는 canvas에서 제거한다.
- const tempLines = [...lineHistory.current]
+ const tempLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed)
lineHistory.current = []
tempLines.forEach((line) => {
if (
@@ -842,7 +852,7 @@ export function useAuxiliaryDrawing(id) {
lineHistory.current.push(line)
})
- const innerLines = lineHistory.current
+ const innerLines = lineHistory.current.filter((line) => line.name === 'auxiliaryLine' && line.visible)
roofBases.forEach((roofBase) => {
const tempPolygonPoints = [...roofBase.points].map((obj) => {
@@ -865,6 +875,7 @@ export function useAuxiliaryDrawing(id) {
actualSize: line.attributes?.actualSize ?? 0,
planeSize: line.getLength(),
}
+ line.isAuxiliaryFixed = true
return true
}
})
diff --git a/src/hooks/roofcover/usePropertiesSetting.js b/src/hooks/roofcover/usePropertiesSetting.js
index 72a9ed0b..564ec3e8 100644
--- a/src/hooks/roofcover/usePropertiesSetting.js
+++ b/src/hooks/roofcover/usePropertiesSetting.js
@@ -1,12 +1,15 @@
import { useEffect, useRef } from 'react'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
-import { useRecoilValue, useResetRecoilState } from 'recoil'
+import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { useMode } from '@/hooks/useMode'
import { usePolygon } from '@/hooks/usePolygon'
import { useLine } from '@/hooks/useLine'
import { outerLinePointsState } from '@/store/outerLineAtom'
import { usePopup } from '@/hooks/usePopup'
+import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
+import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
+import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
// 외벽선 속성 설정
@@ -21,7 +24,7 @@ export function usePropertiesSetting(id) {
const { addPolygonByLines } = usePolygon()
const { removeLine, hideLine } = useLine()
- const { closePopup } = usePopup()
+ const { addPopup, closePopup } = usePopup()
useEffect(() => {
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
@@ -136,7 +139,8 @@ export function usePropertiesSetting(id) {
})
})
canvas.discardActiveObject()
- closePopup(id)
+ // closePopup(id)
+ addPopup(id, 1, )
return
}
@@ -159,10 +163,7 @@ export function usePropertiesSetting(id) {
setPoints([])
canvas.renderAll()
roof.drawHelpLine(settingModalFirstOptions)
-
- closePopup(id)
- return
- } else {
+ addPopup(id, 1, )
return
}
}
diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js
index ee865d65..34ec3f13 100644
--- a/src/hooks/roofcover/useRoofAllocationSetting.js
+++ b/src/hooks/roofcover/useRoofAllocationSetting.js
@@ -1,4 +1,4 @@
-import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
+import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState } from '@/store/canvasAtom'
import { useEffect, useRef, useState } from 'react'
import { useAxios } from '@/hooks/useAxios'
@@ -26,6 +26,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
+import { outerLinePointsState } from '@/store/outerLineAtom'
// 지붕면 할당
export function useRoofAllocationSetting(id) {
@@ -55,6 +56,7 @@ export function useRoofAllocationSetting(id) {
const { setSurfaceShapePattern } = useRoofFn()
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
+ const resetPoints = useResetRecoilState(outerLinePointsState)
useEffect(() => {
setCurrentRoofList(roofList)
@@ -199,7 +201,7 @@ export function useRoofAllocationSetting(id) {
roofWidth: item.width === null || item.width === undefined ? 0 : Number(item.width),
roofHeight: item.length === null || item.length === undefined ? 0 : Number(item.length),
roofHajebichi: item.hajebichi === null || item.hajebichi === undefined ? 0 : Number(item.hajebichi),
- roofGap: item.raft === null || item.raft === undefined ? 'HEI_455' : item.raft,
+ roofGap: !item.raft ? item.raftBaseCd : item.raft,
roofLayout: item.layout === null || item.layout === undefined ? 'P' : item.layout,
roofPitch: item.pitch === null || item.pitch === undefined ? 4 : Number(item.pitch),
roofAngle: item.angle === null || item.angle === undefined ? 21.8 : Number(item.angle),
@@ -240,7 +242,7 @@ export function useRoofAllocationSetting(id) {
const onDeleteRoofMaterial = (idx) => {
const isSelected = currentRoofList[idx].selected
- const newRoofList = [...currentRoofList].filter((_, index) => index !== idx)
+ const newRoofList = JSON.parse(JSON.stringify(currentRoofList)).filter((_, index) => index !== idx)
if (isSelected) {
newRoofList[0].selected = true
}
@@ -256,11 +258,13 @@ export function useRoofAllocationSetting(id) {
addPopup(popupId, 1, )
} else {
apply()
+ resetPoints()
}
}
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
const handleSaveContext = () => {
+ basicSettingSave()
const newRoofList = currentRoofList.map((roof, idx) => {
return { ...roof, index: idx }
})
@@ -273,7 +277,8 @@ export function useRoofAllocationSetting(id) {
setRoofList(newRoofList)
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
- setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
+ setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
+ drawDirectionArrow(currentObject)
modifyModuleSelectionData()
closeAll()
}
@@ -314,7 +319,7 @@ export function useRoofAllocationSetting(id) {
}
const apply = () => {
- const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+ const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.roofMaterial)
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
roofBases.forEach((roofBase) => {
try {
@@ -340,7 +345,6 @@ export function useRoofAllocationSetting(id) {
const newRoofList = currentRoofList.map((roof, idx) => {
return { ...roof, index: idx, ...basicInfo }
})
- console.log('basicInfo', newRoofList)
setBasicSetting((prev) => {
return {
@@ -445,9 +449,9 @@ export function useRoofAllocationSetting(id) {
setCurrentRoofList(newRoofList)
}
- const handleChangeInput = (e, type, index) => {
+ const handleChangeInput = (e, type = '', index) => {
const value = e.target.value
- if (type === 'pitch') {
+ /*if (type === 'pitch') {
// type이 pitch인 경우 소수점 1자리까지만 입력 가능
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
@@ -481,7 +485,7 @@ export function useRoofAllocationSetting(id) {
}
return
- }
+ }*/
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
@@ -494,7 +498,12 @@ export function useRoofAllocationSetting(id) {
}
const handleChangePitch = (e, index) => {
- const value = e.target.value
+ let value = e.target.value
+
+ const reg = /^[0-9]+(\.[0-9]{0,1})?$/
+ if (!reg.test(value)) {
+ value = value.substring(0, value.length - 1)
+ }
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
const result =
diff --git a/src/hooks/roofcover/useRoofShapePassivitySetting.js b/src/hooks/roofcover/useRoofShapePassivitySetting.js
index c51da066..33d5d953 100644
--- a/src/hooks/roofcover/useRoofShapePassivitySetting.js
+++ b/src/hooks/roofcover/useRoofShapePassivitySetting.js
@@ -203,6 +203,20 @@ export function useRoofShapePassivitySetting(id) {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
+
+ let checkedAllSetting = true
+
+ lines.forEach((line) => {
+ if (!line.attributes) {
+ checkedAllSetting = false
+ }
+ })
+
+ if (!checkedAllSetting) {
+ swalFire({ text: '설정이 완료되지 않은 외벽선이 있습니다.', icon: 'warning' })
+ return
+ }
+
exceptObjs.forEach((obj) => {
canvas.remove(obj)
})
diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js
index 8ce7454e..e9b7bafe 100644
--- a/src/hooks/roofcover/useRoofShapeSetting.js
+++ b/src/hooks/roofcover/useRoofShapeSetting.js
@@ -10,6 +10,7 @@ import { outerLineFixState } from '@/store/outerLineAtom'
import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'
import { getChonByDegree } from '@/util/canvas-util'
+import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
// 지붕형상 설정
@@ -47,7 +48,7 @@ export function useRoofShapeSetting(id) {
const jerkinHeadPitchRef = useRef(null)
const history = useRef([])
- const { closePopup } = usePopup()
+ const { closePopup, addPopup } = usePopup()
const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
@@ -170,9 +171,14 @@ export function useRoofShapeSetting(id) {
]
const handleSave = () => {
- let outerLines
+ let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.visible)
let direction
+ if (outerLines.length < 2) {
+ swalFire({ text: '외벽선이 없습니다.', icon: 'error' })
+ return
+ }
+
switch (shapeNum) {
case 1: {
outerLines = saveRidge()
@@ -188,19 +194,25 @@ export function useRoofShapeSetting(id) {
}
case 4: {
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
+
const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch
+ let isValid = outerLines.every((line) => line.attributes.isFixed)
// 변별로 설정중 한쪽흐름일 경우 한쪽흐름의 pitch로 설정
if (pitch) {
outerLines.forEach((line) => {
- if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
+ if (line.attributes.type === LINE_TYPE.WALLLINE.SHED) {
line.attributes = {
...line.attributes,
- pitch: pitch,
+ pitch: pitchRef.current,
onlyOffset: true,
}
}
})
}
+ if (!isValid) {
+ swalFire({ text: '설정이 완료되지 않았습니다.', icon: 'error' })
+ return
+ }
break
}
@@ -219,15 +231,15 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
if (line.direction === 'top') {
line.attributes = {
offset: shedWidth / 10,
- pitch: pitch,
+ pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
} else {
@@ -236,7 +248,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -245,6 +256,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
}
@@ -267,7 +279,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -276,6 +287,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
} else {
@@ -284,7 +296,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -293,6 +304,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
}
@@ -314,7 +326,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -323,6 +334,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
} else {
@@ -331,7 +343,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -340,6 +351,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
}
@@ -362,7 +374,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -371,6 +382,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
} else {
@@ -379,7 +391,6 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.EAVES,
- onlyOffset: true,
}
}
@@ -388,6 +399,7 @@ export function useRoofShapeSetting(id) {
offset: shedWidth / 10,
pitch: pitchRef.current,
type: LINE_TYPE.WALLLINE.SHED,
+ onlyOffset: true,
}
}
}
@@ -414,7 +426,13 @@ export function useRoofShapeSetting(id) {
canvas.remove(obj)
})
- const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText' || obj.name === 'lengthText')
+ const removeTargets = canvas
+ .getObjects()
+ .filter(
+ (obj) =>
+ (obj.name === 'pitchText' || obj.name === 'lengthText') &&
+ canvas.getObjects().find((parent) => parent.id === obj.parentId)?.name !== POLYGON_TYPE.ROOF,
+ )
removeTargets.forEach((obj) => {
canvas.remove(obj)
})
@@ -428,7 +446,7 @@ export function useRoofShapeSetting(id) {
canvas?.renderAll()
roof.drawHelpLine(settingModalFirstOptions)
isFixRef.current = true
- closePopup(id)
+ addPopup(id, 1, )
}
const initLineSetting = () => {
@@ -488,7 +506,7 @@ export function useRoofShapeSetting(id) {
outerLines.forEach((line) => {
line.attributes = {
offset: eavesOffset / 10,
- pitch: pitchRef.current,
+ pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
type: LINE_TYPE.WALLLINE.EAVES,
onlyOffset: false,
}
@@ -511,7 +529,7 @@ export function useRoofShapeSetting(id) {
} else if (line.direction === 'top' || line.direction === 'bottom') {
line.attributes = {
offset: eavesOffset / 10,
- pitch: pitchRef.current,
+ pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
type: LINE_TYPE.WALLLINE.EAVES,
}
}
@@ -534,7 +552,7 @@ export function useRoofShapeSetting(id) {
} else if (line.direction === 'left' || line.direction === 'right') {
line.attributes = {
offset: eavesOffset / 10,
- pitch: pitchRef.current,
+ pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
type: LINE_TYPE.WALLLINE.EAVES,
}
}
@@ -560,6 +578,7 @@ export function useRoofShapeSetting(id) {
pitch: pitchRef.current,
offset: eavesOffset / 10,
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject)
selectedLine.set({ strokeWidth: 4 })
selectedLine.set({ stroke: '#45CD7D' })
@@ -571,6 +590,7 @@ export function useRoofShapeSetting(id) {
type: LINE_TYPE.WALLLINE.GABLE,
offset: gableOffset / 10,
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
selectedLine.set({ strokeWidth: 4 })
selectedLine.set({ stroke: '#3FBAE6' })
break
@@ -582,6 +602,7 @@ export function useRoofShapeSetting(id) {
width: hasSleeve === '0' ? 0 : sleeveOffset / 10,
sleeve: hasSleeve === '1',
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
break
}
case 4: {
@@ -592,6 +613,7 @@ export function useRoofShapeSetting(id) {
offset: eavesOffset / 10,
width: hipAndGableWidth / 10,
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject)
selectedLine.set({ strokeWidth: 4 })
selectedLine.set({ stroke: '#45CD7D' })
@@ -605,6 +627,7 @@ export function useRoofShapeSetting(id) {
width: jerkinHeadWidth / 10,
pitch: jerkinHeadPitchRef.current,
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject)
selectedLine.set({ strokeWidth: 4 })
selectedLine.set({ stroke: '#3FBAE6' })
@@ -617,13 +640,13 @@ export function useRoofShapeSetting(id) {
pitch: shedPitchRef.current,
width: shedWidth / 10,
}
+ selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject)
selectedLine.set({ strokeWidth: 4 })
selectedLine.set({ stroke: '#000000' })
break
}
}
- selectedLine.attributes = { ...attributes, isFixed: true }
canvas.renderAll()
nextLineFocus(selectedLine)
@@ -635,7 +658,7 @@ export function useRoofShapeSetting(id) {
const index = lines.findIndex((line) => line.idx === selectedLine.idx)
const nextLine = lines[index + 1] || lines[0]
- if (nextLine.attributes.isFixed) {
+ if (nextLine.attributes?.isFixed) {
canvas.discardActiveObject()
return
}
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js
index 54993dbb..10201c8c 100644
--- a/src/hooks/surface/useSurfaceShapeBatch.js
+++ b/src/hooks/surface/useSurfaceShapeBatch.js
@@ -85,6 +85,10 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP))
points = getSurfaceShape(surfaceId, pointer, { length1, length2, length3, length4, length5 })
+ console.log('surfaceRefs.xInversion', surfaceRefs.xInversion)
+ console.log('surfaceRefs.yInversion', surfaceRefs.yInversion)
+ console.log('surfaceRefs.rotate', surfaceRefs.rotate)
+
const options = {
fill: 'transparent',
stroke: 'black',
@@ -100,7 +104,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
name: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP,
flipX: surfaceRefs.yInversion,
flipY: surfaceRefs.xInversion,
- angle: surfaceRefs.rotate,
+ angle: Math.abs(surfaceRefs.rotate),
originX: 'center',
originY: 'center',
pitch: globalPitch,
@@ -637,7 +641,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
y: pointer.y + length3 / 2,
},
{
- x: pointer.x - length1 / 2 + length4 * Math.cos(angle),
+ x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)),
y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)),
},
{
diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js
index d6443c2a..8dec3cc0 100644
--- a/src/hooks/useCanvas.js
+++ b/src/hooks/useCanvas.js
@@ -13,7 +13,8 @@ import { writeImage } from '@/lib/canvas'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { useAxios } from '@/hooks/useAxios'
import { useFont } from '@/hooks/common/useFont'
-import { OBJECT_PROTOTYPE, RELOAD_TYPE_PROTOTYPE, SAVE_KEY } from '@/common/common'
+import { OBJECT_PROTOTYPE, POLYGON_TYPE, RELOAD_TYPE_PROTOTYPE, SAVE_KEY } from '@/common/common'
+import { usePlan } from './usePlan'
export function useCanvas(id) {
const [canvas, setCanvas] = useRecoilState(canvasState)
@@ -23,7 +24,6 @@ export function useCanvas(id) {
const [canvasSize] = useRecoilState(canvasSizeState)
const [fontSize] = useRecoilState(fontSizeState)
const { setCanvasForEvent, attachDefaultEventOnCanvas } = useCanvasEvent()
- const { post } = useAxios()
const {} = useFont()
/**
@@ -383,18 +383,18 @@ export function useCanvas(id) {
console.log('err', err)
})
- const canvasStatus = addCanvas()
+ // const canvasStatus = addCanvas()
- const patternData = {
- userId: userId,
- imageName: title,
- objectNo: 'test123240822001',
- canvasStatus: JSON.stringify(canvasStatus).replace(/"/g, '##'),
- }
+ // const patternData = {
+ // userId: userId,
+ // imageName: title,
+ // objectNo: 'test123240822001',
+ // canvasStatus: JSON.stringify(canvasStatus).replace(/"/g, '##'),
+ // }
- await post({ url: '/api/canvas-management/canvas-statuses', data: patternData })
+ // await post({ url: '/api/canvas-management/canvas-statuses', data: patternData })
- setThumbnails((prev) => [...prev, { imageName: `/canvasState/${title}.png`, userId, canvasStatus: JSON.stringify(canvasStatus) }])
+ // setThumbnails((prev) => [...prev, { imageName: `/canvasState/${title}.png`, userId, canvasStatus: JSON.stringify(canvasStatus) }])
}
const handleFlip = () => {
diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js
new file mode 100644
index 00000000..4cae3ab3
--- /dev/null
+++ b/src/hooks/useCirCuitTrestle.js
@@ -0,0 +1,293 @@
+import { GlobalDataContext } from '@/app/GlobalDataProvider'
+import { POLYGON_TYPE } from '@/common/common'
+import { canvasState } from '@/store/canvasAtom'
+import {
+ makersState,
+ modelsState,
+ moduleStatisticsState,
+ pcsCheckState,
+ selectedMakerState,
+ selectedModelsState,
+ seriesState,
+} from '@/store/circuitTrestleAtom'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
+import { useContext } from 'react'
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
+import { useMessage } from './useMessage'
+import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController'
+
+export function useCircuitTrestle() {
+ const [makers, setMakers] = useRecoilState(makersState)
+ const [selectedMaker, setSelectedMaker] = useRecoilState(selectedMakerState)
+ const [series, setSeries] = useRecoilState(seriesState)
+ const [models, setModels] = useRecoilState(modelsState)
+ const [selectedModels, setSelectedModels] = useRecoilState(selectedModelsState)
+ const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
+ const selectedModules = useRecoilValue(selectedModuleState)
+ const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
+ const canvas = useRecoilValue(canvasState)
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+ const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
+ const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
+ const { getMessage } = useMessage()
+ const getOptYn = () => {
+ return {
+ maxConnYn: pcsCheck.max ? 'Y' : 'N',
+ smpCirYn: pcsCheck.division ? 'Y' : 'N',
+ coldZoneYn: managementState?.coldRegionFlg === '1' ? 'Y' : 'N',
+ }
+ }
+ // PCS 아이템 목록
+ const getPcsItemList = () => {
+ return models.map((model) => {
+ return {
+ itemId: model.itemId,
+ pcsMkrCd: model.pcsMkrCd,
+ pcsSerCd: model.pcsSerCd,
+ }
+ })
+ }
+
+ // 선택된 PCS 아이템 목록
+ const getSelectedPcsItemList = () => {
+ return selectedModels.map((model) => {
+ return {
+ itemId: model.itemId,
+ pcsMkrCd: model.pcsMkrCd,
+ pcsSerCd: model.pcsSerCd,
+ }
+ })
+ }
+
+ // 사용된 모듈아이템 목록
+ const getUseModuleItemList = () => {
+ console.log('🚀 ~ getUseModuleItemList ~ selectedModules:', selectedModules)
+ return moduleSelectionData.module?.itemList?.map((m) => {
+ return {
+ itemId: m.itemId,
+ mixMatlNo: m.mixMatlNo,
+ }
+ })
+ }
+
+ // 지붕면 목록
+ const getRoofSurfaceList = () => {
+ const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
+ return roofSurfaceList
+ .map((obj) => {
+ return {
+ roofSurfaceId: obj.id,
+ roofSurface: canvas
+ .getObjects()
+ .filter((o) => o.id === obj.parentId)[0]
+ .directionText.replace(/[0-9]/g, ''),
+ roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
+ moduleList: getModuleList(obj).map((module) => {
+ return {
+ itemId: module.moduleInfo.itemId,
+ circuit: module.circuitNumber ? module.circuitNumber : null,
+ pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
+ uniqueId: module.id ? module.id : null,
+ }
+ }),
+ }
+ })
+ .filter((surface) => surface.moduleList.length > 0)
+ }
+
+ // 모듈 목록
+ const getModuleList = (surface) => {
+ let moduleList = []
+ let [xObj, yObj] = [{}, {}]
+ let [xPoints, yPoints] = [[], []]
+ surface.modules.forEach((module) => {
+ if (!xObj[module.left]) {
+ xObj[module.left] = module.left
+ xPoints.push(module.left)
+ }
+ if (!yObj[module.top]) {
+ yObj[module.top] = module.top
+ yPoints.push(module.top)
+ }
+ })
+ switch (surface.direction) {
+ case 'south':
+ xPoints.sort((a, b) => a - b)
+ yPoints.sort((a, b) => b - a)
+ yPoints.forEach((y, index) => {
+ let temp = surface.modules.filter((m) => m.top === y)
+ if (index % 2 === 0) {
+ temp.sort((a, b) => a.left - b.left)
+ } else {
+ temp.sort((a, b) => b.left - a.left)
+ }
+ moduleList = [...moduleList, ...temp]
+ })
+ break
+ case 'north':
+ xPoints.sort((a, b) => b - a)
+ yPoints.sort((a, b) => a - b)
+ yPoints.forEach((y, index) => {
+ let temp = surface.modules.filter((m) => m.top === y)
+ if (index % 2 === 0) {
+ temp.sort((a, b) => b.left - a.left)
+ } else {
+ temp.sort((a, b) => a.left - b.left)
+ }
+ moduleList = [...moduleList, ...temp]
+ })
+ break
+ case 'west':
+ xPoints.sort((a, b) => a - b)
+ yPoints.sort((a, b) => a - b)
+ xPoints.forEach((x, index) => {
+ let temp = surface.modules.filter((m) => m.left === x)
+ if (index % 2 === 0) {
+ temp.sort((a, b) => a.top - b.top)
+ } else {
+ temp.sort((a, b) => b.top - a.top)
+ }
+ moduleList = [...moduleList, ...temp]
+ })
+ break
+ case 'east':
+ xPoints.sort((a, b) => b - a)
+ yPoints.sort((a, b) => b - a)
+ xPoints.forEach((x, index) => {
+ let temp = surface.modules.filter((m) => m.left === x)
+ if (index % 2 === 0) {
+ temp.sort((a, b) => b.top - a.top)
+ } else {
+ temp.sort((a, b) => a.top - b.top)
+ }
+ moduleList = [...moduleList, ...temp]
+ })
+ break
+ default:
+ return []
+ }
+ return moduleList
+ }
+
+ const removeNotAllocationModules = () => {
+ const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
+ canvas.remove(...notAllocationModules)
+ canvas.renderAll()
+ }
+
+ const setPowerConditionerData = () => {}
+
+ const setModuleStatisticsData = () => {
+ console.log(canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE))
+ if (selectedModules?.length === 0) return
+ const tempHeader = [
+ { name: getMessage('simulator.table.sub1'), prop: 'name' },
+ { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
+ ...selectedModules?.itemList?.map((module) => {
+ return {
+ name: module.itemNm,
+ prop: module.itemId,
+ }
+ }),
+ { name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
+ ]
+ const surfaceObjects = {}
+ const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+
+ surfaces.forEach((surface) => {
+ surfaceObjects[surface.id] = {
+ roofSurface: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText,
+ circuit: '-',
+ amount: 0,
+ wpOut: 0,
+ circuits: {},
+ }
+
+ surface.modules.forEach((module) => {
+ if (!surfaceObjects[surface.id][module.moduleInfo.itemId]) {
+ // 지붕면에 모듈 존재 여부
+ surfaceObjects[surface.id][module.moduleInfo.itemId] = 0 // 모듈 초기화
+ }
+
+ surfaceObjects[surface.id][module.moduleInfo.itemId]++
+ surfaceObjects[surface.id].wpOut += +module.moduleInfo.wpOut
+ if (module.circuit) {
+ if (!surfaceObjects[surface.id].circuits[module.circuitNumber]) {
+ surfaceObjects[surface.id].circuits[module.circuitNumber] = {
+ circuit: module.circuitNumber,
+ wpOut: 0,
+ circuits: { wpOut: 0 },
+ }
+ }
+
+ if (!surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]) {
+ surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId] = 0
+ }
+ surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]++
+ surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut += +module.moduleInfo.wpOut
+ surfaceObjects[surface.id].wpOut -= +module.moduleInfo.wpOut
+ surfaceObjects[surface.id][module.moduleInfo.itemId]--
+ }
+ })
+ })
+ let tempRows = []
+ Object.keys(surfaceObjects).forEach((key) => {
+ let tempRow = {
+ name: surfaceObjects[key].roofSurface,
+ circuit: surfaceObjects[key].circuit,
+ wpOut: parseFloat(surfaceObjects[key].wpOut / 1000),
+ }
+ selectedModules.itemList.forEach((module) => {
+ tempRow[module.itemId] = surfaceObjects[key][module.itemId]
+ })
+ tempRows.push(tempRow)
+
+ Object.keys(surfaceObjects[key].circuits).forEach((circuit) => {
+ let row = {
+ name: surfaceObjects[key].roofSurface,
+ circuit: surfaceObjects[key].circuits[circuit].circuit,
+ wpOut: parseFloat(surfaceObjects[key].circuits[circuit].circuits.wpOut / 1000),
+ }
+ selectedModules.itemList.forEach((module) => {
+ row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
+ })
+ tempRows.push(row)
+ })
+ })
+
+ const tempFooter = {
+ name: getMessage('modal.panel.batch.statistic.total'),
+ circuit: '-',
+ wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0),
+ }
+ selectedModules.itemList.forEach((module) => {
+ tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0)
+ })
+ canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
+ setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
+ }
+
+ return {
+ makers,
+ setMakers,
+ selectedMaker,
+ setSelectedMaker,
+ series,
+ setSeries,
+ models,
+ setModels,
+ selectedModels,
+ setSelectedModels,
+ pcsCheck,
+ setPcsCheck,
+ getOptYn,
+ getPcsItemList,
+ getSelectedPcsItemList,
+ getUseModuleItemList,
+ getRoofSurfaceList,
+ getModuleList,
+ removeNotAllocationModules,
+ setModuleStatisticsData,
+ }
+}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index a0b42438..184a3aea 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -67,8 +67,8 @@ export function useContextMenu() {
const commonTextFont = useRecoilValue(fontSelector('commonText'))
const { settingsData, setSettingsDataSave } = useCanvasSetting()
const { swalFire } = useSwal()
- const { alignModule, modulesRemove } = useModule()
- const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial } = useRoofFn()
+ const { alignModule, modulesRemove, moduleRoofRemove } = useModule()
+ const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines } = useRoofFn()
const currentMenuSetting = () => {
switch (currentMenu) {
@@ -150,7 +150,9 @@ export function useContextMenu() {
{
id: 'wallLineRemove',
name: getMessage('contextmenu.wallline.remove'),
- fn: () => deleteOuterLineObject(),
+ fn: (currentMousePos) => {
+ removeOuterLines(currentMousePos)
+ },
},
],
[
@@ -176,7 +178,14 @@ export function useContextMenu() {
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
fn: () => {
+ if (!currentObject) return
const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]
+ if (!roof) {
+ // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거
+ canvas.remove(currentObject)
+ canvas.discardActiveObject()
+ return
+ }
const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id)
roof.innerLines = [...innerLines]
canvas.remove(currentObject)
@@ -187,6 +196,7 @@ export function useContextMenu() {
id: 'auxiliaryVerticalBisector',
name: getMessage('contextmenu.auxiliary.vertical.bisector'),
fn: () => {
+ if (!currentObject) return
const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1)
const length = currentObject.length
@@ -217,6 +227,11 @@ export function useContextMenu() {
name: 'auxiliaryLine',
attributes: { ...currentObject.attributes },
})
+
+ if (!currentObject.attributes.roofId) {
+ return
+ }
+
canvas
.getObjects()
.filter((obj) => obj.id === currentObject.attributes.roofId)[0]
@@ -231,11 +246,21 @@ export function useContextMenu() {
swalFire({ text: '지붕을 선택해주세요.' })
return
}
- const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0].innerLines
- innerLines.forEach((line) => {
+ const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines
+ if (innerLines) {
+ innerLines.forEach((line) => {
+ canvas.remove(line)
+ })
+ innerLines.length = 0
+ }
+
+ // 확정되지 않은 보조선
+ const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed)
+
+ notFixedAuxiliaryLines.forEach((line) => {
canvas.remove(line)
})
- innerLines.length = 0
+
canvas.renderAll()
},
},
@@ -332,8 +357,8 @@ export function useContextMenu() {
}, [currentContextMenu])
useEffect(() => {
+ console.log('currentObject', currentObject)
if (currentObject?.name) {
- console.log('object', currentObject)
switch (currentObject.name) {
case 'triangleDormer':
case 'pentagonDormer':
@@ -725,38 +750,40 @@ export function useContextMenu() {
{
id: 'moduleVerticalCenterAlign',
name: getMessage('contextmenu.module.vertical.align'),
- fn: () => alignModule(MODULE_ALIGN_TYPE.VERTICAL),
+ fn: () => alignModule(MODULE_ALIGN_TYPE.VERTICAL, currentObject.arrayData),
},
{
id: 'moduleHorizonCenterAlign',
name: getMessage('contextmenu.module.horizon.align'),
- fn: () => alignModule(MODULE_ALIGN_TYPE.HORIZONTAL),
+ fn: () => alignModule(MODULE_ALIGN_TYPE.HORIZONTAL, currentObject.arrayData),
},
{
id: 'moduleRemove',
name: getMessage('contextmenu.module.remove'),
fn: () => {
- const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
- const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
- canvas.remove(...modules)
- canvas.renderAll()
+ moduleRoofRemove(currentObject.arrayData)
+
+ // const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ // const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
+ // canvas.remove(...modules)
+ // canvas.renderAll()
},
},
{
id: 'moduleMove',
name: getMessage('contextmenu.module.move'),
- component: ,
+ component: ,
},
{
id: 'moduleCopy',
name: getMessage('contextmenu.module.copy'),
- component: ,
- },
- {
- id: 'moduleCircuitNumberEdit',
- name: getMessage('contextmenu.module.circuit.number.edit'),
- component: ,
+ component: ,
},
+ // {
+ // id: 'moduleCircuitNumberEdit',
+ // name: getMessage('contextmenu.module.circuit.number.edit'),
+ // component: ,
+ // },
],
])
break
diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js
new file mode 100644
index 00000000..7abe27b1
--- /dev/null
+++ b/src/hooks/useEstimate.js
@@ -0,0 +1,78 @@
+import { useContext } from 'react'
+import { useRouter } from 'next/navigation'
+
+import { useRecoilValue } from 'recoil'
+
+import { useAxios } from '@/hooks/useAxios'
+import { useSwal } from '@/hooks/useSwal'
+import { GlobalDataContext } from '@/app/GlobalDataProvider'
+import { QcastContext } from '@/app/QcastProvider'
+import { currentCanvasPlanState } from '@/store/canvasAtom'
+import { loginUserStore } from '@/store/commonAtom'
+
+export function useEstimate() {
+ const { managementStateLoaded } = useContext(GlobalDataContext)
+ const { setIsGlobalLoading } = useContext(QcastContext)
+ const router = useRouter()
+ const loginUserState = useRecoilValue(loginUserStore)
+ const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
+
+ const { promisePost } = useAxios()
+ const { swalFire } = useSwal()
+
+ /**
+ * 도면 견적서 저장
+ */
+ const saveEstimate = async (estimateParam) => {
+ // 로딩 임시 주석
+ // setIsGlobalLoading(true)
+
+ const userId = loginUserState.userId
+ const saleStoreId = managementStateLoaded.saleStoreId
+ const objectNo = currentCanvasPlan.objectNo
+ const planNo = currentCanvasPlan.planNo
+ const slope = estimateParam.roofSurfaceList[0].slope
+ const angle = estimateParam.roofSurfaceList[0].angle
+ const surfaceType = managementStateLoaded.surfaceType
+ const setupHeight = managementStateLoaded.installHeight
+ const standardWindSpeedId = managementStateLoaded.standardWindSpeedId
+ const snowfall = managementStateLoaded.verticalSnowCover
+ const drawingFlg = '1'
+
+ const saveEstimateData = {
+ ...estimateParam,
+ userId: userId,
+ saleStoreId: saleStoreId,
+ objectNo: objectNo,
+ planNo: planNo,
+ slope: slope,
+ angle: angle,
+ surfaceType: surfaceType,
+ setupHeight: setupHeight,
+ standardWindSpeedId: standardWindSpeedId,
+ snowfall: snowfall,
+ drawingFlg: drawingFlg,
+ }
+
+ await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData })
+ .then(async () => {
+ // 견적서 저장이 완료되면 견적서 페이지로 이동
+ moveEstimate(planNo, objectNo)
+ })
+ .catch((error) => {
+ swalFire({ text: error.message, icon: 'error' })
+ })
+ }
+
+ /**
+ * 견적서 페이지로 이동
+ */
+ const moveEstimate = (planNo, objectNo) => {
+ router.push(`/floor-plan/estimate/5?pid=${planNo}&objectNo=${objectNo}`)
+ }
+
+ return {
+ saveEstimate,
+ moveEstimate,
+ }
+}
diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js
index dd251463..e2667e80 100644
--- a/src/hooks/useLine.js
+++ b/src/hooks/useLine.js
@@ -93,10 +93,11 @@ export const useLine = () => {
let left, top
- const textStr =
- currentAngleType === ANGLE_TYPE.SLOPE
- ? `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${!onlyOffset && attributes.pitch ? '-∠' + attributes.pitch + angleUnit : ''}`
- : `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${!onlyOffset && attributes.pitch ? '-∠' + getDegreeByChon(attributes.pitch) + angleUnit : ''}`
+ const textStr = `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}`
+
+ // currentAngleType === ANGLE_TYPE.SLOPE
+ // ? `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${!onlyOffset && attributes.pitch ? '-∠' + attributes.pitch + angleUnit : ''}`
+ // : `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${!onlyOffset && attributes.pitch ? '-∠' + getDegreeByChon(attributes.pitch) + angleUnit : ''}`
if (direction === 'top') {
left = (startPoint.x + endPoint.x) / 2
@@ -125,6 +126,7 @@ export const useLine = () => {
name: 'pitchText',
parentId: line.id,
pitch: attributes.pitch,
+ onlyOffset,
})
canvas.add(text)
diff --git a/src/hooks/useMouse.js b/src/hooks/useMouse.js
index 456ab278..e88b4cb0 100644
--- a/src/hooks/useMouse.js
+++ b/src/hooks/useMouse.js
@@ -1,21 +1,10 @@
import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
-import { getInterSectionLineNotOverCoordinate } from '@/util/canvas-util'
+import { calculateIntersection, getInterSectionLineNotOverCoordinate } from '@/util/canvas-util'
export function useMouse() {
const canvas = useRecoilValue(canvasState)
- //가로선, 세로선의 교차점을 return
- /*const getIntersectMousePoint = (e) => {
- let pointer = canvas.getPointer(e.e)
- const mouseLines = canvas.getObjects().filter((obj) => obj.name === 'mouseLine')
-
- if (mouseLines.length < 2) {
- return pointer
- }
-
- return getInterSectionLineNotOverCoordinate(mouseLines[0], mouseLines[1]) || pointer
- }*/
//가로선, 세로선의 교차점을 return
const getIntersectMousePoint = (e) => {
let pointer = canvas.getPointer(e.e)
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index 6b468405..9db69642 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -3,7 +3,7 @@
import { useContext, useEffect, useState } from 'react'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
-import { useRecoilState } from 'recoil'
+import { useRecoilState, useResetRecoilState } from 'recoil'
import { canvasState, currentCanvasPlanState, plansState } from '@/store/canvasAtom'
import { useAxios } from '@/hooks/useAxios'
@@ -14,6 +14,8 @@ import { SAVE_KEY } from '@/common/common'
import { readImage, removeImage } from '@/lib/fileAction'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
+import { outerLinePointsState } from '@/store/outerLineAtom'
+import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
export function usePlan(params = {}) {
const { floorPlanState } = useContext(FloorPlanContext)
@@ -33,6 +35,10 @@ export function usePlan(params = {}) {
const { get, promisePost, promisePut, promiseDel, promiseGet } = useAxios()
const { setEstimateContextState } = useEstimateController()
+
+ const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
+ const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
+
/**
* 마우스 포인터의 가이드라인을 제거합니다.
*/
@@ -120,16 +126,16 @@ export function usePlan(params = {}) {
/**
* 페이지 내 캔버스를 저장
*/
- const saveCanvas = async () => {
+ const saveCanvas = async (saveAlert = true) => {
const canvasStatus = currentCanvasData('save')
- await putCanvasStatus(canvasStatus)
+ await putCanvasStatus(canvasStatus, saveAlert)
}
/**
* objectNo에 해당하는 canvas 목록을 조회
*/
- const getCanvasByObjectNo = async (userId, objectNo, planNo) => {
- return await get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) =>
+ const getCanvasByObjectNo = async (objectNo, planNo) => {
+ return await get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` }).then((res) =>
res.map((item) => ({
id: item.id,
objectNo: item.objectNo,
@@ -144,55 +150,63 @@ export function usePlan(params = {}) {
}
/**
- * 물건번호(object) plan 추가 (canvas 생성 전 planNo 할당)
+ * 신규 plan 추가
+ *
+ * case 1) 초기 플랜 생성 : isInitPlan = true, isCopy = false
+ * case 2) 빈 플랜 생성 : isInitPlan = false, isCopy = false
+ * case 3) 복제 플랜 생성 : isInitPlan = false, isCopy = true
*/
- const postObjectPlan = async (userId, objectNo) => {
- return await promisePost({ url: '/api/object/add-plan', data: { userId: userId, objectNo: objectNo } })
+ const postObjectPlan = async (userId, objectNo, isCopy = false, isInitPlan = false) => {
+ const planData = isCopy
+ ? {
+ userId: userId,
+ objectNo: objectNo,
+ copyFlg: '1',
+ planNo: currentCanvasPlan?.planNo,
+ }
+ : {
+ userId: userId,
+ objectNo: objectNo,
+ copyFlg: '0',
+ }
+ await promisePost({ url: '/api/object/add-plan', data: planData })
.then((res) => {
- return res.data.planNo
- })
- .catch((error) => {
- swalFire({ text: error.response.data.message, icon: 'error' })
- return null
- })
- }
+ let newPlan = {
+ id: res.data.canvasId,
+ objectNo: objectNo,
+ planNo: res.data.planNo,
+ userId: userId,
+ canvasStatus: '',
+ isCurrent: true,
+ bgImageName: null,
+ mapPositionAddress: null,
+ }
- /**
- * 신규 canvas 데이터를 저장
- */
- const postCanvasStatus = async (userId, objectNo, canvasStatus, isInitPlan = false) => {
- const planNo = await postObjectPlan(userId, objectNo)
- if (!planNo) return
-
- const planData = {
- userId: userId,
- objectNo: objectNo,
- planNo: planNo,
- bgImageName: currentCanvasPlan?.bgImageName ?? null,
- mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null,
- canvasStatus: canvasToDbFormat(canvasStatus),
- }
- await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData })
- .then((res) => {
- const newPlan = { id: res.data, objectNo: objectNo, planNo: planNo, userId: userId, canvasStatus: canvasStatus, isCurrent: true }
- setCurrentCanvasPlan(newPlan)
if (isInitPlan) {
// 초기 플랜 생성인 경우 플랜 목록 초기화
+ setCurrentCanvasPlan(newPlan)
setPlans([newPlan])
} else {
+ if (isCopy) {
+ // 복제 플랜 생성인 경우 현재 캔버스 데이터를 복제
+ newPlan.canvasStatus = currentCanvasData()
+ newPlan.bgImageName = currentCanvasPlan?.bgImageName ?? null
+ newPlan.mapPositionAddress = currentCanvasPlan?.mapPositionAddress ?? null
+ }
+ setCurrentCanvasPlan(newPlan)
setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan])
swalFire({ text: getMessage('plan.message.save') })
}
})
.catch((error) => {
- swalFire({ text: error.message, icon: 'error' })
+ swalFire({ text: error.response.data.message, icon: 'error' })
})
}
/**
* id에 해당하는 canvas 데이터를 수정
*/
- const putCanvasStatus = async (canvasStatus) => {
+ const putCanvasStatus = async (canvasStatus, saveAlert = true) => {
const planData = {
id: currentCanvasPlan.id,
bgImageName: currentCanvasPlan?.bgImageName ?? null,
@@ -202,7 +216,7 @@ export function usePlan(params = {}) {
await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
.then((res) => {
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
- swalFire({ text: getMessage('plan.message.save') })
+ if (saveAlert) swalFire({ text: getMessage('plan.message.save') })
})
.catch((error) => {
swalFire({ text: error.message, icon: 'error' })
@@ -238,7 +252,9 @@ export function usePlan(params = {}) {
if (res.status === 200) {
const estimateDetail = res.data
if (pathname === '/floor-plan/estimate/5') {
- if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
+ // 견적서 이동 조건 수정
+ // if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
+ if (estimateDetail.estimateDate !== null) {
res.data.resetFlag = 'N'
if (res.data.itemList.length > 0) {
@@ -263,7 +279,7 @@ export function usePlan(params = {}) {
}
} else {
// 발전시뮬레이션
- if (estimateDetail.tempFlg === '0') {
+ if (estimateDetail.estimateDate !== null) {
setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId))
setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId })))
} else {
@@ -281,7 +297,9 @@ export function usePlan(params = {}) {
})
} else {
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
- await saveCanvas()
+ await saveCanvas(true)
+
+ clearRecoilState()
}
setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId))
setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId })))
@@ -294,9 +312,15 @@ export function usePlan(params = {}) {
// setBgImage()
}, [currentCanvasPlan])
+ const clearRecoilState = () => {
+ //clear가 필요한 recoil state 관리
+ resetOuterLinePoints()
+ resetPlacementShapeDrawingPoints()
+ }
+
const handleCurrentPlanUrl = () => {
- const currentPlan = plans.find((plan) => plan.isCurrent)
- if (currentPlan) router.push(`${pathname}?pid=${currentPlan?.planNo}&objectNo=${floorPlanState?.objectNo}`)
+ if (currentCanvasPlan?.planNo && currentCanvasPlan?.objectNo)
+ router.push(`${pathname}?pid=${currentCanvasPlan?.planNo}&objectNo=${currentCanvasPlan?.objectNo}`)
}
const setBgImage = () => {
@@ -309,20 +333,20 @@ export function usePlan(params = {}) {
*/
const handleAddPlan = async (userId, objectNo) => {
if (currentCanvasPlan?.id) {
- await saveCanvas()
+ await saveCanvas(true)
}
JSON.parse(currentCanvasData()).objects.length > 0
? swalFire({
text: `Plan ${currentCanvasPlan.planNo} ` + getMessage('plan.message.confirm.copy'),
type: 'confirm',
confirmFn: async () => {
- await postCanvasStatus(userId, objectNo, currentCanvasData(), false)
+ await postObjectPlan(userId, objectNo, true, false)
},
denyFn: async () => {
- await postCanvasStatus(userId, objectNo, '', false)
+ await postObjectPlan(userId, objectNo, false, false)
},
})
- : await postCanvasStatus(userId, objectNo, '', false)
+ : await postObjectPlan(userId, objectNo, false, false)
}
/**
@@ -373,16 +397,40 @@ export function usePlan(params = {}) {
*/
const loadCanvasPlanData = async (userId, objectNo, planNo) => {
console.log('🚀 ~ loadCanvasPlanData ~ userId, objectNo, planNo:', userId, objectNo, planNo)
- await getCanvasByObjectNo(userId, objectNo, planNo).then((res) => {
+ await getCanvasByObjectNo(objectNo, planNo).then(async (res) => {
if (res.length > 0) {
setCurrentCanvasPlan(res.find((plan) => plan.planNo === planNo))
setPlans(res)
} else {
- postCanvasStatus(userId, objectNo, '', true)
+ await postObjectPlan(userId, objectNo, false, true)
}
})
}
+ /**
+ * plan canvasStatus 초기화
+ */
+ const resetCanvasStatus = () => {
+ setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: null }))
+ setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: null })))
+ }
+
+ /**
+ * plan canvasStatus 불러오기
+ *
+ * 견적서/발전시뮬레이션에서 플랜 이동 시 현재 플랜의 canvasStatus를 불러오기 위해 사용
+ */
+ const reloadCanvasStatus = async (objectNo, planNo) => {
+ if (pathname === '/floor-plan/estimate/5' || pathname === '/floor-plan/simulator/6') {
+ await getCanvasByObjectNo(objectNo, planNo).then((res) => {
+ if (res.length > 0) {
+ setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus }))
+ setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus })))
+ }
+ })
+ }
+ }
+
/**
* 현재 plan 이동 -> 새로운 링크로 이동
*/
@@ -394,11 +442,14 @@ export function usePlan(params = {}) {
canvas,
plans,
currentCanvasPlan,
+ setCurrentCanvasPlan,
selectedPlan,
saveCanvas,
handleCurrentPlan,
handleAddPlan,
handleDeletePlan,
loadCanvasPlanData,
+ resetCanvasStatus,
+ reloadCanvasStatus,
}
}
diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js
index 532f2aac..309688a7 100644
--- a/src/hooks/usePolygon.js
+++ b/src/hooks/usePolygon.js
@@ -61,12 +61,18 @@ export const usePolygon = () => {
let left, top
- if (line.direction === 'left' || line.direction === 'right') {
+ if (line.direction === 'right') {
left = (x1 + x2) / 2
top = (y1 + y2) / 2 + 10
- } else if (line.direction === 'top' || line.direction === 'bottom') {
+ } else if (line.direction === 'top') {
left = (x1 + x2) / 2 + 10
top = (y1 + y2) / 2
+ } else if (line.direction === 'left') {
+ left = (x1 + x2) / 2
+ top = (y1 + y2) / 2 - 30
+ } else if (line.direction === 'bottom') {
+ left = (x1 + x2) / 2 - 50
+ top = (y1 + y2) / 2
}
const minX = line.left
@@ -199,62 +205,94 @@ export const usePolygon = () => {
const polygonMinX = Math.min(...polygon.getCurrentPoints().map((point) => point.x))
const polygonMaxY = Math.max(...polygon.getCurrentPoints().map((point) => point.y))
const polygonMinY = Math.min(...polygon.getCurrentPoints().map((point) => point.y))
+ const lines = polygon.lines
+ let centerPoints
+ switch (direction) {
+ case 'south':
+ // lines중 가장 아래에 있는 라인을 찾는다.
+ const line = lines.reduce((acc, cur) => {
+ return acc.y2 > cur.y2 ? acc : cur
+ }, lines[0])
+ centerPoint = { x: (line.x2 + line.x1) / 2, y: Math.max(line.y1, line.y2) }
+ break
+ case 'north':
+ // lines중 가장 위에 있는 라인을 찾는다.
+ const line2 = lines.reduce((acc, cur) => {
+ return acc.y2 < cur.y2 ? acc : cur
+ }, lines[0])
+ centerPoint = { x: (line2.x2 + line2.x1) / 2, y: Math.min(line2.y1, line2.y2) }
+ break
+ case 'west':
+ // lines중 가장 왼쪽에 있는 라인을 찾는다.
+ const line3 = lines.reduce((acc, cur) => {
+ return acc.x2 < cur.x2 ? acc : cur
+ }, lines[0])
+ centerPoint = { x: Math.min(line3.x1, line3.x2), y: (line3.y1 + line3.y2) / 2 }
+ break
+ case 'east':
+ // lines중 가장 오른쪽에 있는 라인을 찾는다.
+ const line4 = lines.reduce((acc, cur) => {
+ return acc.x2 > cur.x2 ? acc : cur
+ }, lines[0])
+ centerPoint = { x: Math.max(line4.x1, line4.x2), y: (line4.y1 + line4.y2) / 2 }
+ break
+ }
switch (direction) {
case 'north':
points = [
- { x: centerPoint.x - width / 2, y: polygonMinY - 50 },
- { x: centerPoint.x + 20 - width / 2, y: polygonMinY - 50 },
- { x: centerPoint.x + 20 - width / 2, y: polygonMinY - 80 },
- { x: centerPoint.x + 50 - width / 2, y: polygonMinY - 80 },
- { x: centerPoint.x - width / 2, y: polygonMinY - 110 },
- { x: centerPoint.x - 50 - width / 2, y: polygonMinY - 80 },
- { x: centerPoint.x - 20 - width / 2, y: polygonMinY - 80 },
- { x: centerPoint.x - 20 - width / 2, y: polygonMinY - 50 },
+ { x: centerPoint.x, y: polygonMinY - 50 },
+ { x: centerPoint.x + 20, y: polygonMinY - 50 },
+ { x: centerPoint.x + 20, y: polygonMinY - 80 },
+ { x: centerPoint.x + 50, y: polygonMinY - 80 },
+ { x: centerPoint.x, y: polygonMinY - 110 },
+ { x: centerPoint.x - 50, y: polygonMinY - 80 },
+ { x: centerPoint.x - 20, y: polygonMinY - 80 },
+ { x: centerPoint.x - 20, y: polygonMinY - 50 },
]
- stickeyPoint = { x: centerPoint.x - width / 2, y: polygonMinY - 110 }
+ stickeyPoint = { x: centerPoint.x, y: polygonMinY - 110 }
break
case 'south':
points = [
- { x: centerPoint.x + width / 2, y: polygonMaxY + 50 },
- { x: centerPoint.x + 20 + width / 2, y: polygonMaxY + 50 },
- { x: centerPoint.x + 20 + width / 2, y: polygonMaxY + 80 },
- { x: centerPoint.x + 50 + width / 2, y: polygonMaxY + 80 },
- { x: centerPoint.x + width / 2, y: polygonMaxY + 110 },
- { x: centerPoint.x - 50 + width / 2, y: polygonMaxY + 80 },
- { x: centerPoint.x - 20 + width / 2, y: polygonMaxY + 80 },
- { x: centerPoint.x - 20 + width / 2, y: polygonMaxY + 50 },
+ { x: centerPoint.x, y: polygonMaxY + 50 },
+ { x: centerPoint.x + 20, y: polygonMaxY + 50 },
+ { x: centerPoint.x + 20, y: polygonMaxY + 80 },
+ { x: centerPoint.x + 50, y: polygonMaxY + 80 },
+ { x: centerPoint.x, y: polygonMaxY + 110 },
+ { x: centerPoint.x - 50, y: polygonMaxY + 80 },
+ { x: centerPoint.x - 20, y: polygonMaxY + 80 },
+ { x: centerPoint.x - 20, y: polygonMaxY + 50 },
]
- stickeyPoint = { x: centerPoint.x + width / 2, y: polygonMaxY + 110 }
+ stickeyPoint = { x: centerPoint.x, y: polygonMaxY + 110 }
break
case 'west':
points = [
- { x: polygonMinX - 50, y: centerPoint.y - height / 2 },
- { x: polygonMinX - 50, y: centerPoint.y + 20 - height / 2 },
- { x: polygonMinX - 80, y: centerPoint.y + 20 - height / 2 },
- { x: polygonMinX - 80, y: centerPoint.y + 50 - height / 2 },
- { x: polygonMinX - 110, y: centerPoint.y - height / 2 },
- { x: polygonMinX - 80, y: centerPoint.y - 50 - height / 2 },
- { x: polygonMinX - 80, y: centerPoint.y - 20 - height / 2 },
- { x: polygonMinX - 50, y: centerPoint.y - 20 - height / 2 },
+ { x: polygonMinX - 50, y: centerPoint.y },
+ { x: polygonMinX - 50, y: centerPoint.y + 20 },
+ { x: polygonMinX - 80, y: centerPoint.y + 20 },
+ { x: polygonMinX - 80, y: centerPoint.y + 50 },
+ { x: polygonMinX - 110, y: centerPoint.y },
+ { x: polygonMinX - 80, y: centerPoint.y - 50 },
+ { x: polygonMinX - 80, y: centerPoint.y - 20 },
+ { x: polygonMinX - 50, y: centerPoint.y - 20 },
]
- stickeyPoint = { x: polygonMinX - 110, y: centerPoint.y - height / 2 }
+ stickeyPoint = { x: polygonMinX - 110, y: centerPoint.y }
break
case 'east':
points = [
- { x: polygonMaxX + 50, y: centerPoint.y + height / 2 },
- { x: polygonMaxX + 50, y: centerPoint.y + 20 + height / 2 },
- { x: polygonMaxX + 80, y: centerPoint.y + 20 + height / 2 },
- { x: polygonMaxX + 80, y: centerPoint.y + 50 + height / 2 },
- { x: polygonMaxX + 110, y: centerPoint.y + height / 2 },
- { x: polygonMaxX + 80, y: centerPoint.y - 50 + height / 2 },
- { x: polygonMaxX + 80, y: centerPoint.y - 20 + height / 2 },
- { x: polygonMaxX + 50, y: centerPoint.y - 20 + height / 2 },
+ { x: polygonMaxX + 50, y: centerPoint.y },
+ { x: polygonMaxX + 50, y: centerPoint.y + 20 },
+ { x: polygonMaxX + 80, y: centerPoint.y + 20 },
+ { x: polygonMaxX + 80, y: centerPoint.y + 50 },
+ { x: polygonMaxX + 110, y: centerPoint.y },
+ { x: polygonMaxX + 80, y: centerPoint.y - 50 },
+ { x: polygonMaxX + 80, y: centerPoint.y - 20 },
+ { x: polygonMaxX + 50, y: centerPoint.y - 20 },
]
- stickeyPoint = { x: polygonMaxX + 110, y: centerPoint.y + height / 2 }
+ stickeyPoint = { x: polygonMaxX + 110, y: centerPoint.y }
break
}
@@ -309,7 +347,35 @@ export const usePolygon = () => {
let text = ''
- const compassType = (375 - getDegreeInOrientation(moduleCompass)) / 15
+ let compassType = (375 - getDegreeInOrientation(moduleCompass)) / 15
+
+ if (moduleCompass === 0 || (moduleCompass < 0 && moduleCompass >= -6)) {
+ compassType = 1
+ } else if (moduleCompass < 0 && moduleCompass >= -21) {
+ compassType = 2
+ } else if (moduleCompass < 0 && moduleCompass >= -36) {
+ compassType = 3
+ } else if (moduleCompass < 0 && moduleCompass >= -51) {
+ compassType = 4
+ } else if (moduleCompass < 0 && moduleCompass >= -66) {
+ compassType = 5
+ } else if (moduleCompass < 0 && moduleCompass >= -81) {
+ compassType = 6
+ } else if (moduleCompass < 0 && moduleCompass >= -96) {
+ compassType = 7
+ } else if (moduleCompass < 0 && moduleCompass >= -111) {
+ compassType = 8
+ } else if (moduleCompass < 0 && moduleCompass >= -126) {
+ compassType = 9
+ } else if (moduleCompass < 0 && moduleCompass >= -141) {
+ compassType = 10
+ } else if (moduleCompass < 0 && moduleCompass >= -156) {
+ compassType = 11
+ } else if (moduleCompass < 0 && moduleCompass >= -171) {
+ compassType = 12
+ } else if (moduleCompass === 180) {
+ compassType = 13
+ }
if ([1, 25].includes(compassType)) {
direction === 'north' ? (text = '北') : direction === 'south' ? (text = '南') : direction === 'west' ? (text = '西') : (text = '東')
diff --git a/src/hooks/useTempGrid.js b/src/hooks/useTempGrid.js
index 7bfcf263..d43a19c0 100644
--- a/src/hooks/useTempGrid.js
+++ b/src/hooks/useTempGrid.js
@@ -13,7 +13,7 @@ export function useTempGrid() {
//임의 그리드 모드일 경우
let pointer = canvas.getPointer(e.e)
- const tempGrid = new fabric.Line([pointer.x, 0, pointer.x, canvas.height], {
+ const tempGrid = new fabric.Line([pointer.x, -1500, pointer.x, 2500], {
stroke: gridColor,
strokeWidth: 1,
selectable: true,
@@ -41,7 +41,7 @@ export function useTempGrid() {
//임의 그리드 모드일 경우
let pointer = { x: e.offsetX, y: e.offsetY }
- const tempGrid = new fabric.Line([0, pointer.y, canvas.width, pointer.y], {
+ const tempGrid = new fabric.Line([-1500, pointer.y, 2500, pointer.y], {
stroke: gridColor,
strokeWidth: 1,
selectable: true,
diff --git a/src/lib/authActions.js b/src/lib/authActions.js
index 929d3895..e1bbd192 100644
--- a/src/lib/authActions.js
+++ b/src/lib/authActions.js
@@ -16,9 +16,7 @@ export async function getSession() {
let session
session = await getIronSession(cookies(), sessionOptions)
- console.log('session:', session)
if (!session.isLoggedIn) {
- // session.isLoggedIn = defaultSession.isLoggedIn
session.isLoggedIn = false
}
@@ -27,10 +25,6 @@ export async function getSession() {
export async function checkSession() {
const session = await getSession()
-
- // if (!session.isLoggedIn) {
- // redirect('/login')
- // }
return session.isLoggedIn
}
@@ -54,7 +48,6 @@ export async function setSession(data) {
session.pwdInitYn = data.pwdInitYn
session.custCd = data.custCd
session.isLoggedIn = true
- // console.log('session:', session)
await session.save()
}
@@ -64,31 +57,33 @@ export async function login() {
if (session) {
redirect('/')
}
-
- // const userId = formData.get('id')
- // const password = formData.get('password')
-
- // console.log('id:', userId)
- // console.log('password:', password)
-
- // // const loginUser = await getUserByIdAndPassword({ userId, password })
- // const loginUser = {
- // id: 1,
- // userId: 'test123',
- // name: 'jinsoo Kim',
- // email: 'jinsoo.kim@example.com',
- // }
-
- // if (!loginUser) {
- // throw Error('Wrong Credentials!')
- // }
-
- // session.name = loginUser.name
- // session.userId = loginUser.userId
- // session.email = loginUser.email
- // session.isLoggedIn = true
- // console.log('session:', session)
-
- // await session.save()
- // redirect('/')
+}
+
+export const customSetMenuNumber = async ({ objectNo, pid, menuNum, callback = () => {} }) => {
+ let db = null
+
+ if (!db) {
+ db = await open({
+ filename: 'qcast3.global.sqlite',
+ driver: sqlite3.Database,
+ })
+ }
+
+ const chkSql = `SELECT menu_num FROM current_menu WHERE object_no = ? AND pid = ?`
+ const prevMenuNum = await getInstance().get(chkSql, objectNo, pid)
+
+ if (prevMenuNum) {
+ if (prevMenuNum > menuNum) {
+ callback()
+ } else {
+ const sql = `UPDATE current_menu SET menu_num = ? WHERE object_no = ? AND pid = ?`
+ await getInstance().run(sql, menuNum, objectNo, pid)
+
+ setMenuNumber(menuNum)
+ }
+ } else {
+ const sql = `INSERT INTO current_menu (object_no, pid, menu_num) VALUES (?, ?, ?)`
+ await getInstance().run(sql, objectNo, pid, menuNum)
+ setMenuNumber(menuNum)
+ }
}
diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js
index d2c4cff9..fab487c6 100644
--- a/src/lib/fileAction.js
+++ b/src/lib/fileAction.js
@@ -72,15 +72,7 @@ const writeImage = async (fileName, file) => {
}
const readImage = async (fileName) => {
- const file = await fs.readFile(`${FILE_PATH}/${fileName}`)
- // .then((res) => {
- // console.log('readImage-then', res)
- // })
- // .catch((e) => {
- // console.log('readImage-catch', e)
- // })
- console.log('🚀 ~ readImage ~ file:', file)
-
+ const file = await fs.readFile(`${process.env.NEXT_PUBLIC_HOST_URL}${fileName}`)
return file
}
@@ -88,7 +80,7 @@ const removeImage = async (fileName) => {
try {
await fs.rm(`${FILE_PATH}/${fileName}.png`)
} catch (e) {
- console.log(e)
+ // Error handling without console.log
}
}
diff --git a/src/locales/ja.json b/src/locales/ja.json
index 4f7ca481..7646c783 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -1,171 +1,181 @@
{
"hi": "こんにちは",
- "welcome": "환영합니다. {0}님",
- "header.menus.home": "ホームへv",
- "header.menus.management": "物品及び図面管理",
- "header.menus.management.newStuff": "新規 物件 登録",
+ "welcome": "ようこそ。 {0}さん",
+ "header.menus.home": "ホーム",
+ "header.menus.management": "オブジェクトと図面の管理",
+ "header.menus.management.newStuff": "新規物件登録",
"header.menus.management.detail": "物件詳細",
- "header.menus.management.stuffList": "物件の状況",
+ "header.menus.management.stuffList": "見積状況",
"header.menus.community": "コミュニティ",
"header.menus.community.notice": "お知らせ",
"header.menus.community.faq": "FAQ",
- "header.menus.community.archive": "素材のダウンロード",
+ "header.menus.community.archive": "文書ダウンロード",
"header.logout": "ログアウト",
"header.go": "移動",
- "header.online.warranty.system": "オンライン保証シ",
- "header.stem": "ステム",
- "plan.menu.plan.drawing": "물건정보(JA)",
- "plan.menu.placement.surface.initial.setting": "配置面 初期設定",
- "modal.placement.initial.setting.plan.drawing.size.stuff": "寸法入力による物品作成",
- "modal.placement.initial.setting.plan.": "図面の作成方法",
+ "header.online.warranty.system": "オンライン保証システム",
+ "header.stem": "Stem",
+ "plan.menu.plan.drawing": "物件情報",
+ "plan.menu.placement.surface.initial.setting": "配置面初期設定",
+ "modal.placement.initial.setting.plan.drawing": "図面の作成方法",
+ "modal.placement.initial.setting.plan.drawing.size.stuff": "寸法入力による物件作成",
"modal.placement.initial.setting.size": "寸法入力方法",
"modal.placement.initial.setting.size.info": "寸法入力方法案内",
- "modal.placement.initial.setting.size.roof": "複視図入力",
- "modal.placement.initial.setting.size.roof.info": "平面の外壁線と立面の屋根勾配に基づいて作画する場合に選択",
+ "modal.placement.initial.setting.size.roof": "伏図入力",
+ "modal.placement.initial.setting.size.roof.info": "平面の外壁線と立面の屋根勾配に基づいて作画する場合選択",
"modal.placement.initial.setting.size.actual": "実測値入力",
- "modal.placement.initial.setting.size.actual.info": "現地屋根の外周寸法を入力して作画する場合選択",
- "modal.placement.initial.setting.size.none.pitch": "陸上屋根",
+ "modal.placement.initial.setting.size.actual.info": "屋根の外周寸法を入力して作画する場合選択",
+ "modal.placement.initial.setting.size.none.pitch": "陸屋根",
"modal.placement.initial.setting.size.none.pitch.info": "傾斜のない平面形状の屋根にパネルを配置する場合に選択",
- "modal.placement.initial.setting.roof.angle.setting": "屋根角度設定",
+ "modal.placement.initial.setting.roof.angle.setting": "角度設定",
"modal.placement.initial.setting.roof.pitch": "傾斜",
"modal.placement.initial.setting.roof.angle": "角度",
- "modal.placement.initial.setting.roof.material": "屋根材の選択(単位:mm)",
+ "modal.placement.initial.setting.roof.material": "屋根材選択(単位mm)",
"modal.placement.initial.setting.roof.material.info": "対応可能な屋根材や足場は限定されますので、必ず事前マニュアルをご確認ください。",
- "modal.placement.initial.setting.rafter": "垂木の間隔",
+ "modal.placement.initial.setting.rafter": "垂木",
"modal.roof.shape.setting": "屋根形状の設定",
- "modal.roof.shape.setting.ridge": "龍丸屋根",
+ "modal.roof.shape.setting.ridge": "棟",
"modal.roof.shape.setting.patten.a": "Aパターン",
"modal.roof.shape.setting.patten.b": "Bパターン",
"modal.roof.shape.setting.side": "別に設定",
- "plan.menu.roof.cover": "지붕덮개",
- "plan.menu.roof.cover.outline.drawing": "外壁線を描",
- "plan.menu.roof.cover.roof.shape.setting": "屋根形状設定",
- "plan.menu.roof.cover.roof.shape.passivity.setting": "屋根形状設定",
- "plan.menu.roof.cover.eaves.kerava.edit": "처마·케라바 변경",
- "plan.menu.roof.cover.movement.shape.updown": "동선이동·형올림내림(JA)",
- "modal.movement.flow.line.move": "銅線の移動軒",
- "modal.movement.flow.line.move.alert": "이동 할 수 없습니다.(JA)",
- "modal.movement.flow.line.updown": "型上げ・降り",
- "modal.movement.flow.line.updown.info": "を選択して幅を指定してください桁の異なる辺。",
+ "plan.menu.roof.cover": "屋根カバー",
+ "plan.menu.roof.cover.outline.drawing": "外壁線を描く",
+ "plan.menu.roof.cover.roof.shape.setting": "屋根形状の設定",
+ "plan.menu.roof.cover.roof.shape.passivity.setting": "屋根形状の手動設定",
+ "plan.menu.roof.cover.eaves.kerava.edit": "軒・ケラバ変更",
+ "plan.menu.roof.cover.movement.shape.updown": "軒線移動・桁上げ下り",
+ "modal.movement.flow.line.move": "軒線の移動",
+ "modal.movement.flow.line.move.alert": "移動する数ない。",
+ "modal.movement.flow.line.updown": "桁上げ・下り",
+ "modal.movement.flow.line.updown.info": "桁の異なる辺を選択し、幅を指定します。",
"modal.movement.flow.line.updown.up": "桁を上げる",
"modal.movement.flow.line.updown.down": "桁数を下げる",
- "modal.movement.flow.line.info": "家屋などの壁に面する屋根を作成します。",
+ "modal.movement.flow.line.info": "軒線を選択して移動幅を指定します",
"modal.movement.flow.line.bottom.left": "高さ変更:下、左",
"modal.movement.flow.line.top.right": "高さ変更:上、右",
- "plan.menu.roof.cover.outline.edit.offset": "외벽선 편집 및 오프셋(JA)",
- "plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당(JA)",
- "plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집(JA)",
- "plan.menu.roof.cover.auxiliary.line.drawing": "補助線を描",
- "modal.cover.outline.drawing": "外壁線を描",
+ "plan.menu.roof.cover.outline.edit.offset": "外壁の編集とオフセット",
+ "plan.menu.roof.cover.roof.surface.alloc": "屋根面の割り当て",
+ "plan.menu.roof.cover.roof.shape.edit": "屋根形状編集",
+ "plan.menu.roof.cover.auxiliary.line.drawing": "補助線の作成",
+ "modal.cover.outline.drawing": "外壁線の作成",
"modal.cover.outline": "外壁線",
"modal.cover.outline.right.angle": "直角",
- "modal.cover.outline2": "イ・グベ",
+ "modal.cover.outline2": "異勾配",
"modal.cover.outline.angle": "角度",
- "modal.cover.outline.diagonal": "対角線の",
- "modal.cover.outline.setting": "설정",
- "modal.cover.outline.length": "長さ (mm)",
- "modal.cover.outline.arrow": "方向 (矢印)",
+ "modal.cover.outline.diagonal": "対角線",
+ "modal.cover.outline.setting": "設定",
+ "modal.cover.outline.length": "長さ(mm)",
+ "modal.cover.outline.arrow": "方向(矢印)",
"modal.cover.outline.fix": "外壁線確定",
- "modal.cover.outline.rollback": "一変戦に戻る",
+ "modal.cover.outline.rollback": "前に戻る",
"modal.cover.outline.finish": "設定完了",
"common.setting.finish": "設定完了",
- "modal.cover.outline.remove": "外壁の削除",
- "modal.cover.outline.select.move": "外壁の選択、移動",
- "plan.menu.roof.cover.roof.setting": "屋根形状設定",
- "plan.menu.roof.cover.roof.edit": "지붕형상 편집",
- "plan.menu.roof.cover.sub.line": "補助線を描",
+ "common.setting.rollback": "前に戻る",
+ "modal.cover.outline.remove": "外壁の取り外し",
+ "modal.cover.outline.select.move": "外壁選択の移動",
"plan.menu.placement.surface": "配置面",
"plan.menu.placement.surface.slope.setting": "傾斜設定",
"plan.menu.placement.surface.drawing": "配置面の描画",
+ "modal.placement.surface.drawing.straight.line": "直線",
+ "modal.placement.surface.drawing.right.angle": "直角",
+ "modal.placement.surface.drawing.double.pitch": "異勾配",
+ "modal.placement.surface.drawing.angle": "角度",
+ "modal.placement.surface.drawing.diagonal": "対角線",
+ "modal.placement.surface.drawing.fix": "配置面確定",
"plan.menu.placement.surface.arrangement": "面形状の配置",
- "plan.menu.placement.surface.object": "オブジェクトの配置",
+ "plan.menu.placement.surface.object": "モジュール配置",
"plan.menu.placement.surface.all.remove": "配置面全体を削除",
- "plan.menu.module.circuit.setting": "モジュール回路構成",
- "plan.menu.module.circuit.setting.default": "基本設定",
+ "plan.menu.module.circuit.setting": "モジュール、回路構成",
+ "plan.menu.module.circuit.setting.default": "モジュール/架台設定",
"modal.module.basic.setting.orientation.setting": "方位設定",
"modal.module.basic.setting.orientation.setting.info": "※シミュレーション計算用方位を指定します。南の方位を設定してください。",
- "modal.module.basic.setting.orientation.setting.angle.passivity": "角度を直接入力",
+ "modal.module.basic.setting.orientation.setting.angle.passivity": "勾配を直接入力",
"modal.module.basic.setting.module.roof.material": "屋根材",
"modal.module.basic.setting.module.trestle.maker": "架台メーカー",
- "modal.module.basic.setting.module.rafter.margin": "マンドンピッチ",
+ "modal.module.basic.setting.module.rafter.margin": "垂木の間隔",
"modal.module.basic.setting.module.construction.method": "工法",
"modal.module.basic.setting.module.under.roof": "屋根の下",
"modal.module.basic.setting.module.setting": "モジュールの選択",
- "modal.module.basic.setting.module.setting.info1": "※勾配の 範囲には制限があります。屋根傾斜が2.5値未満、10値を超える場合には施工が可能か 施工マニュアルを確認してください。",
- "modal.module.basic.setting.module.setting.info2": "モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ず確認してください",
- "modal.module.basic.setting.module.stuff.info": "商品情報",
- "modal.module.basic.setting.module.surface.type": "면조도구분(JA)",
+ "modal.module.basic.setting.module.hajebichi": "ハゼピッチ",
+ "modal.module.basic.setting.module.setting.info1": "※勾配の範囲には制限があります。屋根傾斜が2.5値未満10値を超える場合は、施工が可能かどうか施工マニュアルを確認してください。",
+ "modal.module.basic.setting.module.setting.info2": "※モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ずご確認ください。",
+ "modal.module.basic.setting.module.stuff.info": "物件情報",
+ "modal.module.basic.setting.module.surface.type": "面粗度区分",
"modal.module.basic.setting.module.fitting.height": "設置高さ",
"modal.module.basic.setting.module.standard.wind.speed": "基準風速",
- "modal.module.basic.setting.module.standard.snowfall.amount": "基準積雪量",
+ "modal.module.basic.setting.module.standard.snowfall.amount": "積雪量",
"modal.module.basic.setting.module.standard.construction": "標準施工",
"modal.module.basic.setting.module.enforce.construction": "強化施工",
"modal.module.basic.setting.module.multiple.construction": "多設施工",
- "modal.module.basic.setting.module.eaves.bar.fitting": "庇力バーの設置",
- "modal.module.basic.setting.module.blind.metal.fitting": "目幕金具の設置",
+ "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置",
+ "modal.module.basic.setting.module.blind.metal.fitting": "積雪防止金具設置",
+ "modal.module.basic.setting.module.select": "モジュール/架台選択",
"modal.module.basic.setting.module.placement": "モジュールの配置",
- "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してくださ",
- "modal.module.basic.setting.module.placement.waterfowl.arrangement": "水鳥の配置",
+ "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
+ "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
"modal.module.basic.setting.module.placement.do": "する",
- "modal.module.basic.setting.module.placement.do.not": "しない。",
+ "modal.module.basic.setting.module.placement.do.not": "しない",
"modal.module.basic.setting.module.placement.arrangement.standard": "配置基準",
- "modal.module.basic.setting.module.placement.arrangement.standard.center": "中央配置",
- "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側",
- "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側",
- "modal.module.basic.setting.module.placement.maximum": "最大配置する。",
- "modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準の設定",
- "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向きに設置す",
- "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置する",
+ "modal.module.basic.setting.module.placement.arrangement.standard.center": "中央",
+ "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒",
+ "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "棟",
+ "modal.module.basic.setting.module.placement.maximum": "最大配置",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準設定",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向き設置",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置",
"modal.module.basic.setting.pitch.module.allocation.setting": "割り当て設定",
- "modal.module.basic.setting.pitch.module.allocation.setting.info": "※バッチパネルの種類が1種類の場合にのみ使用できます。",
+ "modal.module.basic.setting.pitch.module.allocation.setting.info": "※配置パネルの種類が1種類の場合のみ使用できます。",
"modal.module.basic.setting.pitch.module.row.amount": "単数",
"modal.module.basic.setting.pitch.module.row.margin": "上下間隔",
- "modal.module.basic.setting.pitch.module.column.amount": "熱数",
+ "modal.module.basic.setting.pitch.module.column.amount": "列数",
"modal.module.basic.setting.pitch.module.column.margin": "左右間隔",
- "modal.module.basic.setting.prev": "以前",
+ "modal.module.basic.setting.prev": "移転",
"modal.module.basic.setting.passivity.placement": "手動配置",
"modal.module.basic.setting.auto.placement": "設定値に自動配置",
- "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路と架台の設定",
- "modal.circuit.trestle.setting": "回路と架台設定",
- "modal.circuit.trestle.setting.alloc.trestle": "仮割り当て",
- "modal.circuit.trestle.setting.power.conditional.select": "パワーコンディショナーを選択",
+ "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定",
+ "modal.circuit.trestle.setting": "回路設定",
+ "modal.circuit.trestle.setting.alloc.trestle": "架台配置",
+ "modal.circuit.trestle.setting.power.conditional.select": "パワーコンディショナーの選択",
"modal.circuit.trestle.setting.power.conditional.select.cold.region": "寒冷地仕様",
"modal.circuit.trestle.setting.power.conditional.select.name": "名称",
"modal.circuit.trestle.setting.power.conditional.select.rated.output": "定格出力",
"modal.circuit.trestle.setting.power.conditional.select.circuit.amount": "回路数",
- "modal.circuit.trestle.setting.power.conditional.select.max.connection": "最大接続枚数",
- "modal.circuit.trestle.setting.power.conditional.select.max.overload": "過積最大枚数",
+ "modal.circuit.trestle.setting.power.conditional.select.max.connection": "標準枚数",
+ "modal.circuit.trestle.setting.power.conditional.select.max.overload": "最大枚数",
"modal.circuit.trestle.setting.power.conditional.select.output.current": "出力電流",
- "modal.circuit.trestle.setting.power.conditional.select.check1": "同一傾斜同一方面の面積の場合、同じ面として回路を分ける。",
+ "modal.circuit.trestle.setting.power.conditional.select.check1": "同じ傾斜同じ方向の面積ケース同じ面として回路分ける。",
"modal.circuit.trestle.setting.power.conditional.select.check2": "MAX接続(過積)で回路を分ける。",
"modal.circuit.trestle.setting.circuit.allocation": "回路割り当て",
"modal.circuit.trestle.setting.circuit.allocation.auto": "自動回路割り当て",
- "modal.circuit.trestle.setting.circuit.allocation.passivity": "手動回路割当",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity": "手動回路割り当て",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit": "回路",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.info": "同じ回路のモジュールを選択状態にした後、 [番号確認]ボタンを押すと番号が割り当てられます。",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.series": "시리즈(JA)",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.name": "명칭(JA)",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.info": "同じ回路のモジュールを選択状態にした後、[番号確定]ボタンを押すと番号が割り当てられます。",
"modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional": "選択したパワーコンディショナー",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num": "設定する回路番号 (1~)",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "標準回路{0}枚~{1}枚",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset": "選択されたパワーコンディショナーの回路番号の初期化",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num": "設定する回路番号(1~)",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "標準回路{0}章~{1}章",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset": "選択したパワーコンディショナーの回路番号の初期化",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset.info": "선택된 파워 컨디셔너의 회로할당을 초기화합니다.(JA)",
"modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset": "すべての回路番号の初期化",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset.info": "회로 할당의 설정을 초기화합니다.(JA)",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error01": "배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.(JA)",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02": "시리즈를 선택해주세요.(JA)",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num.fix": "番号確定",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.init.info": "선택된 파워 컨디셔너의 회로할당을 초기화합니다.(JA)",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.init.setting.info": "회로 할당의 설정을 초기화합니다.(JA)",
"modal.circuit.trestle.setting.step.up.allocation": "昇圧設定",
"modal.circuit.trestle.setting.step.up.allocation.serial.amount": "シリアル枚数",
"modal.circuit.trestle.setting.step.up.allocation.total.amount": "総回路数",
"modal.circuit.trestle.setting.step.up.allocation.connected": "接続する",
"modal.circuit.trestle.setting.step.up.allocation.circuit.amount": "昇圧回路数",
"modal.circuit.trestle.setting.step.up.allocation.option": "昇圧オプション",
- "modal.circuit.trestle.setting.step.up.allocation.select.monitor": "モニターの選択",
+ "modal.circuit.trestle.setting.step.up.allocation.select.monitor": "オプションを選択",
"plan.menu.module.circuit.setting.plan.orientation": "図面方位の適用",
- "plan.menu.estimate": "見積",
+ "plan.menu.estimate": "見積書",
"plan.menu.estimate.roof.alloc": "屋根面の割り当て",
"modal.roof.alloc.info": "※配置面初期設定で保存した[基本屋根材]を変更したり、屋根材を追加して割り当てることができます。",
"modal.roof.alloc.default.roof.material": "基本屋根材",
"modal.roof.alloc.select.roof.material": "屋根材の選択",
"modal.roof.alloc.select.parallel": "並列式",
- "modal.roof.alloc.select.stairs": "カスケード",
+ "modal.roof.alloc.select.stairs": "階段式",
"modal.roof.alloc.apply": "選択した屋根材として割り当て",
"plan.menu.estimate.docDown": "文書のダウンロード",
"plan.menu.estimate.save": "保存",
@@ -173,27 +183,27 @@
"plan.menu.estimate.copy": "見積書のコピー",
"plan.menu.estimate.unLock": "ロック解除",
"plan.menu.estimate.lock": "ロック",
- "plan.menu.simulation": "発展シミュレーション",
+ "plan.menu.simulation": "発電シミュレーション",
"plan.menu.simulation.excel": "Excel",
"plan.menu.simulation.pdf": "PDF",
"plan.mode.vertical.horizontal": "垂直水平モード",
- "plan.mode.free": "프리 모드(JA)",
+ "plan.mode.free": "フリーモード",
"modal.font.setting": "フォント設定",
"modal.font": "フォント",
"modal.font.style": "フォントスタイル",
"modal.font.size": "サイズ",
- "modal.font.color": "フォン",
- "common.horizon": "ガロ",
- "common.vertical": "縦ロ",
+ "modal.font.color": "フォントの色",
+ "common.horizon": "横",
+ "common.vertical": "縦",
"modal.font.setting.display": "見る",
- "modal.font.setting.info": "ントです。プリンタと画面 でも同じフォントを使用します.",
- "modal.canvas.setting": "Canvas設定",
+ "modal.font.setting.info": "これはOpen Typeフォントです。プリンタや画面でも同じフォントを使用してください。",
+ "modal.canvas.setting": "作図の設定",
"modal.canvas.setting.display": "ディスプレイ設定",
- "modal.canvas.setting.font.plan": " フォントと図面サイズの設定",
- "modal.canvas.setting.grid": "그리드(JA)",
+ "modal.canvas.setting.font.plan": "フォントと図面サイズの設定",
+ "modal.canvas.setting.grid": "グリッド",
"modal.canvas.setting.grid.optional.line": "ランダムグリッド",
- "modal.canvas.setting.grid.dot.line": "ドット・ライングリッド",
- "modal.canvas.setting.grid.dot.line.setting": "ドット・ライングリッドの設定",
+ "modal.canvas.setting.grid.dot.line": "点・線グリッド",
+ "modal.canvas.setting.grid.dot.line.setting": "点・線グリッド設定",
"modal.canvas.setting.grid.dot.line.setting.dot.display": "点グリッド表示",
"modal.canvas.setting.grid.dot.line.setting.line.display": "ライングリッドの表示",
"modal.canvas.setting.grid.dot.line.setting.line.origin": "原寸",
@@ -207,21 +217,22 @@
"modal.auxiliary.drawing": "補助線の作成",
"modal.grid.move": "グリッド移動",
"modal.grid.move.info": "移動する方向を入力してください",
- "modal.grid.move.all": "グリッド全体移動",
+ "modal.grid.move.all": "グリッド全体を移動",
"modal.grid.move.length": "長さ",
"modal.grid.move.save": "保存",
"modal.grid.copy": "グリッドのコピー",
"modal.grid.copy.info": "間隔を設定し、コピー方向を選択します",
"modal.grid.copy.length": "長さ",
"modal.grid.copy.save": "保存",
- "modal.grid.color.edit": "그리드 색 변경(JA)",
- "modal.dormer.offset.info": "移動する方向を入力してください",
+ "modal.grid.color.edit": "グリッドの色の変更",
+ "modal.dormer.offset.info": "移動する距離と方向を入力してください。",
"modal.common.save": "保存",
"modal.common.add": "追加",
"modal.common.prev": "以前",
+ "modal.common.next": "次",
"modal.canvas.setting.font.plan.edit": "フォントとサイズの変更",
"modal.canvas.setting.font.plan.edit.word": "文字フォントの変更",
- "modal.canvas.setting.font.plan.edit.flow": "フロー方向フォントの変更",
+ "modal.canvas.setting.font.plan.edit.flow": "流れ方向フォントの変更",
"modal.canvas.setting.font.plan.edit.dimension": "寸法フォントの変更",
"modal.canvas.setting.font.plan.edit.circuit.num": "回路番号フォントの変更",
"modal.canvas.setting.font.plan.absorption": "吸着範囲の設定",
@@ -231,42 +242,42 @@
"modal.canvas.setting.font.plan.absorption.medium": "中",
"modal.canvas.setting.font.plan.absorption.large": "ティーン",
"modal.canvas.setting.font.plan.absorption.dimension.line": "寸法線の設定",
- "modal.canvas.setting.font.plan.absorption.dimension.line.font.size": "寸法線の線太さ",
- "modal.canvas.setting.font.plan.absorption.dimension.line.color": "寸法線の線の色",
+ "modal.canvas.setting.font.plan.absorption.dimension.line.font.size": "寸法線の太さ",
+ "modal.canvas.setting.font.plan.absorption.dimension.line.color": "寸法線の色",
"modal.canvas.setting.font.plan.absorption.dimension.display": "見る",
"modal.canvas.setting.font.plan.absorption.plan.size.setting": "図面サイズの設定",
"modal.canvas.setting.first.option.info": "※図面に表示する項目をクリックすると適用されます。",
"modal.canvas.setting.first.option.alloc": "割り当て表示",
"modal.canvas.setting.first.option.outline": "外壁線表示",
"modal.canvas.setting.first.option.grid": "グリッド表示",
- "modal.canvas.setting.first.option.roof.line": "屋根線標示",
+ "modal.canvas.setting.first.option.roof.line": "屋根線表示",
"modal.canvas.setting.first.option.word": "文字表示",
"modal.canvas.setting.first.option.circuit.num": "回路番号表示",
"modal.canvas.setting.first.option.flow": "流れ方向表示",
"modal.canvas.setting.first.option.trestle": "架台表示",
"modal.canvas.setting.first.option.image": "画像表示",
- "modal.canvas.setting.first.option.total": "集計表表示",
+ "modal.canvas.setting.first.option.total": "集計表を表示",
"modal.canvas.setting.first.option.dimension": "寸法表示",
- "modal.canvas.setting.first.option.corridor.dimension": "廊下寸法表示",
- "modal.canvas.setting.first.option.real.dimension": "実際の寸法表示",
+ "modal.canvas.setting.first.option.corridor.dimension": "伏せ図寸法表示",
+ "modal.canvas.setting.first.option.real.dimension": "実寸表示",
"modal.canvas.setting.first.option.none.dimension": "寸法表示なし",
"modal.canvas.setting.first.option.display": "画面表示",
"modal.canvas.setting.first.option.border": "ボーダーのみ",
"modal.canvas.setting.first.option.line": "ラインハッチ",
"modal.canvas.setting.first.option.all": "All painted",
"modal.canvas.setting.wallline.properties.setting": "外壁のプロパティの設定",
- "modal.canvas.setting.wallline.properties.setting.info": "※属性を変更する外壁線を選択し、軒で設定またはケラバで設定 ボタンをクリックして設定値を適用します。",
+ "modal.canvas.setting.wallline.properties.setting.info": "※属性を変更する外壁線を選択し、軒で設定またはケラバで設定\nボタンをクリックして設定値を適用してください。\n",
"modal.canvas.setting.wallline.properties.setting.eaves": "軒で設定",
"modal.canvas.setting.wallline.properties.setting.edge": "ケラバに設定",
- "modal.eaves.gable.edit": "軒・ケラバ変更",
+ "modal.eaves.gable.edit": "軒/ケラバ変更",
"modal.eaves.gable.edit.basic": "通常",
- "modal.eaves.gable.edit.wall.merge.info": "家屋などの壁に面する屋根を作成します。",
+ "modal.eaves.gable.edit.wall.merge.info": "河屋などの壁に面する屋根を作成します。",
"modal.wallline.offset.setting": "外壁の編集とオフセット",
"modal.wallline.offset.setting.wallline.edit": "外壁の編集",
"modal.wallline.offset.setting.wallline.edit.info": "辺と始点を選択して長さと方向を指定してください。",
- "modal.wallline.offset.setting.wallline.edit.position": "支店",
+ "modal.wallline.offset.setting.wallline.edit.position": "始点",
"modal.wallline.offset.setting.offset": "オフセット",
- "modal.wallline.offset.setting.offset.info": "オフセットしたい外壁を選択してください。",
+ "modal.wallline.offset.setting.offset.info": "オフセットしたい外壁線を選択してください。",
"modal.object.setting.type.open.space.placement": "開口部の配置",
"modal.object.setting.type.shadow.placement": "影の配置",
"modal.object.setting.type.triangle.dormer": "三角形ドーマー",
@@ -277,25 +288,19 @@
"modal.object.setting.height": "縦長",
"modal.object.setting.area.cross": "エリア交差",
"modal.object.setting.size.setting": "サイズ設定",
- "modal.object.setting.agreement.depth": "同意の深さ",
- "modal.object.setting.offset.depth": "出幅 (深さ)",
- "modal.object.setting.offset.width": "出幅 (幅)",
+ "modal.object.setting.agreement.depth": "棟の長さ・深さ",
+ "modal.object.setting.offset.depth": "出幅(深さ)",
+ "modal.object.setting.offset.width": "出幅(幅)",
"modal.object.setting.direction.select": "方向の選択",
- "modal.placement.surface.setting.info": "ⓘ ①の長さ入力後に対角線の長さを入力すると、②の長さを自動計算します。",
+ "modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。",
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
- "modal.placement.surface.drawing.straight.line": "직선(JA)",
- "modal.placement.surface.drawing.right.angle": "직각(JA)",
- "modal.placement.surface.drawing.double.pitch": "이구배(JA)",
- "modal.placement.surface.drawing.angle": "각도(JA)",
- "modal.placement.surface.drawing.diagonal": "대각선(JA)",
- "modal.placement.surface.drawing.fix": "배치면 확정(JA)",
- "modal.color.picker.title": "色の設定",
+ "modal.color.picker.title": "色設定",
"modal.color.picker.default.color": "基本色",
"modal.size.setting": "サイズ変更",
"modal.shape.flow.direction.setting": "面フローの設定",
"modal.shape.flow.direction.setting.orientation.setting.info": "シミュレーション計算の方向を指定します。面が向いている方位を選択してください。",
- "modal.shape.flow.direction.setting.orientation.8": "8方位に選ぶ",
- "modal.shape.flow.direction.setting.orientation.24": "24方位から選択する (表記は8方位です。)",
+ "modal.shape.flow.direction.setting.orientation.8": "8方位で選択する。",
+ "modal.shape.flow.direction.setting.orientation.24": "24方位で選択する。(表記は8方位です。)",
"modal.panel.batch.statistic": "パネル配置集計",
"modal.panel.batch.statistic.roof.shape": "屋根面",
"modal.panel.batch.statistic.power.generation.amount": "発電量",
@@ -303,265 +308,270 @@
"modal.flow.direction.setting": "流れ方向の設定",
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
"modal.actual.size.setting": "実測値設定",
- "modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。",
- "modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)",
- "modal.actual.size.setting.not.exist.size": "실제치수 길이를 입력해 주세요.(JA)",
- "modal.actual.size.setting.plane.size.length": "廊下の寸法の長さ",
+ "modal.actual.size.setting.info": "※実際寸法入力してください。",
+ "modal.actual.size.setting.not.exist.auxiliary.line": "実測値入力する補助線を選択してください",
+ "modal.actual.size.setting.not.exist.size": "実際の寸法の長さを入力してください",
+ "modal.actual.size.setting.plane.size.length": "廊下寸法の長さ",
"modal.actual.size.setting.actual.size.length": "実寸長",
- "plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
- "plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
- "plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
- "plan.message.save": "저장되었습니다.",
- "plan.message.delete": "삭제되었습니다.",
- "plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は、保存して移動します。",
- "plan.message.confirm.yes": "はい",
+ "plan.message.confirm.save": "プラン保存しますか??",
+ "plan.message.confirm.copy": "プランコピーしますか??",
+ "plan.message.confirm.delete": "プラン削除しますか??",
+ "plan.message.save": "保存されました。",
+ "plan.message.delete": "削除されました。",
+ "plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は保存して移動します。",
+ "plan.message.corfirm.yes": "はい",
"plan.message.confirm.no": "いいえ",
"setting": "設定",
- "delete": "삭제(JA)",
- "delete.all": "전체 삭제(JA)",
- "refresh": "새로고침(JA)",
+ "delete": "削除",
+ "delete.all": "完全削除",
+ "refresh": "リフレッシュ",
"margin": "間隔",
- "contextmenu.roof.material.placement": "지붕재 배치(JA)",
- "contextmenu.roof.material.edit": "지붕재 변경(JA)",
- "contextmenu.roof.material.remove": "지붕재 삭제(JA)",
- "contextmenu.roof.material.remove.all": "지붕재 전체 삭제(JA)",
- "contextmenu.dormer.offset": "도머 오프셋(JA)",
- "contextmenu.select.move": "선택・이동(JA)",
- "contextmenu.wallline.remove": "외벽선 삭제(JA)",
+ "contextmenu.roof.material.placement": "屋根材の配置",
+ "contextmenu.roof.material.edit": "屋根材の変更",
+ "modal.roof.material.edit": "屋根材の変更",
+ "contextmenu.roof.material.remove": "屋根材の削除",
+ "contextmenu.roof.material.remove.all": "屋根材全体を削除",
+ "contextmenu.dormer.offset": "ドーマーオフセット",
+ "contextmenu.select.move": "選択移動",
+ "contextmenu.wallline.remove": "外壁の削除",
"contextmenu.size.edit": "サイズ変更",
"modal.auxiliary.size.edit": "補助線サイズ変更",
- "modal.auxiliary.size.edit.point": "支店",
+ "modal.auxiliary.size.edit.point": "始点",
"contextmenu.auxiliary.move": "補助線の移動",
"modal.auxiliary.move": "補助線の移動",
- "modal.auxiliary.move.info": "移動する方向を入力してください",
+ "modal.auxiliary.move.info": "移動する方向を入力してください。",
"contextmenu.auxiliary.copy": "補助線のコピー",
"modal.auxiliary.copy": "補助線のコピー",
- "modal.auxiliary.copy.info": "コピーする方向を入力してください",
- "contextmenu.auxiliary.remove": "보조선 삭제(JA)",
- "contextmenu.auxiliary.vertical.bisector": "보조선 수직이등분선(JA)",
- "contextmenu.auxiliary.cut": "보조선 절삭(JA)",
- "contextmenu.auxiliary.remove.all": "보조선 전체 삭제(JA)",
+ "modal.auxiliary.copy.info": "コピーする方向を入力してください。",
+ "contextmenu.auxiliary.remove": "補助線の削除",
+ "contextmenu.auxiliary.vertical.bisector": "補助線垂直二等分線",
+ "contextmenu.auxiliary.cut": "補助線切削",
+ "contextmenu.auxiliary.remove.all": "補助線全体を削除",
"contextmenu.line.property.edit": "各辺属性の変更",
- "contextmenu.column.move": "열 이동(JA)",
- "contextmenu.column.copy": "열 복사(JA)",
- "contextmenu.column.remove": "コピー設定",
- "modal.panel.column.remove": "コピー設定",
+ "contextmenu.column.move": "列の移動",
+ "contextmenu.column.copy": "列のコピー",
+ "contextmenu.column.remove": "列を削除",
+ "modal.panel.column.remove": "列を削除",
"modal.panel.column.remove.info": "削除列をどのようにしますか?",
"modal.panel.column.remove.type.left": "左に減らす",
"modal.panel.column.remove.type.right": "右に減らす",
"modal.panel.column.remove.type.side": "両側に減る",
"modal.panel.column.remove.type.none": "減らさない",
"modal.panel.select.column": "選択列",
- "modal.panel.select.row": "選択段",
+ "modal.panel.select.row": "選択ステージ",
"modal.panel.insert.column": "挿入列",
"modal.panel.insert.row": "挿入段",
+ "contextmenu.column.insert": "列の挿入",
"modal.panel.column.insert": "列の挿入",
"modal.panel.column.insert.info": "挿入する方向を選択してください。",
"modal.panel.column.insert.type.left": "左挿入",
"modal.panel.column.insert.type.right": "右挿入",
- "modal.image.load.size.rotate": "サイズ調整と回転",
- "contextmenu.column.insert": "列の挿入",
- "contextmenu.row.move": "단 이동(JA)",
- "contextmenu.row.copy": "단 복사(JA)",
- "contextmenu.row.remove": "ただし削除",
- "modal.row.remove": "ただし削除",
- "modal.row.remove.info": "削除列をどのようにしますか?",
- "modal.row.remove.type.up": "上向きに減らす",
+ "modal.image.load.size.rotate": "サイズ変更と回転",
+ "contextmenu.row.move": "段移動",
+ "contextmenu.row.copy": "段コピー",
+ "contextmenu.row.remove": "段削除",
+ "modal.row.remove": "段削除",
+ "modal.row.remove.info": "削除ステージをどのようにしますか?",
+ "modal.row.remove.type.up": "上に減らす",
"modal.row.remove.type.down": "下向きに減らす",
- "modal.row.remove.type.side": "両側に減らす",
+ "modal.row.remove.type.side": "両側に減る",
"modal.row.remove.type.none": "減らさない",
"contextmenu.row.insert": "段挿入",
"modal.row.insert": "段挿入",
"modal.row.insert.info": "挿入する方向を選択してください。",
"modal.row.insert.type.up": "上部挿入",
- "modal.row.insert.type.down": "下の挿入",
+ "modal.row.insert.type.down": "下部挿入",
"modal.move.setting": "移動設定",
"modal.move.setting.info": "間隔を設定し、移動方向を選択します。",
"modal.copy.setting": "コピー設定",
"modal.copy.setting.info": "間隔を設定し、コピー方向を選択します。",
"modal.line.property.edit.info": "属性を変更する辺を選択してください。",
"modal.line.property.edit.selected": "選択した値",
- "contextmenu.flow.direction.edit": "흐름 방향 변경(JA)",
- "contextmenu.font.setting": "폰트 설정(JA)",
- "contextmenu.grid.color.edit": "그리드 색 변경(JA)",
- "contextmenu.dimension.auxiliary.line.edit": "치수 보조선 변경(JA)",
+ "contextmenu.flow.direction.edit": "流れ方向の変更",
+ "contextmenu.font.setting": "フォント設定",
+ "contextmenu.grid.color.edit": "グリッドの色の変更",
+ "contextmenu.dimension.auxiliary.line.edit": "寸法補助線の変更",
"contextmenu.display.edit": "表示の変更",
- "modal.display.edit.info": "寸法線に表示する数値を入力してください",
+ "modal.display.edit.info": "寸法線に表示する数値を入力してください。",
"modal.display.edit.before.length": "既存の長さ",
"modal.display.edit.after.length": "変更の長さ",
- "modal.display.edit.corner.valley": "コーナー・ゴールの場合",
- "modal.display.edit.input.slope": "경사를 傾斜を着せてください。",
+ "modal.display.edit.corner.valley": "隅·谷の場合",
+ "modal.display.edit.input.slope": "傾きを入力してください。",
"modal.display.edit.input.slope.info": "傾き設定されている場合、入力した数値に傾き計算をした数値が表示されます。",
"modal.distance": "距離測定",
"modal.distance.dual.point": "2点間距離",
"modal.distance.horizon": "水平距離",
"modal.distance.vertical": "垂直距離",
- "contextmenu.opening.offset": "개구 오프셋(JA)",
- "contextmenu.remove": "삭제(JA)",
- "contextmenu.remove.all": "전체 삭제(JA)",
- "contextmenu.move": "이동(JA)",
- "contextmenu.copy": "복사(JA)",
- "contextmenu.edit": "편집(JA)",
- "contextmenu.module.vertical.align": "모듈 세로 가운데 정렬(JA)",
- "contextmenu.module.horizon.align": "모듈 가로 가운데 정렬(JA)",
- "contextmenu.module.left.align": "모듈 왼쪽 정렬(JA)",
- "contextmenu.module.right.align": "모듈 오른쪽 정렬(JA)",
- "contextmenu.module.up.align": "모듈 위쪽 정렬(JA)",
- "contextmenu.module.down.align": "모듈 아래쪽 정렬(JA)",
- "contextmenu.module.remove": "모듈 일괄 삭제(JA)",
- "contextmenu.module.move": "모듈 일괄 이동(JA)",
- "contextmenu.module.copy": "모듈 일괄 복사(JA)",
+ "contextmenu.opening.offset": "開口オフセット",
+ "contextmenu.remove": "削除",
+ "contextmenu.remove.all": "完全削除",
+ "contextmenu.move": "移動",
+ "contextmenu.copy": "コピー",
+ "contextmenu.edit": "編集",
+ "contextmenu.module.vertical.align": "モジュールの垂直方向の中央揃え",
+ "contextmenu.module.horizon.align": "モジュールの水平方向の中央揃え",
+ "contextmenu.module.left.align": "モジュール左揃え",
+ "contextmenu.module.right.align": "モジュールの右揃え",
+ "contextmenu.module.up.align": "モジュールの上揃え",
+ "contextmenu.module.down.align": "モジュールの下向き",
+ "contextmenu.module.remove": "モジュール一括削除",
+ "contextmenu.module.move": "モジュール一括移動",
+ "contextmenu.module.copy": "モジュール一括コピー",
"contextmenu.module.circuit.number.edit": "モジュール一括回路番号の変更",
"modal.module.circuit.number.edit": "モジュール一括回路番号の変更",
"modal.module.circuit.number.edit.info": "回路番号を入力してください。",
"modal.module.circuit.number": "回路番号",
- "common.message.no.data": "No data",
+ "modal.module.can.not.edit": "회로 구성을 완료한 모듈은 변경할 수 없습니다.(JA)",
+ "modal.line.property.change": "変更する属性を選択してください。",
+ "modal.line.property.change.unselect": "変更するラインを選択してください。",
+ "modal.line.property.change.confirm": "プロパティを変更しますか?",
+ "common.message.no.data": "データなし",
"common.message.no.dataDown": "ダウンロードするデータがありません",
"common.message.noData": "表示するデータがありません",
- "common.message.search": "search success",
- "common.message.insert": "insert success",
- "common.message.update": "update success",
- "common.message.delete": "削除",
+ "common.message.search": "検索成功",
+ "common.message.insert": "挿入成功",
+ "common.message.update": "更新成功",
+ "common.message.delete": "削除されました",
"common.message.restoration": "復元",
"common.message.cancel": "キャンセル",
- "common.message.send": "メールを送信しました.",
- "common.message.no.delete": "削除するデータがありません",
- "common.message.save": "保存",
- "common.message.transfer": "転送",
- "common.message.batch.exec": "batch success",
- "common.message.not.mov": "移動できません.",
- "common.message.required.data": "{0} は入力必須項目となります。",
- "common.message.save.error": "データの保存中にエラーが発生しました。 サイト管理者にお問い合わせください。",
- "common.message.transfer.error": "データの転送中にエラーが発生しました。 サイト管理者にお問い合わせください。",
- "common.message.delete.error": "データの削除中にエラーが発生しました。 サイト管理者にお問い合わせください。",
- "common.message.batch.error": "バッチの実行中にエラーが発生しました。 サイト管理者に連絡してください。",
- "common.message.send.error": "データの送信中にエラーが発生しました。サイト管理者にお問い合わせください",
- "common.message.communication.error": "ネットワークエラーが発生しました。サイト管理者に連絡してください。",
- "common.message.data.error": "{0} はデータ形式が無効です。",
+ "common.message.send": "メールが送信されました。",
+ "common.message.no.delete": "削除するデータはありません。",
+ "common.message.save": "保存されました。",
+ "common.message.transfer": "転送済み",
+ "common.message.batch.exec": "バッチ成功",
+ "common.message.not.mov": "移動は不可能です。",
+ "common.message.required.data": "{0} は必須の入力値です。",
+ "common.message.save.error": "データの保存中にエラーが発生しました。サイト管理者に連絡してください。",
+ "common.message.transfer.error": "データの転送中にエラーが発生しました。サイト管理者に連絡してください。",
+ "common.message.delete.error": "データの削除中にエラーが発生しました。サイト管理者に連絡してください。",
+ "common.message.batch.error": "バッチの実行中にエラーが発生しました。サイト管理者に連絡してください。",
+ "common.message.send.error": "データ送信中にエラーが発生しました。管理者にお問い合わせください。",
+ "common.message.communication.error": "ネットワークエラーが発生しました。\nサイト管理者に連絡してください。",
+ "common.message.data.error": "{0} データ形式が無効です。",
"common.message.data.setting.error": "{0} は削除されたか、すでに構成されているデータです。",
"common.message.parameter.error": "パラメータエラー",
"common.message.product.parameter.error": "存在しない製品があります。",
- "common.message.customer.parameter.error": "存在しない顧客があります。",
- "common.message.file.exists.error": "ファイルが正常にアップロードされないためにエラーが発生しました",
+ "common.message.customer.parameter.error": "存在しない顧客がいます。",
+ "common.message.file.exists.error": "ファイルが正常にアップロードされないためエラーが発生しました",
"common.message.file.download.exists": "ファイルが存在しません。",
- "common.message.file.download.error": "ァイルのダウンロードエラー",
+ "common.message.file.download.error": "ファイルのダウンロード エラー",
"common.message.file.template.validation01": "フォルダをアップロードできません",
- "common.message.file.template.validation02": "アップロードできるのはExcelファイルのみです。",
- "common.message.file.template.validation03": "登録できない拡張子です",
- "common.message.file.template.validation04": "容量を超えています アップロード可能な容量:{0} MB",
- "common.message.file.template.validation05": "アップロードファイルを選択して下さい",
- "common.message.multi.insert": "合計 {0} 件数 ({1}成功、 {2} 失敗 {3})",
- "common.message.error": "エラーが発生しました。サイト管理者に連絡してください。",
- "common.message.data.save": "保存しますか?",
- "common.message.data.delete": " 削除しますか?",
- "common.message.data.exists": "{0} はすでに存在するデータです。",
- "common.message.data.no.exists": "{0} は存在しないデータです。",
- "common.message.all": "All",
- "common.message.tab.close.all": "すべてのタブを閉じますか?",
- "common.message.transfer.save": "{0}件転送しますか?",
- "common.message.confirm.save": "保存しますか?",
- "common.message.confirm.confirm": "承認しますか?",
- "common.message.confirm.request": "承認リクエストしますか?",
- "common.message.confirm.delete": "削除しますか?",
+ "common.message.file.template.validation02": "アップロードできるのは Excel ファイルのみです。",
+ "common.message.file.template.validation03": "登録できない拡張子",
+ "common.message.file.template.validation04": "容量超過\nアップロード可能な容量",
+ "common.message.file.template.validation05": "アップロードファイル選択してください。 {0} MB",
+ "common.message.multi.insert": "Total {0} cases ({1} successes {2} failures {3})",
+ "common.message.error": "エラーが発生しました。サイト管理者にお問い合わせください。",
+ "common.message.data.save": "保存しますか?",
+ "common.message.data.delete": "本当に削除しますか?",
+ "common.message.data.exists": "{0} is data that already exists.",
+ "common.message.data.no.exists": "{0} is data that does not exist.",
+ "common.message.all": "全て",
+ "common.message.tab.close.all": "すべてのタブを閉じますか?",
+ "common.message.transfer.save": "{0} 転送しますか?",
+ "common.message.confirm.save": "保存しますか?",
+ "common.message.confirm.confirm": "承認しますか?",
+ "common.message.confirm.request": "承認をリクエストしますか?",
+ "common.message.confirm.delete": "削除しますか?",
"common.message.confirm.close": "閉じますか?",
- "common.message.confirm.unclose": "クローズ中止しますか?",
+ "common.message.confirm.unclose": "クローズをキャンセルしますか?",
"common.message.confirm.cancel": "キャンセルしますか?",
- "common.message.confirm.uncancel": "キャンセル中止しますか?",
- "common.message.confirm.copy": "コピーしますか?",
- "common.message.confirm.createSo": "S/O作成しますか?",
- "common.message.confirm.mark": "保存完了",
- "common.message.confirm.mail": "メールを送信しますか?",
- "common.message.confirm.printPriceItem": "価格を印刷しますか?",
- "common.message.confirm.allAppr ": "Do you want to Batch approve the selected data?",
- "common.message.confirm.deliveryFee": "送料を登録しますか?",
- "common.message.success.delete": "削除完了",
- "common.message.success.close": "閉じる",
- "common.message.success.unclose": "キャンセルしました",
- "common.message.validation.date": "終了日を開始日より前にすることはできません。 もう一度入力してください。",
+ "common.message.confirm.uncancel": "キャンセルをキャンセルしますか?",
+ "common.message.confirm.copy": "コピーしますか?",
+ "common.message.confirm.createSo": "販売注文を作成しますか?",
+ "common.message.confirm.mark": "保存しました。",
+ "common.message.confirm.mail": "メールを送信しますか?",
+ "common.message.confirm.printPriceItem": "商品の価格を印刷しますか?",
+ "common.message.confirm.allAppr ": "選択したデータを一括承認しますか?",
+ "common.message.confirm.deliveryFee": "配送料を登録しますか?",
+ "common.message.success.delete": "削除しました。",
+ "common.message.success.close": "閉じる。",
+ "common.message.success.unclose": "キャンセル 閉じました。",
+ "common.message.validation.date": "終了日は開始日より前に設定できません。もう一度入力してください。",
"common.message.no.editfield": "フィールドを編集できません",
- "common.message.success.rmmail": "リスク管理チームにメールを送信しました。",
- "common.message.password.validation01": "パスワードの変更が一致しません。",
- "common.message.password.validation02": "英語、数字、特殊文字を組み合わせた8桁以上を入力してください。",
- "common.message.password.validation03": "パスワードをIDと同じにすることはできません。",
- "common.message.menu.validation01": "注文を保存するメニューはありません.",
- "common.message.menu.validation02": "The same sort order exists.",
+ "common.message.success.rmmail": "リスク管理チームにメールを正常に送信しました。",
+ "common.message.password.validation01": "変更パスワードが一致しません。",
+ "common.message.password.validation02": "英語の数字と特殊文字を組み合わせて少なくとも 8 桁を入力してください。",
+ "common.message.password.validation03": "パスワードはIDと同じにすることはできません。",
+ "common.message.menu.validation01": "注文を保存するメニューはありません。",
+ "common.message.menu.validation02": "同じソート順序が存在します。",
"common.message.menuCode.check01": "登録可能",
- "common.message.menuCode.check02": "登録できません",
- "common.message.pleaseSelect": "{0}を選択してください",
- "common.message.pleaseInput": "{0}を入力してください。",
- "common.message.pleaseInputOr": "{0}または{1}を入力してください。",
- "common.message.please.input.over": "{0} 이상 값을 입력해주세요.(JA)",
- "common.message.approved ": "承認済み",
- "common.message.errorFieldExist": "エラー項目が存在します",
- "common.message.storeIdExist ": "既に利用されている販売店IDです",
- "common.message.userIdExist ": "すでに使用しているユーザーID。",
- "common.message.noExists ": "削除された掲示物です",
- "common.message.emailReqTo": "メール宛先が必要です",
- "common.message.downloadPeriod": "ダウンロード検索期間を{0}日以内に選択してください。",
- "common.message.backToSubmit": "販売店ブロック解除実行しますか?",
- "common.message.backToG3": "Back to G3処理実行しますか?",
+ "common.message.menuCode.check02": "Unable to register",
+ "common.message.pleaseSelect": "Please Select {0}",
+ "common.message.pleaseInput": "Please Input a {0}.",
+ "common.message.pleaseInputOr": "Please Input a {0} or {1}.",
+ "common.message.please.input.over": "{0}以上の値を入力してください。",
+ "common.message.approved ": "承認されました。",
+ "common.message.errorFieldExist": "エラーフィールドが存在します",
+ "common.message.storeIdExist ": "すでに使用している販売店IDです。",
+ "common.message.userIdExist ": "すでに使用しているユーザーIDです。",
+ "common.message.noExists ": "削除された投稿です。",
+ "common.message.emailReqTo": "Email To is required",
+ "common.message.downloadPeriod": "Please select the download search period within {0} days.",
+ "common.message.backToSubmit": "販売店のブロック解除を実行しますか?",
+ "common.message.backToG3": "Back to G3処理を実行しますか?",
"common.message.writeToConfirm": "作成解除を実行しますか?",
- "common.message.password.init.success": "パスワード [{0}] に初期化されました。",
- "common.message.no.edit.save": "この文書は変更できません。",
- "common.load": "ファイルの追加",
+ "common.message.password.init.success": "パスワード[{0}]に初期化されました。",
+ "common.message.no.edit.save": "このドキュメントは変更できません。",
+ "common.load": "読込",
"common.input.file": "ファイルを読み込む",
- "common.input.file.load": "ファイルの追加",
- "common.input.image.load": "이미지 불러오기",
+ "common.input.file.load": "読込",
+ "common.input.image.load": "画像を読み込む",
"common.input.address.load": "アドレスを読み込む",
"common.require": "必須",
"common.finish": "完了",
"common.ok": "確認",
"common.cancel": "キャンセル",
- "commons.west": "立つ",
- "commons.east": "ドン",
+ "commons.west": "西",
+ "commons.east": "東",
"commons.south": "南",
"commons.north": "北",
- "commons.none": "선택안함(JA)",
+ "commons.none": "選択しない",
"common.type": "分類",
- "font.style.normal": "보통(JA)",
- "font.style.italic": "기울임꼴(JA)",
- "font.style.bold": "굵게(JA)",
- "font.style.bold.italic": "굵은 기울임꼴(JA)",
- "color.black": "검정색(JA)",
- "color.red": "빨강색(JA)",
- "color.blue": "파랑색(JA)",
- "color.gray": "회색(JA)",
- "color.yellow": "황색(JA)",
- "color.green": "녹색(JA)",
- "color.pink": "분홍색(JA)",
- "color.gold": "황금색(JA)",
- "color.darkblue": "남색(JA)",
- "site.name": "Q.CAST III",
+ "font.style.normal": "通常",
+ "font.style.italic": "イタリック体",
+ "font.style.bold": "太字",
+ "font.style.bold.italic": "太い斜体",
+ "color.black": "ブラック",
+ "color.red": "赤色",
+ "color.blue": "青色",
+ "color.gray": "グレー",
+ "color.yellow": "黄色",
+ "color.green": "グリーン",
+ "color.pink": "ピンク",
+ "color.gold": "黄金色",
+ "color.darkblue": "藍色",
+ "site.name": "HANASYS設計",
"site.sub_name": "太陽光発電システム図面管理サイト",
"site.header.link1": "選択してください。",
"site.header.link2": "オンライン保証システム",
"board.notice.title": "お知らせ",
"board.notice.sub.title": "お知らせ一覧",
"board.faq.title": "FAQ",
- "board.faq.sub.title": "FAQ 一覧",
- "board.archive.title": "資料ダウンロード",
+ "board.faq.sub.title": "FAQリスト",
+ "board.archive.title": "資料のダウンロード",
"board.archive.sub.title": "文書一覧",
"board.list.header.rownum": "番号",
"board.list.header.title": "タイトル",
"board.list.header.regDt": "登録日",
"board.sub.search.placeholder": "検索語を入力してください。",
- "board.sub.search.result": "{0}について、合計{1}件の投稿が検索されました。",
- "board.sub.search.archive.result": "{0}について、合計{1}件の文書が検索されました。",
+ "board.sub.search.result": "{0}の合計{1}件の投稿が検索されました。",
+ "board.sub.search.archive.result": "{0}の合計{1}件の文書が検索されました。",
"board.sub.total": "全体",
"board.sub.fileList": "添付ファイル一覧",
- "board.sub.updDt": "更新日",
+ "board.sub.updDt": "更新",
"board.sub.btn.close": "閉じる",
- "myinfo.title": "マイプロフィール",
+ "myinfo.title": "社員情報",
"myinfo.info.userId": "ユーザーID",
- "myinfo.info.nameKana": "担当者名ふりがな",
+ "myinfo.info.nameKana": "担当者名日本語",
"myinfo.info.name": "担当者名",
"myinfo.info.password": "パスワード",
- "myinfo.info.chg.password": "新しいパスワード入力",
+ "myinfo.info.chg.password": "変更パスワードの入力",
"myinfo.info.category": "部署名",
"myinfo.info.tel": "電話番号",
"myinfo.info.fax": "FAX番号",
"myinfo.info.mail": "メールアドレス",
- "myinfo.sub.validation.password": "※ 半角10文字以内",
+ "myinfo.sub.validation.password": "※半角10文字以内",
"myinfo.btn.close": "閉じる",
"myinfo.btn.chg.password": "パスワード変更",
"myinfo.btn.chg": "変更",
@@ -569,7 +579,7 @@
"myinfo.btn.confirm": "確認",
"myinfo.message.validation.password1": "パスワードを入力してください。",
"myinfo.message.validation.password2": "既存のパスワードと同じです。",
- "myinfo.message.validation.password3": "半角文字10文字以内で入力してください。",
+ "myinfo.message.validation.password3": "半角文字は10文字以内でなければなりません。",
"myinfo.message.validation.password4": "変更パスワードを入力してください。",
"myinfo.message.save": "パスワードが変更されました。",
"myinfo.message.password.error": "パスワードが間違っています。",
@@ -578,26 +588,26 @@
"login.id.save": "ID保存",
"login.id.placeholder": "IDを入力してください。",
"login.password.placeholder": "パスワードを入力してください。",
- "login.guide.text": "当サイトを利用するには、事前申請が必要です。",
- "login.guide.sub1": "IDをお持ちでない方は",
+ "login.guide.text": "当サイトをご利用の際は事前申請が必要です。",
+ "login.guide.sub1": "IDがない方は",
"login.guide.sub2": "をクリックしてください。",
"login.guide.join.btn": "ID申請",
- "login.init_password.btn": "パスワードリセット",
- "login.init_password.btn.back": "前の画面に戻る",
- "login.init_password.title": "パスワードリセット",
- "login.init_password.sub_title": "パスワードをリセットするIDとメールアドレスを入力してください。",
- "login.init_password.complete_message": "パスワードがリセットされました。リセット後のパスワードはIDと同じです。",
+ "login.init_password.btn": "パスワードの初期化",
+ "login.init_password.btn.back": "前の画面へ",
+ "login.init_password.title": "パスワードの初期化",
+ "login.init_password.sub_title": "パスワードを初期化するIDとEメールアドレスを入力してください。",
+ "login.init_password.complete_message": "パスワードが初期化されました。初期化されたパスワードはIDと同じです。",
"login.init_password.id.placeholder": "IDを入力してください。",
- "login.init_password.email.placeholder": "メールアドレスを入力してください。",
- "join.title": "Q.CAST3 ログインID発行申請",
+ "login.init_password.email.placeholder": "メールを入力してください。",
+ "join.title": "HANASYS設計ログインID発行申請",
"join.sub1.title": "販売代理店情報",
- "join.sub1.comment": "※ 登録する販売店の会社名を入力してください。(2次店の場合「○○販売株式会社(2次店:××設備株式会社)」と記載してください。)",
+ "join.sub1.comment": "※登録される販売店の会社名を入力してください。 (2次店は「○○販売株式会社(2次店:××設備株式会社)」でご記入ください。)",
"join.sub1.storeQcastNm": "販売代理店名",
- "join.sub1.storeQcastNm_placeholder": "株式会社 エナジー ギア ソリューション アンド サービス(2次店: 山口重機販売有限会社)",
- "join.sub1.storeQcastNmKana": "販売代理店名ふりがな",
- "join.sub1.storeQcastNmKana_placeholder": "株式会社 エナジー ギア ソリューション",
+ "join.sub1.storeQcastNm_placeholder": "株式会社エネルギーギアソリューションアンサービス(2次点:山口周期販売有限会社)",
+ "join.sub1.storeQcastNmKana": "販売代理店名フリガナ",
+ "join.sub1.storeQcastNmKana_placeholder": "株式会社エネルギーギアソリューション",
"join.sub1.postCd": "郵便番号",
- "join.sub1.postCd_placeholder": "7桁の数字",
+ "join.sub1.postCd_placeholder": "数字7桁",
"join.sub1.addr": "住所",
"join.sub1.addr_placeholder": "全角50文字以内",
"join.sub1.telNo": "電話番号",
@@ -616,41 +626,41 @@
"join.sub2.fax_placeholder": "00-0000-0000",
"join.sub2.category": "部署名",
"join.btn.login_page": "ログイン画面に移動",
- "join.btn.approval_request": "ID承認申請",
- "join.complete.title": "Q.CAST3 ログインID発行申請完了",
- "join.complete.contents": "※ 申請したIDが承認されると、担当者情報に入力されたメールアドレスにログイン案内メールが送信されます。",
- "join.complete.email_comment": "担当者メールアドレス",
- "join.validation.check1": "{0} の形式を確認してください。",
- "join.complete.save.confirm": "Hanwha Japan担当者にID承認を要請されると、これ以上情報を修正できません。 本当にリクエストしますか?",
+ "join.btn.approval_request": "ID承認要求",
+ "join.complete.title": "HANASYS設計ログインID発行申請完了",
+ "join.complete.contents": "※申請したIDが承認されると、担当者情報に入力したEメールアドレスにログイン関連案内メールが送信されます。",
+ "join.complete.email_comment": "担当者のメールアドレス",
+ "join.validation.check1": "{0}形式を確認してください。",
+ "join.complete.save.confirm": "ハンファジャパンの担当者にID承認が要求された場合、これ以上情報を修正することはできません。申請しますか?",
"stuff.gridHeader.lastEditDatetime": "更新日時",
- "stuff.gridHeader.objectNo": "品番",
+ "stuff.gridHeader.objectNo": "物件番号",
"stuff.gridHeader.planTotCnt": "プラン数",
"stuff.gridHeader.objectName": "商品名",
"stuff.gridHeader.saleStoreId": "代理店ID",
"stuff.gridHeader.saleStoreName": "代理店名",
- "stuff.gridHeader.address": "商品アドレス",
+ "stuff.gridHeader.address": "物件住所",
"stuff.gridHeader.dispCompanyName": "見積もり",
"stuff.gridHeader.receiveUser": "担当者",
"stuff.gridHeader.specificationConfirmDate": "仕様確認日",
"stuff.gridHeader.createDatetime": "登録日",
"stuff.gridData.tempObjectNo": "一時保存物",
- "stuff.message.periodError": "最大1年間閲覧可能.",
+ "stuff.message.periodError": "最大1年閲覧可能です。",
"stuff.addressPopup.title": "郵便番号",
"stuff.addressPopup.placeholder": "郵便番号の7桁を入力してください。",
"stuff.addressPopup.error.message1": "登録された郵便番号に住所が見つかりません。もう一度入力してください。",
- "stuff.addressPopup.error.message2": "住所を選択してください.",
+ "stuff.addressPopup.error.message2": "住所を選択してください。",
"stuff.addressPopup.gridHeader.address1": "都道府県",
"stuff.addressPopup.gridHeader.address2": "市区町村",
- "stuff.addressPopup.gridHeader.address3": "市区町村 以下",
+ "stuff.addressPopup.gridHeader.address3": "市区町村以下",
"stuff.addressPopup.btn1": "閉じる",
"stuff.addressPopup.btn2": "住所適用",
"stuff.planReqPopup.title": "設計依頼のインポート",
"stuff.temp.subTitle": "商品情報",
"stuff.temp.subTitle2": "作図",
"stuff.detail.header.notExistObjectNo": "存在しないものです。",
- "stuff.detail.header.successCopy": "商品番号がコピーされました。",
- "stuff.detail.header.failCopy": "存在しないものです。",
- "stuff.detail.header.objectNo": "商品番号のコピーに失敗しました。",
+ "stuff.detail.header.successCopy": "物件番号がコピーされました。",
+ "stuff.detail.header.failCopy": "物件番号のコピーに失敗しました。",
+ "stuff.detail.header.objectNo": "物件番号",
"stuff.detail.header.specificationConfirmDate": "仕様確認日",
"stuff.detail.header.lastEditDatetime": "更新日時",
"stuff.detail.header.createDatetime": "登録日",
@@ -659,23 +669,23 @@
"stuff.detail.receiveUser": "担当者",
"stuff.detail.objectStatusId": "物品区分/物件名",
"stuff.detail.objectStatus0": "新築",
- "stuff.detail.objectStatus1": "基軸",
+ "stuff.detail.objectStatus1": "既築",
"stuff.detail.objectNameOmit": "敬称",
- "stuff.detail.objectNameKana": "商品名 ふりがな",
+ "stuff.detail.objectNameKana": "フリガナ",
"stuff.detail.saleStoreId": "一次販売店名/ID",
"stuff.detail.otherSaleStoreId": "二次販売店名/ID",
- "stuff.detail.zipNo": "郵便番号 ",
- "stuff.detail.address": "住所 ",
+ "stuff.detail.zipNo": "郵便番号",
+ "stuff.detail.address": "住所",
"stuff.detail.btn.addressPop": "住所検索",
- "stuff.detail.btn.addressPop.guide": "※ 郵便番号7桁を入力した後、アドレス検索ボタンをクリックしてください",
- "stuff.detail.prefId": "都道府県 / 住所 ",
- "stuff.detail.areaId": "発電量シミュレーション地域 ",
+ "stuff.detail.btn.addressPop.guide": "※住所検索ボタンをクリックして都道府県情報を選択してください。",
+ "stuff.detail.prefId": "都道府県/住所",
+ "stuff.detail.areaId": "発電量シミュレーション地域",
"stuff.detail.standardWindSpeedId": "基準風速",
"stuff.detail.standardWindSpeedIdSpan": "m/s以下",
"stuff.detail.btn.windSpeedPop": "風速選択",
- "stuff.detail.verticalSnowCover": "垂直説説",
+ "stuff.detail.verticalSnowCover": "垂直積雪量",
"stuff.detail.coldRegionFlg": "寒冷地対策施行",
- "stuff.detail.surfaceType": "面調図区分",
+ "stuff.detail.surfaceType": "面粗度",
"stuff.detail.saltAreaFlg": "塩害地域用アイテムの使用",
"stuff.detail.installHeight": "設置高さ",
"stuff.detail.conType": "契約条件",
@@ -684,16 +694,16 @@
"stuff.detail.remarks": "メモ",
"stuff.detail.tooltip.saleStoreId": "販売代理店または販売代理店IDを1文字以上入力してください",
"stuff.detail.tooltip.surfaceType": "塩害地域の定義は各メーカーの設置マニュアルをご確認ください",
- "stuff.detail.tempSave.message1": "一時保存されました。商品番号を取得するには、必須項目をすべて入力してください。",
- "stuff.detail.tempSave.message2": "担当者は10桁以下で入力してください.",
- "stuff.detail.tempSave.message3": "二次販売店を選択してください.",
+ "stuff.detail.tempSave.message1": "一時保存されました。物件番号を取得するには、必須項目をすべて入力してください。",
+ "stuff.detail.tempSave.message2": "担当者名は10桁以下で入力してください。",
+ "stuff.detail.tempSave.message3": "二次販売店を選択してください。",
"stuff.detail.confirm.message1": "販売店情報を変更すると、設計依頼文書番号が削除されます。変更しますか?",
"stuff.detail.delete.message1": "仕様が確定したものは削除できません。",
"stuff.detail.planList.title": "プランリスト",
"stuff.detail.planList.cnt": "全体",
"stuff.detail.planList.help": "ヘルプ",
- "stuff.detail.planList.guide1": "1.発注は同一品番基準1件のみ可能です。",
- "stuff.detail.planList.guide2": "2.[Excelダウンロード]は見積書、図面、シミュレーション結果をExcelファイルで一度にダウンロードします。",
+ "stuff.detail.planList.guide1": "1.発注は同一物件番号基準1件のみ可能です。",
+ "stuff.detail.planList.guide2": "2. [Excelダウンロード]は見積書図面シミュレーション結果をExcelファイルとして一度にダウンロードします。",
"stuff.detail.planList.guide3": "3. プラン情報をダブルクリックすると図面作成画面に移動します。",
"stuff.detail.btn.delete": "物の削除",
"stuff.detail.btn.moveList": "商品リスト",
@@ -702,25 +712,25 @@
"stuff.detail.save": "保存しました",
"stuff.detail.tempSave": "一時保存されました",
"stuff.detail.noChgData": "変更内容はありません",
- "stuff.detail.save.valierror1": "垂直説説は0より大きい値を入力してください",
+ "stuff.detail.save.valierror1": "垂直積雪量は0より大きい値を入力してください",
"stuff.detail.save.valierror2": "設置高さ0より大きい値を入力してください",
- "stuff.detail.save.valierror3": "{0} 必須入力項目です.",
- "stuff.detail.save.valierror4": "二次販売店名は必須オプションです.",
+ "stuff.detail.save.valierror3": "{0} 必須入力項目です。",
+ "stuff.detail.save.valierror4": "二次販売店名は必須オプションです。",
"stuff.detail.move.confirmMsg": "商品情報画面に移動します。 [保存]していない図面情報は削除されます。商品情報画面に移動しますか?",
"stuff.planReqPopup.popTitle": "設計依頼検索",
"stuff.planReqPopup.btn1": "検索",
"stuff.planReqPopup.btn2": "初期化",
"stuff.planReqPopup.btn3": "閉じる",
- "stuff.planReqPopup.btn4": "選択の適用",
- "stuff.planReqPopup.gridHeader.planStatName": "상태",
- "stuff.planReqPopup.gridHeader.planReqNo": "설계의뢰 번호",
- "stuff.planReqPopup.gridHeader.saleStoreId": "판매대리점ID",
- "stuff.planReqPopup.gridHeader.saleStoreName": "판매대리점명",
- "stuff.planReqPopup.gridHeader.title": "안건명",
- "stuff.planReqPopup.gridHeader.address1": "도도부현",
- "stuff.planReqPopup.gridHeader.houseCntName": "설치가옥수",
- "stuff.planReqPopup.gridHeader.planReqName": "의뢰자명",
- "stuff.planReqPopup.gridHeader.submitDt": "설계의뢰 제출일",
+ "stuff.planReqPopup.btn4": "オプション適用",
+ "stuff.planReqPopup.gridHeader.planStatName": "状態",
+ "stuff.planReqPopup.gridHeader.planReqNo": "設計依頼番号",
+ "stuff.planReqPopup.gridHeader.saleStoreId": "販売代理店ID",
+ "stuff.planReqPopup.gridHeader.saleStoreName": "販売代理店名",
+ "stuff.planReqPopup.gridHeader.title": "案件名",
+ "stuff.planReqPopup.gridHeader.address1": "都道府県",
+ "stuff.planReqPopup.gridHeader.houseCntName": "設置家屋",
+ "stuff.planReqPopup.gridHeader.planReqName": "依頼者名",
+ "stuff.planReqPopup.gridHeader.submitDt": "設計依頼提出日",
"stuff.planReqPopup.search.planReqNo": "設計依頼番号",
"stuff.planReqPopup.search.title": "案件名",
"stuff.planReqPopup.search.address1": "都道府県",
@@ -730,13 +740,13 @@
"stuff.planReqPopup.search.period": "期間検索",
"stuff.planReqPopup.search.schDateGbnS": "提出日",
"stuff.planReqPopup.search.schDateGbnR": "受付日",
- "stuff.planReqPopup.error.message1": "設計依頼を選択してください.",
- "stuff.planReqPopup.error.message2": "販売店を選択してください.",
+ "stuff.planReqPopup.error.message1": "設計依頼を選択してください。",
+ "stuff.planReqPopup.error.message2": "販売店を選択してください。",
"stuff.search.title": "物件状況",
- "stuff.search.btn.register": "新規 物件 登録",
+ "stuff.search.btn.register": "新規物件登録",
"stuff.search.btn.search": "照会",
"stuff.search.btn.reset": "初期化",
- "stuff.search.schObjectNo": "品番",
+ "stuff.search.schObjectNo": "物件番号",
"stuff.search.schSaleStoreName": "販売代理店名",
"stuff.search.schAddress": "商品アドレス",
"stuff.search.schObjectName": "商品名",
@@ -755,11 +765,11 @@
"stuff.search.grid.all": "全体",
"stuff.search.grid.selected": "選択",
"stuff.search.grid.schSortTypeR": "最近の登録日",
- "stuff.search.grid.schSortTypeU": "最近修正日",
+ "stuff.search.grid.schSortTypeU": "最近の修正日",
"stuff.windSelectPopup.title": "風速選択",
"stuff.windSelectPopup.table.selected": "選択",
"stuff.windSelectPopup.table.windspeed": "風速",
- "stuff.windSelectPopup.error.message1": "住所を先に検索してください",
+ "stuff.windSelectPopup.error.message1": "住所を先に検索してください。",
"stuff.windSelectPopup.error.message2": "風速を選択してください。",
"stuff.windSelectPopup.search.address1": "県",
"stuff.windSelectPopup.btn1": "閉じる",
@@ -780,85 +790,86 @@
"height": "高さ",
"output": "出力",
"slope": "傾斜",
- "eaves.offset": "軒の",
- "gable.offset": "ケラバ出幅",
+ "eaves.offset": "軒の幅",
+ "gable.offset": "ケラバ",
"offset": "出幅",
"width": "幅",
- "size": "寸",
+ "size": "寸法",
"size.angle": "寸(度)",
"eaves": "軒",
"eaves.line": "軒先",
"gable": "ケラバ",
"gable.left": "ケラバ左",
"gable.right": "ケラバ右",
- "ridge": "龍丸",
- "oneside.flow.ridge": "片側の流れ",
- "yosemune": "ヨセムネ",
+ "ridge": "棟",
+ "oneside.flow.ridge": "片流れの棟側",
+ "yosemune": "寄棟",
"valley": "谷",
"l.abandon.valley": "Lの捨て渓谷",
- "mansard": "マンサード",
+ "mansard": "メンサード",
"wall": "壁",
"wall.merge": "壁取り",
- "wall.merge.type": "壁取り(型)",
- "wall.merge.flow": "壁取合(流れ)",
- "wall.merge.flow.left": "壁取合(流れ左)",
- "wall.merge.flow.right": "壁取り(流れ右)",
- "no.setting": "설정없음",
- "hajebichi": "ハゼビーチ",
+ "wall.merge.type": "壁取合(型)",
+ "wall.merge.flow": "壁取り(流れ)",
+ "wall.merge.flow.left": "壁取り(流れ左)",
+ "wall.merge.flow.right": "壁取り(流れ右)",
+ "no.setting": "設定なし",
+ "hajebichi": "ハゼピッチ",
"straight.line": "直線",
"right.angle": "直角",
- "double.pitch": "イ・グベ",
+ "double.pitch": "異勾配",
"angle": "角度",
"diagonal": "対角線",
- "hipandgable": "八作屋根",
- "hipandgable.width": "八作屋根 出幅",
- "jerkinhead": "半折",
+ "hipandgable": "入母屋造",
+ "hipandgable.width": "入母屋造の幅",
+ "jerkinhead": "半切妻",
"shed": "片側の流れ",
"apply": "適用",
"module": "モジュール",
"legend": "凡例",
"has.sleeve": "袖あり",
"has.not.sleeve": "袖なし",
- "jerkinhead.width": "半折先幅",
- "jerkinhead.slope": "半折先傾斜",
+ "jerkinhead.width": "半切妻幅",
+ "jerkinhead.slope": "半切妻傾斜",
"shed.width": "片流幅",
- "windage": "漂流",
- "windage.width": "漂流の出幅",
+ "windage": "片流れ",
+ "windage.width": "片流れの出幅",
"write": "作成",
"main.storeId": "販売店ID",
"main.storeName": "販売店名",
"main.objectNo": "物件番号",
"main.faq": "FAQ",
- "main.content.objectList.noData1": "登録された商品情報はありません.",
- "main.content.objectList.noData2": "下のボタンをクリックして商品情報を登録してください.",
+ "main.content.objectList.noData1": "登録された商品情報はありません。",
+ "main.content.objectList.noData2": "下のボタンをクリックして商品情報を登録してください。",
"main.content.objectList": "最近の更新物件一覧",
"main.content.notice": "お知らせ",
"main.content.download1": "操作マニュアル",
"main.content.download2": "屋根の説明書",
"main.content.noBusiness": "Hanwha Japanにお問い合わせください",
- "main.content.alert.noFile": "資料が準備中です",
+ "main.content.alert.noFile": "資料準備中です",
"main.popup.login.popupTitle": "パスワード変更",
"main.popup.login.newPassword1": "新しいパスワードを入力",
- "main.popup.login.newPassword2": "新規パスワード再入力",
- "main.popup.login.placeholder": "半角10文字以内 ",
- "main.popup.login.guide1": "初期化されたパスワードでログインした場合、パスワードを変更しなければサイト利用が可能です。",
- "main.popup.login.guide2": "パスワードを変更しない場合は、ログイン画面に進みます。",
+ "main.popup.login.newPassword2": "新しいパスワードの再入力",
+ "main.popup.login.placeholder": "半角10文字以内",
+ "main.popup.login.guide1": "初期化されたパスワードでログインした場合、パスワードを変更しなければサイト利用が可能です.",
+ "main.popup.login.guide2": "パスワードを変更しない場合は、ログイン画面に進みます.",
"main.popup.login.btn1": "変更",
"main.popup.login.btn2": "変更しない",
- "main.popup.login.validate1": "入力したパスワードが異なります。",
- "main.popup.login.validate2": "半角10文字以内で入力してください。",
- "main.popup.login.validate3": "비밀번호를 입력해주세요.",
- "main.popup.login.success": "パスワードが変更されました。",
- "common.canvas.validate.size": "寸法を入力してください.",
- "surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.",
- "surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.",
- "surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.",
- "surface.shape.validate.size.1to23low": "①길이는 ②+③보다 클 수 없습니다..",
- "surface.shape.validate.size.2to3": "②길이는 ③보다 큰 값을 넣어주세요.",
- "surface.shape.validate.size.3to4": "③길이는 ④보다 큰 값을 넣어주세요.",
- "surface.shape.validate.size.4to5": "④길이는 ⑤보다 큰 값을 넣어주세요.",
+ "main.popup.login.validate1": "入力したパスワードが異なります.",
+ "main.popup.login.validate2": "半角10文字以内で入力してください.",
+ "main.popup.login.validate3": "パスワードを入力してください.",
+ "main.popup.login.success": "パスワードが変更されました.",
+ "common.canvas.validate.size": "サイズを入力してください。",
+ "surface.shape.validate.size.1to2": "①長さは②より大きい値を入れてください。",
+ "surface.shape.validate.size.1to3": "①長さは③より大きい値を入れてください。",
+ "surface.shape.validate.size.1to23": "①長さは②+③より大きい値を入れてください。",
+ "surface.shape.validate.size.2to3": "②長さは③より大きい値を入れてください。",
+ "surface.shape.validate.size.3to2": "③長さは②より大きい値を入れてください。",
+ "surface.shape.validate.size.3to4": "③長さは④より大きい値を入れてください。",
+ "surface.shape.validate.size.4to3": "④長さは③より大きい値を入れてください。",
+ "surface.shape.validate.size.4to5": "④長さは⑤より大きい値を入れてください。",
"estimate.detail.header.title": "基本情報",
- "estimate.detail.objectNo": "品番",
+ "estimate.detail.objectNo": "物件番号",
"estimate.detail.docNo": "見積書番号",
"estimate.detail.drawingEstimateCreateDate": "登録日",
"estimate.detail.lastEditDatetime": "変更日時",
@@ -866,58 +877,59 @@
"estimate.detail.estimateDate": "見積日",
"estimate.detail.otherSaleStoreId": "二次販売店名",
"estimate.detail.noOtherSaleStoreId": "二次点なし",
- "estimate.detail.receiveUser": "担当者 ",
+ "estimate.detail.receiveUser": "担当者",
"estimate.detail.objectName": "案件名",
"estimate.detail.objectRemarks": "メモ",
"estimate.detail.estimateType": "注文分類",
"estimate.detail.estimateType.yjss": "住宅PKG",
- "estimate.detail.estimateType.yjod": "積上げ( YJOD )",
+ "estimate.detail.estimateType.yjod": "積上げ(YJOD)",
"estimate.detail.roofCns": "屋根材・仕様施工",
"estimate.detail.remarks": "備考",
"estimate.detail.fileFlg": "後日資料提出",
+ "estimate.detail.dragFileGuide": "(※北面設置の場合、ファイル添付が必須です.)",
"estimate.detail.header.fileList1": "ファイル添付",
"estimate.detail.fileList.btn": "ファイル選択",
- "estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能.",
+ "estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能です。",
"estimate.detail.header.fileList2": "添付ファイル一覧",
"estimate.detail.fileList2.btn.return": "復元",
- "estimate.detail.header.specialEstimate": "見積もりの具体的な",
+ "estimate.detail.header.specialEstimate": "見積もりの特定",
"estimate.detail.header.specialEstimateProductInfo": "製品情報",
- "estimate.detail.sepcialEstimateProductInfo.totAmount": "数量 (PCS)",
- "estimate.detail.sepcialEstimateProductInfo.totVolKw": "容量 (Kw)",
+ "estimate.detail.sepcialEstimateProductInfo.totAmount": "数量(PCS)",
+ "estimate.detail.sepcialEstimateProductInfo.totVolKw": "容量(Kw)",
"estimate.detail.sepcialEstimateProductInfo.supplyPrice": "供給価格",
- "estimate.detail.sepcialEstimateProductInfo.vatPrice": "付加価値税 (10%)",
+ "estimate.detail.sepcialEstimateProductInfo.vatPrice": "税(10%)",
"estimate.detail.sepcialEstimateProductInfo.totPrice": "総額",
- "estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
- "estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
+ "estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価(W)",
+ "estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量(Kw)",
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
"estimate.detail.header.showPrice": "価格表示",
"estimate.detail.header.unitPrice": "定価",
"estimate.detail.showPrice.pricingBtn": "Pricing",
- "estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください.",
- "estimate.detail.showPrice.description1": "製品価格 OPEN",
- "estimate.detail.showPrice.description2": "追加, 変更資材",
+ "estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください。",
+ "estimate.detail.showPrice.description1": "製品価格OPEN",
+ "estimate.detail.showPrice.description2": "追加の変更品目",
"estimate.detail.showPrice.description3": "添付必須",
"estimate.detail.showPrice.description4": "クリックして製品の特異性を確認する",
- "estimate.detail.showPrice.addItem": "製品を追加",
- "estimate.detail.showPrice.delItem": "製品削除",
- "estimate.detail.itemTableHeader.dispOrder": "アイテム",
+ "estimate.detail.showPrice.addItem": "製品追加",
+ "estimate.detail.showPrice.delItem": "製品の削除",
+ "estimate.detail.itemTableHeader.dispOrder": "No.",
"estimate.detail.itemTableHeader.itemId": "品番",
- "estimate.detail.itemTableHeader.itemNo": "型板",
+ "estimate.detail.itemTableHeader.itemNo": "型名",
"estimate.detail.itemTableHeader.amount": "数量",
"estimate.detail.itemTableHeader.unit": "単位",
"estimate.detail.itemTableHeader.salePrice": "単価",
- "estimate.detail.itemTableHeader.saleTotPrice": "金額 (税別別)",
- "estimate.detail.docPopup.title": "ドキュメントダウンロードオプションの設定",
- "estimate.detail.docPopup.explane": "ダウンロードする文書のオプションを選択したら、 [文書のダウンロード]ボタンをクリックします.",
+ "estimate.detail.itemTableHeader.saleTotPrice": "金額(税別)",
+ "estimate.detail.docPopup.title": "文章ダウンロードオプションの設定",
+ "estimate.detail.docPopup.explane": "ダウンロードする文書オプションを選択し、[文書のダウンロード]ボタンをクリックします。",
"estimate.detail.docPopup.schUnitPriceFlg": "ダウンロードファイル",
- "estimate.detail.docPopup.schUnitPriceFlg.excelFlg0": "見積もり Excel",
- "estimate.detail.docPopup.schUnitPriceFlg.excelFlg1": "定価用 Excel",
- "estimate.detail.docPopup.schUnitPriceFlg.pdfFlg0": "見積もり PDF",
- "estimate.detail.docPopup.schUnitPriceFlg.pdfFlg1": "定価用 PDF",
- "estimate.detail.docPopup.schDisplayFlg": "見積提出先表示名",
+ "estimate.detail.docPopup.schUnitPriceFlg.excelFlg0": "仕切用Excel",
+ "estimate.detail.docPopup.schUnitPriceFlg.excelFlg1": "定価用Excel",
+ "estimate.detail.docPopup.schUnitPriceFlg.pdfFlg0": "仕切用PDF",
+ "estimate.detail.docPopup.schUnitPriceFlg.pdfFlg1": "定価用PDF",
+ "estimate.detail.docPopup.schDisplayFlg": "見積提出書の表示名",
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg0": "販売店名",
"estimate.detail.docPopup.schDisplayFlg.schDisplayFlg1": "案件名",
- "estimate.detail.docPopup.schWeightFlg": "架台重量表を含む",
+ "estimate.detail.docPopup.schWeightFlg": "架台重量表付き",
"estimate.detail.docPopup.schWeightFlg.schWeightFlg1": "含む",
"estimate.detail.docPopup.schWeightFlg.schWeightFlg0": "含まない",
"estimate.detail.docPopup.schDrawingFlg": "図面/シミュレーションファイルを含む",
@@ -925,43 +937,44 @@
"estimate.detail.docPopup.schDrawingFlg.schDrawingFlg0": "含まない",
"estimate.detail.docPopup.close": "閉じる",
"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.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.estimateCopyPopup.copyBtn": "見積コピー",
+ "estimate.detail.estimateCopyPopup.copy.alertMessage": "見積書がコピーされました。コピーした商品情報に移動します。",
"estimate.detail.productFeaturesPopup.title": "製品特異事項",
"estimate.detail.productFeaturesPopup.close": "閉じる",
- "estimate.detail.productFeaturesPopup.requiredStoreId": "一次販売店は必須です.",
- "estimate.detail.productFeaturesPopup.requiredReceiveUser": "担当者は必須です.",
- "estimate.detail.save.alertMsg": "保存されている見積書で製品を変更した場合、図面や回路には反映されません.",
- "estimate.detail.copy.alertMsg": "コピーしました.",
- "estimate.detail.save.requiredFileUpload": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください.",
- "estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります.",
- "estimate.detail.save.requiredCharger": "担当者は必須です.",
- "estimate.detail.save.requiredObjectName": "案件名は必須です.",
- "estimate.detail.save.requiredPkgAsp": "住宅pkg単価は0より大きい値を入力してください.",
- "estimate.detail.save.requiredEstimateDate": "見積日は必須です.",
- "estimate.detail.save.requiredItemId": "製品を選択してください.",
- "estimate.detail.save.requiredAmount": "数量は0より大きい値を入力してください.",
- "estimate.detail.save.requiredSalePrice": "単価は0より大きい値を入力してください.",
- "estimate.detail.reset.alertMsg": "初期化されました.",
- "estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?",
- "estimate.detail.lock.alertMsg": "見積書を[ロック]すると、変更できません。見積もりを編集するには、ロックを解除してください.",
- "estimate.detail.unlock.alertMsg": "[ロック解除]すると、見積書を編集できます.\n 解除しますか?",
+ "estimate.detail.productFeaturesPopup.requiredStoreId": "一次販売店は必須です。",
+ "estimate.detail.productFeaturesPopup.requiredReceiveUser": "担当者は必須です。",
+ "estimate.detail.save.alertMsg": "保存されました。見積書で製品を変更すると、図面や回路には反映されません。",
+ "estimate.detail.copy.alertMsg": "コピーされました。",
+ "estimate.detail.save.requiredFileUpload": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください。",
+ "estimate.detail.save.requiredNorthArrangementFileUpload": "北面にモジュールを配置した場合、北面配置許可書を必ず添付する必要があります.",
+ "estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります。",
+ "estimate.detail.save.requiredCharger": "担当者は必須です。",
+ "estimate.detail.save.requiredObjectName": "案件名は必須です。",
+ "estimate.detail.save.requiredPkgAsp": "住宅pkg単価は0より大きい値を入力してください。",
+ "estimate.detail.save.requiredEstimateDate": "見積日は必須です。",
+ "estimate.detail.save.requiredItemId": "製品を選択してください。",
+ "estimate.detail.save.requiredAmount": "数量は0より大きい値を入力してください。",
+ "estimate.detail.save.requiredSalePrice": "単価は0より大きい値を入力してください。",
+ "estimate.detail.reset.alertMsg": "初期化されました。",
+ "estimate.detail.reset.confirmMsg": "保存した見積情報が初期化され、最近保存された図面情報が反映されます。本当に初期化しますか?",
+ "estimate.detail.lock.alertMsg": "見積もりを[ロック]すると変更できません。 見積もりを修正するには、ロックを解除してください。",
+ "estimate.detail.unlock.alertMsg": "[ロック解除]すると、見積書を編集できます。 解除しますか?",
"estimate.detail.unlock.confirmBtnName": "解放",
- "estimate.detail.alert.delFile": "添付ファイルを完全に削除するには[保存]ボタンをクリックしてください",
- "estimate.detail.alert.selectDelItem": "削除する商品を選択してください.",
- "estimate.menu.move.valid1": "回路を分割していないため、見積もりを呼び出すことはできません.",
+ "estimate.detail.alert.delFile": "添付ファイルを完全に削除するには、[保存]ボタンをクリックしてください。",
+ "estimate.detail.alert.selectDelItem": "削除する商品を選択してください。",
+ "estimate.menu.move.valid1": "回路を分割していないため、見積もりを呼び出すことはできません。",
"simulator.title.sub1": "物件番号",
"simulator.title.sub2": "作成日",
"simulator.title.sub3": "システム容量",
"simulator.title.sub4": "年間予測発電量",
"simulator.title.sub5": "都道府県",
- "simulator.title.sub6": "日射量観測地点",
+ "simulator.title.sub6": "日射量観測点",
"simulator.title.sub7": "積雪条件",
"simulator.title.sub8": "風速条件",
"simulator.title.sub9": "以下",
@@ -972,16 +985,33 @@
"simulator.table.sub5": "枚数",
"simulator.table.sub6": "合計",
"simulator.table.sub7": "パワーコンディショナー",
- "simulator.table.sub8": "台",
- "simulator.table.sub9": "予測発電量 (kWh)",
- "simulator.notice.sub1": "Hanwha Japan 年間発電量",
- "simulator.notice.sub2": "シミュレーション案内事項",
- "simulator.menu.move.valid1": "見積書を作成した後に、発電シミュレーションの結果を照会することができます。",
- "master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
- "can.not.move.module": "모듈을 이동할 수 없습니다.(JA)",
- "can.not.copy.module": "모듈을 복사할 수 없습니다.(JA)",
- "can.not.remove.module": "모듈을 삭제할 수 없습니다.(JA)",
- "can.not.insert.module": "모듈을 삽입할 수 없습니다.(JA)",
- "can.not.align.module": "모듈을 정렬할 수 없습니다.(JA)",
- "menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다."
+ "simulator.table.sub8": "ティーン",
+ "simulator.table.sub9": "予測発電量(kWh)",
+ "simulator.notice.sub1": "ハンファジャパン年間発電量",
+ "simulator.notice.sub2": "シミュレーションガイド",
+ "simulator.menu.move.valid1": "見積書を作成したら、発電シミュレーションの結果を確認できます。",
+ "master.moduletypeitem.message.error": "屋根材のコードを入力してください。",
+ "can.not.move.module": "モジュールを移動できません。",
+ "can.not.copy.module": "モジュールをコピーできません。",
+ "can.not.remove.module": "モジュールを削除できません。",
+ "can.not.insert.module": "モジュールを挿入できません。",
+ "selectbox.title": "選択してください。",
+ "can.not.align.module": "モジュールを整列できません。",
+ "module.place.overobject": "オブジェクトの上にモジュールをインストールできません。",
+ "module.place.overlab": "モジュールを重ねて取り付けることはできません。",
+ "module.place.out": "取り付け面からモジュールを取り付けることはできません。",
+ "module.place.no.surface": "選択したモジュール取り付け面がありません。",
+ "module.place.select.module": "モジュールを選択してください。",
+ "module.place.select.one.module": "モジュールは1つだけ選択してください。",
+ "batch.canvas.delete.all": "配置面の内容をすべて削除しますか?",
+ "module.not.found": "インストールモジュールを選択してください。",
+ "construction.length.difference": "屋根面工法をすべて選択してください。",
+ "menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
+ "batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
+ "batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。",
+ "module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다.",
+ "module.trestleDetail.not.exist": "가대 상세 정보가 없습니다.",
+ "max.select": "최대 {0}개까지 선택할 수 있습니다.(JA)",
+ "module.delete.confirm": "パネルを削除して面入力に戻ります。正しいですか?\nはい]を選択すると削除し、面入力に戻ります。\nいいえ」を選択すると、削除せずに現在の状態を維持します。",
+ "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.(JA)"
}
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 6b4561d5..ad5dac68 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -3,19 +3,19 @@
"welcome": "환영합니다. {0}님",
"header.menus.home": "Home",
"header.menus.management": "물건 및 도면 관리",
- "header.menus.management.newStuff": "신규 물건 등록",
- "header.menus.management.detail": "물건 상세",
- "header.menus.management.stuffList": "물건 현황",
+ "header.menus.management.newStuff": "신규물건등록",
+ "header.menus.management.detail": "물건상세",
+ "header.menus.management.stuffList": "물건현황",
"header.menus.community": "커뮤니티",
- "header.menus.community.notice": "공지",
+ "header.menus.community.notice": "공지사항",
"header.menus.community.faq": "FAQ",
- "header.menus.community.archive": "자료 다운로드",
+ "header.menus.community.archive": "문서다운로드",
"header.logout": "로그아웃",
"header.go": "이동",
- "header.online.warranty.system": "온라인 보증 시스템",
+ "header.online.warranty.system": "온라인보증시스템",
"header.stem": "Stem",
"plan.menu.plan.drawing": "물건정보",
- "plan.menu.placement.surface.initial.setting": "배치면 초기 설정",
+ "plan.menu.placement.surface.initial.setting": "배치면 초기설정",
"modal.placement.initial.setting.plan.drawing": "도면 작성방법",
"modal.placement.initial.setting.plan.drawing.size.stuff": "치수 입력에 의한 물건 작성",
"modal.placement.initial.setting.size": "치수 입력방법",
@@ -29,7 +29,7 @@
"modal.placement.initial.setting.roof.angle.setting": "지붕각도 설정",
"modal.placement.initial.setting.roof.pitch": "경사",
"modal.placement.initial.setting.roof.angle": "각도",
- "modal.placement.initial.setting.roof.material": "지붕재 선택(단위: mm)",
+ "modal.placement.initial.setting.roof.material": "지붕재 선택(단위mm)",
"modal.placement.initial.setting.roof.material.info": "대응 가능한 지붕재 및 발판은 한정되므로 반드시 사전 매뉴얼을 확인하십시오.",
"modal.placement.initial.setting.rafter": "서까래",
"modal.roof.shape.setting": "지붕형상 설정",
@@ -44,14 +44,14 @@
"plan.menu.roof.cover.eaves.kerava.edit": "처마·케라바 변경",
"plan.menu.roof.cover.movement.shape.updown": "동선이동·형올림내림",
"modal.movement.flow.line.move": "동선 이동",
- "modal.movement.flow.line.move.alert": "이동 할 수 없습니다.",
+ "modal.movement.flow.line.move.alert": "이동할 수 없습니다.",
"modal.movement.flow.line.updown": "형 올림·내림",
"modal.movement.flow.line.updown.info": "자릿수가 다른 변을 선택하고 폭을 지정하십시오.",
"modal.movement.flow.line.updown.up": "자릿수를 올리다",
"modal.movement.flow.line.updown.down": "자릿수를 낮추다",
"modal.movement.flow.line.info": "동선을 선택하고 이동 폭을 지정하십시오",
- "modal.movement.flow.line.bottom.left": "높이 변경: 아래, 왼쪽",
- "modal.movement.flow.line.top.right": "높이 변경: 위, 오른쪽",
+ "modal.movement.flow.line.bottom.left": "높이변경 : 아래, 왼쪽",
+ "modal.movement.flow.line.top.right": "높이변경 : 위, 오른쪽",
"plan.menu.roof.cover.outline.edit.offset": "외벽선 편집 및 오프셋",
"plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당",
"plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집",
@@ -63,7 +63,7 @@
"modal.cover.outline.angle": "각도",
"modal.cover.outline.diagonal": "대각선",
"modal.cover.outline.setting": "설정",
- "modal.cover.outline.length": "길이 (mm)",
+ "modal.cover.outline.length": "길이(mm)",
"modal.cover.outline.arrow": "방향(화살표)",
"modal.cover.outline.fix": "외벽선 확정",
"modal.cover.outline.rollback": "일변전으로 돌아가기",
@@ -71,7 +71,7 @@
"common.setting.finish": "설정완료",
"common.setting.rollback": "일변전으로 돌아가기",
"modal.cover.outline.remove": "외벽 제거",
- "modal.cover.outline.select.move": "외벽 선택, 이동",
+ "modal.cover.outline.select.move": "외벽 선택 이동",
"plan.menu.placement.surface": "배치면",
"plan.menu.placement.surface.slope.setting": "경사설정",
"plan.menu.placement.surface.drawing": "배치면 그리기",
@@ -84,8 +84,8 @@
"plan.menu.placement.surface.arrangement": "면형상 배치",
"plan.menu.placement.surface.object": "오브젝트 배치",
"plan.menu.placement.surface.all.remove": "배치면 전체 삭제",
- "plan.menu.module.circuit.setting": "모듈,회로 구성",
- "plan.menu.module.circuit.setting.default": "기본 설정",
+ "plan.menu.module.circuit.setting": "모듈, 회로 구성",
+ "plan.menu.module.circuit.setting.default": "모듈/가대설정",
"modal.module.basic.setting.orientation.setting": "방위 설정",
"modal.module.basic.setting.orientation.setting.info": "※시뮬레이션 계산용 방위를 지정합니다. 남쪽의 방위를 설정해주세요.",
"modal.module.basic.setting.orientation.setting.angle.passivity": "각도를 직접 입력",
@@ -96,32 +96,32 @@
"modal.module.basic.setting.module.under.roof": "지붕밑바탕",
"modal.module.basic.setting.module.setting": "모듈 선택",
"modal.module.basic.setting.module.hajebichi": "망둥어 피치",
- "modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만, 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.",
+ "modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.",
"modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.",
"modal.module.basic.setting.module.stuff.info": "물건정보",
- "modal.module.basic.setting.module.surface.type": "면조도구분",
+ "modal.module.basic.setting.module.surface.type": "면조도",
"modal.module.basic.setting.module.fitting.height": "설치높이",
- "modal.module.basic.setting.module.standard.wind.speed": "기준 풍속",
- "modal.module.basic.setting.module.standard.snowfall.amount": "기준 적설량",
+ "modal.module.basic.setting.module.standard.wind.speed": "기준풍속",
+ "modal.module.basic.setting.module.standard.snowfall.amount": "적설량",
"modal.module.basic.setting.module.standard.construction": "표준시공",
"modal.module.basic.setting.module.enforce.construction": "강화시공",
"modal.module.basic.setting.module.multiple.construction": "다설시공",
- "modal.module.basic.setting.module.eaves.bar.fitting": "처마력 바의 설치",
- "modal.module.basic.setting.module.blind.metal.fitting": "눈막이 금구 설치",
- "modal.module.basic.setting.module.select": "모듈 선택",
+ "modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치",
+ "modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치",
+ "modal.module.basic.setting.module.select": "모듈/가대 선택",
"modal.module.basic.setting.module.placement": "모듈 배치",
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택해주세요.",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
"modal.module.basic.setting.module.placement.do": "한다",
"modal.module.basic.setting.module.placement.do.not": "하지 않는다",
"modal.module.basic.setting.module.placement.arrangement.standard": "배치 기준",
- "modal.module.basic.setting.module.placement.arrangement.standard.center": "중앙배치",
- "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마쪽",
- "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루쪽",
- "modal.module.basic.setting.module.placement.maximum": "최대배치 실시한다.",
- "modal.module.basic.setting.pitch.module.placement.standard.setting": "배치 기준 설정",
- "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "남향으로 설치한다",
- "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치한다",
+ "modal.module.basic.setting.module.placement.arrangement.standard.center": "중앙",
+ "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마",
+ "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루",
+ "modal.module.basic.setting.module.placement.maximum": "최대배치",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting": "배치기준 설정",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "남향설치",
+ "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치",
"modal.module.basic.setting.pitch.module.allocation.setting": "할당 설정",
"modal.module.basic.setting.pitch.module.allocation.setting.info": "※배치 패널 종류가 1종류일 경우에만 사용할 수 있습니다.",
"modal.module.basic.setting.pitch.module.row.amount": "단수",
@@ -131,44 +131,48 @@
"modal.module.basic.setting.prev": "이전",
"modal.module.basic.setting.passivity.placement": "수동 배치",
"modal.module.basic.setting.auto.placement": "설정값으로 자동 배치",
- "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로 및 가대 설정",
- "modal.circuit.trestle.setting": "회로 및 가대설정",
+ "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정",
+ "modal.circuit.trestle.setting": "회로설정",
"modal.circuit.trestle.setting.alloc.trestle": "가대할당",
"modal.circuit.trestle.setting.power.conditional.select": "파워컨디셔너 선택",
"modal.circuit.trestle.setting.power.conditional.select.cold.region": "한랭지사양",
"modal.circuit.trestle.setting.power.conditional.select.name": "명칭",
"modal.circuit.trestle.setting.power.conditional.select.rated.output": "정격출력",
"modal.circuit.trestle.setting.power.conditional.select.circuit.amount": "회로수",
- "modal.circuit.trestle.setting.power.conditional.select.max.connection": "최대접속매수",
- "modal.circuit.trestle.setting.power.conditional.select.max.overload": "과적최대매수",
+ "modal.circuit.trestle.setting.power.conditional.select.max.connection": "표준매수",
+ "modal.circuit.trestle.setting.power.conditional.select.max.overload": "최대매수",
"modal.circuit.trestle.setting.power.conditional.select.output.current": "출력전류",
- "modal.circuit.trestle.setting.power.conditional.select.check1": "동일경사 동일 방면의 면적인 경우, 같은 면으로서 회로를 나눈다.",
+ "modal.circuit.trestle.setting.power.conditional.select.check1": "동일경사 동일방면의 면적인 경우 같은 면으로서 회로를 나눈다.",
"modal.circuit.trestle.setting.power.conditional.select.check2": "MAX 접속(과적)으로 회로를 나눈다.",
"modal.circuit.trestle.setting.circuit.allocation": "회로 할당",
- "modal.circuit.trestle.setting.circuit.allocation.auto": "자동 회로 할당",
- "modal.circuit.trestle.setting.circuit.allocation.passivity": "수동 회로 할당",
+ "modal.circuit.trestle.setting.circuit.allocation.auto": "자동회로 할당",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity": "수동회로 할당",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit": "회로",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.series": "시리즈",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.name": "명칭",
"modal.circuit.trestle.setting.circuit.allocation.passivity.info": "동일한 회로의 모듈을 선택 상태로 만든 후 [번호 확정] 버튼을 누르면 번호가 할당됩니다.",
"modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional": "선택된 파워컨디셔너",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num": "설정할 회로번호(1~)",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "표준회로{0}장~{1}장",
"modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset": "선택된 파워컨디셔너의 회로번호 초기화",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset.info": "선택된 파워 컨디셔너의 회로할당을 초기화합니다.",
"modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset": "모든 회로번호 초기화",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset.info": "회로 할당의 설정을 초기화합니다.",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error01": "배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.",
+ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02": "시리즈를 선택해주세요.",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num.fix": "번호 확정",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.init.info": "선택된 파워 컨디셔너의 회로할당을 초기화합니다.",
- "modal.circuit.trestle.setting.circuit.allocation.passivity.init.setting.info": "회로 할당의 설정을 초기화합니다.",
"modal.circuit.trestle.setting.step.up.allocation": "승압 설정",
"modal.circuit.trestle.setting.step.up.allocation.serial.amount": "직렬매수",
"modal.circuit.trestle.setting.step.up.allocation.total.amount": "총 회로수",
"modal.circuit.trestle.setting.step.up.allocation.connected": "연결함",
"modal.circuit.trestle.setting.step.up.allocation.circuit.amount": "승압회로수",
"modal.circuit.trestle.setting.step.up.allocation.option": "승압옵션",
- "modal.circuit.trestle.setting.step.up.allocation.select.monitor": "모니터 선택",
+ "modal.circuit.trestle.setting.step.up.allocation.select.monitor": "옵션선택",
"plan.menu.module.circuit.setting.plan.orientation": "도면 방위 적용",
"plan.menu.estimate": "견적서",
"plan.menu.estimate.roof.alloc": "지붕면 할당",
- "modal.roof.alloc.info": "※ 배치면 초기설정에서 저장한 [기본 지붕재]를 변경하거나, 지붕재를 추가하여 할당할 수 있습니다.",
- "modal.roof.alloc.default.roof.material": "기본지붕재",
+ "modal.roof.alloc.info": "※ 배치면 초기설정에서 저장한 [기본 지붕재]를 변경하거나 지붕재를 추가하여 할당할 수 있습니다.",
+ "modal.roof.alloc.default.roof.material": "기본 지붕재",
"modal.roof.alloc.select.roof.material": "지붕재 선택",
"modal.roof.alloc.select.parallel": "병렬식",
"modal.roof.alloc.select.stairs": "계단식",
@@ -262,10 +266,10 @@
"modal.canvas.setting.first.option.line": "라인해치",
"modal.canvas.setting.first.option.all": "All painted",
"modal.canvas.setting.wallline.properties.setting": "외벽선 속성 설정",
- "modal.canvas.setting.wallline.properties.setting.info": "※ 속성을 변경할 외벽선을 선택하고, 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n",
+ "modal.canvas.setting.wallline.properties.setting.info": "※ 속성을 변경할 외벽선을 선택하고 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n",
"modal.canvas.setting.wallline.properties.setting.eaves": "처마로 설정",
"modal.canvas.setting.wallline.properties.setting.edge": "케라바로 설정",
- "modal.eaves.gable.edit": "처마・케라바 변경",
+ "modal.eaves.gable.edit": "처마/케라바 변경",
"modal.eaves.gable.edit.basic": "통상",
"modal.eaves.gable.edit.wall.merge.info": "하옥 등 벽에 접하는 지붕을 작성합니다.",
"modal.wallline.offset.setting": "외벽선 편집 및 오프셋",
@@ -304,17 +308,17 @@
"modal.flow.direction.setting": "흐름 방향 설정",
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
"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.size": "실제치수 길이를 입력해 주세요",
"modal.actual.size.setting.plane.size.length": "복도치수 길이",
"modal.actual.size.setting.actual.size.length": "실제치수 길이",
- "plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
- "plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
- "plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
+ "plan.message.confirm.save": "플랜을 저장하시겠습니까?",
+ "plan.message.confirm.copy": "플랜을 복사하시겠습니까?",
+ "plan.message.confirm.delete": "플랜을 삭제하시겠습니까?",
"plan.message.save": "저장되었습니다.",
"plan.message.delete": "삭제되었습니다.",
- "plan.message.leave": "물건현황(목록)으로 이동하시겠습니까? [예]를 선택한 경우, 저장하고 이동합니다.",
+ "plan.message.leave": "물건현황(목록)으로 이동하시겠습니까? [예]를 선택한 경우 저장하고 이동합니다.",
"plan.message.corfirm.yes": "예",
"plan.message.confirm.no": "아니오",
"setting": "설정",
@@ -328,7 +332,7 @@
"contextmenu.roof.material.remove": "지붕재 삭제",
"contextmenu.roof.material.remove.all": "지붕재 전체 삭제",
"contextmenu.dormer.offset": "도머 오프셋",
- "contextmenu.select.move": "선택・이동",
+ "contextmenu.select.move": "선택이동",
"contextmenu.wallline.remove": "외벽선 삭제",
"contextmenu.size.edit": "사이즈 변경",
"modal.auxiliary.size.edit": "보조선 사이즈 변경",
@@ -391,7 +395,7 @@
"modal.display.edit.info": "치수선에 표시할 수치를 입력해 주세요.",
"modal.display.edit.before.length": "기존 길이",
"modal.display.edit.after.length": "변경 길이",
- "modal.display.edit.corner.valley": "구석・골의 경우",
+ "modal.display.edit.corner.valley": "구석ㆍ골의 경우",
"modal.display.edit.input.slope": "경사를 입력해주세요.",
"modal.display.edit.input.slope.info": "경사 설정되어 있는 경우 입력한 수치에 경사 계산을 한 수치가 표시됩니다.",
"modal.distance": "거리 측정",
@@ -417,6 +421,7 @@
"modal.module.circuit.number.edit": "모듈 일괄 회로 번호 변경",
"modal.module.circuit.number.edit.info": "회로 번호를 입력해주세요.",
"modal.module.circuit.number": "회로 번호",
+ "modal.module.can.not.edit": "회로 구성을 완료한 모듈은 변경할 수 없습니다.",
"modal.line.property.change": "변경할 속성을 선택해 주세요.",
"modal.line.property.change.unselect": "변경할 라인을 선택해 주세요.",
"modal.line.property.change.confirm": "속성을 변경하시겠습니까?",
@@ -440,7 +445,7 @@
"common.message.transfer.error": "An error occurred while transfer the data. Please contact site administrator.",
"common.message.delete.error": "An error occurred while deleting data. Please contact site administrator.",
"common.message.batch.error": "An error occurred while executing the batch. Please contact site administrator.",
- "common.message.send.error": "Error sending data, please contact your administrator.",
+ "common.message.send.error": "Error sending data please contact your administrator.",
"common.message.communication.error": "Network error occurred. \n Please contact site administrator.",
"common.message.data.error": "{0} The data format is not valid.",
"common.message.data.setting.error": "{0} is data that has been deleted or already configured.",
@@ -453,10 +458,10 @@
"common.message.file.template.validation01": "Unable to upload folder",
"common.message.file.template.validation02": "Only Excel files can be uploaded.",
"common.message.file.template.validation03": "Non-registerable extension",
- "common.message.file.template.validation04": "Exceed capacity \n Uploadable capacity : {0} MB",
- "common.message.file.template.validation05": "업로드 파일을 선택해주세요.",
- "common.message.multi.insert": "Total {0} cases ({1} successes, {2} failures {3})",
- "common.message.error": "Error occurred, please contact site administrator.",
+ "common.message.file.template.validation04": "Exceed capacity \n Uploadable capacity ",
+ "common.message.file.template.validation05": "업로드 파일을 선택해주세요. {0} MB",
+ "common.message.multi.insert": "Total {0} cases ({1} successes {2} failures {3})",
+ "common.message.error": "Error occurred please contact site administrator.",
"common.message.data.save": "Do you want to save it?",
"common.message.data.delete": "정말로 삭제하시겠습니까?",
"common.message.data.exists": "{0} is data that already exists.",
@@ -486,7 +491,7 @@
"common.message.no.editfield": "Can not edit field",
"common.message.success.rmmail": "You have successfully sent mail to the Risk Management team.",
"common.message.password.validation01": "Change passwords do not match.",
- "common.message.password.validation02": "Please enter at least 8 digits combining English, numbers, and special characters.",
+ "common.message.password.validation02": "Please enter at least 8 digits combining English numbers and special characters.",
"common.message.password.validation03": "Password cannot be the same as ID.",
"common.message.menu.validation01": "There is no menu to save the order.",
"common.message.menu.validation02": "The same sort order exists.",
@@ -537,7 +542,7 @@
"color.gold": "황금색",
"color.darkblue": "남색",
"site.name": "Q.CAST III",
- "site.sub_name": "태양광 발전 시스템 도면관리 사이트",
+ "site.sub_name": "태양광발전시스템 도면ㆍ견적 시스템",
"site.header.link1": "선택하세요.",
"site.header.link2": "온라인보증시스템",
"board.notice.title": "공지사항",
@@ -556,9 +561,9 @@
"board.sub.fileList": "첨부파일 목록",
"board.sub.updDt": "업데이트",
"board.sub.btn.close": "닫기",
- "myinfo.title": "My profile",
+ "myinfo.title": "내정보",
"myinfo.info.userId": "사용자ID",
- "myinfo.info.nameKana": "담당자명 후리가나",
+ "myinfo.info.nameKana": "담당자명 일본어",
"myinfo.info.name": "담당자명",
"myinfo.info.password": "비밀번호",
"myinfo.info.chg.password": "변경 비밀번호 입력",
@@ -583,7 +588,7 @@
"login.id.save": "ID Save",
"login.id.placeholder": "아이디를 입력해주세요.",
"login.password.placeholder": "비밀번호를 입력해주세요.",
- "login.guide.text": "당 사이트를 이용할 때는, 사전 신청이 필요합니다.",
+ "login.guide.text": "당 사이트를 이용할 때는 사전 신청이 필요합니다.",
"login.guide.sub1": "ID가 없는 분은",
"login.guide.sub2": "을 클릭해주십시오.",
"login.guide.join.btn": "ID신청",
@@ -623,7 +628,7 @@
"join.btn.login_page": "로그인 화면으로 이동",
"join.btn.approval_request": "ID 승인요청",
"join.complete.title": "Q.CAST3 로그인ID 발행신청 완료",
- "join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
+ "join.complete.contents": "※ 신청한 ID가 승인되면 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
"join.complete.email_comment": "담당자 이메일 주소",
"join.validation.check1": "{0} 형식을 확인해주세요.",
"join.complete.save.confirm": "Hanwha Japan 담당자에게 ID승인이 요청되면 더 이상 정보를 수정할 수 없습니다. 정말로 요청하시겠습니까?",
@@ -672,7 +677,7 @@
"stuff.detail.zipNo": "우편번호",
"stuff.detail.address": "주소",
"stuff.detail.btn.addressPop": "주소검색",
- "stuff.detail.btn.addressPop.guide": "※ 주소검색 버튼을 클릭한 후, 도도부현 정보를 선택해주십시오.",
+ "stuff.detail.btn.addressPop.guide": "※ 주소검색 버튼을 클릭한 후 도도부현 정보를 선택해주십시오.",
"stuff.detail.prefId": "도도부현 / 주소",
"stuff.detail.areaId": "발전량시뮬레이션지역",
"stuff.detail.standardWindSpeedId": "기준풍속",
@@ -680,7 +685,7 @@
"stuff.detail.btn.windSpeedPop": "풍속선택",
"stuff.detail.verticalSnowCover": "수직적설량",
"stuff.detail.coldRegionFlg": "한랭지대책시행",
- "stuff.detail.surfaceType": "면조도구분",
+ "stuff.detail.surfaceType": "면조도",
"stuff.detail.saltAreaFlg": "염해지역용아이템사용",
"stuff.detail.installHeight": "설치높이",
"stuff.detail.conType": "계약조건",
@@ -688,17 +693,17 @@
"stuff.detail.conType1": "전량",
"stuff.detail.remarks": "메모",
"stuff.detail.tooltip.saleStoreId": "판매대리점 또는 판매대리점ID를 1자 이상 입력하세요",
- "stuff.detail.tooltip.surfaceType": "염해지역 정의는 각 메이커의 설치 메뉴얼을 확인해주십시오",
+ "stuff.detail.tooltip.surfaceType": "염해지역 정의는 각 메이커의 설치 매뉴얼을 확인해주십시오",
"stuff.detail.tempSave.message1": "임시저장 되었습니다. 물건번호를 획득하려면 필수 항목을 모두 입력해 주십시오.",
- "stuff.detail.tempSave.message2": "담당자는 10자리 이하로 입력해 주십시오.",
+ "stuff.detail.tempSave.message2": "담당자이름은 10자리 이하로 입력해 주십시오.",
"stuff.detail.tempSave.message3": "2차 판매점을 선택해주세요.",
- "stuff.detail.confirm.message1": "판매점 정보를 변경하면, 설계의뢰 문서번호가 삭제됩니다. 변경하시겠습니까?",
+ "stuff.detail.confirm.message1": "판매점 정보를 변경하면 설계의뢰 문서번호가 삭제됩니다. 변경하시겠습니까?",
"stuff.detail.delete.message1": "사양이 확정된 물건은 삭제할 수 없습니다.",
- "stuff.detail.planList.title": "플랜리스트",
+ "stuff.detail.planList.title": "플랜목록",
"stuff.detail.planList.cnt": "전체",
"stuff.detail.planList.help": "도움말",
"stuff.detail.planList.guide1": "1.발주는 동일 물건번호 기준 1건만 가능합니다.",
- "stuff.detail.planList.guide2": "2.[Excel 다운로드]는 견적서, 도면, 시뮬레이션 결과를 엑셀파일로 한번에 다운로드 합니다.",
+ "stuff.detail.planList.guide2": "2.[Excel 다운로드]는 견적서 도면 시뮬레이션 결과를 엑셀파일로 한번에 다운로드 합니다.",
"stuff.detail.planList.guide3": "3.플랜정보를 더블 클릭하면 도면작성 화면으로 이동합니다.",
"stuff.detail.btn.delete": "물건삭제",
"stuff.detail.btn.moveList": "물건목록",
@@ -846,8 +851,8 @@
"main.popup.login.newPassword1": "새 비밀번호 입력",
"main.popup.login.newPassword2": "새 비밀번호 재입력",
"main.popup.login.placeholder": "반각 10자 이내",
- "main.popup.login.guide1": "초기화된 비밀번호로 로그인한 경우, 비밀번호를 변경해야 사이트 이용이 가능합니다.",
- "main.popup.login.guide2": "비밀번호를 변경하지 않을 경우, 로그인 화면으로 이동합니다.",
+ "main.popup.login.guide1": "초기화된 비밀번호로 로그인한 경우 비밀번호를 변경해야 사이트 이용이 가능합니다.",
+ "main.popup.login.guide2": "비밀번호를 변경하지 않을 경우 로그인 화면으로 이동합니다.",
"main.popup.login.btn1": "변경",
"main.popup.login.btn2": "변경안함",
"main.popup.login.validate1": "입력한 패스워드가 다릅니다.",
@@ -882,6 +887,7 @@
"estimate.detail.roofCns": "지붕재・사양시공",
"estimate.detail.remarks": "비고",
"estimate.detail.fileFlg": "후일자료제출",
+ "estimate.detail.dragFileGuide": "(※ 북면설치인 경우, 파일 첨부가 필수입니다.)",
"estimate.detail.header.fileList1": "파일첨부",
"estimate.detail.fileList.btn": "파일선택",
"estimate.detail.fileList.extCheck": "이미지 파일만 첨부 가능합니다.",
@@ -902,12 +908,12 @@
"estimate.detail.showPrice.pricingBtn": "Pricing",
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.",
"estimate.detail.showPrice.description1": "제품 가격 OPEN",
- "estimate.detail.showPrice.description2": "추가, 변경 자재",
+ "estimate.detail.showPrice.description2": "추가 변경 자재",
"estimate.detail.showPrice.description3": "첨부필수",
"estimate.detail.showPrice.description4": "클릭하여 제품 특이사항 확인",
"estimate.detail.showPrice.addItem": "제품추가",
"estimate.detail.showPrice.delItem": "제품삭제",
- "estimate.detail.itemTableHeader.dispOrder": "Item",
+ "estimate.detail.itemTableHeader.dispOrder": "No.",
"estimate.detail.itemTableHeader.itemId": "품번",
"estimate.detail.itemTableHeader.itemNo": "형명",
"estimate.detail.itemTableHeader.amount": "수량",
@@ -944,9 +950,10 @@
"estimate.detail.productFeaturesPopup.close": "닫기",
"estimate.detail.productFeaturesPopup.requiredStoreId": "1차 판매점은 필수값 입니다.",
"estimate.detail.productFeaturesPopup.requiredReceiveUser": "담당자는 필수값 입니다.",
- "estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우, 도면 및 회로에 반영되지 않습니다.",
+ "estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우 도면 및 회로에 반영되지 않습니다.",
"estimate.detail.copy.alertMsg": "복사되었습니다.",
"estimate.detail.save.requiredFileUpload": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.",
+ "estimate.detail.save.requiredNorthArrangementFileUpload": "북면에 모듈을 배치한 경우, 북면배치허가서를 반드시 첨부해야 합니다.",
"estimate.detail.save.requiredItem": "제품은 1개이상 등록해야 됩니다.",
"estimate.detail.save.requiredCharger": "담당자는 필수값 입니다.",
"estimate.detail.save.requiredObjectName": "안건명은 필수값 입니다.",
@@ -956,8 +963,8 @@
"estimate.detail.save.requiredAmount": "수량은 0보다 큰값을 입력해주세요.",
"estimate.detail.save.requiredSalePrice": "단가는 0보다 큰값을 입력해주세요.",
"estimate.detail.reset.alertMsg": "초기화 되었습니다.",
- "estimate.detail.reset.confirmMsg": "수기 변경(저장)한 견적 정보가 초기화되고, 최근 저장된 도면정보가 반영됩니다. 정말로 초기화하시겠습니까?",
- "estimate.detail.lock.alertMsg": "견적서를 [잠금]하면, 수정할 수 없습니다. 견적서를 수정하려면 잠금해제를 하십시오.",
+ "estimate.detail.reset.confirmMsg": "수기 변경(저장)한 견적 정보가 초기화되고 최근 저장된 도면정보가 반영됩니다. 정말로 초기화하시겠습니까?",
+ "estimate.detail.lock.alertMsg": "견적서를 [잠금]하면 수정할 수 없습니다. 견적서를 수정하려면 잠금해제를 하십시오.",
"estimate.detail.unlock.alertMsg": "[잠금해제]하면 견적서를 수정할 수 있습니다. 해제하시겠습니까?",
"estimate.detail.unlock.confirmBtnName": "해제",
"estimate.detail.alert.delFile": "첨부파일을 완전히 삭제하려면 [저장]버튼을 클릭하십시오.",
@@ -983,7 +990,7 @@
"simulator.table.sub9": "예측발전량 (kWh)",
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
"simulator.notice.sub2": "시뮬레이션 안내사항",
- "simulator.menu.move.valid1": "견적서를 생성한 후에, 발전시뮬레이션 결과를 조회할 수 있습니다.",
+ "simulator.menu.move.valid1": "견적서를 생성한 후에 발전시뮬레이션 결과를 조회할 수 있습니다.",
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
"can.not.move.module": "모듈을 이동할 수 없습니다.",
"can.not.copy.module": "모듈을 복사할 수 없습니다.",
@@ -998,9 +1005,14 @@
"module.place.select.module": "모듈을 선택해주세요.",
"module.place.select.one.module": "모듈은 하나만 선택해주세요.",
"batch.canvas.delete.all": "배치면 내용을 전부 삭제하시겠습니까?",
- "module.not.found": "설치 모듈을 선택하세요.",
+ "module.not.found": "모듈을 선택하세요.",
"construction.length.difference": "지붕면 공법을 전부 선택해주세요.",
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",
- "batch.object.notinstall.cross": "오브젝트는 겹쳐서 설치 할 수 없습니다."
+ "batch.object.notinstall.cross": "오브젝트는 겹쳐서 설치 할 수 없습니다.",
+ "module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다.",
+ "module.trestleDetail.not.exist": "가대 상세 정보가 없습니다.",
+ "max.select": "최대 {0}개까지 선택할 수 있습니다.",
+ "module.delete.confirm": "패널을 삭제하고 면입력으로 돌아갑니다. 맞습니까?\n[예]를 선택하면 삭제하고, 면 입력으로 돌아갑니다.\n[아니오]를 선택하면 삭제하지 않고 현재 상태를 유지합니다.",
+ "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다."
}
diff --git a/src/store/circuitTrestleAtom.js b/src/store/circuitTrestleAtom.js
index ea54835a..d1477e13 100644
--- a/src/store/circuitTrestleAtom.js
+++ b/src/store/circuitTrestleAtom.js
@@ -40,7 +40,10 @@ export const moduleStatisticsState = atom({
{ name: `발전량(kW)`, prop: 'amount' },
],
rows: [],
- footer: ['합계', '0'],
+ footer: [
+ { name: '-', prop: 'name' },
+ { name: 0, prop: 'amount' },
+ ],
},
dangerouslyAllowMutability: true,
})
diff --git a/src/store/estimateAtom.js b/src/store/estimateAtom.js
new file mode 100644
index 00000000..410921fc
--- /dev/null
+++ b/src/store/estimateAtom.js
@@ -0,0 +1,23 @@
+import { atom } from 'recoil'
+
+export const estimateParamAtom = atom({
+ // 견적서 post parameter
+ key: 'estimateParamAtom',
+ default: {
+ saleStoreId: '',
+ objectNo: '',
+ planNo: '',
+ slope: '',
+ angle: '',
+ surfaceType: '',
+ setupHeight: '',
+ standardWindSpeedId: '',
+ snowfall: '',
+ northArrangement: '',
+ drawingFlg: '1',
+ userId: '',
+ roofSurfaceList: [],
+ circuitItemList: [],
+ itemList: [],
+ },
+})
diff --git a/src/store/localeAtom.js b/src/store/localeAtom.js
index 0f20fa87..0564e633 100644
--- a/src/store/localeAtom.js
+++ b/src/store/localeAtom.js
@@ -2,7 +2,7 @@ import { atom } from 'recoil'
export const globalLocaleStore = atom({
key: 'globalLocaleState',
- default: 'ko',
+ default: 'ja',
})
export const appMessageStore = atom({
diff --git a/src/store/menuAtom.js b/src/store/menuAtom.js
index 2cf4b841..759df0fd 100644
--- a/src/store/menuAtom.js
+++ b/src/store/menuAtom.js
@@ -64,11 +64,11 @@ export const subMenusState = atom({
name: 'plan.menu.module.circuit.setting.circuit.trestle.setting',
menu: MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING,
},
- {
- id: 2,
- name: 'plan.menu.module.circuit.setting.plan.orientation',
- menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
- },
+ // {
+ // id: 2,
+ // name: 'plan.menu.module.circuit.setting.plan.orientation',
+ // menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
+ // },
],
},
})
diff --git a/src/store/selectedModuleOptions.js b/src/store/selectedModuleOptions.js
index c312c694..5165fb48 100644
--- a/src/store/selectedModuleOptions.js
+++ b/src/store/selectedModuleOptions.js
@@ -42,7 +42,6 @@ export const moduleSelectionOptionParamsState = atom({
stdWindSpeed: '',
stdSnowLd: '',
inclCd: '',
- roofMatlCd: '',
},
dangerouslyAllowMutability: true,
})
diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss
index 1a13f77e..10a04637 100644
--- a/src/styles/_contents.scss
+++ b/src/styles/_contents.scss
@@ -792,6 +792,12 @@
}
// file drag box
+.drag-file-guide{
+ font-size: 13px;
+ font-weight: 400;
+ color: #45576F;
+ margin-left: 5px;
+}
.drag-file-box{
padding: 10px;
.btn-area{
diff --git a/src/styles/_main.scss b/src/styles/_main.scss
index 4322b535..e3ccabeb 100644
--- a/src/styles/_main.scss
+++ b/src/styles/_main.scss
@@ -254,7 +254,7 @@
font-weight: 600;
margin-bottom: 25px;
line-height: 24px;
- word-break: keep-all;
+ word-break: break-all;
}
.notice-contents{
font-size: 12px;
diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss
index 61f631cd..7c959e83 100644
--- a/src/styles/_modal.scss
+++ b/src/styles/_modal.scss
@@ -259,6 +259,12 @@ $alert-color: #101010;
border-bottom: 1px solid #424242;
}
}
+.grid-check-form-block{
+ display: block;
+ > div{
+ margin-bottom: 10px;
+ }
+}
.grid-option-overflow{
max-height: 350px;
overflow-y: auto;
@@ -305,6 +311,25 @@ $alert-color: #101010;
}
.grid-option-block-form{
flex: 1;
+ .flex-ment{
+ position: relative;
+ padding-right: 70px;
+ flex: 1 1 auto;
+ span{
+ width: 70px;
+ &.absol{
+ width: fit-content;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+
+ }
+ }
+ .input-grid{
+ flex: 1;
+ }
+ }
}
}
.select-form{
@@ -312,6 +337,7 @@ $alert-color: #101010;
}
.grid-select{
flex: 1;
+ height: 30px;
&.no-flx{
flex: unset;
}
@@ -2013,7 +2039,7 @@ $alert-color: #101010;
}
}
.roof-module-tab2-overflow{
- max-height: 500px;
+ max-height: 650px;
overflow-y: auto;
padding-bottom: 15px;
border-bottom: 1px solid #4D4D4D;
@@ -2088,17 +2114,3 @@ $alert-color: #101010;
justify-content: flex-end;
}
}
-
-.reset-word-wrap{
- display: flex;
- align-items: center;
- .grid-btn-wrap{
- margin-left: auto;
- }
-}
-.reset-word{
- font-size: 12px;
- color: #FFCACA;
- font-weight: 400;
- margin-top: 10px;
-}
\ No newline at end of file
diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss
index 2f5c7f79..bb5ff100 100644
--- a/src/styles/_reset.scss
+++ b/src/styles/_reset.scss
@@ -535,7 +535,15 @@ input[type=text]{
}
}
}
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+input[type=number] {
+ -moz-appearance: textfield;
+}
// check-btn
@@ -651,7 +659,7 @@ input[type=text]{
padding-left: 10px;
margin-bottom: 0;
word-break: break-all;
- line-height: 1.2;
+ line-height: 1.4;
display: inline;
vertical-align: top;
color: #fff;
@@ -1000,5 +1008,5 @@ input:checked + .slider {
// alert z-index
.swal2-container{
- z-index: 100000;
+ z-index: 120000;
}
\ No newline at end of file
diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js
index 4ec7a4be..6ad06e45 100644
--- a/src/util/canvas-util.js
+++ b/src/util/canvas-util.js
@@ -958,7 +958,10 @@ export const getAllRelatedObjects = (id, canvas) => {
// 모듈,회로 구성에서 사용하는 degree 범위 별 값
export const getDegreeInOrientation = (degree) => {
- if (degree >= 352) {
+ if (degree === 180 || degree === -180) {
+ return 180
+ }
+ if (degree >= 180 || degree < -180) {
return 0
}
if (degree % 15 === 0) return degree
@@ -1032,8 +1035,3 @@ export function calculateVisibleModuleHeight(sourceWidth, sourceHeight, angle, d
height: Number(visibleHeight.toFixed(1)), // 소수점 두 자리로 고정
}
}
-
-export function getTrestleLength(length, degree) {
- const radians = (degree * Math.PI) / 180
- return length * Math.cos(radians)
-}
diff --git a/src/util/common-utils.js b/src/util/common-utils.js
index ee003ec3..842eace0 100644
--- a/src/util/common-utils.js
+++ b/src/util/common-utils.js
@@ -130,7 +130,7 @@ export const calculateFlowDirection = (canvasAngle) => {
*/
export const getQueryString = (o) => {
const queryString = Object.keys(o)
- .map((key) => `${key}=${o[key]}`)
+ .map((key) => `${key}=${o[key] ?? ''}`)
.join('&')
return `?${queryString}`
}
diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js
index e7e2de42..97f4f88d 100644
--- a/src/util/qpolygon-utils.js
+++ b/src/util/qpolygon-utils.js
@@ -248,6 +248,7 @@ export default function offsetPolygon(vertices, offset) {
const arcSegments = 0
const originPolygon = new QPolygon(vertices, { fontSize: 0 })
+ originPolygon.setViewLengthText(false)
if (offset > 0) {
let result = createMarginPolygon(polygon, offset, arcSegments).vertices
|