From 2e01d1eccfc7fa1eadb7ac086e3495e053a55411 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 10 Dec 2024 11:33:30 +0900 Subject: [PATCH 01/22] =?UTF-8?q?Canvas=20=EC=84=A4=EC=A0=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/color-picker/ColorPickerModal.jsx | 24 ++- .../floor-plan/modal/grid/DotLineGrid.jsx | 38 ++-- .../modal/setting01/FirstOption.jsx | 19 +- .../floor-plan/modal/setting01/GridOption.jsx | 16 +- .../modal/setting01/SecondOption.jsx | 54 ++++-- .../modal/setting01/SettingModal01.jsx | 20 +- .../dimensionLine/DimensionLineSetting.jsx | 23 ++- .../setting01/planSize/PlanSizeSetting.jsx | 11 +- src/hooks/option/useCanvasSetting.js | 183 ++++++++---------- 9 files changed, 243 insertions(+), 145 deletions(-) diff --git a/src/components/common/color-picker/ColorPickerModal.jsx b/src/components/common/color-picker/ColorPickerModal.jsx index 37a5343c..62abd2e2 100644 --- a/src/components/common/color-picker/ColorPickerModal.jsx +++ b/src/components/common/color-picker/ColorPickerModal.jsx @@ -8,13 +8,28 @@ import { contextPopupPositionState } from '@/store/popupAtom' export default function ColorPickerModal(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) // 현재 메뉴 - const { isShow, setIsShow, pos = contextPopupPosition, color, setColor, id, isConfig = false } = props //color = '#ff0000' + const { + isShow, + setIsShow, + pos = contextPopupPosition, + color, + setColor, + id, + name, + isConfig = false, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, + } = props //color = '#ff0000' const [originColor, setOriginColor] = useState(color) const { getMessage } = useMessage() const { closePopup } = usePopup() useEffect(() => { setOriginColor(originColor) + //치수선색설정 아닐 때만 바로 저장 실행 + if (name !== 'DimensionLineColor') setSettingsDataSave({ ...settingsData }) }, [isShow]) return ( @@ -49,6 +64,13 @@ export default function ColorPickerModal(props) { if (setColor) setColor(originColor) if (setIsShow) setIsShow(false) + //치수선색설정 아닐 때만 바로 저장 실행 + if (name !== 'DimensionLineColor') + setSettingsData({ + ...settingsData, + color: originColor, + }) + closePopup(id, isConfig) }} > diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index 3928353c..e9b5197e 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -1,6 +1,6 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import QSelectBox from '@/components/common/select/QSelectBox' -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { canvasState } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' @@ -17,27 +17,26 @@ const TYPE = { export default function DotLineGrid(props) { // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state //const interval = useRecoilValue(dotLineIntervalSelector) - const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false } = props + const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props const canvas = useRecoilValue(canvasState) const { getMessage } = useMessage() const { closePopup } = usePopup() const { swalFire } = useSwal() - const { - selectOption, - setSelectOption, - SelectOptions, - currentSetting, - setCurrentSetting, - dotLineGridSettingState, - setSettingModalGridOptions, - setDotLineGridSettingState, - } = useCanvasSetting() + const [selectOption, setSelectOption] = useState() + + const { SelectOptions, currentSetting, setCurrentSetting, dotLineGridSettingState, setSettingModalGridOptions, setDotLineGridSettingState } = + useCanvasSetting() // 데이터를 최초 한 번만 조회 useEffect(() => { console.log('DotLineGrid useEffect 실행') + setSettingsDataSave({ ...settingsData }) + + // dimension 값에 맞는 옵션을 선택 + const matchedOption = SelectOptions.find((option) => option.value == currentSetting.INTERVAL.dimension) + setSelectOption(matchedOption) return () => { setSettingModalGridOptions((prev) => { @@ -84,11 +83,24 @@ export default function DotLineGrid(props) { }, DOT: currentSetting.DOT, LINE: currentSetting.LINE, - flag: true, + //flag: true, } //setDotLineGridSettingState({ ...currentSetting }) }) + setSettingsData({ + ...settingsData, + INTERVAL: { + type: currentSetting.INTERVAL.type, + horizontalInterval: currentSetting.INTERVAL.horizontalInterval, + verticalInterval: currentSetting.INTERVAL.verticalInterval, + ratioInterval: currentSetting.INTERVAL.ratioInterval, + dimension: currentSetting.INTERVAL.dimension, + }, + DOT: currentSetting.DOT, + LINE: currentSetting.LINE, + }) + setIsShow(false) closePopup(id, isConfig) } diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index f3ef9b8b..a9532efb 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -8,21 +8,22 @@ import { useEvent } from '@/hooks/useEvent' export default function FirstOption(props) { const { getMessage } = useMessage() // const { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = useCanvasSetting() - let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = props + let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props const { option1, option2, dimensionDisplay } = settingModalFirstOptions const { initEvent } = useEvent() // 데이터를 최초 한 번만 조회 useEffect(() => { console.log('FirstOption useEffect 실행') + setSettingsDataSave({ ...settingsData }) }, []) const onClickOption = async (item) => { - //치수 표시(단 건 선택) let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay let option1 = settingModalFirstOptions?.option1 let option2 = settingModalFirstOptions?.option2 + //치수 표시(단 건 선택) if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') { dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.map((option) => { option.selected = option.id === item.id @@ -33,9 +34,9 @@ export default function FirstOption(props) { //화면 표시(단 건 선택) } else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') { - option2 = settingModalFirstOptions?.option2.map((option2) => { - option2.selected = option2.id === item.id - return option2 + option2 = settingModalFirstOptions?.option2.map((option) => { + option.selected = option.id === item.id + return option }) // setSettingModalFirstOptions({ ...settingModalFirstOptions, option2: [...options] }) @@ -47,11 +48,11 @@ export default function FirstOption(props) { }) //디스플레이 설정 표시(단 건 선택) } else { - option1 = settingModalFirstOptions?.option1.map((opt) => { - if (opt.id === item.id) { - opt.selected = !opt.selected + option1 = settingModalFirstOptions?.option1.map((option) => { + if (option.id === item.id) { + option.selected = !option.selected } - return opt + return option }) // setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] }) diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index 1d40ddbc..b5b61acc 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -28,8 +28,13 @@ export default function GridOption(props) { const { initEvent } = useEvent() + const { SelectOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = useCanvasSetting() + useEffect(() => { console.log('GridOption useEffect 실행') + }, []) + + useEffect(() => { setGridColor(color.hex) }, [color]) @@ -96,7 +101,7 @@ export default function GridOption(props) { } useEffect(() => { - console.log('🚀 ~ useEffect ~ initEvent:') + //console.log('🚀 ~ useEffect ~ initEvent:') initEvent() }, [gridOptions]) @@ -108,10 +113,15 @@ export default function GridOption(props) { x: 845, y: 180, }, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } const colorPickerProps = { id: colorId, + name: 'gridOptionColor', color: gridColor, setColor: setGridColor, isShow: showColorPickerModal, @@ -121,6 +131,10 @@ export default function GridOption(props) { x: 785, y: 180, }, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } return ( diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index df60763d..5b11cd5a 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -37,6 +37,7 @@ export default function SecondOption(props) { // setAdsorptionPointMode, // setAdsorptionRange, // } = useCanvasSetting() + const { fetchSettings, planSizeSettingMode, @@ -46,12 +47,17 @@ export default function SecondOption(props) { adsorptionPointMode, setAdsorptionPointMode, setAdsorptionRange, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } = props const { option3, option4 } = settingModalSecondOptions // 데이터를 최초 한 번만 조회 useEffect(() => { console.log('SecondOption useEffect 실행') + setSettingsDataSave({ ...settingsData }) }, []) const handlePopup = (type) => { @@ -142,18 +148,24 @@ export default function SecondOption(props) { return { ...prev, [fontProps.type]: { - // fontFamily: font.fontFamily.value, - // fontWeight: font.fontWeight.value, - // fontSize: font.fontSize.value, - // fontColor: font.fontColor.value, fontFamily: font.fontFamily, fontWeight: font.fontWeight, fontSize: font.fontSize, fontColor: font.fontColor, }, - fontFlag: true, + //fontFlag: true, } }) + + setSettingsData({ + ...settingsData, + [fontProps.type]: { + fontFamily: font.fontFamily, + fontWeight: font.fontWeight, + fontSize: font.fontSize, + fontColor: font.fontColor, + }, + }) } const fontProps = { @@ -168,6 +180,10 @@ export default function SecondOption(props) { id: dimensionId, isShow: showDimensionLineSettingModal, setIsShow: setShowDimensionLineSettingModal, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } const planSizeProps = { @@ -177,9 +193,16 @@ export default function SecondOption(props) { isShow: showPlanSizeSettingModal, setIsShow: setShowPlanSizeSettingModal, pos: { x: 1025, y: 180 }, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } const onClickOption = async (item) => { + let option4Data = settingModalSecondOptions?.option4 + let adsorpPointData = adsorptionPointMode.adsorptionPoint + //흡착범위 설정(단 건 선택) if ( item.column === 'adsorpRangeSmall' || @@ -189,21 +212,26 @@ export default function SecondOption(props) { ) { // option4에서 한 개만 선택 가능하도록 처리 //const updatedOption4 = option4.map((option) => (option.id === item.id ? { ...option, selected: true } : { ...option, selected: false })) - const options = settingModalSecondOptions?.option4.map((option4) => { - option4.selected = option4.id === item.id - return option4 + option4Data = settingModalSecondOptions?.option4.map((option) => { + option.selected = option.id === item.id + return option }) - setSettingModalSecondOptions({ ...settingModalSecondOptions, option3, option4, fontFlag: true }) + //사용여부 확인 필요 + setAdsorptionRange(item.range) + //setAdsorptionRange(50) + + setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: adsorpPointData }) } else if (item === 'adsorpPoint') { - setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: !adsorptionPointMode.adsorptionPoint, fontFlag: true }) + setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: !adsorpPointData }) + adsorpPointData = !adsorpPointData } - //setAdsorptionRange(item.range) //사용여부 확인 필요 - setAdsorptionRange(50) + + setSettingsData({ ...settingsData, option4: [...option4Data], adsorptionPoint: adsorpPointData }) } useEffect(() => { - console.log('🚀 ~ useEffect ~ initEvent:') + //console.log('🚀 ~ useEffect ~ initEvent:') initEvent() }, [adsorptionPointMode]) diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 73ce8fa2..f5e6e3ca 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -24,7 +24,11 @@ export default function SettingModal01(props) { setSettingModalFirstOptions, settingsData, setSettingsData, + settingsDataSave, + setSettingsDataSave, fetchSettings, + globalFont, + setGlobalFont, planSizeSettingMode, setPlanSizeSettingMode, settingModalSecondOptions, @@ -36,9 +40,19 @@ export default function SettingModal01(props) { setGridColor, color, } = useCanvasSetting() - const firstProps = { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } + const firstProps = { + canvas, + settingModalFirstOptions, + setSettingModalFirstOptions, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, + } const secondProps = { fetchSettings, + globalFont, + setGlobalFont, planSizeSettingMode, setPlanSizeSettingMode, settingModalSecondOptions, @@ -46,6 +60,10 @@ export default function SettingModal01(props) { adsorptionPointMode, setAdsorptionPointMode, setAdsorptionRange, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } const gridProps = { gridColor, setGridColor, color } diff --git a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx index 63581d5d..48f3ccf0 100644 --- a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx @@ -33,7 +33,7 @@ const fontSizes = [ ] export default function DimensionLineSetting(props) { - const { isShow, setIsShow, id, pos = { x: 985, y: 180 } } = props + const { isShow, setIsShow, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props const { addPopup, closePopup, closePopups } = usePopup() const pixels = Array.from({ length: 5 }).map((_, index) => { return { id: index, name: index + 1, value: index + 1 } @@ -111,11 +111,16 @@ export default function DimensionLineSetting(props) { color: originColor, setColor: setOriginColor, id: colorModalId, + name: 'DimensionLineColor', isConfig: true, pos: { x: 495, y: 180, }, + settingsData, + setSettingsData, + settingsDataSave, + setSettingsDataSave, } const fontProps = { @@ -157,9 +162,10 @@ export default function DimensionLineSetting(props) { fontSize: originFontSize, fontColor: originFontColor, }, - fontFlag: true, + //fontFlag: true, } }) + setDimensionLineSettings((prev) => { return { ...prev, @@ -167,6 +173,19 @@ export default function DimensionLineSetting(props) { color: originColor, } }) + + setSettingsData({ + ...settingsData, + dimensionLineText: { + fontFamily: originFont, + fontWeight: originFontWeight, + fontSize: originFontSize, + fontColor: originFontColor, + }, + pixel: originPixel.name, + color: originColor, + }) + setIsShow(false) closePopups([fontModalId, colorModalId, id]) } diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index e65d28ca..8de04e1d 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -8,7 +8,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { onlyNumberInputChange } from '@/util/input-utils' export default function PlanSizeSetting(props) { - const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 } } = props + const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props const { closePopup } = usePopup() const { getMessage } = useMessage() @@ -26,10 +26,15 @@ export default function PlanSizeSetting(props) { ...prev, originHorizon: Number(planSizeSettingMode.originHorizon), originVertical: Number(planSizeSettingMode.originVertical), - flag: true, } }) + setSettingsData({ + ...settingsData, + originHorizon: Number(planSizeSettingMode.originHorizon), + originVertical: Number(planSizeSettingMode.originVertical), + }) + canvas.setWidth(planSizeSettingMode.originHorizon) canvas.setHeight(planSizeSettingMode.originVertical) canvas.renderAll() @@ -40,7 +45,7 @@ export default function PlanSizeSetting(props) { const changeInput = (value, e) => { const { name } = e.target - console.log('name', name, value) + setPlanSizeSettingMode((prev) => { return { ...prev, diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 77ff8bc3..032361e0 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -48,28 +48,15 @@ export function useCanvasSetting() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) - // const [settingsData, setSettingsData] = useRecoilState(settingsState) - const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions }) - const { option1, option2, dimensionDisplay } = settingModalFirstOptions - const { option4 } = settingModalSecondOptions - - const corridorDimension = useRecoilValue(corridorDimensionSelector) - - const globalLocaleState = useRecoilValue(globalLocaleStore) - const { get, post } = useAxios(globalLocaleState) - const { getMessage } = useMessage() - const { swalFire } = useSwal() - - const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState) - const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState) - const [planSizeSettingMode, setPlanSizeSettingMode] = useRecoilState(planSizeSettingState) - //const setAdsorptionRange = useSetRecoilState(adsorptionRangeState) - const [selectedFont, setSelectedFont] = useState() const [selectedFontWeight, setSelectedFontWeight] = useState() const [selectedFontSize, setSelectedFontSize] = useState() const [selectedFontColor, setSelectedFontColor] = useState() const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) + + const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState) + const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState) + const [planSizeSettingMode, setPlanSizeSettingMode] = useRecoilState(planSizeSettingState) const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState) const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) @@ -80,7 +67,26 @@ export function useCanvasSetting() { ) const [gridColor, setGridColor] = useRecoilState(gridColorState) const [color, setColor] = useColor(gridColor ?? '#FF0000') - const [colorTemp, setColorTemp] = useState() + + const [settingsData, setSettingsData] = useState({ + ...settingModalFirstOptions, + ...settingModalSecondOptions, + ...globalFont, + ...dotLineGridSetting, + ...planSizeSettingMode, + ...dimensionLineSettings, + ...color, + }) + const [settingsDataSave, setSettingsDataSave] = useState() + const { option1, option2, dimensionDisplay } = settingModalFirstOptions + const { option4 } = settingModalSecondOptions + + const corridorDimension = useRecoilValue(corridorDimensionSelector) + + const globalLocaleState = useRecoilValue(globalLocaleStore) + const { get, post } = useAxios(globalLocaleState) + const { getMessage } = useMessage() + const { swalFire } = useSwal() const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) @@ -91,7 +97,6 @@ export function useCanvasSetting() { { id: 3, name: '1/4', value: 1 / 4 }, { id: 4, name: '1/10', value: 1 / 10 }, ] - const [selectOption, setSelectOption] = useState(SelectOptions[0]) useEffect(() => { if (!canvas) { @@ -132,58 +137,10 @@ export function useCanvasSetting() { }, [canvasSetting]) useEffect(() => { - console.log('🚀 ~ useEffect ~ settingsData:', settingsData) + console.log('🚀 ~ useEffect ~ settingsDataSave:', settingsDataSave) + if (settingsDataSave !== undefined) onClickOption2() }, [settingsData]) - //흡착점 ON/OFF 변경 시 - // useEffect(() => { - // //console.log('useCanvasSetting 실행2', adsorptionPointMode.fontFlag, correntObjectNo) - // if (adsorptionPointMode.fontFlag) { - // onClickOption2() - // } - // }, [adsorptionPointMode]) - - // 1 과 2 변경 시 - // useEffect(() => { - // //console.log('useCanvasSetting 실행3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo) - // if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) { - // onClickOption2() - // } - // }, [settingModalFirstOptions, settingModalSecondOptions]) - - // 글꼴 변경 시 - // useEffect(() => { - // //console.log('useCanvasSetting 실행4', globalFont.fontFlag, correntObjectNo) - // if (globalFont.fontFlag) { - // onClickOption2() - // } - // }, [globalFont]) - - // 도명크기 변경 시 - // useEffect(() => { - // //console.log('useCanvasSetting 실행5', planSizeSettingMode.flag, correntObjectNo) - // if (planSizeSettingMode.flag) { - // onClickOption2() - // } - // }, [planSizeSettingMode]) - - // 점/선 그리드 변경 시 - // useEffect(() => { - // //console.log('useCanvasSetting 실행6', dotLineGridSetting.flag) - // if (dotLineGridSetting.flag) { - // onClickOption2() - // } - // }, [dotLineGridSetting]) - - // 그리드 색 설정 변경 시 - // useEffect(() => { - // console.log('useCanvasSetting 실행7', colorTemp, gridColor) - // //colorTemp는 변경 전.. 값이 있고 변경된 컬러와 다를 때 실행 - // if (colorTemp !== undefined && colorTemp !== gridColor) { - // onClickOption2() - // } - // }, [color]) - const getFonts = (itemValue) => { if (!itemValue) return { id: 1, name: 'MS PGothic', value: 'MS PGothic' } const data = [ @@ -357,18 +314,13 @@ export function useCanvasSetting() { const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item })) //흡착점 ON/OFF - setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint, fontFlag: false }) + setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint }) //치수선 설정 setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor }) //도면크기 설정 - setPlanSizeSettingMode({ - ...planSizeSettingMode, - originHorizon: res.originHorizon, - originVertical: res.originVertical, - flag: false, - }) + setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical }) // 데이터 설정 setSettingModalFirstOptions({ @@ -376,13 +328,13 @@ export function useCanvasSetting() { option1: optionData1, option2: optionData2, dimensionDisplay: optionData5, - fontFlag: false, + //fontFlag: false, }) setSettingModalSecondOptions({ ...settingModalSecondOptions, option3: optionData3, option4: optionData4, - fontFlag: false, + //fontFlag: false, }) const fontPatternData = { @@ -422,7 +374,7 @@ export function useCanvasSetting() { fontColor: getFontColors(res.lengthFontColor), }, //글꼴 설정 Flag - fontFlag: false, + //fontFlag: false, } //조회된 글꼴 데이터 set @@ -439,55 +391,45 @@ export function useCanvasSetting() { }, DOT: res.dotGridDisplay, LINE: res.lineGridDisplay, - flag: false, } - const matchedOption = SelectOptions.find((option) => option.value == res.gridDimen) - - // dimension 값에 맞는 옵션을 선택 - setSelectOption(matchedOption) - setDotLineGridSettingState(patternData) //setCurrentSetting(patternData) //그리드 색 설정 setGridColor(res.gridColor) - setColorTemp(res.gridColor) } else { //조회된 글꼴 데이터가 없는 경우 //흡착점 ON/OFF - setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false, fontFlag: false }) + setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false }) //치수선 설정 setDimensionLineSettings({ ...dimensionLineSettings }) //도면크기 설정 - setPlanSizeSettingMode({ - ...planSizeSettingMode, - flag: false, - }) + setPlanSizeSettingMode({ ...planSizeSettingMode }) // 데이터 설정 setSettingModalFirstOptions({ ...settingModalFirstOptions, - fontFlag: false, + //fontFlag: false, }) setSettingModalSecondOptions({ ...settingModalSecondOptions, - fontFlag: false, + //fontFlag: false, }) - setGlobalFont({ ...globalFont, fontFlag: false }) + setGlobalFont({ ...globalFont }) //점/선 그리드 - setDotLineGridSettingState({ ...defaultDotLineGridSetting, flag: false }) + setDotLineGridSettingState({ ...defaultDotLineGridSetting }) //setCurrentSetting({ ...defaultDotLineGridSetting }) //그리드 색 설정 setGridColor('#FF0000') - setColorTemp('#FF0000') } + frontSettings() } catch (error) { console.error('Data fetching error:', error) @@ -513,8 +455,31 @@ export function useCanvasSetting() { secondOption2: option4.map((item) => ({ column: item.column, selected: item.selected, + range: item.range, })), } + + // const option1Array = dataToSend.firstOption1.map((item) => ({ + // allocDisplay: item.selected, + // outlineDisplay: item.selected, + // gridDisplay: item.selected, + // lineDisplay: item.selected, + // wordDisplay: item.selected, + // circuitNumDisplay: item.selected, + // flowDisplay: item.selected, + // trestleDisplay: item.selected, + // imageDisplay: item.selected, + // totalDisplay: item.selected, + // })) + // console.log('option1Array ', option1Array) + + // const option2Array = dataToSend.firstOption2.map((item) => ({ + // corridorDimension: item.selected, + // realDimension: item.selected, + // noneDimension: item.selected, + // })) + // console.log('option2Array ', option2Array) + // console.log('globalFont', globalFont) const patternData = { //견적서 번호 @@ -543,6 +508,23 @@ export function useCanvasSetting() { adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, adsorpRangeMedium: dataToSend.secondOption2[2].selected, adsorpRangeLarge: dataToSend.secondOption2[3].selected, + + //adsorptionRange: dataToSend.secondOption2[0].range, + + // //디스플레이 설정(다중) + // option1Array, + // //차수 표시(단 건) + // option2Array, + // //화면 표시(단 건) + // onlyBorder: dataToSend.firstOption2[0].selected, + // lineHatch: dataToSend.firstOption2[1].selected, + // allPainted: dataToSend.firstOption2[2].selected, + // //흡착범위 설정(단 건) + // adsorpRangeSmall: dataToSend.secondOption2[0].selected, + // adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, + // adsorpRangeMedium: dataToSend.secondOption2[2].selected, + // adsorpRangeLarge: dataToSend.secondOption2[3].selected, + //흡착점 ON/OFF adsorpPoint: adsorptionPointMode.adsorptionPoint, //??: adsorptionRange, 사용여부 확인 필요 @@ -594,14 +576,11 @@ export function useCanvasSetting() { gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, gridDimen: dotLineGridSetting.INTERVAL.dimension, - //gridColor: gridColor.gridColor, gridColor: gridColor, } console.log('patternData ', patternData) - setColorTemp(gridColor) - // HTTP POST 요청 보내기 await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) .then((res) => { @@ -719,15 +698,13 @@ export function useCanvasSetting() { setDimensionLineSettings, planSizeSettingMode, setPlanSizeSettingMode, - selectOption, - setSelectOption, SelectOptions, currentSetting, setCurrentSetting, dotLineGridSettingState, - setSettingModalGridOptions, setDotLineGridSettingState, resetDotLineGridSetting, + setSettingModalGridOptions, gridColor, setGridColor, color, @@ -740,5 +717,7 @@ export function useCanvasSetting() { basicSettingSave, settingsData, setSettingsData, + settingsDataSave, + setSettingsDataSave, } } From 4bb0fc2000bbb48cf34a6b8bebd300ba5c882f32 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 11:55:55 +0900 Subject: [PATCH 02/22] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index eb7d89d1..452e57be 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1100,9 +1100,11 @@ export default function Estimate({ params }) {
-
- -
+ {constructSpecificationMulti ? ( +
+ +
+ ) : null} ) })} From 414886121ea5936260d5f24289d95bada6c3680d Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 13:16:29 +0900 Subject: [PATCH 03/22] =?UTF-8?q?=ED=99=95=EC=9D=B8=EC=9A=A9=20=EC=BD=98?= =?UTF-8?q?=EC=86=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Main.jsx | 13 ++++++++++--- src/components/auth/Login.jsx | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/Main.jsx b/src/components/Main.jsx index 29d1305a..7fa1d810 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -13,8 +13,11 @@ import ChangePasswordPop from './main/ChangePasswordPop' import { searchState } from '@/store/boardAtom' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' +import { getSession } from '@/lib/authActions' +import { sessionStore } from '@/store/commonAtom' -export default function MainPage() { +export default function MainPage(mainPageProps) { + const [sessionState, setSessionState] = useRecoilState(sessionStore) const [chagePasswordPopOpen, setChagePasswordPopOpen] = useState(false) const { session } = useContext(SessionContext) @@ -74,11 +77,15 @@ export default function MainPage() { } useEffect(() => { - if (session?.pwdInitYn !== 'Y') { + // console.log('mainPageProps:::', mainPageProps) + if (mainPageProps?.pwdInitYn !== 'Y') { setChagePasswordPopOpen(true) } - }, [session]) + }, [mainPageProps]) + console.log('sessionState::', sessionState) + console.log('session::', session) + console.log('mainPageProps::', mainPageProps) return ( <> {(!chagePasswordPopOpen && ( diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index af50a515..af8bc3df 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -89,6 +89,7 @@ export default function Login() { .then((res) => { if (res) { if (res.data.result.resultCode === 'S') { + console.log('res.data.data::', res.data.data) setSession(res.data.data) setSessionState(res.data.data) // ID SAVE 체크되어 있는 경우, 쿠키 저장 From 929bad0515d158d008ecdfa09ed00c4dff710614 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 10 Dec 2024 13:49:12 +0900 Subject: [PATCH 04/22] =?UTF-8?q?fix:=20layout=20=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EB=B6=84=EA=B8=B0=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/layout.js b/src/app/layout.js index fbe6c39a..e8fc6532 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -55,6 +55,10 @@ export default async function RootLayout({ children }) { redirect('/login') } + if (headerPathname === '/login' && session.isLoggedIn) { + redirect('/main') + } + return ( From 6db65f6173d8845e2b0bf4216a05a44e9562364f Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 10 Dec 2024 13:51:03 +0900 Subject: [PATCH 05/22] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/layout.js b/src/app/layout.js index e8fc6532..3383aa10 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -56,7 +56,7 @@ export default async function RootLayout({ children }) { } if (headerPathname === '/login' && session.isLoggedIn) { - redirect('/main') + redirect('/') } return ( From 7aac1bbfeba6998b251dd45775503c7d7d3323ba Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 14:21:46 +0900 Subject: [PATCH 06/22] =?UTF-8?q?=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=8C=9D=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Main.jsx | 12 ++---------- src/components/auth/Login.jsx | 1 - src/components/main/ChangePasswordPop.jsx | 12 ++++++++---- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/components/Main.jsx b/src/components/Main.jsx index 7fa1d810..ac25a26e 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -13,7 +13,6 @@ import ChangePasswordPop from './main/ChangePasswordPop' import { searchState } from '@/store/boardAtom' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' -import { getSession } from '@/lib/authActions' import { sessionStore } from '@/store/commonAtom' export default function MainPage(mainPageProps) { @@ -21,9 +20,6 @@ export default function MainPage(mainPageProps) { const [chagePasswordPopOpen, setChagePasswordPopOpen] = useState(false) const { session } = useContext(SessionContext) - const globalLocaleState = useRecoilValue(globalLocaleStore) - - const { promiseGet } = useAxios(globalLocaleState) const router = useRouter() const { getMessage } = useMessage() @@ -77,15 +73,11 @@ export default function MainPage(mainPageProps) { } useEffect(() => { - // console.log('mainPageProps:::', mainPageProps) - if (mainPageProps?.pwdInitYn !== 'Y') { + if (sessionState?.pwdInitYn !== 'Y') { setChagePasswordPopOpen(true) } - }, [mainPageProps]) + }, [sessionState]) - console.log('sessionState::', sessionState) - console.log('session::', session) - console.log('mainPageProps::', mainPageProps) return ( <> {(!chagePasswordPopOpen && ( diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index af8bc3df..af50a515 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -89,7 +89,6 @@ export default function Login() { .then((res) => { if (res) { if (res.data.result.resultCode === 'S') { - console.log('res.data.data::', res.data.data) setSession(res.data.data) setSessionState(res.data.data) // ID SAVE 체크되어 있는 경우, 쿠키 저장 diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx index 2af060e7..4eb7164d 100644 --- a/src/components/main/ChangePasswordPop.jsx +++ b/src/components/main/ChangePasswordPop.jsx @@ -7,7 +7,7 @@ import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { useRouter } from 'next/navigation' import { setSession } from '@/lib/authActions' - +import { logout } from '@/lib/authActions' export default function ChangePasswordPop(props) { const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -77,18 +77,21 @@ export default function ChangePasswordPop(props) { if (res?.result?.code === 200) { if (res?.result?.resultCode === 'S') { alert(getMessage('main.popup.login.success')) + logout() //로그인 화면으로 이동해서 다시 로그인해야되서 setSessionState필요없음 // setSessionState({ ...sessionState, pwdInitYn: 'Y' }) - props.setChagePasswordPopOpen(false) - router.push('/login') + //props.setChagePasswordPopOpen(false) + //router.push('/login') } else { alert(res?.result?.resultMsg) } } else { + logout() console.log('code not 200 error') } }) .catch((error) => { + logout() console.log('catch::::::::', error) }) } @@ -165,7 +168,8 @@ export default function ChangePasswordPop(props) { type="button" className="btn-origin grey" onClick={() => { - router.push('/login') + logout() + // router.push('/login') }} > {getMessage('main.popup.login.btn2')} From 69a0a989fec401a1dbe202ff2529fab4539b5aaa Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 14:26:26 +0900 Subject: [PATCH 07/22] =?UTF-8?q?main=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Main.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/Main.jsx b/src/components/Main.jsx index ac25a26e..1a436582 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -14,6 +14,7 @@ import { searchState } from '@/store/boardAtom' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' import { sessionStore } from '@/store/commonAtom' +import { isObjectNotEmpty } from '@/util/common-utils' export default function MainPage(mainPageProps) { const [sessionState, setSessionState] = useRecoilState(sessionStore) @@ -73,8 +74,10 @@ export default function MainPage(mainPageProps) { } useEffect(() => { - if (sessionState?.pwdInitYn !== 'Y') { - setChagePasswordPopOpen(true) + if (isObjectNotEmpty(sessionState)) { + if (sessionState?.pwdInitYn !== 'Y') { + setChagePasswordPopOpen(true) + } } }, [sessionState]) From 021e425c84ae334ce489d9c6ecab5931ae6db906 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 10 Dec 2024 14:36:29 +0900 Subject: [PATCH 08/22] =?UTF-8?q?QPolygon=20containsPoint=20=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=8B=A4=EB=A5=B4?= =?UTF-8?q?=EA=B2=8C=20=EC=9E=91=EB=8F=99=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/fabric/QPolygon.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 0f7bd815..0ec436fe 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -4,7 +4,7 @@ import { QLine } from '@/components/fabric/QLine' import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util' import { calculateAngle, drawGabledRoof, drawRidgeRoof, drawShedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils' import * as turf from '@turf/turf' -import { LINE_TYPE } from '@/common/common' +import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' export const QPolygon = fabric.util.createClass(fabric.Polygon, { type: 'QPolygon', @@ -690,6 +690,15 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { return intersects % 2 === 1 }, + containsPoint: function (point) { + if (this.name === POLYGON_TYPE.ROOF && this.isFixed) { + const isInside = this.inPolygon(point) + this.set('selectable', isInside) + return isInside + } else { + return this.callSuper('containsPoint', point) + } + }, inPolygonABType(x, y, polygon) { let inside = false From b3d1c2d7d0183d61ab36c1baf1fd86a14782da05 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 16:27:22 +0900 Subject: [PATCH 09/22] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20=EB=A9=80=ED=8B=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 3 - .../estimate/EstimateFileUploader.jsx | 60 +++++++++++++++---- .../estimate/useEstimateController.js | 13 ++-- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 452e57be..5ba366a9 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -25,7 +25,6 @@ export default function Estimate({ params }) { const [uniqueData, setUniqueData] = useState([]) const [handlePricingFlag, setHandlePricingFlag] = useState(false) const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false) - const fixedKey = 'itemKey' const [itemChangeYn, setItemChangeYn] = useState(false) const { session } = useContext(SessionContext) const [objectNo, setObjectNo] = useState('') //물건번호 @@ -1193,7 +1192,6 @@ export default function Estimate({ params }) { {originFiles.map((originFile) => { return (
  • - {/*
  • */}
    0 && specialNoteList.map((row) => { return ( - //
    diff --git a/src/components/estimate/EstimateFileUploader.jsx b/src/components/estimate/EstimateFileUploader.jsx index cda14e24..950ed6af 100644 --- a/src/components/estimate/EstimateFileUploader.jsx +++ b/src/components/estimate/EstimateFileUploader.jsx @@ -1,14 +1,12 @@ 'use client' -import { useContext, useRef } from 'react' +import { useRef } from 'react' import { v4 as uuidv4 } from 'uuid' import { useMessage } from '@/hooks/useMessage' -import { SessionContext } from '@/app/SessionProvider' export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { const fileInputRef = useRef(null) const { getMessage } = useMessage() - const { session } = useContext(SessionContext) const handleButtonClick = (e) => { e.preventDefault() @@ -20,13 +18,32 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { return } - const { files } = e.target - const file = files[0] - const fileType = file.type - if (!fileType.includes('image')) { - return alert(getMessage('estimate.detail.fileList.extCheck')) + const fileList = [] + let passFlag = true + Array.from(e.target.files).forEach((file) => { + let fileType = file.type + if (!fileType.includes('image')) { + passFlag = false + } else { + fileList.push({ data: file, id: uuidv4() }) + } + }) + + if (!passFlag) { + alert(getMessage('estimate.detail.fileList.extCheck')) } + // const { files } = e.target + // const file = files[0] + // const fileType = file.type + // if (!fileType.includes('image')) { + // return alert(getMessage('estimate.detail.fileList.extCheck')) + // } + + // setUploadFiles([...uploadFiles, { data: e.target.files[0], id: uuidv4() }]) + //다중으로 변경 + setUploadFiles([...uploadFiles, ...fileList]) + e.target.value = '' // const formData = new FormData() // formData.append('file', e.target.files[0]) // formData.append('objectNo', objectNo) // 받아와야 하는 값 @@ -37,8 +54,6 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { // await promisePost({ url: '/api/file/fileUpload', data: formData }).then((res) => { // if (res.data > 0) setUploadFiles([...files, { name: e.target.files[0].name, id: uuidv4() }]) // }) - setUploadFiles([...uploadFiles, { data: e.target.files[0], id: uuidv4() }]) - e.target.value = '' } const deleteFile = (id) => { @@ -49,9 +64,21 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { e.preventDefault() e.stopPropagation() const fileList = [] + let passFlag = true + Array.from(e.dataTransfer.files).forEach((file) => { - fileList.push({ data: file, id: uuidv4() }) + let fileType = file.type + if (!fileType.includes('image')) { + passFlag = false + } else { + fileList.push({ data: file, id: uuidv4() }) + } }) + + if (!passFlag) { + alert(getMessage('estimate.detail.fileList.extCheck')) + } + setUploadFiles([...uploadFiles, ...fileList]) } @@ -76,7 +103,16 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { - onChangeFiles(e)} /> + onChangeFiles(e)} + />
    { export const useEstimateController = (planNo) => { const [fileList, setFileList] = useState([]) - const [deleteFileList, setDeleteFileList] = useState([]) + const { setIsGlobalLoading } = useContext(QcastContext) const router = useRouter() const { session } = useContext(SessionContext) @@ -52,6 +53,7 @@ export const useEstimateController = (planNo) => { const fetchSetting = async (objectNo, planNo) => { try { await promiseGet({ url: `/api/estimate/${objectNo}/${planNo}/detail` }).then((res) => { + setIsGlobalLoading(true) if (res.status === 200) { if (isObjectNotEmpty(res.data)) { if (res.data.itemList.length > 0) { @@ -72,9 +74,11 @@ export const useEstimateController = (planNo) => { } }) setIsLoading(true) + setIsGlobalLoading(false) } catch (error) { console.error('견적서 상세조회 Error: ', error) setIsLoading(true) + setIsGlobalLoading(false) } } @@ -354,15 +358,16 @@ export const useEstimateController = (planNo) => { // return try { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { + setIsGlobalLoading(true) if (res.status === 201) { estimateData.newFileList = [] - // estimateData.originFiles = [] alert(getMessage('estimate.detail.save.alertMsg')) //어디로 보낼지 fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) } }) } catch (e) { + setIsGlobalLoading(false) console.log('error::::::::::::', e.response.data.message) } } diff --git a/src/locales/ja.json b/src/locales/ja.json index 8521c658..243418a8 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -840,7 +840,7 @@ "estimate.detail.fileFlg": "後日資料提出", "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": "見積もりの具体的な", diff --git a/src/locales/ko.json b/src/locales/ko.json index cc65bb7d..495fe2dc 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -850,7 +850,7 @@ "estimate.detail.fileFlg": "후일자료제출", "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": "견적특이사항", From 28dd23d93f4d4ce249ef2756141ab99fdb6f014b Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 10 Dec 2024 17:51:06 +0900 Subject: [PATCH 10/22] =?UTF-8?q?=EA=B2=AC=EC=A0=81=ED=8A=B9=EC=9D=B4?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=94=94=ED=8F=B4=ED=8A=B8=EC=B2=B4?= =?UTF-8?q?=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 5ba366a9..d92ba071 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -146,14 +146,18 @@ export default function Estimate({ params }) { } } }) - //detail과 상관없이 디폴트 체크목록 - //ATTR003,ATTR007 if (row.code === 'ATTR003') { //row.check = true } if (row.code === 'ATTR007') { //row.check = true } + + if (estimateContextState.estimateType === 'YJOD') { + if (row.code === 'ATTR002') { + row.check = true + } + } }) setSpecialNoteList(res) From 75d116ad98cd0ceaac327570aef9d886b31ee621 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 10 Dec 2024 18:19:21 +0900 Subject: [PATCH 11/22] =?UTF-8?q?Canvas=20=EC=84=A4=EC=A0=95=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B2=98=EB=A6=AC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/grid/DotLineGrid.jsx | 1 - .../modal/setting01/SecondOption.jsx | 15 +------ .../dimensionLine/DimensionLineSetting.jsx | 1 - .../setting01/planSize/PlanSizeSetting.jsx | 1 - src/hooks/option/useCanvasSetting.js | 45 ------------------- 5 files changed, 1 insertion(+), 62 deletions(-) diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index e9b5197e..9e402a71 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -83,7 +83,6 @@ export default function DotLineGrid(props) { }, DOT: currentSetting.DOT, LINE: currentSetting.LINE, - //flag: true, } //setDotLineGridSettingState({ ...currentSetting }) }) diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index 5b11cd5a..941c2d3e 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -27,17 +27,6 @@ export default function SecondOption(props) { const { initEvent } = useEvent() - // const { - // fetchSettings, - // planSizeSettingMode, - // setPlanSizeSettingMode, - // settingModalSecondOptions, - // setSettingModalSecondOptions, - // adsorptionPointMode, - // setAdsorptionPointMode, - // setAdsorptionRange, - // } = useCanvasSetting() - const { fetchSettings, planSizeSettingMode, @@ -153,7 +142,6 @@ export default function SecondOption(props) { fontSize: font.fontSize, fontColor: font.fontColor, }, - //fontFlag: true, } }) @@ -217,9 +205,8 @@ export default function SecondOption(props) { return option }) - //사용여부 확인 필요 + //흡착점 범위 setAdsorptionRange(item.range) - //setAdsorptionRange(50) setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: adsorpPointData }) } else if (item === 'adsorpPoint') { diff --git a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx index 48f3ccf0..571741ed 100644 --- a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx @@ -162,7 +162,6 @@ export default function DimensionLineSetting(props) { fontSize: originFontSize, fontColor: originFontColor, }, - //fontFlag: true, } }) diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index 8de04e1d..0691046d 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -50,7 +50,6 @@ export default function PlanSizeSetting(props) { return { ...prev, [name]: Number(value), - flag: false, } }) } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 032361e0..220bdae4 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -328,13 +328,11 @@ export function useCanvasSetting() { option1: optionData1, option2: optionData2, dimensionDisplay: optionData5, - //fontFlag: false, }) setSettingModalSecondOptions({ ...settingModalSecondOptions, option3: optionData3, option4: optionData4, - //fontFlag: false, }) const fontPatternData = { @@ -373,8 +371,6 @@ export function useCanvasSetting() { fontSize: getFontSizes(res.lengthFontSize), fontColor: getFontColors(res.lengthFontColor), }, - //글꼴 설정 Flag - //fontFlag: false, } //조회된 글꼴 데이터 set @@ -413,11 +409,9 @@ export function useCanvasSetting() { // 데이터 설정 setSettingModalFirstOptions({ ...settingModalFirstOptions, - //fontFlag: false, }) setSettingModalSecondOptions({ ...settingModalSecondOptions, - //fontFlag: false, }) setGlobalFont({ ...globalFont }) @@ -458,29 +452,6 @@ export function useCanvasSetting() { range: item.range, })), } - - // const option1Array = dataToSend.firstOption1.map((item) => ({ - // allocDisplay: item.selected, - // outlineDisplay: item.selected, - // gridDisplay: item.selected, - // lineDisplay: item.selected, - // wordDisplay: item.selected, - // circuitNumDisplay: item.selected, - // flowDisplay: item.selected, - // trestleDisplay: item.selected, - // imageDisplay: item.selected, - // totalDisplay: item.selected, - // })) - // console.log('option1Array ', option1Array) - - // const option2Array = dataToSend.firstOption2.map((item) => ({ - // corridorDimension: item.selected, - // realDimension: item.selected, - // noneDimension: item.selected, - // })) - // console.log('option2Array ', option2Array) - - // console.log('globalFont', globalFont) const patternData = { //견적서 번호 objectNo: correntObjectNo, @@ -509,22 +480,6 @@ export function useCanvasSetting() { adsorpRangeMedium: dataToSend.secondOption2[2].selected, adsorpRangeLarge: dataToSend.secondOption2[3].selected, - //adsorptionRange: dataToSend.secondOption2[0].range, - - // //디스플레이 설정(다중) - // option1Array, - // //차수 표시(단 건) - // option2Array, - // //화면 표시(단 건) - // onlyBorder: dataToSend.firstOption2[0].selected, - // lineHatch: dataToSend.firstOption2[1].selected, - // allPainted: dataToSend.firstOption2[2].selected, - // //흡착범위 설정(단 건) - // adsorpRangeSmall: dataToSend.secondOption2[0].selected, - // adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, - // adsorpRangeMedium: dataToSend.secondOption2[2].selected, - // adsorpRangeLarge: dataToSend.secondOption2[3].selected, - //흡착점 ON/OFF adsorpPoint: adsorptionPointMode.adsorptionPoint, //??: adsorptionRange, 사용여부 확인 필요 From 9736e7ed5835a7163079035d8a716c3bcefa4a76 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 11 Dec 2024 10:19:19 +0900 Subject: [PATCH 12/22] =?UTF-8?q?roofMaterials=20recoil=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementShape/PlacementShapeSetting.jsx | 317 +++++------------- src/hooks/option/useCanvasSetting.js | 9 + src/store/settingAtom.js | 19 +- 3 files changed, 92 insertions(+), 253 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 1ce18a85..bc9fb401 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -8,68 +8,37 @@ import MaterialGuide from '@/components/floor-plan/modal/placementShape/Material import WithDraggable from '@/components/common/draggable/WithDraggable' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useRecoilState, useRecoilValue } from 'recoil' +import { roofMaterialsAtom } from '@/store/settingAtom' +import { isObjectNotEmpty } from '@/util/common-utils' export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) { const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) const { closePopup } = usePopup() const { getMessage } = useMessage() + const roofMaterials = useRecoilValue(roofMaterialsAtom) const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() + const [currentRoofMaterial, setCurrentRoofMaterial] = useState( + isObjectNotEmpty(basicSetting.selectedRoofMaterial) ? basicSetting.selectedRoofMaterial : roofMaterials[0], + ) // 데이터를 최초 한 번만 조회 useEffect(() => { fetchBasicSettings() }, []) + useEffect(() => { + console.log(currentRoofMaterial) + }, [roofMaterials]) + // Function to update the roofType and corresponding values - const handleRoofTypeChange = (index, value) => { - const updatedRoofs = [...basicSetting.roofs] - const roofType = parseInt(value, 10) - - // Reset other values based on the selected roofType - if (roofType === 1) { - updatedRoofs[index] = { - ...updatedRoofs[index], - roofType: 1, - roofWidth: 265, - roofHeight: 235, - roofGap: 455, - roofHajebichi: 0, - } - } else if (roofType === 2) { - updatedRoofs[index] = { - ...updatedRoofs[index], - roofType: 2, - roofGap: 265, - roofHajebichi: 265, - roofWidth: 0, - roofHeight: 0, - } - } else if (roofType === 3) { - updatedRoofs[index] = { - ...updatedRoofs[index], - roofType: 3, - roofHajebichi: 265, - roofGap: 0, - roofWidth: 0, - roofHeight: 0, - } - } else if (roofType === 4) { - updatedRoofs[index] = { - ...updatedRoofs[index], - roofType: 4, - roofHeight: 265, - roofGap: 265, - roofHajebichi: 0, - roofWidth: 0, - } - } - - setBasicSettings({ - ...basicSetting, - roofs: updatedRoofs, - }) + const handleRoofTypeChange = (value) => { + const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value) + setCurrentRoofMaterial(selectedRoofMaterial) + /*const newBasicSetting = { ...basicSetting } + setBasicSettings({ ...newBasicSetting, selectedRoofMaterial: selectedRoofMaterial })*/ } return ( @@ -180,16 +149,19 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
    - {basicSetting.roofs[0].roofType === 1 ? ( + {['R', 'C'].includes(currentRoofMaterial.widAuth) && ( <>
    W @@ -197,204 +169,67 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set -
    -
    -
    - L -
    - -
    -
    -
    - {getMessage('modal.placement.initial.setting.rafter')} -
    -
    - ) : basicSetting.roofs[0].roofType === 2 ? ( - <> -
    - {getMessage('hajebichi')} -
    - -
    + )} + {['R', 'C'].includes(currentRoofMaterial.lenAuth) && ( +
    + L +
    +
    -
    - {getMessage('modal.placement.initial.setting.rafter')} -
    - -
    +
    + )} + {['C', 'R'].includes(currentRoofMaterial.raftAuth) && ( +
    + {getMessage('modal.placement.initial.setting.rafter')} +
    +
    - - ) : basicSetting.roofs[0].roofType === 3 ? ( - <> -
    - {getMessage('hajebichi')} -
    - -
    +
    + )} + {['C', 'R'].includes(currentRoofMaterial.roofPchAuth) && ( +
    + {getMessage('hajebichi')} +
    +
    - - ) : basicSetting.roofs[0].roofType === 4 ? ( - <> -
    - L -
    - -
    -
    -
    - {getMessage('modal.placement.initial.setting.rafter')} -
    - -
    -
    - - ) : ( - '' +
    )}
    diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 220bdae4..660dcefa 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -20,6 +20,7 @@ import { settingModalGridOptionsState, basicSettingState, settingsState, + roofMaterialsAtom, } from '@/store/settingAtom' import { POLYGON_TYPE } from '@/common/common' import { globalFontAtom } from '@/store/fontAtom' @@ -91,6 +92,8 @@ export function useCanvasSetting() { const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) + const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom) + 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 }, @@ -98,6 +101,12 @@ export function useCanvasSetting() { { id: 4, name: '1/10', value: 1 / 10 }, ] + useEffect(() => { + get({ url: `/api/v1/master/getRoofMaterialList` }).then((res) => { + setRoofMaterials(res.data) + }) + }, []) + useEffect(() => { if (!canvas) { return diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 9e64d72f..7a07175b 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -203,21 +203,16 @@ export const basicSettingState = atom({ default: { roofSizeSet: 1, roofAngleSet: 'slope', - roofs: [ - { - roofApply: true, - roofSeq: 1, - roofType: 1, - roofWidth: 200, - roofHeight: 200, - roofHajebichi: 200, - roofGap: 0, - roofLayout: 'parallel', - }, - ], + selectedRoofMaterial: {}, }, }) +// db에 등록된 지붕재 목록 +export const roofMaterialsAtom = atom({ + key: 'roofMaterialState', + default: [], +}) + /** * 현재 선택된 물건 번호 */ From 6dbe47a7e8cb8e9c9243627d9bdcc74d342b473e Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Wed, 11 Dec 2024 11:33:33 +0900 Subject: [PATCH 13/22] =?UTF-8?q?feat:=20=EC=A7=80=EB=B6=95=EC=9E=AC,=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=EC=95=84=EC=9D=B4=ED=85=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=ED=98=B8=EC=B6=9C=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Playground.jsx | 20 ++++++++++++++++++++ src/hooks/common/useMasterController.js | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/hooks/common/useMasterController.js diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx index a908ba0f..e3d185ec 100644 --- a/src/components/Playground.jsx +++ b/src/components/Playground.jsx @@ -8,6 +8,7 @@ import { FaAnglesDown } from 'react-icons/fa6' import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' +import { useMasterController } from '@/hooks/common/useMasterController' import { convertDwgToPng } from '@/lib/cadAction' import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom' @@ -35,6 +36,7 @@ export default function Playground() { const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL const { getMessage } = useMessage() const { swalFire } = useSwal() + const { getRoofMaterialList, getModuleTypeItemList } = useMasterController() const [color, setColor] = useState('#ff0000') @@ -156,6 +158,24 @@ export default function Playground() { <>
    이 영역은 테스트입니다.
    +
    + + +
    { setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) setSelectedOrientation(e) @@ -116,7 +139,7 @@ export default function FlowDirectionSetting(props) { {Array.from({ length: 180 / 15 + 1 }).map((dot, index) => (
    { setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) setCompasDeg(15 * (12 + index)) @@ -126,7 +149,7 @@ export default function FlowDirectionSetting(props) { {Array.from({ length: 180 / 15 - 1 }).map((dot, index) => (
    { setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) setCompasDeg(15 * (index + 1)) diff --git a/src/hooks/contextpopup/useFlowDirectionSetting.js b/src/hooks/contextpopup/useFlowDirectionSetting.js deleted file mode 100644 index 9e77aa4a..00000000 --- a/src/hooks/contextpopup/useFlowDirectionSetting.js +++ /dev/null @@ -1,30 +0,0 @@ -import { canvasState } from '@/store/canvasAtom' -import { useRecoilValue } from 'recoil' -import { usePolygon } from '@/hooks/usePolygon' -import { useState } from 'react' -import { usePopup } from '@/hooks/usePopup' - -export const FLOW_DIRECTION_TYPE = { - EIGHT_AZIMUTH: 'eightAzimuth', - TWENTY_FOUR_AZIMUTH: 'twentyFourAzimuth', -} - -export function useFlowDirectionSetting(id) { - const canvas = useRecoilValue(canvasState) - const { drawDirectionArrow } = usePolygon() - const { closePopup } = usePopup() - - const [type, setType] = useState(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) - - const changeSurfaceFlowDirection = (roof, direction, orientation) => { - roof.set({ - direction: direction, - surfaceCompass: orientation, - }) - drawDirectionArrow(roof) - canvas?.renderAll() - closePopup(id) - } - - return { changeSurfaceFlowDirection, type, setType } -} From 7e2180cd76b036f45c34742db234680b1fd14635 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 11 Dec 2024 15:08:36 +0900 Subject: [PATCH 16/22] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20hook=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMasterController.js | 2 ++ src/hooks/option/useCanvasSetting.js | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js index e2125af1..d0cac892 100644 --- a/src/hooks/common/useMasterController.js +++ b/src/hooks/common/useMasterController.js @@ -14,6 +14,7 @@ export function useMasterController() { const getRoofMaterialList = async () => { return await get({ url: '/api/v1/master/getRoofMaterialList' }).then((res) => { console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res) + return res }) } @@ -25,6 +26,7 @@ export function useMasterController() { const getModuleTypeItemList = async (roofMaterialCd) => { return await get({ url: `/api/v1/master/getModuleTypeItemList/${roofMaterialCd}` }).then((res) => { console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res) + return res }) } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 660dcefa..dfc0c244 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -27,6 +27,7 @@ import { globalFontAtom } from '@/store/fontAtom' import { dimensionLineSettingsState } from '@/store/commonUtilsAtom' import { gridColorState } from '@/store/gridAtom' import { useColor } from 'react-color-palette' +import { useMasterController } from '@/hooks/common/useMasterController' const defaultDotLineGridSetting = { INTERVAL: { @@ -91,7 +92,7 @@ export function useCanvasSetting() { const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) - + const { getRoofMaterialList } = useMasterController() const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom) const SelectOptions = [ @@ -101,10 +102,9 @@ export function useCanvasSetting() { { id: 4, name: '1/10', value: 1 / 10 }, ] - useEffect(() => { - get({ url: `/api/v1/master/getRoofMaterialList` }).then((res) => { - setRoofMaterials(res.data) - }) + useEffect(async () => { + const { data } = await getRoofMaterialList() + setRoofMaterials(data) }, []) useEffect(() => { From 61c99c1458cfe6020cdd192c61d20fd5b954c19b Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 11 Dec 2024 17:25:38 +0900 Subject: [PATCH 17/22] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/basic/step/pitch/PitchPlacement.jsx | 9 +- src/hooks/module/useModuleBasicSetting.js | 667 ++++++++++++++---- 2 files changed, 539 insertions(+), 137 deletions(-) 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 7b00478e..d14bf0cc 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -1,17 +1,17 @@ import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' -import { compasDegAtom } from '@/store/orientationAtom' import { canvasState } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { POLYGON_TYPE } from '@/common/common' +import { useEvent } from '@/hooks/useEvent' const PitchPlacement = forwardRef((props, refs) => { const { getMessage } = useMessage() const [setupLocation, setSetupLocation] = useState('south') const { makeModuleInstArea } = useModuleBasicSetting() - const compasDeg = useRecoilValue(compasDegAtom) const canvas = useRecoilValue(canvasState) + const { initEvent } = useEvent() useEffect(() => { makeModuleInstArea() @@ -45,6 +45,7 @@ const PitchPlacement = forwardRef((props, refs) => { } const handleSetupLocation = (e) => { + initEvent() refs.setupLocation.current = e.target setSetupLocation(e.target.value) } @@ -153,7 +154,7 @@ const PitchPlacement = forwardRef((props, refs) => { value={'south'} checked={setupLocation === 'south'} defaultChecked - onChange={handleSetupLocation} + onClick={handleSetupLocation} />
    @@ -164,7 +165,7 @@ const PitchPlacement = forwardRef((props, refs) => { id="ra02" value={'excreta'} checked={setupLocation === 'excreta'} - onChange={handleSetupLocation} + onClick={handleSetupLocation} />
    diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index f51cf00f..e54b227f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -12,6 +12,7 @@ import { v4 as uuidv4 } from 'uuid' import { useSwal } from '@/hooks/useSwal' import { canvasSettingState } from '@/store/canvasAtom' import { compasDegAtom } from '@/store/orientationAtom' +import { QLine } from '@/components/fabric/QLine' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) @@ -51,6 +52,7 @@ export function useModuleBasicSetting() { const makeModuleInstArea = () => { //지붕 객체 반환 const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') + let offsetLength = canvasSetting.roofSizeSet === 3 ? -90 : -20 if (!roofs) { return @@ -63,13 +65,11 @@ export function useModuleBasicSetting() { } setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경 - const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset + const offsetPoints = offsetPolygon(roof.points, offsetLength) //안쪽 offset //모듈설치영역?? 생성 const surfaceId = uuidv4() - console.log('roof.moduleCompass', roof.moduleCompass) - let setupSurface = new QPolygon(offsetPoints, { stroke: 'red', fill: 'transparent', @@ -88,7 +88,10 @@ export function useModuleBasicSetting() { flipX: roof.flipX, flipY: roof.flipY, surfaceId: surfaceId, + originX: 'center', + originY: 'center', modules: [], + // angle: -compasDeg, }) setupSurface.setViewLengthText(false) @@ -102,6 +105,7 @@ export function useModuleBasicSetting() { } setupSurface.set({ flowLines: flowLines }) + flatRoofMakeSurface(roof, setupSurface) //지붕면 선택 금지 roof.set({ @@ -656,7 +660,7 @@ export function useModuleBasicSetting() { } } - const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, aaa, isCenter = false) => { let startPoint = flowModuleLine.left //중앙배치일 경우에는 계산한다 @@ -1206,9 +1210,10 @@ export function useModuleBasicSetting() { return turf.polygon([coordinates]) } - const polygonToTurfPolygon = (object) => { + const polygonToTurfPolygon = (object, current = false) => { let coordinates coordinates = object.points.map((point) => [point.x, point.y]) + if (current) coordinates = object.getCurrentPoints().map((point) => [point.x, point.y]) coordinates.push(coordinates[0]) return turf.polygon( [coordinates], @@ -1526,17 +1531,18 @@ export function useModuleBasicSetting() { let flatBatchType = placementFlatRef.setupLocation.current.value let excretaLinesAngle = [] - if (flatBatchType === 'south') { - applyAngle = compasDeg - } else { - const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine' && obj.isSelected === true) + if (flatBatchType === 'excreta') { + const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine') excretaLines.forEach((obj) => { - const points1 = { x: obj.x1, y: obj.y1 } - const points2 = { x: obj.x2, y: obj.y2 } - excretaLinesAngle.push({ - surfaceId: obj.surfaceId, - angle: calculateAngle(points1, points2), - }) + if (obj.isSelected) { + const points1 = { x: obj.x1, y: obj.y1 } + const points2 = { x: obj.x2, y: obj.y2 } + excretaLinesAngle.push({ + surfaceId: obj.surfaceId, + angle: calculateAngle(points1, points2), + }) + } + canvas.remove(obj) }) } @@ -1591,8 +1597,6 @@ export function useModuleBasicSetting() { return transformedCorners } - function getSelectedExcretaLine() {} - if (moduleSetupSurfaces.length !== 0) { let tempModule let manualDrawModules = [] @@ -1606,7 +1610,7 @@ export function useModuleBasicSetting() { const mousePoint = canvas.getPointer(e.e) for (let i = 0; i < moduleSetupSurfaces.length; i++) { - turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) + turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i], true) trestlePolygon = moduleSetupSurfaces[i] manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨 flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향 @@ -1616,18 +1620,11 @@ export function useModuleBasicSetting() { if (tempLine) { applyAngle = tempLine.angle } else { + //혹시나 두개의 지붕을 그리고 한쪽면만 선택했을때 한면은 그냥 기본 기울기를 준다 applyAngle = compasDeg } } - // const excretaLine = excretaLines.find((obj) => obj.isSelected === true && obj.surfaceId === trestlePolygon.surfaceId) - - // console.log('excretaLine', excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) - - // applyAngle = calculateAngle(excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) - - // console.log('applyAngle', applyAngle) - let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113 let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172 @@ -1667,123 +1664,125 @@ export function useModuleBasicSetting() { let snapDistance = 10 let cellSnapDistance = 20 - 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 + // if (applyAngle === 90 || applyAngle === 180 || applyAngle === 270 || applyAngle === 0) { + // 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 + // // 작은 폴리곤의 경계 좌표 계산 + // 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 (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 - 0.5 - } + // //설치된 셀에 좌측에 스냅 + // if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // tempModule.left = holdCellLeft - width - 0.5 + // } - //설치된 셀에 우측에 스냅 - if (Math.abs(smallLeft - holdCellRight) < snapDistance) { - tempModule.left = holdCellRight + 0.5 - } + // //설치된 셀에 우측에 스냅 + // if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // tempModule.left = holdCellRight + 0.5 + // } - //설치된 셀에 위쪽에 스냅 - if (Math.abs(smallBottom - holdCellTop) < snapDistance) { - tempModule.top = holdCellTop - height - 0.5 - } + // //설치된 셀에 위쪽에 스냅 + // if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + // tempModule.top = holdCellTop - height - 0.5 + // } - //설치된 셀에 밑쪽에 스냅 - if (Math.abs(smallTop - holdCellBottom) < snapDistance) { - tempModule.top = holdCellBottom + 0.5 - } - //가운데 -> 가운데 - 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 - holdCellBottom) < snapDistance) { + // tempModule.top = holdCellBottom + 0.5 + // } + // //가운데 -> 가운데 + // 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 - 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(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 (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 (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(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(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 - } - } + // 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 + // } + // } + // } inside = true break @@ -1833,8 +1832,6 @@ export function useModuleBasicSetting() { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 if (!isOverlap) { - console.log('tempModule.points', tempModule.points) - let manualModule = new QPolygon(tempModule.points, { ...moduleOptions }) canvas?.add(manualModule) manualDrawModules.push(tempModule) @@ -1849,7 +1846,411 @@ export function useModuleBasicSetting() { } } - const autoFlatroofModuleSetup = (placementFlatRef) => {} + const autoFlatroofModuleSetup = (placementFlatRef) => { + initEvent() //마우스 이벤트 초기화 + + let flatBatchType = placementFlatRef.setupLocation.current.value + const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 + + const notSelectedTrestlePolygons = canvas + ?.getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것 + + 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 객체 + + if (moduleSetupSurfaces.length === 0) { + alert('선택된 모듈 설치면이 없습니다.') + return + } + + //어짜피 자동으로 누르면 선택안된데도 다 날아간다 + canvas.getObjects().forEach((obj) => { + if (obj.name === 'module') { + canvas.remove(obj) + } + }) + + notSelectedTrestlePolygons.forEach((obj) => { + if (obj.modules) { + obj.modules.forEach((module) => { + canvas?.remove(module) + }) + obj.modules = [] + } + }) + + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: false, // 선택 가능하게 설정 + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + lockScalingX: true, // X 축 크기 조정 잠금 + lockScalingY: true, // Y 축 크기 조정 잠금 + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } + + let leftMargin, bottomMargin, square, chidoriLength + + //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 + const objectsIncludeSurface = (turfModuleSetupSurface) => { + let containsBatchObjects = [] + containsBatchObjects = batchObjects.filter((batchObject) => { + let convertBatchObject + + if (batchObject.type === 'group') { + //도머는 그룹형태임 + convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) + } else { + //개구, 그림자 + batchObject.set({ points: rectToPolygon(batchObject) }) + canvas?.renderAll() // set된걸 바로 적용하기 위해 + convertBatchObject = polygonToTurfPolygon(batchObject) //rect를 폴리곤으로 변환 -> turf 폴리곤으로 변환 + } + + // 폴리곤 안에 도머 폴리곤이 포함되어있는지 확인해서 반환하는 로직 + return turf.booleanContains(turfModuleSetupSurface, convertBatchObject) || turf.booleanWithin(convertBatchObject, turfModuleSetupSurface) + }) + + return containsBatchObjects + } + + /** + * 도머나 개구가 모듈에 걸치는지 확인하는 로직 + * @param {*} squarePolygon + * @param {*} containsBatchObjects + * @returns + */ + const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => { + let isDisjoint = false + + if (containsBatchObjects.length > 0) { + let convertBatchObject + //도머가 있으면 적용되는 로직 + isDisjoint = containsBatchObjects.every((batchObject) => { + if (batchObject.type === 'group') { + convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) + } else { + convertBatchObject = polygonToTurfPolygon(batchObject) + } + /** + * 도머가 여러개일수있으므로 겹치는게 있다면... + * 안겹치는지 확인하는 로직이라 안겹치면 true를 반환 + */ + return turf.booleanDisjoint(squarePolygon, convertBatchObject) + }) + } else { + isDisjoint = true + } + return isDisjoint + } + + /** + * 배치면 안에 있는지 확인 + * @param {*} squarePolygon + * @param {*} turfModuleSetupSurface + * @returns + */ + const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => { + return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) + } + + let moduleGroup = [] + + const flatRoofDownFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => { + let startPoint = moduleSetupSurface.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] })) + + 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 //최하단 + + 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 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) { + 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 maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + 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 //최대배치인지 확인하려고 넣음 + + for (let j = 0; j < diffBottomEndPoint; j++) { + bottomMargin = marginHeight * j + for (let i = 0; i < diffRightEndPoint; i++) { + leftMargin = marginWidth * i + + 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], + ] + + 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) { + 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) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + moduleGroup.push(tempModule) + } + } + } + + moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { + moduleSetupSurface.fire('mousedown') + const moduleSetupArray = [] + + let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { + return acc.length > cur.length ? acc : cur + }) + + 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 = 0 + const marginHeight = 0 + + canvas.renderAll() + + if (compasDeg >= 0 && compasDeg < 90) { + flatRoofDownFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) + } else if (compasDeg >= 90 && compasDeg < 180) { + flatRoofLeftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) + } else if (compasDeg >= 180 && compasDeg < 270) { + flatRoofRightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) + } else { + flatRoofTopFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) + } + + const setupedModules = moduleSetupArray.filter((module, index) => { + let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) + let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) + + if (!(disjointFromTrestle && isDisjoint)) { + canvas?.remove(module) + // module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + return false + } else { + return module + } + }) + + canvas?.renderAll() + + //나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기 + // setupedModules.forEach((module, index) => { + // if (isMaxSetup && index > 0) { + // const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module)) + // //겹치는지 확인 + // if (isOverlap) { + // //겹쳐있으면 삭제 + // // canvas?.remove(module) + // module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 }) + // canvas.renderAll() + // setupedModules.splice(index, 1) + // return false + // } + // } + // }) + + moduleSetupSurface.set({ modules: setupedModules }) + + // const moduleArray = [...moduleIsSetup] + // moduleArray.push({ + // surfaceId: moduleSetupSurface.surfaceId, + // moduleSetupArray: setupedModules, + // }) + // setModuleIsSetup(moduleArray) + }) + // console.log(calculateForApi()) + } + + const flatRoofMakeSurface = (roof, setupSurface) => { + setupSurface.angle = -compasDeg + roof.angle = -compasDeg + + const roofPoints = roof.getCurrentPoints() + const roofLines = roofPoints.map((point, index) => { + const nextIndex = (index + 1) % roofPoints.length + const nextPoint = roofPoints[nextIndex] + + return { + x1: point.x, + y1: point.y, + x2: nextPoint.x, + y2: nextPoint.y, + } + }) + roof.set({ lines: roofLines }) + roof.fire('modified') + + const surfacePoints = setupSurface.getCurrentPoints() + const surfaceLines = surfacePoints.map((point, index) => { + const nextIndex = (index + 1) % surfacePoints.length + const nextPoint = surfacePoints[nextIndex] + + return { + x1: point.x, + y1: point.y, + x2: nextPoint.x, + y2: nextPoint.y, + } + }) + setupSurface.set({ lines: surfaceLines }) + + const flowLines = { + bottom: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'bottom'), + top: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'top'), + left: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'left'), + right: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'right'), + } + setupSurface.set({ flowLines: flowLines }) + setupSurface.fire('modified') + } return { makeModuleInstArea, From 1aee8d6425da96873e9fb20c1482f024b51a77c4 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 11 Dec 2024 18:02:12 +0900 Subject: [PATCH 18/22] =?UTF-8?q?useEffect=20async=20await=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index dfc0c244..7309d3d2 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -102,10 +102,14 @@ export function useCanvasSetting() { { id: 4, name: '1/10', value: 1 / 10 }, ] - useEffect(async () => { + useEffect(() => { + addRoofMaterials() + }, []) + + const addRoofMaterials = async () => { const { data } = await getRoofMaterialList() setRoofMaterials(data) - }, []) + } useEffect(() => { if (!canvas) { @@ -295,7 +299,7 @@ export function useCanvasSetting() { objectNo: correntObjectNo, roofSizeSet: basicSetting.roofSizeSet, roofAngleSet: basicSetting.roofAngleSet, - roofMaterialsAddList: basicSetting.roofs, + roofMaterialsAddList: basicSetting.roofs, // TODO : 선택된 roof로 변경해야함 } await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { From 3f97239d88d9f9f91820f02dacce87f479b46202 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Wed, 11 Dec 2024 18:10:56 +0900 Subject: [PATCH 19/22] =?UTF-8?q?=EB=B0=B0=EC=B9=98=20API=20=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMasterController.js | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js index d0cac892..ced80244 100644 --- a/src/hooks/common/useMasterController.js +++ b/src/hooks/common/useMasterController.js @@ -1,4 +1,5 @@ import { useAxios } from '@/hooks/useAxios' +import axios from 'axios' /** * 마스터 컨트롤러 훅 @@ -30,8 +31,47 @@ export function useMasterController() { }) } + /** + * 가대 목록 조회 + * @param + * @returns + */ + const getTrestleList = async (params) => { + return await get({ url: `/api/v1/master/getTrestleList/${params}` }).then((res) => { + console.log('🚀🚀 ~ getTrestleList ~ res:', res) + return res + }) + } + + /** + * 모듈 시공법 목록 조회 + * @param + * @returns + */ + const getConstructionList = async (params) => { + return await get({ url: `/api/v1/master/getConstructionList/${params}` }).then((res) => { + console.log('🚀🚀 ~ getConstructionList ~ res:', res) + return res + }) + } + + /** + * 가대 상세 조회 + * @param + * @returns + */ + const getTrestleDetailList = async (params) => { + return await get({ url: `/api/v1/master/getTrestleDetailList/${params}` }).then((res) => { + console.log('🚀🚀 ~ getTrestleDetailList ~ res:', res) + return res + }) + } + return { getRoofMaterialList, getModuleTypeItemList, + getTrestleList, + getConstructionList, + getTrestleDetailList, } } From 00cf733b59bbb7a91eb0fb9a8443a280f9d90d5b Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 12 Dec 2024 09:53:41 +0900 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=91=8CgetQueryString=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/common-utils.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/util/common-utils.js b/src/util/common-utils.js index 06b96b60..95e6be87 100644 --- a/src/util/common-utils.js +++ b/src/util/common-utils.js @@ -117,3 +117,15 @@ export const calculateFlowDirection = (canvasAngle) => { right: -90 - canvasAngle < -180 ? -90 - canvasAngle + 360 : -90 - canvasAngle, } } + +/** + * 자바스크립트 객체로 쿼리스트링 생성 + * @param {javascript object} o 쿼리스트링 생성할 객체 + * @returns {string} 쿼리스트링 + */ +export const getQueryString = (o) => { + const queryString = Object.keys(o) + .map((key) => `${key}=${o[key]}`) + .join('&') + return `?${queryString}` +} From fca9ce557f2e840f9898f1ea3357c3e5732fbfa6 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 12 Dec 2024 11:27:29 +0900 Subject: [PATCH 21/22] =?UTF-8?q?=EB=AC=BC=EA=B1=B4,=20=EA=B2=AC=EC=A0=81?= =?UTF-8?q?=EC=84=9C=20=EC=9E=91=EC=84=B1=EC=9E=90=EA=B0=80=20T01=EC=9D=B8?= =?UTF-8?q?=EB=8D=B0=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20T01=EC=9D=B4=20=EC=95=84=EB=8B=8C=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EB=8F=84=EB=A9=B4=EC=9E=91=EC=84=B1,=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EB=93=B1=20=EB=B2=84=ED=8A=BC=20=EC=88=A8=EA=B9=80?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 19 ++++++++++++++-- src/components/management/StuffDetail.jsx | 3 +-- src/components/management/StuffSubHeader.jsx | 23 +++++++++++++++++--- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 5ed215f9..435fc762 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -41,6 +41,7 @@ import { pwrGnrSimTypeState } from '@/store/simulatorAtom' import { useAxios } from '@/hooks/useAxios' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' +import { isObjectNotEmpty } from '@/util/common-utils' export default function CanvasMenu(props) { const { menuNumber, setMenuNumber } = props @@ -78,6 +79,9 @@ export default function CanvasMenu(props) { const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext) const { restoreModuleInstArea } = useModuleBasicSetting() + //견적서버튼 노출용 + const [buttonStyle, setButtonStyle] = useState('') + const onClickNav = (menu) => { setMenuNumber(menu.index) setCurrentMenu(menu.title) @@ -241,6 +245,16 @@ export default function CanvasMenu(props) { }) } + useEffect(() => { + if (isObjectNotEmpty(estimateRecoilState)) { + if (estimateRecoilState?.createUser === 'T01') { + if (sessionState.userId !== 'T01') { + setButtonStyle('none') + } + } + } + }, [estimateRecoilState]) + return (
    num === menuNumber) ? 'active' : ''}`}>
    @@ -320,11 +334,12 @@ export default function CanvasMenu(props) { {getMessage('plan.menu.estimate.docDown')} - )} - diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index bba99266..95cb2fef 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -10,7 +10,7 @@ import { globalLocaleStore } from '@/store/localeAtom' import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' -import { useRecoilValue, useSetRecoilState, useResetRecoilState, useRecoilState } from 'recoil' +import { useRecoilValue, useSetRecoilState, useResetRecoilState } from 'recoil' import { SessionContext } from '@/app/SessionProvider' import FindAddressPop from './popup/FindAddressPop' import PlanRequestPop from './popup/PlanRequestPop' @@ -41,7 +41,6 @@ export default function StuffDetail() { const { session } = useContext(SessionContext) const router = useRouter() - const pathname = usePathname() const searchParams = useSearchParams() const { getMessage } = useMessage() const globalLocaleState = useRecoilValue(globalLocaleStore) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index ab838335..27acf615 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -1,6 +1,6 @@ 'use client' -import { useContext, useEffect } from 'react' +import { useState, useContext, useEffect } from 'react' import Link from 'next/link' import Image from 'next/image' @@ -11,20 +11,37 @@ import { useSetRecoilState } from 'recoil' import { QcastContext } from '@/app/QcastProvider' import { useMessage } from '@/hooks/useMessage' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' -import { queryStringFormatter } from '@/util/common-utils' +import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' + +import { ManagementContext } from '@/app/management/ManagementProvider' +import { SessionContext } from '@/app/SessionProvider' export default function StuffSubHeader({ type }) { const { getMessage } = useMessage() const router = useRouter() + const { session } = useContext(SessionContext) const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) const { isGlobalLoading } = useContext(QcastContext) + const { managementState } = useContext(ManagementContext) + + const [buttonStyle, setButtonStyle] = useState('') useEffect(() => { window.scrollTo(0, 0) }, []) + useEffect(() => { + if (isObjectNotEmpty(managementState)) { + if (managementState.createUser === 'T01') { + if (session.userId !== 'T01') { + setButtonStyle('none') + } + } + } + }, [managementState]) + const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set @@ -98,7 +115,7 @@ export default function StuffSubHeader({ type }) { {getMessage('stuff.temp.subTitle')}
  • -
  • +
  • {getMessage('stuff.temp.subTitle2')} From e296c1799406ed40a067c01a109ac293ecf29bff Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Thu, 12 Dec 2024 13:32:38 +0900 Subject: [PATCH 22/22] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EB=B3=84=20=EC=95=84=EC=9D=B4=ED=85=9C=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20api=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=B0=A9=EC=8B=9D=EC=9D=84=20query=20string=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20va?= =?UTF-8?q?lidation=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMasterController.js | 17 ++++++++++++++--- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js index ced80244..4f8bb799 100644 --- a/src/hooks/common/useMasterController.js +++ b/src/hooks/common/useMasterController.js @@ -1,4 +1,7 @@ import { useAxios } from '@/hooks/useAxios' +import { useMessage } from '@/hooks/useMessage' +import { useSwal } from '@/hooks/useSwal' +import { getQueryString } from '@/util/common-utils' import axios from 'axios' /** @@ -7,6 +10,8 @@ import axios from 'axios' */ export function useMasterController() { const { get } = useAxios() + const { getMessage } = useMessage() + const { swalFire } = useSwal() /** * 지붕재 목록 조회 @@ -21,11 +26,17 @@ export function useMasterController() { /** * 모듈 타입별 아이템 목록 조회 - * @param {지붕재 코드} roofMaterialCd + * @param {지붕재 코드} roofMatlCd * @returns */ - const getModuleTypeItemList = async (roofMaterialCd) => { - return await get({ url: `/api/v1/master/getModuleTypeItemList/${roofMaterialCd}` }).then((res) => { + const getModuleTypeItemList = async (roofMatlCd) => { + if (!roofMatlCd || roofMatlCd.trim() === '') { + swalFire({ text: getMessage('master.moduletypeitem.message.error'), type: 'alert', icon: 'error' }) + return null + } + const param = { roofMatlCd: roofMatlCd } + const paramString = getQueryString(param) + return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => { console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res) return res }) diff --git a/src/locales/ja.json b/src/locales/ja.json index 243418a8..e0559649 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -932,5 +932,6 @@ "simulator.table.sub8": "台", "simulator.table.sub9": "予測発電量 (kWh)", "simulator.notice.sub1": "Hanwha Japan 年間発電量", - "simulator.notice.sub2": "シミュレーション案内事項" + "simulator.notice.sub2": "シミュレーション案内事項", + "master.moduletypeitem.message.error": "지붕재 코드를 입력하세요." } diff --git a/src/locales/ko.json b/src/locales/ko.json index 495fe2dc..b4b745bc 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -942,5 +942,6 @@ "simulator.table.sub8": "대", "simulator.table.sub9": "예측발전량 (kWh)", "simulator.notice.sub1": "Hanwha Japan 연간 발전량", - "simulator.notice.sub2": "시뮬레이션 안내사항" + "simulator.notice.sub2": "시뮬레이션 안내사항", + "master.moduletypeitem.message.error": "지붕재 코드를 입력하세요." }