Merge branch 'dev' of ssh://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev

This commit is contained in:
yoosangwook 2025-02-05 09:58:13 +09:00
commit bc1de6e490
21 changed files with 932 additions and 420 deletions

View File

@ -1366,6 +1366,9 @@ export default function Estimate({}) {
{getMessage('estimate.detail.fileFlg')} {getMessage('estimate.detail.fileFlg')}
</label> </label>
</div> </div>
{estimateContextState?.northArrangement === '1' && (
<div className="drag-file-guide">{getMessage('estimate.detail.dragFileGuide')}</div>
)}
</div> </div>
</div> </div>
<div className="common-table mb10"> <div className="common-table mb10">

View File

@ -28,7 +28,6 @@ export default function CanvasFrame() {
const { currentCanvasPlan } = usePlan() const { currentCanvasPlan } = usePlan()
const totalDisplay = useRecoilValue(totalDisplaySelector) // const totalDisplay = useRecoilValue(totalDisplaySelector) //
const { setIsGlobalLoading } = useContext(QcastContext) const { setIsGlobalLoading } = useContext(QcastContext)
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
const reset = useResetRecoilState(moduleStatisticsState) const reset = useResetRecoilState(moduleStatisticsState)
const loadCanvas = () => { const loadCanvas = () => {
if (canvas) { if (canvas) {

View File

@ -84,10 +84,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
setIsManualModuleSetup(!isManualModuleSetup) setIsManualModuleSetup(!isManualModuleSetup)
} }
useEffect(() => {
manualModuleSetup()
}, [isManualModuleSetup])
const updateObjectDataApi = async (params) => { const updateObjectDataApi = async (params) => {
const res = await updateObjectDate(params) const res = await updateObjectDate(params)
} }

View File

@ -189,7 +189,7 @@ export default function Module({ setTabNum }) {
onChange={(e) => setInputInstallHeight(e.target.value)} onChange={(e) => setInputInstallHeight(e.target.value)}
/> />
</div> </div>
<span className="thin">mm</span> <span className="thin">m</span>
</div> </div>
</div> </div>
</div> </div>
@ -226,7 +226,7 @@ export default function Module({ setTabNum }) {
onChange={(e) => setInputVerticalSnowCover(e.target.value)} onChange={(e) => setInputVerticalSnowCover(e.target.value)}
/> />
</div> </div>
<span className="thin">mm</span> <span className="thin">cm</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -10,7 +10,7 @@ const Placement = forwardRef((props, refs) => {
const [isChidori, setIsChidori] = useState(false) const [isChidori, setIsChidori] = useState(false)
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
const [setupLocation, setSetupLocation] = useState('center') const [setupLocation, setSetupLocation] = useState('eaves')
const [isMaxSetup, setIsMaxSetup] = useState('false') const [isMaxSetup, setIsMaxSetup] = useState('false')
const [selectedItems, setSelectedItems] = useState({}) const [selectedItems, setSelectedItems] = useState({})

View File

@ -21,6 +21,7 @@ import { selectedModuleState } from '@/store/selectedModuleOptions'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { stepUpListDataState } from '@/store/circuitTrestleAtom' import { stepUpListDataState } from '@/store/circuitTrestleAtom'
import { useEstimate } from '@/hooks/useEstimate'
const ALLOCATION_TYPE = { const ALLOCATION_TYPE = {
AUTO: 'auto', AUTO: 'auto',
@ -31,6 +32,7 @@ export default function CircuitTrestleSetting({ id }) {
const { closePopup } = usePopup() const { closePopup } = usePopup()
const { apply } = useTrestle() const { apply } = useTrestle()
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { saveEstimate } = useEstimate()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const [makers, setMakers] = useRecoilState(makersState) const [makers, setMakers] = useRecoilState(makersState)
@ -45,7 +47,7 @@ export default function CircuitTrestleSetting({ id }) {
const [circuitAllocationType, setCircuitAllocationType] = useState(1) const [circuitAllocationType, setCircuitAllocationType] = useState(1)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState) const selectedModules = useRecoilValue(selectedModuleState)
const { getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController() const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList } = useMasterController()
// () // ()
const [selectedStepUpValues, setSelectedStepUpValues] = useState({}) const [selectedStepUpValues, setSelectedStepUpValues] = useState({})
@ -61,6 +63,7 @@ export default function CircuitTrestleSetting({ id }) {
} }
}, []) }, [])
//
useEffect(() => { useEffect(() => {
if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) { if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) {
const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
@ -69,6 +72,7 @@ export default function CircuitTrestleSetting({ id }) {
} }
}, [tabNum]) }, [tabNum])
// PCS
const onAutoRecommend = () => { const onAutoRecommend = () => {
if (series.filter((s) => s.selected).length === 0) { if (series.filter((s) => s.selected).length === 0) {
swalFire({ swalFire({
@ -85,7 +89,9 @@ export default function CircuitTrestleSetting({ id }) {
pcsItemList: getPcsItemList(), pcsItemList: getPcsItemList(),
} }
//
if (selectedModels.length === 0) { if (selectedModels.length === 0) {
// PCS
getPcsAutoRecommendList(params).then((res) => { getPcsAutoRecommendList(params).then((res) => {
if (res.data?.pcsItemList) { if (res.data?.pcsItemList) {
const itemList = models.filter((model) => { const itemList = models.filter((model) => {
@ -98,15 +104,25 @@ export default function CircuitTrestleSetting({ id }) {
isUsed: false, isUsed: false,
} }
}) })
//
const pcsVoltageChkParams = { const pcsVoltageChkParams = {
...getOptYn(), ...getOptYn(),
useModuleItemList: getUseModuleItemList(), useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(), roofSurfaceList: getRoofSurfaceList(),
pcsItemList: getPcsItemList(), pcsItemList: getPcsItemList(),
} }
//
setSelectedModels(selectedModels) setSelectedModels(selectedModels)
//
getPcsVoltageChk(pcsVoltageChkParams).then((res) => { getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
if (res.resultCode === 'S') {
setTabNum(2) setTabNum(2)
} else {
swalFire({
title: res.resultMsg,
type: 'alert',
})
}
}) })
} else { } else {
// //
@ -124,12 +140,27 @@ export default function CircuitTrestleSetting({ id }) {
} }
}) })
} else { } else {
getPcsVoltageChk(params).then((res) => { //
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
if (res.resultCode === 'S') {
//
getPcsVoltageStepUpList({
...params,
pcsItemList: getSelectedPcsItemList(),
}).then((res) => {
setTabNum(2) setTabNum(2)
}) })
} else {
swalFire({
title: res.resultMsg,
type: 'alert',
})
}
})
} }
} }
// Y/N
const getOptYn = () => { const getOptYn = () => {
return { return {
maxConnYn: pcsCheck.max ? 'Y' : 'N', maxConnYn: pcsCheck.max ? 'Y' : 'N',
@ -138,6 +169,7 @@ export default function CircuitTrestleSetting({ id }) {
} }
} }
// PCS
const getPcsItemList = () => { const getPcsItemList = () => {
return models.map((model) => { return models.map((model) => {
return { return {
@ -148,6 +180,18 @@ export default function CircuitTrestleSetting({ id }) {
}) })
} }
// PCS
const getSelectedPcsItemList = () => {
return selectedModels.map((model) => {
return {
itemId: model.itemId,
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
}
})
}
//
const getUseModuleItemList = () => { const getUseModuleItemList = () => {
return selectedModules.itemList.map((m) => { return selectedModules.itemList.map((m) => {
return { return {
@ -157,6 +201,7 @@ export default function CircuitTrestleSetting({ id }) {
}) })
} }
//
const getRoofSurfaceList = () => { const getRoofSurfaceList = () => {
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) 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) roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
@ -180,6 +225,7 @@ export default function CircuitTrestleSetting({ id }) {
}) })
} }
//
const getModuleList = (surface) => { const getModuleList = (surface) => {
let moduleList = [] let moduleList = []
let [xObj, yObj] = [{}, {}] let [xObj, yObj] = [{}, {}]
@ -253,6 +299,40 @@ export default function CircuitTrestleSetting({ id }) {
return moduleList 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)
moduleMaxQty = selectedModels.reduce((acc, model) => {
return acc + parseInt(model.moduleMaxQty)
}, 0)
}
// const target = pcsCheck.max ? moduleMaxQty : moduleStdQty
// const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
// if (placementModules.length > target) {
// swalFire({
// title: ' . .',
// type: 'alert',
// })
// return
// }
// setAllocationType(ALLOCATION_TYPE.AUTO)
// setTabNum(2)
}
//
const onPassivityAllocation = () => { const onPassivityAllocation = () => {
if (selectedModels.length === 0) { if (selectedModels.length === 0) {
const params = { const params = {
@ -262,6 +342,7 @@ export default function CircuitTrestleSetting({ id }) {
pcsItemList: getPcsItemList(), pcsItemList: getPcsItemList(),
} }
//
getPcsAutoRecommendList(params).then((res) => { getPcsAutoRecommendList(params).then((res) => {
if (res.data?.pcsItemList) { if (res.data?.pcsItemList) {
const itemList = models.filter((model) => { const itemList = models.filter((model) => {
@ -273,22 +354,28 @@ export default function CircuitTrestleSetting({ id }) {
id: uuidv4(), id: uuidv4(),
} }
}) })
const PcsVoltageChkParams = { const pcsVoltageChkParams = {
...getOptYn(), ...getOptYn(),
useModuleItemList: getUseModuleItemList(), useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(), roofSurfaceList: getRoofSurfaceList(),
pcsItemList: getPcsItemList(), pcsItemList: getPcsItemList(),
} }
setSelectedModels(selectedModels) setSelectedModels(selectedModels)
getPcsVoltageChk(PcsVoltageChkParams).then((res) => {}) getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
})
} else { } else {
swalFire({ swalFire({
title: '파워컨디셔너를 추가해 주세요.', title: res.result.resultMsg,
type: 'alert', type: 'alert',
confirmFn: () => {
return
},
}) })
return
} }
}) })
} else if (pcsCheck.max) { } else {
const moduleStdQty = selectedModels.reduce((acc, model) => { const moduleStdQty = selectedModels.reduce((acc, model) => {
return acc + parseInt(model.moduleStdQty) return acc + parseInt(model.moduleStdQty)
}, 0) }, 0)
@ -306,10 +393,10 @@ export default function CircuitTrestleSetting({ id }) {
}) })
return return
} }
}
setAllocationType(ALLOCATION_TYPE.PASSIVITY) setAllocationType(ALLOCATION_TYPE.PASSIVITY)
} }
}
// StepUp // StepUp
const handleStepUpValuesSelected = (selectionData) => { const handleStepUpValuesSelected = (selectionData) => {
@ -336,8 +423,10 @@ export default function CircuitTrestleSetting({ id }) {
}) })
const result = await apply() const result = await apply()
if (result) {
await saveEstimate(result)
}
removeNotAllocationModules() removeNotAllocationModules()
apply()
} }
const removeNotAllocationModules = () => { const removeNotAllocationModules = () => {
@ -346,6 +435,7 @@ export default function CircuitTrestleSetting({ id }) {
canvas.renderAll() canvas.renderAll()
} }
//
const onClickPrev = () => { const onClickPrev = () => {
setAllocationType(ALLOCATION_TYPE.AUTO) setAllocationType(ALLOCATION_TYPE.AUTO)
swalFire({ swalFire({
@ -367,6 +457,7 @@ export default function CircuitTrestleSetting({ id }) {
}) })
} }
//
const powerConditionalSelectProps = { const powerConditionalSelectProps = {
tabNum, tabNum,
setTabNum, setTabNum,
@ -383,6 +474,7 @@ export default function CircuitTrestleSetting({ id }) {
managementState, managementState,
} }
//
const passivityProps = { const passivityProps = {
tabNum, tabNum,
setTabNum, setTabNum,
@ -394,13 +486,18 @@ export default function CircuitTrestleSetting({ id }) {
getRoofSurfaceList, getRoofSurfaceList,
} }
//
const stepUpProps = { const stepUpProps = {
tabNum, tabNum,
setTabNum, setTabNum,
models, models,
setModels, setModels,
allocationType,
circuitAllocationType, circuitAllocationType,
setCircuitAllocationType, setCircuitAllocationType,
selectedModels,
setSelectedModels,
getSelectedPcsItemList,
getOptYn, // Y/N getOptYn, // Y/N
getUseModuleItemList, // List getUseModuleItemList, // List
getRoofSurfaceList, // getRoofSurfaceList, //
@ -410,8 +507,10 @@ export default function CircuitTrestleSetting({ id }) {
setStepUpListData, setStepUpListData,
seletedOption, seletedOption,
setSeletedOption, setSeletedOption,
getModuleList,
} }
//
const getStepUpListData = () => { const getStepUpListData = () => {
return stepUpListData[0].pcsItemList.map((item) => { return stepUpListData[0].pcsItemList.map((item) => {
return item.serQtyList return item.serQtyList
@ -422,7 +521,6 @@ export default function CircuitTrestleSetting({ id }) {
pcsSerCd: item.pcsSerCd, pcsSerCd: item.pcsSerCd,
pcsItemId: item.itemId, pcsItemId: item.itemId,
pscOptCd: seletedOption.code, pscOptCd: seletedOption.code,
// pcsOptCd: 'CLC_RMC',
paralQty: serQty.paralQty, paralQty: serQty.paralQty,
connections: [ connections: [
{ {
@ -434,12 +532,65 @@ export default function CircuitTrestleSetting({ id }) {
}) })
} }
//
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)
swalFire({
title: '변경사항을 저장하시겠습니까?',
//text: ' .',
type: 'confirm',
confirmButtonText: '저장',
cancelButtonText: '취소',
icon: 'warning',
confirmFn: async () => {
//
await onApply()
closePopup(id)
},
denyFn: () => {
//
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 ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: 230 }}> <WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
<div className={`modal-pop-wrap l-2`}> <div className={`modal-pop-wrap l-2`}>
<div className="modal-head modal-handle"> <div className="modal-head modal-handle">
<h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1> <h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}> {/* <button className="modal-close" onClick={() => closePopup(id)}> */}
<button className="modal-close" onClick={handleClose}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -10,16 +10,29 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom' import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { globalLocaleStore } from '@/store/localeAtom'
import { POLYGON_TYPE } from '@/common/common'
export default function StepUp(props) { export default function StepUp(props) {
const { stepUpListData, setStepUpListData, seletedOption, setSeletedOption } = props const {
models,
allocationType,
stepUpListData,
setStepUpListData,
seletedOption,
setSeletedOption,
selectedModels,
setSelectedModels,
getSelectedPcsItemList,
getModuleList,
} = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const globalLocale = useRecoilValue(globalLocaleStore)
const [moduleTab, setModuleTab] = useState(1) const [moduleTab, setModuleTab] = useState(1)
const [moduleTabs, setModuleTabs] = useState({}) const [moduleTabs, setModuleTabs] = useState({})
const [arrayLength, setArrayLength] = useState(3) //module-table-inner const [arrayLength, setArrayLength] = useState(3) //module-table-inner
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState) const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
const { models } = props const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()
const { getPcsVoltageStepUpList, getPcsAutoRecommendList } = useMasterController()
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const selectedModules = useRecoilValue(selectedModuleState) const selectedModules = useRecoilValue(selectedModuleState)
@ -39,23 +52,36 @@ export default function StepUp(props) {
useEffect(() => { useEffect(() => {
// PCS // PCS
if (allocationType === 'auto') {
fetchStepUpData() fetchStepUpData()
} else {
// 1-1 2-2
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
.map((module) => module.circuitNumber)
}
}, []) }, [])
// PCS // PCS
const fetchStepUpData = async () => { const fetchStepUpData = async () => {
try { try {
const params = { const params = {
useYn: props.getOptYn(), // Y/N ...props.getOptYn(), // Y/N
useModuleItemList: props.getUseModuleItemList(), // List useModuleItemList: props.getUseModuleItemList(), // List
roofSurfaceList: props.getRoofSurfaceList(), // roofSurfaceList: props.getRoofSurfaceList(), //
pcsItemList: props.getPcsItemList(), // PCS pcsItemList: selectedModels.length === 0 ? props.getPcsItemList() : getSelectedPcsItemList(), // PCS
} }
// PCS //
const res = await getPcsVoltageStepUpList(params) getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
if (res.resultCode === 'S') {
//
getPcsVoltageStepUpList(params).then((res) => {
if (res?.result.code === 200 && res?.data) { if (res?.result.code === 200 && res?.data) {
if (selectedModels.length === 0) {
setSelectedModels(res.data.pcsItemList)
}
const dataArray = Array.isArray(res.data) ? res.data : [res.data] const dataArray = Array.isArray(res.data) ? res.data : [res.data]
const stepUpListData = formatStepUpListData(dataArray) const stepUpListData = formatStepUpListData(dataArray)
@ -67,6 +93,14 @@ export default function StepUp(props) {
setOptCodes(formattedOptCodes) setOptCodes(formattedOptCodes)
setSeletedOption(formattedOptCodes[0]) setSeletedOption(formattedOptCodes[0])
} }
})
} else {
swalFire({
title: res.resultMsg,
type: 'alert',
})
}
})
} catch (error) { } catch (error) {
console.error('Error fetching step up data:', error) console.error('Error fetching step up data:', error)
} }
@ -121,6 +155,7 @@ export default function StepUp(props) {
}) })
}) })
// selectedValues
setSelectedValues(initialSelectedValues) setSelectedValues(initialSelectedValues)
return formattedData return formattedData
@ -212,17 +247,57 @@ export default function StepUp(props) {
} }
item.selected = index === subIdx item.selected = index === subIdx
}) })
//
setStepUpListData(tempStepUpListData) setStepUpListData(tempStepUpListData)
console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData) console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData)
console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData) console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData)
//
const params = {
...props.getOptYn(), // Y/N
useModuleItemList: props.getUseModuleItemList(), // List
roofSurfaceList: props.getRoofSurfaceList(), //
pcsItemList: props.getSelectedPcsItemList().map((pcsItem) => {
// PCS
// tempStepUpListData PCS
const matchingPcsItem = tempStepUpListData[0].pcsItemList.find((item) => item.pcsId === pcsItem.pcsId && item.itemId === pcsItem.itemId)
// serQty
const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0
return {
...pcsItem,
applySerQty: selectedSerQty,
}
}),
}
// 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) => { selectedData.roofSurfaceList.forEach((roofSurface) => {
const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0]
const moduleIds = targetSurface.modules.map((module) => { const moduleIds = targetSurface.modules.map((module) => {
return module.id return module.id
}) })
//
canvas canvas
.getObjects() .getObjects()
.filter((obj) => moduleIds.includes(obj.parentId)) .filter((obj) => moduleIds.includes(obj.parentId))
@ -230,7 +305,9 @@ export default function StepUp(props) {
canvas.remove(text) canvas.remove(text)
}) })
//
canvas.renderAll() canvas.renderAll()
roofSurface.moduleList.forEach((module) => { roofSurface.moduleList.forEach((module) => {
const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0]
const moduleCircuitText = new fabric.Text(module.circuit, { const moduleCircuitText = new fabric.Text(module.circuit, {
@ -415,8 +492,11 @@ export default function StepUp(props) {
<div className="grid-select mr10"> <div className="grid-select mr10">
{/* <QSelectBox title={'電力検出ユニット (モニター付き)'} /> */} {/* <QSelectBox title={'電力検出ユニット (モニター付き)'} /> */}
<QSelectBox <QSelectBox
options={optCodes} //options={optCodes}
title={optCodes[0].name} options={optCodes.map((roof) => {
return { ...roof, name: globalLocale === 'ko' ? roof.name : roof.nameJp }
})}
title={globalLocale === 'ko' ? optCodes[0].name : optCodes[0].nameJp}
value={seletedOption} value={seletedOption}
sourceKey="code" sourceKey="code"
targetKey="code" targetKey="code"

View File

@ -1,6 +1,7 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider' import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { useModule } from '@/hooks/module/useModule'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
@ -11,37 +12,29 @@ import { useRecoilState, useRecoilValue } from 'recoil'
export default function PassivityCircuitAllocation(props) { export default function PassivityCircuitAllocation(props) {
const { const {
tabNum,
setTabNum,
selectedModels, selectedModels,
setSelectedModels, setSelectedModels,
getOptYn: getApiProps, getOptYn: getApiProps,
getUseModuleItemList: getSelectedModuleList, getUseModuleItemList: getSelectedModuleList,
getSelectModelList: getSelectModelList, getSelectModelList: getSelectModelList,
getRoofSurfaceList,
getModelList,
} = props } = props
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState) const selectedModules = useRecoilValue(selectedModuleState)
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
// const [totalWpout, setTotalWpout] = useState(0)
const [selectedPcs, setSelectedPcs] = useState(selectedModels[0]) const [selectedPcs, setSelectedPcs] = useState(selectedModels[0])
// const { header, rows: row } = moduleStatistics const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const [header, setHeader] = useState(moduleStatistics.header)
const [rows, setRows] = useState(moduleStatistics.rows)
const [footer, setFooter] = useState(['합계'])
const [circuitNumber, setCircuitNumber] = useState(1) const [circuitNumber, setCircuitNumber] = useState(1)
const [targetModules, setTargetModules] = useState([]) const [targetModules, setTargetModules] = useState([])
const { setModuleStatisticsData } = useModule()
const { getPcsManualConfChk } = useMasterController() const { getPcsManualConfChk } = useMasterController()
useEffect(() => { useEffect(() => {
console.log('header, rows', header, rows) console.log('header, rows', header, rows)
console.log('selectedModels', selectedModels) console.log('selectedModels', selectedModels)
// setSurfaceInfo() // setSurfaceInfo()
setTableData() setModuleStatisticsData()
if (!managementState) { if (!managementState) {
setManagementState(managementStateLoaded) setManagementState(managementStateLoaded)
} }
@ -158,7 +151,14 @@ export default function PassivityCircuitAllocation(props) {
} }
const handleCircuitNumberFix = () => { 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) { if (!circuitNumber || circuitNumber === 0) {
swalFire({ swalFire({
text: '회로번호를 1 이상입력해주세요.', text: '회로번호를 1 이상입력해주세요.',
@ -174,15 +174,6 @@ export default function PassivityCircuitAllocation(props) {
}) })
return return
} else if (selectedModels.length > 1) { } 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 let result = false
uniqueCircuitNumbers.forEach((number) => { uniqueCircuitNumbers.forEach((number) => {
if ( if (
@ -335,7 +326,7 @@ export default function PassivityCircuitAllocation(props) {
setTargetModules([]) setTargetModules([])
setCircuitNumber(+circuitNumber + 1) setCircuitNumber(+circuitNumber + 1)
setTableData() setModuleStatisticsData()
}) })
} }
@ -347,100 +338,6 @@ 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 = () => { const initSelectedPcsCircuitNumber = () => {
swalFire({ swalFire({
title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'), title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'),
@ -516,9 +413,7 @@ export default function PassivityCircuitAllocation(props) {
<tr> <tr>
{header.map((header, i) => ( {header.map((header, i) => (
<td className="al-c" key={'footer' + i}> <td className="al-c" key={'footer' + i}>
{typeof footer[header.prop] === 'number' {footer[header.prop]}
? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 })
: footer[header.prop]}
</td> </td>
))} ))}
</tr> </tr>

View File

@ -45,6 +45,8 @@ export default function ContextRoofAllocationSetting(props) {
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lr mount`}> <div className={`modal-pop-wrap lr mount`}>
{currentRoofList && (
<>
<div className="modal-head modal-handle"> <div className="modal-head modal-handle">
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1> <h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
<button className="modal-close" onClick={() => closePopup(id)}> <button className="modal-close" onClick={() => closePopup(id)}>
@ -78,9 +80,9 @@ export default function ContextRoofAllocationSetting(props) {
{getMessage('modal.common.add')} {getMessage('modal.common.add')}
</button> </button>
</div> </div>
<div className="grid-option-overflow">
<div className="grid-option-wrap"> <div className="grid-option-wrap">
{currentRoofList.length > 0 && {currentRoofList.map((roof, index) => {
currentRoofList.map((roof, index) => {
return ( return (
<div className="grid-option-box" key={index}> <div className="grid-option-box" key={index}>
<div className="d-check-radio pop no-text"> <div className="d-check-radio pop no-text">
@ -95,7 +97,7 @@ export default function ContextRoofAllocationSetting(props) {
<div className="grid-option-block-form"> <div className="grid-option-block-form">
<div className="block-box"> <div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<div className="grid-select" style={{ width: '248px' }}> <div className="grid-select">
<QSelectBox <QSelectBox
options={roofMaterials} options={roofMaterials}
value={roof} value={roof}
@ -105,14 +107,18 @@ export default function ContextRoofAllocationSetting(props) {
onChange={(e) => handleChangeRoofMaterial(e, index)} onChange={(e) => handleChangeRoofMaterial(e, index)}
/> />
</div> </div>
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>} {index === 0 && <span className="absol dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>} {index !== 0 && (
<span className="absol">
<button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>
</span>
)}
</div> </div>
</div> </div>
<div className="block-box"> <div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>{getMessage('slope')}</span> <span>{getMessage('slope')}</span>
<div className="input-grid" style={{ width: '214px' }}> <div className="input-grid">
<input <input
type="text" type="text"
className="input-origin block" className="input-origin block"
@ -122,37 +128,41 @@ export default function ContextRoofAllocationSetting(props) {
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle} defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/> />
</div> </div>
<span>{pitchText}</span> <span className="absol">{pitchText}</span>
</div> </div>
</div> </div>
{(roof.widAuth || roof.lenAuth) && ( {(roof.widAuth || roof.lenAuth) && (
<div className="block-box"> <>
{roof.widAuth && ( {roof.widAuth && (
<div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>W</span> <span>W</span>
<div className="input-grid" style={{ width: '100px' }}> <div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} /> <input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
</div> </div>
</div> </div>
</div>
)} )}
{roof.lenAuth && ( {roof.lenAuth && (
<div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>L</span> <span>L</span>
<div className="input-grid" style={{ width: '100px' }}> <div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} /> <input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
</div> </div>
</div> </div>
)}
</div> </div>
)} )}
</>
)}
{(roof.raftAuth || roof.roofPchAuth) && ( {(roof.raftAuth || roof.roofPchAuth) && (
<div className="block-box"> <>
{roof.raftAuth && ( {roof.raftAuth && (
<div className="block-box"> <div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span> <span>{getMessage('modal.placement.initial.setting.rafter')}</span>
{raftCodes.length > 0 && ( {raftCodes.length > 0 && (
<div className="grid-select" style={{ width: '160px' }}> <div className="grid-select">
<QSelectBox <QSelectBox
options={raftCodes} options={raftCodes}
value={roof} value={roof}
@ -169,7 +179,7 @@ export default function ContextRoofAllocationSetting(props) {
<div className="block-box"> <div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>{getMessage('hajebichi')}</span> <span>{getMessage('hajebichi')}</span>
<div className="input-grid" style={{ width: '84px' }}> <div className="input-grid">
<input <input
type="text" type="text"
className="input-origin block" className="input-origin block"
@ -180,7 +190,7 @@ export default function ContextRoofAllocationSetting(props) {
</div> </div>
</div> </div>
)} )}
</div> </>
)} )}
<div className="block-box"> <div className="block-box">
<div className="icon-btn-wrap"> <div className="icon-btn-wrap">
@ -208,12 +218,15 @@ export default function ContextRoofAllocationSetting(props) {
) )
})} })}
</div> </div>
</div>
<div className="grid-btn-wrap"> <div className="grid-btn-wrap">
<button className="btn-frame modal act" onClick={handleSaveContext}> <button className="btn-frame modal act" onClick={handleSaveContext}>
{getMessage('modal.roof.alloc.apply')} {getMessage('modal.roof.alloc.apply')}
</button> </button>
</div> </div>
</div> </div>
</>
)}
<div className="modal-foot modal-handle"></div> <div className="modal-foot modal-handle"></div>
</div> </div>
</WithDraggable> </WithDraggable>

View File

@ -411,11 +411,12 @@ export default function StuffDetail() {
if (session?.storeId === 'T01') { if (session?.storeId === 'T01') {
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}` url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
} else { } else {
if (session.storeLvl === '1') { // 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}` 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}`
}
} }
get({ url: url }).then((res) => { get({ url: url }).then((res) => {
@ -523,11 +524,12 @@ export default function StuffDetail() {
if (session?.storeId === 'T01') { if (session?.storeId === 'T01') {
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}` url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
} else { } else {
if (session.storeLvl === '1') { // 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}` 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}`
}
} }
get({ url: url }).then((res) => { get({ url: url }).then((res) => {
if (!isEmptyArray(res)) { if (!isEmptyArray(res)) {

View File

@ -474,12 +474,13 @@ export default function StuffSearchCondition() {
//T01 //T01
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}` url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
} else { } else {
if (session.storeLvl === '1') { // if (session.storeLvl === '1') {
//T01 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}` 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}`
}
} }
get({ url: url }).then((res) => { get({ url: url }).then((res) => {

View File

@ -201,13 +201,22 @@ export function useMasterController() {
* @returns * @returns
*/ */
const getPcsVoltageStepUpList = async (params2 = null) => { 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 = { const params = {
...params2, ...params2,
maxConnYn: params2.useYn.maxConnYn, maxConnYn: params2.maxConnYn,
smpCirYn: params2.useYn.smpCirYn, smpCirYn: params2.smpCirYn,
coldZoneYn: params2.useYn.coldZoneYn, coldZoneYn: params2.coldZoneYn,
useModuleItemList: params2.useModuleItemList, useModuleItemList: params2.useModuleItemList,
roofSurfaceList: params2.roofSurfaceList, roofSurfaceList: modifiedRoofSurfaceList,
pcsItemList: params2.pcsItemList, pcsItemList: params2.pcsItemList,
} }

View File

@ -80,7 +80,6 @@ export const useEstimateController = (planNo) => {
res.data.pkgAsp = roundedNumber.toString() res.data.pkgAsp = roundedNumber.toString()
} }
setEstimateContextState(res.data) setEstimateContextState(res.data)
} }
} }
@ -155,7 +154,7 @@ export const useEstimateController = (planNo) => {
}) })
.catch((error) => { .catch((error) => {
console.log('::FileDownLoad Error::', 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) { if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) {
flag = false flag = false
setIsGlobalLoading(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) { if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) {
flag = false flag = false
setIsGlobalLoading(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))) { if (isNaN(Date.parse(estimateData.estimateDate))) {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredEstimateDate')) return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert' })
} }
if (estimateData.estimateType === 'YJSS') { if (estimateData.estimateType === 'YJSS') {
@ -189,7 +188,7 @@ export const useEstimateController = (planNo) => {
if (pkgAsp === '0') { if (pkgAsp === '0') {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredPkgAsp')) return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert' })
} }
} }
@ -209,6 +208,14 @@ export const useEstimateController = (planNo) => {
//기존에 첨부된 파일이 없으면 //기존에 첨부된 파일이 없으면
if (isEmptyArray(estimateData.newFileList)) { if (isEmptyArray(estimateData.newFileList)) {
//새로 첨부한 파일이 없으면 //새로 첨부한 파일이 없으면
//북면 먼저 체크
if (estimateData?.northArrangement === '1') {
fileFlg = false
setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert' })
}
if (estimateData.itemList.length > 1) { if (estimateData.itemList.length > 1) {
estimateData.itemList.map((row) => { estimateData.itemList.map((row) => {
if (row.delFlg === '0') { if (row.delFlg === '0') {
@ -217,7 +224,7 @@ export const useEstimateController = (planNo) => {
if (estimateData.fileFlg === '0') { if (estimateData.fileFlg === '0') {
fileFlg = false fileFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredFileUpload')) return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert' })
} }
} }
} }
@ -235,7 +242,7 @@ export const useEstimateController = (planNo) => {
if (item.itemId === '') { if (item.itemId === '') {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredItemId')) return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert' })
} }
} }
@ -251,7 +258,7 @@ export const useEstimateController = (planNo) => {
if (item.amount < 1) { if (item.amount < 1) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredAmount')) return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert' })
} }
if (estimateData.estimateType !== 'YJSS') { if (estimateData.estimateType !== 'YJSS') {
@ -263,7 +270,7 @@ export const useEstimateController = (planNo) => {
if (item.salePrice < 1) { if (item.salePrice < 1) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredSalePrice')) return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
} }
} }
@ -274,7 +281,7 @@ export const useEstimateController = (planNo) => {
if (isNaN(item.salePrice)) { if (isNaN(item.salePrice)) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredSalePrice')) return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
} }
} }
} }
@ -292,7 +299,7 @@ export const useEstimateController = (planNo) => {
}) })
if (delCnt === estimateData.itemList.length) { if (delCnt === estimateData.itemList.length) {
setIsGlobalLoading(false) setIsGlobalLoading(false)
return alert(getMessage('estimate.detail.save.requiredItem')) return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert' })
} }
} }

View File

@ -1,12 +1,14 @@
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common' import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util' import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
import { useRecoilValue } from 'recoil' import { useRecoilValue, useSetRecoilState } from 'recoil'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import { useSwal } from '../useSwal' import { useSwal } from '../useSwal'
import { useModuleBasicSetting } from './useModuleBasicSetting' import { useModuleBasicSetting } from './useModuleBasicSetting'
import { useMessage } from '../useMessage' import { useMessage } from '../useMessage'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
export const MODULE_REMOVE_TYPE = { export const MODULE_REMOVE_TYPE = {
LEFT: 'left', LEFT: 'left',
@ -35,6 +37,8 @@ export function useModule() {
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { checkModuleDisjointObjects } = useModuleBasicSetting() const { checkModuleDisjointObjects } = useModuleBasicSetting()
const selectedModules = useRecoilValue(selectedModuleState)
const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
const moduleMove = (length, direction) => { const moduleMove = (length, direction) => {
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴 const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
@ -929,6 +933,92 @@ export function useModule() {
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name)) .filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
} }
const setModuleStatisticsData = () => {
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)
const rows = surfaces.map((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: parseInt((surfaceObjects[key].wpOut / 1000).toFixed(3)),
}
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: parseInt((surfaceObjects[key].circuits[circuit].circuits.wpOut / 1000).toFixed(3)),
}
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)
})
setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
}
return { return {
moduleMove, moduleMove,
moduleMultiMove, moduleMultiMove,
@ -942,5 +1032,6 @@ export function useModule() {
muduleRowInsert, muduleRowInsert,
modulesRemove, modulesRemove,
alignModule, alignModule,
setModuleStatisticsData,
} }
} }

View File

@ -324,6 +324,18 @@ export function useModuleBasicSetting(tabNum) {
}) })
} }
useEffect(() => {
console.log('리코일 바뀌냐??')
console.log('isManualModuleSetup', isManualModuleSetup)
console.log('saleStoreNorthFlg', saleStoreNorthFlg)
if (moduleSelectionData.common.saleStoreNorthFlg === '1') {
setSaleStoreNorthFlg(true)
}
manualModuleSetup()
}, [isManualModuleSetup])
/** /**
* trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 진입여부를 확인 * trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 진입여부를 확인
* 확인 셀을 이동시킴 * 확인 셀을 이동시킴
@ -364,7 +376,7 @@ export function useModuleBasicSetting(tabNum) {
lockRotation: true, // 회전 잠금 lockRotation: true, // 회전 잠금
lockScalingX: true, // X 축 크기 조정 잠금 lockScalingX: true, // X 축 크기 조정 잠금
lockScalingY: true, // Y 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금
name: 'module', name: POLYGON_TYPE.MODULE,
} }
if (moduleSetupSurfaces.length !== 0) { if (moduleSetupSurfaces.length !== 0) {
@ -429,6 +441,10 @@ export function useModuleBasicSetting(tabNum) {
parentId: moduleSetupSurfaces[i].parentId, parentId: moduleSetupSurfaces[i].parentId,
}) })
console.log('trestlePolygon', trestlePolygon)
console.log('saleStoreNorthFlg', saleStoreNorthFlg)
console.log('trestlePolygon.isNorth', trestlePolygon.isNorth)
//북면이고 북면설치상점이 아니면 그냥 return //북면이고 북면설치상점이 아니면 그냥 return
if (trestlePolygon.isNorth && !saleStoreNorthFlg) { if (trestlePolygon.isNorth && !saleStoreNorthFlg) {
return return
@ -646,6 +662,7 @@ export function useModuleBasicSetting(tabNum) {
}) })
} }
} else { } else {
if (moduleSetupSurfaces) {
//수동모드 해제시 모듈 설치면 선택 잠금 //수동모드 해제시 모듈 설치면 선택 잠금
moduleSetupSurfaces.forEach((obj) => { moduleSetupSurfaces.forEach((obj) => {
obj.set({ obj.set({
@ -653,6 +670,7 @@ export function useModuleBasicSetting(tabNum) {
evented: true, evented: true,
}) })
}) })
}
removeMouseEvent('mouse:up') removeMouseEvent('mouse:up')
removeMouseEvent('mouse:move') removeMouseEvent('mouse:move')
@ -1693,7 +1711,7 @@ export function useModuleBasicSetting(tabNum) {
lockScalingY: true, // Y 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금
parentId: moduleSetupSurface.parentId, parentId: moduleSetupSurface.parentId,
surfaceId: moduleSetupSurface.id, surfaceId: moduleSetupSurface.id,
name: 'module', name: POLYGON_TYPE.MODULE,
} }
if (moduleSetupSurfaces.length !== 0) { if (moduleSetupSurfaces.length !== 0) {
@ -2102,7 +2120,7 @@ export function useModuleBasicSetting(tabNum) {
lockScalingY: true, // Y 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금
parentId: moduleSetupSurface.parentId, parentId: moduleSetupSurface.parentId,
surfaceId: moduleSetupSurface.id, surfaceId: moduleSetupSurface.id,
name: 'module', name: POLYGON_TYPE.MODULE,
} }
let leftMargin, bottomMargin, square let leftMargin, bottomMargin, square
@ -2450,7 +2468,7 @@ export function useModuleBasicSetting(tabNum) {
...surface, ...surface,
name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면 name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면
// powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }), // powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }),
wpOut: wpOut, wpOut: (wpOut / 1000).toFixed(3),
} }
}) })
@ -2463,7 +2481,7 @@ export function useModuleBasicSetting(tabNum) {
}), }),
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' }, { name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
] ]
let footer = ['합계'] let footer = [getMessage('modal.panel.batch.statistic.total')]
let footerData = {} let footerData = {}
rows.forEach((row) => { rows.forEach((row) => {
Object.keys(moduleInfo).map((key) => { Object.keys(moduleInfo).map((key) => {
@ -2474,7 +2492,7 @@ export function useModuleBasicSetting(tabNum) {
Object.keys(footerData).forEach((key) => { Object.keys(footerData).forEach((key) => {
footer.push(footerData[key]) footer.push(footerData[key])
}) })
footer.push(totalWpout) footer.push((totalWpout / 1000).toFixed(3))
console.log({ header: header, rows, footer: footer }) console.log({ header: header, rows, footer: footer })
setModuleStatistics({ header: header, rows, footer: footer }) setModuleStatistics({ header: header, rows, footer: footer })
} }

View File

@ -89,11 +89,12 @@ export function useModuleSelection(props) {
getModuleData(roofsIds) getModuleData(roofsIds)
//메뉴 이동시 배치면 삭제 //해당 메뉴 이동시 배치면 삭제
const moduleSurfacesArray = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const moduleSurfacesArray = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE)
if (moduleSurfacesArray.length > 0) { if (moduleSurfacesArray.length > 0) {
moduleSurfacesArray.forEach((moduleSurface) => { moduleSurfacesArray.forEach((moduleSurface) => {
moduleSurface.module = []
canvas.remove(moduleSurface) canvas.remove(moduleSurface)
}) })
canvas.renderAll() canvas.renderAll()

View File

@ -1,18 +1,16 @@
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom' import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util' import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { estimateParamAtom } from '@/store/estimateAtom'
// 회로 및 가대설정 // 회로 및 가대설정
export const useTrestle = () => { export const useTrestle = () => {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
const { getQuotationItem } = useMasterController() const { getQuotationItem } = useMasterController()
const [estimateParam, setEstimateParam] = useRecoilState(estimateParamAtom)
const currentAngleType = useRecoilValue(currentAngleTypeSelector) const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const apply = () => { const apply = () => {
@ -41,6 +39,7 @@ export const useTrestle = () => {
return return
} }
const plvrYn = construction.plvrYn
let moduleRowsTotCnt = 0 let moduleRowsTotCnt = 0
let isEaveBar = construction.setupCover let isEaveBar = construction.setupCover
let isSnowGuard = construction.setupSnowCover let isSnowGuard = construction.setupSnowCover
@ -102,6 +101,14 @@ export const useTrestle = () => {
leftExposedHalfTopModules.length > 0 || leftExposedHalfTopModules.length > 0 ||
rightExposedHalfTopPoints.length > 0 rightExposedHalfTopPoints.length > 0
console.log('isChidory', isChidory)
if (plvrYn === 'N' && isChidory) {
alert('치조불가공법입니다.')
clear()
throw new Error('치조불가공법입니다.')
}
surface.set({ isChidory: isChidory }) surface.set({ isChidory: isChidory })
canvas canvas
@ -210,6 +217,10 @@ export const useTrestle = () => {
let findLeft = true let findLeft = true
let findRight = true let findRight = true
let leftFindModuleList = [module]
let rightFindModuleList = [module]
let centerFindModuleList = [module]
//우선 절반을 나눈 뒤 왼쪽부터 찾는다. //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
while (hasNextModule) { while (hasNextModule) {
//바로 위에 있는지 확인한다. //바로 위에 있는지 확인한다.
@ -218,6 +229,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
leftRows++ leftRows++
leftFindModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -233,6 +245,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
leftRows++ leftRows++
leftFindModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -253,6 +266,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
rightRows++ rightRows++
rightFindModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -268,6 +282,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
rightRows++ rightRows++
rightFindModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -287,6 +302,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
centerFindModuleList.push(nextModule)
centerRows++ centerRows++
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
@ -295,19 +311,77 @@ export const useTrestle = () => {
} }
} }
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) => { const leftRacks = rackInfos.find((rack) => {
return rack.value.moduleRows === leftRows 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 })?.value.racks
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다. // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
const rightRacks = rackInfos.find((rack) => { const rightRacks = rackInfos.find((rack) => {
return rack.value.moduleRows === rightRows 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 })?.value.racks
// 해당 rack으로 그려준다. // 해당 rack으로 그려준다.
const centerRacks = rackInfos.find((rack) => { const centerRacks = rackInfos.find((rack) => {
return rack.value.moduleRows === centerRows 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 })?.value.racks
mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule) mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule)
@ -336,6 +410,7 @@ export const useTrestle = () => {
let leftRows = 1 let leftRows = 1
let hasNextModule = true let hasNextModule = true
let findLeft = true let findLeft = true
let findModuleList = [module]
//우선 절반을 나눈 뒤 왼쪽부터 찾는다. //우선 절반을 나눈 뒤 왼쪽부터 찾는다.
while (hasNextModule) { while (hasNextModule) {
@ -345,6 +420,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
leftRows++ leftRows++
findModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -371,6 +447,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
leftRows++ leftRows++
findModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -379,10 +456,30 @@ export const useTrestle = () => {
} }
} }
const leftModuleInfos = findModuleList.map((module) => {
return {
moduleTpCd: module.moduleInfo.moduleTpCd,
}
})
const leftRowsInfo = moduleTransformData(leftModuleInfos)
// 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다. // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
const leftRacks = rackInfos.find((rack) => { const leftRacks = rackInfos.find((rack) => {
return rack.value.moduleRows === leftRows 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 })?.value.racks
mostRowsModule = Math.max(leftRows, mostRowsModule) mostRowsModule = Math.max(leftRows, mostRowsModule)
if (rackYn === 'Y') { if (rackYn === 'Y') {
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn) drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
@ -400,6 +497,7 @@ export const useTrestle = () => {
let rightRows = 1 let rightRows = 1
let hasNextModule = true let hasNextModule = true
let findRight = true let findRight = true
let findModuleList = [module]
// 오른쪽 찾는다. // 오른쪽 찾는다.
while (hasNextModule) { while (hasNextModule) {
@ -409,6 +507,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
rightRows++ rightRows++
findModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -424,6 +523,7 @@ export const useTrestle = () => {
if (nextModule) { if (nextModule) {
// 바로 위 모듈을 찾는다. // 바로 위 모듈을 찾는다.
rightRows++ rightRows++
findModuleList.push(nextModule)
x = nextModule.x x = nextModule.x
y = nextModule.y y = nextModule.y
} else { } else {
@ -432,11 +532,30 @@ export const useTrestle = () => {
} }
} }
const rightRowsInfos = findModuleList.map((module) => {
return {
moduleTpCd: module.moduleInfo.moduleTpCd,
}
})
const rightRowsInfo = moduleTransformData(rightRowsInfos)
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다. // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
const rightRacks = rackInfos.find((rack) => { const rightRacks = rackInfos.find((rack) => {
return rack.value.moduleRows === rightRows 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 })?.value.racks
mostRowsModule = Math.max(rightRows, mostRowsModule) mostRowsModule = Math.max(rightRows, mostRowsModule)
// 해당 rack으로 그려준다. // 해당 rack으로 그려준다.
if (rackYn === 'Y') { if (rackYn === 'Y') {
@ -462,10 +581,24 @@ export const useTrestle = () => {
return setEstimateData() return setEstimateData()
} catch (e) { } catch (e) {
return false return null
} }
} }
//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에 저장 // itemList 조회 후 estimateParam에 저장
const setEstimateData = async () => { const setEstimateData = async () => {
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
@ -480,7 +613,7 @@ export const useTrestle = () => {
//견적서 itemList 조회 //견적서 itemList 조회
const res = await getQuotationItem(params) const res = await getQuotationItem(params)
if (!res.data) { if (!res.data) {
return false return null
} }
const itemList = res.data const itemList = res.data
//northArrangement 북면 설치 여부 //northArrangement 북면 설치 여부
@ -540,10 +673,10 @@ export const useTrestle = () => {
} }
}) })
setEstimateParam({ ...estimateParam, itemList, northArrangement, roofSurfaceList, circuitItemList }) const estimateParam = { itemList, northArrangement, roofSurfaceList, circuitItemList }
// 정상적으로 완료 되면 true 반환 // 정상적으로 완료 되면 true 반환
return true return estimateParam
} }
const getNorthArrangement = () => { const getNorthArrangement = () => {
@ -565,9 +698,11 @@ export const useTrestle = () => {
} }
const findNextModule = (currentPoint, centerPoints, direction) => { const findNextModule = (currentPoint, centerPoints, direction) => {
let { x, y, width, height, horizontal, vertical } = { ...currentPoint } let { x, y, horizontal, vertical } = { ...currentPoint }
width = width + horizontal let { widthArr, heightArr } = centerPoints[0]
height = height + vertical
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 maxX = 2 + horizontal * 3
let maxY = 2 + vertical * 3 let maxY = 2 + vertical * 3
@ -596,7 +731,11 @@ export const useTrestle = () => {
} }
const findNextLeftModule = (currentPoint, centerPoints, direction) => { 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 result
let topLeftPoint let topLeftPoint
@ -631,9 +770,11 @@ export const useTrestle = () => {
return result return result
} }
const findNextRightModule = (currentPoint, centerPoints, direction) => { const findNextRightModule = (currentPoint, centerPoints, direction) => {
let { x, y, width, height, horizontal, vertical } = { ...currentPoint } let { x, y, horizontal, vertical } = { ...currentPoint }
width = width + horizontal let { widthArr, heightArr } = centerPoints[0]
height = height + vertical
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 result
let topRightPoint let topRightPoint
@ -665,6 +806,9 @@ export const useTrestle = () => {
} }
const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => { const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => {
if (!rackInfos) {
return
}
const { width, height, left, top, lastX, lastY, surfaceId } = module const { width, height, left, top, lastX, lastY, surfaceId } = module
const surface = canvas.getObjects().find((obj) => obj.id === surfaceId) const surface = canvas.getObjects().find((obj) => obj.id === surfaceId)
const roof = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roof = canvas.getObjects().find((obj) => obj.id === surface.parentId)
@ -762,7 +906,7 @@ export const useTrestle = () => {
name: 'smartRack', name: 'smartRack',
stroke: 'red', stroke: 'red',
strokeWidth: 4, strokeWidth: 4,
selectable: false, selectable: true,
shadow: { shadow: {
color: 'black', // Outline color color: 'black', // Outline color
blur: 10, blur: 10,
@ -774,17 +918,18 @@ export const useTrestle = () => {
surfaceId: surface.id, surfaceId: surface.id,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen: rackLength,
rackRowsCd, rackRowsCd,
seq, seq,
smartRackId, smartRackId,
rackId: itemId, rackId: itemId,
direction: 'top', direction: 'top',
}) })
startPointY -= rackLength + 8
canvas.add(rack) canvas.add(rack)
canvas.renderAll() canvas.renderAll()
} else if (setRackTpCd === 'INTVL') { } else if (setRackTpCd === 'INTVL') {
startPointY -= rackLength + 8 startPointY -= rackLength
} }
}) })
} else { } else {
@ -844,13 +989,14 @@ export const useTrestle = () => {
surfaceId: surface.id, surfaceId: surface.id,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen: rackLength,
rackRowsCd, rackRowsCd,
seq, seq,
smartRackId, smartRackId,
rackId: itemId, rackId: itemId,
direction: 'left', direction: 'left',
}) })
startPointX -= rackLength + 8
canvas.add(rack) canvas.add(rack)
canvas.renderAll() canvas.renderAll()
} else if (setRackTpCd === 'INTVL') { } else if (setRackTpCd === 'INTVL') {
@ -873,7 +1019,7 @@ export const useTrestle = () => {
selectable: false, selectable: false,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen: rackLength,
rackYn, rackYn,
rackRowsCd, rackRowsCd,
rackId: itemId, rackId: itemId,
@ -913,17 +1059,18 @@ export const useTrestle = () => {
surfaceId: surface.id, surfaceId: surface.id,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen: rackLength,
rackRowsCd, rackRowsCd,
seq, seq,
smartRackId, smartRackId,
rackId: itemId, rackId: itemId,
direction: 'right', direction: 'right',
}) })
startPointX += rackLength + 8
canvas.add(rack) canvas.add(rack)
canvas.renderAll() canvas.renderAll()
} else if (setRackTpCd === 'INTVL') { } else if (setRackTpCd === 'INTVL') {
startPointX += rackLength + 8 startPointX += rackLength
} }
}) })
} else { } else {
@ -989,8 +1136,9 @@ export const useTrestle = () => {
}) })
canvas.add(rack) canvas.add(rack)
canvas.renderAll() canvas.renderAll()
} else if (setRackTpCd === 'INTVL') {
startPointY += rackLength + 8 startPointY += rackLength + 8
} else if (setRackTpCd === 'INTVL') {
startPointY += rackLength
} }
}) })
} else { } else {
@ -1043,17 +1191,16 @@ export const useTrestle = () => {
canvas.renderAll() canvas.renderAll()
racks.forEach((rack) => { 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 const bracketLength = 10
if (direction === 'top') { if (direction === 'top') {
const result = getBracketPoints(supFitQty, supFitIntvlPct) const result = getBracketPoints(supFitQty, supFitIntvlPct)
result.forEach((percent) => { result.forEach((percent) => {
const bracket = new fabric.Rect({ const bracket = new fabric.Rect({
left: x2 - bracketLength / 3, left: x2 - bracketLength / 3,
top: y2 + (rackLen / 10) * percent, top: name === 'smartRack' ? y2 + rackLen * percent : y2 + (rackLen / 10) * percent,
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
parentId: rack.parentId, parentId: rack.parentId,
@ -1071,7 +1218,7 @@ export const useTrestle = () => {
result.forEach((percent) => { result.forEach((percent) => {
const bracket = new fabric.Rect({ const bracket = new fabric.Rect({
left: x2 + (rackLen / 10) * percent, left: name === 'smartRack' ? x2 + rackLen * percent : x2 + (rackLen / 10) * percent,
top: y2 - bracketLength / 3, top: y2 - bracketLength / 3,
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
@ -1090,7 +1237,7 @@ export const useTrestle = () => {
result.forEach((percent) => { result.forEach((percent) => {
const bracket = new fabric.Rect({ const bracket = new fabric.Rect({
left: x2 - (rackLen / 10) * percent, left: name === 'smartRack' ? x2 - rackLen * percent : x2 - (rackLen / 10) * percent,
top: y2 - bracketLength / 3, top: y2 - bracketLength / 3,
fill: 'green', fill: 'green',
parentId: rack.parentId, parentId: rack.parentId,
@ -1110,7 +1257,7 @@ export const useTrestle = () => {
result.forEach((percent) => { result.forEach((percent) => {
const bracket = new fabric.Rect({ const bracket = new fabric.Rect({
left: x2 - bracketLength / 3, left: x2 - bracketLength / 3,
top: y2 - (rackLen / 10) * percent, top: name === 'smartRack' ? y2 - rackLen * percent : y2 - (rackLen / 10) * percent,
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
parentId: rack.parentId, parentId: rack.parentId,
@ -1337,8 +1484,49 @@ export const useTrestle = () => {
return points.slice(0, 2) return points.slice(0, 2)
} }
const calculateForApi = (moduleSurface) => { const getCenterPoints = (moduleSurface) => {
const centerPoints = [] 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 direction = moduleSurface.direction
const modules = moduleSurface.modules const modules = moduleSurface.modules
@ -1350,12 +1538,6 @@ export const useTrestle = () => {
const maxX = 2 + horizontal * 3 const maxX = 2 + horizontal * 3
const maxY = 2 + vertical * 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 if (centerPoints.length === 0) return
@ -1382,7 +1564,7 @@ export const useTrestle = () => {
let rightExposedHalfTopPoints = [] let rightExposedHalfTopPoints = []
centerPoints.forEach((centerPoint, index) => { 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가 있는지 확인 // centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
let bottomCell let bottomCell
let bottomLeftPoint let bottomLeftPoint
@ -1392,28 +1574,29 @@ export const useTrestle = () => {
switch (direction) { switch (direction) {
case 'south': case 'south':
width = width + horizontal //widthArr의 값을 전부 더한 후 widthArr의 길이로 나누어 평균값을 구한다.
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) 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 } bottomLeftPoint = { x: x - width / 2, y: y + height }
bottomRightPoint = { x: x + width / 2, y: y + height } bottomRightPoint = { x: x + width / 2, y: y + height }
break break
case 'north': case 'north':
width = width + horizontal width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
height = height + vertical 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) 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 } bottomLeftPoint = { x: x + width / 2, y: y - height }
bottomRightPoint = { x: x - width / 2, y: y - height } bottomRightPoint = { x: x - width / 2, y: y - height }
break break
case 'east': case 'east':
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) 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 } bottomLeftPoint = { x: x + width, y: y + height / 2 }
bottomRightPoint = { x: x + width, y: y - height / 2 } bottomRightPoint = { x: x + width, y: y - height / 2 }
break break
case 'west': case 'west':
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) 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 } bottomLeftPoint = { x: x - width, y: y - height / 2 }
bottomRightPoint = { x: x - width, y: y + height / 2 } bottomRightPoint = { x: x - width, y: y + height / 2 }
break break
@ -1870,16 +2053,16 @@ export const useTrestle = () => {
const { direction, modules } = surface const { direction, modules } = surface
let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail
const centerPoints = modules.map((module) => { const centerPoints = getCenterPoints(surface)
return module.getCenterPoint()
})
const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer
const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor
const maxX = 2 + horizontal * 3 const maxX = 2 + horizontal * 3
const maxY = 2 + vertical * 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 { x, y } = { ...module.getCenterPoint() }
let halfBottomLeftPoint let halfBottomLeftPoint

59
src/hooks/useEstimate.js Normal file
View File

@ -0,0 +1,59 @@
import { useContext } from 'react'
import { useRecoilValue } from 'recoil'
import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { currentCanvasPlanState } from '@/store/canvasAtom'
import { loginUserStore } from '@/store/commonAtom'
export function useEstimate() {
const { managementStateLoaded } = useContext(GlobalDataContext)
const loginUserState = useRecoilValue(loginUserStore)
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
const { swalFire } = useSwal()
const { promisePost } = useAxios()
/**
* 도면 견적서 저장
*/
const saveEstimate = async (estimateParam) => {
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 }).catch((error) => {
swalFire({ text: error.message, icon: 'error' })
})
}
return {
saveEstimate,
}
}

View File

@ -999,5 +999,6 @@
"construction.length.difference": "屋根面工法をすべて選択してください。", "construction.length.difference": "屋根面工法をすべて選択してください。",
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。", "menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。", "batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
"batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。" "batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。",
"module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다."
} }

View File

@ -90,7 +90,7 @@
"modal.module.basic.setting.orientation.setting.info": "※시뮬레이션 계산용 방위를 지정합니다. 남쪽의 방위를 설정해주세요.", "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.roof.material": "지붕재",
"modal.module.basic.setting.module.trestle.maker": "가대메이", "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.construction.method": "공법",
"modal.module.basic.setting.module.under.roof": "지붕밑바탕", "modal.module.basic.setting.module.under.roof": "지붕밑바탕",

View File

@ -40,7 +40,10 @@ export const moduleStatisticsState = atom({
{ name: `발전량(kW)`, prop: 'amount' }, { name: `발전량(kW)`, prop: 'amount' },
], ],
rows: [], rows: [],
footer: ['합계', '0'], footer: [
{ name: '-', prop: 'name' },
{ name: 0, prop: 'amount' },
],
}, },
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,
}) })