dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
- onChange={(e) => setEavesMargin(+e.target.value)}
- />
+
-
{getMessage('modal.module.basic.setting.module.placement.area.ridge')}
-
- dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
- onChange={(e) => setRidgeMargin(+e.target.value)}
- />
+
+
+
{getMessage('modal.module.basic.setting.module.placement.margin')}
+
+
+
{getMessage('modal.module.basic.setting.module.placement.margin.horizontal')}
+
+
+
+
mm
-
mm
-
-
-
{getMessage('modal.module.basic.setting.module.placement.area.keraba')}
-
-
dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
- onChange={(e) => setKerabaMargin(+e.target.value)}
- />
+
+
{getMessage('modal.module.basic.setting.module.placement.margin.vertical')}
+
+
+
+
mm
-
mm
diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx
index f524f8cd..7ce753df 100644
--- a/src/components/header/Header.jsx
+++ b/src/components/header/Header.jsx
@@ -75,19 +75,19 @@ export default function Header(props) {
userSession.storeId === 'T01'
? [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
- { id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
- { id: 2, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
+ { id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
+ { id: 2, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
]
: userSession.groupId === '60000'
? [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
- { id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
+ { id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
]
: [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
- { id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
+ { id: 1, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
],
)
diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js
index 60aab800..21220726 100644
--- a/src/hooks/common/useMasterController.js
+++ b/src/hooks/common/useMasterController.js
@@ -18,7 +18,7 @@ export function useMasterController() {
*/
const getRoofMaterialList = async () => {
return await get({ url: '/api/v1/master/getRoofMaterialList' }).then((res) => {
- console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res)
+ // console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res)
return res
})
}
diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js
index a0765766..a4c83fe7 100644
--- a/src/hooks/floorPlan/estimate/useEstimateController.js
+++ b/src/hooks/floorPlan/estimate/useEstimateController.js
@@ -310,6 +310,7 @@ export const useEstimateController = (planNo, flag) => {
//봄 컴포넌트 제품은 0으로
item.openFlg = '0'
+ item.unitOpenFlg = '0'
}
}
})
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js
index 1871e34a..a3f2eb0e 100644
--- a/src/hooks/module/useModuleBasicSetting.js
+++ b/src/hooks/module/useModuleBasicSetting.js
@@ -19,7 +19,7 @@ import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qp
import { QPolygon } from '@/components/fabric/QPolygon'
import { moduleSetupSurfaceState } from '@/store/canvasAtom'
import { useEvent } from '@/hooks/useEvent'
-import { POLYGON_TYPE, BATCH_TYPE, LINE_TYPE } from '@/common/common'
+import { POLYGON_TYPE, BATCH_TYPE, LINE_TYPE, MODULE_SETUP_TYPE } from '@/common/common'
import * as turf from '@turf/turf'
import { useSwal } from '@/hooks/useSwal'
import { compasDegAtom } from '@/store/orientationAtom'
@@ -49,20 +49,17 @@ export function useModuleBasicSetting(tabNum) {
const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState)
const canvasSetting = useRecoilValue(canvasSettingState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
- const [trestleDetailParams, setTrestleDetailParams] = useState([])
const [trestleDetailList, setTrestleDetailList] = useState([])
const selectedModules = useRecoilValue(selectedModuleState)
- const { getTrestleDetailList } = useMasterController()
const [saleStoreNorthFlg, setSaleStoreNorthFlg] = useState(false)
const setCurrentObject = useSetRecoilState(currentObjectState)
const { setModuleStatisticsData } = useCircuitTrestle()
const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode()
- const { drawDirectionArrow } = usePolygon()
const moduleSetupOption = useRecoilValue(moduleSetupOptionState)
const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState)
- const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState)
+ const setModuleRowColArray = useSetRecoilState(moduleRowColArrayState)
useEffect(() => {
return () => {
@@ -92,12 +89,12 @@ export function useModuleBasicSetting(tabNum) {
//roofIndex 넣기
const roofConstructionArray = roofConstructions.map((detail) => ({ ...detail.trestleDetail, roofIndex: detail.roofIndex }))
- setTrestleDetailList(roofConstructionArray)
-
//북면 설치 가능 판매점
- if (moduleSelectionData.common.saleStoreNorthFlg === '1') {
+ if (moduleSelectionData.common.saleStoreNorthFlg == '1') {
setSaleStoreNorthFlg(true)
}
+
+ setTrestleDetailList(roofConstructionArray)
}
} else {
//육지붕 일경우에는 바로 배치면 설치LL
@@ -149,7 +146,7 @@ export function useModuleBasicSetting(tabNum) {
const moduleRowArray = []
if (isObjectNotEmpty(detail) && detail.module.length > 0) {
detail.module.forEach((module) => {
- moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows })
+ moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows, maxRow: detail.moduleMaxRows })
})
}
rowColArray.push(moduleRowArray)
@@ -236,8 +233,26 @@ export function useModuleBasicSetting(tabNum) {
}
})
+ let isNorth = false
+
const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id)
+
if (isExistSurface) {
+ if (canvasSetting.roofSizeSet != '3') {
+ //북면이 있지만
+ if (roof.directionText && roof.directionText.indexOf('北') > -1) {
+ //북쪽일때 해당 서북서, 동북동은 제외한다고 한다
+ if (!(roof.directionText.indexOf('西北西') > -1 || roof.directionText.indexOf('東北東') > -1)) {
+ isNorth = true
+ }
+ }
+
+ isExistSurface.set({
+ isNorth: isNorth, //북면여부
+ isSaleStoreNorthFlg: moduleSelectionData.common.saleStoreNorthFlg == '1' ? true : false, //북면설치가능점 여부
+ })
+ }
+
addTargetMouseEventListener('mousedown', isExistSurface, function () {
toggleSelection(isExistSurface)
})
@@ -270,7 +285,6 @@ export function useModuleBasicSetting(tabNum) {
//모듈설치영역?? 생성
const surfaceId = uuidv4()
- let isNorth = false
if (canvasSetting.roofSizeSet != '3') {
//북면이 있지만
@@ -307,6 +321,7 @@ export function useModuleBasicSetting(tabNum) {
trestleDetail: trestleDetail,
isNorth: isNorth,
perPixelTargetFind: true,
+ isSaleStoreNorthFlg: moduleSelectionData.common.saleStoreNorthFlg == '1' ? true : false, //북면설치가능점 여부
// angle: -compasDeg,
})
@@ -352,8 +367,11 @@ export function useModuleBasicSetting(tabNum) {
const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
//최초 선택일때
if (!isExist) {
- //설치면이 북면이고 북면설치 허용점이 아니면
- if (setupSurface.isNorth && !saleStoreNorthFlg) {
+ //모듈에 북면 설치 가능 모듈이 있는지 확인함
+ const isNorthModuleYn = moduleSelectionData?.module.itemList.some((module) => module.northModuleYn === 'Y')
+
+ //설치면이 북면이고 북면설치 허용점이 아니면 북면 모듈이 한개도 없으면
+ if (setupSurface.isNorth && !setupSurface.isSaleStoreNorthFlg && !isNorthModuleYn) {
swalFire({ text: getMessage('module.not.batch.north'), icon: 'warning' })
return
}
@@ -431,14 +449,14 @@ export function useModuleBasicSetting(tabNum) {
}
if (checkedModule.length === 0) {
- swalFire({ text: getMessage('module.place.select.module') })
+ swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' })
setIsManualModuleSetup(false)
setManualSetupMode(`manualSetup_false`)
return
}
if (checkedModule.length > 1) {
- swalFire({ text: getMessage('module.place.select.one.module') })
+ swalFire({ text: getMessage('module.place.select.one.module'), icon: 'warning' })
setIsManualModuleSetup(false)
setManualSetupMode(`manualSetup_false`)
return
@@ -538,9 +556,15 @@ export function useModuleBasicSetting(tabNum) {
parentId: moduleSetupSurfaces[i].parentId,
})
+ const northModuleYn = checkedModule.some((module) => module.northModuleYn === 'Y')
//북면이고 북면설치상점이 아니면 그냥 return
- if (trestlePolygon.isNorth && !saleStoreNorthFlg) {
- return
+ if (trestlePolygon.isNorth && !trestlePolygon.isSaleStoreNorthFlg) {
+ if (!northModuleYn) {
+ //북면이고 설치 가능 상점이 아닌데 북면 설치 모듈이 있으면
+ return
+ } else {
+ canvas?.add(tempModule) //움직여가면서 추가됨
+ }
} else {
canvas?.add(tempModule) //움직여가면서 추가됨
}
@@ -765,7 +789,7 @@ export function useModuleBasicSetting(tabNum) {
const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn
//현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능
if (checkedModule[0].mixAsgYn !== mixAsgYn) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
return
}
}
@@ -798,7 +822,7 @@ export function useModuleBasicSetting(tabNum) {
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
//겹치면 안됨
if (intersection) {
- swalFire({ text: getMessage('module.place.overobject') })
+ swalFire({ text: getMessage('module.place.overobject'), icon: 'warning' })
isIntersection = false
}
})
@@ -841,10 +865,10 @@ export function useModuleBasicSetting(tabNum) {
// getModuleStatistics()
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
}
} else {
- swalFire({ text: getMessage('module.place.out') })
+ swalFire({ text: getMessage('module.place.out'), icon: 'warning' })
}
}
})
@@ -876,7 +900,7 @@ export function useModuleBasicSetting(tabNum) {
}
if (checkedModule.length === 0) {
- swalFire({ text: getMessage('module.place.select.module') })
+ swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' })
setIsManualModuleLayoutSetup(false)
setManualSetupMode(`manualLayoutSetup_false`)
return
@@ -890,7 +914,7 @@ export function useModuleBasicSetting(tabNum) {
)
if (hasZeroLength) {
- swalFire({ text: getMessage('module.layout.setup.has.zero.value') })
+ swalFire({ text: getMessage('module.layout.setup.has.zero.value'), icon: 'warning' })
setIsManualModuleLayoutSetup(false)
setManualSetupMode(`manualLayoutSetup_false`)
return
@@ -902,7 +926,7 @@ export function useModuleBasicSetting(tabNum) {
//Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가
if (mixAsgY.length > 0 && mixAsgN.length > 0) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
return
}
@@ -1017,26 +1041,6 @@ export function useModuleBasicSetting(tabNum) {
},
]
- //아래래
- // let points = [
- // {
- // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth,
- // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight,
- // },
- // {
- // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth,
- // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight,
- // },
- // {
- // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth,
- // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight,
- // },
- // {
- // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth,
- // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight,
- // },
- // ]
-
const turfPoints = coordToTurfPolygon(points)
if (turf.booleanWithin(turfPoints, turfPolygon)) {
@@ -1068,9 +1072,15 @@ export function useModuleBasicSetting(tabNum) {
parentId: moduleSetupSurfaces[i].parentId,
})
+ const northModuleYn = checkedModule.some((module) => module.northModuleYn === 'Y')
//북면이고 북면설치상점이 아니면 그냥 return
- if (trestlePolygon.isNorth && !saleStoreNorthFlg) {
- return
+ if (trestlePolygon.isNorth && !trestlePolygon.isSaleStoreNorthFlg) {
+ if (!northModuleYn) {
+ //북면이고 설치 가능 상점이 아닌데 북면 설치 모듈이 있으면
+ return
+ } else {
+ canvas?.add(tempModule) //움직여가면서 추가됨
+ }
} else {
canvas?.add(tempModule) //움직여가면서 추가됨
}
@@ -1256,7 +1266,7 @@ export function useModuleBasicSetting(tabNum) {
const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn
//현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능
if (checkedModule[0].mixAsgYn !== mixAsgYn) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
return
}
}
@@ -1415,7 +1425,7 @@ export function useModuleBasicSetting(tabNum) {
// canvas.renderAll()
}
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
return
}
}
@@ -1510,7 +1520,7 @@ export function useModuleBasicSetting(tabNum) {
// canvas.renderAll()
}
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
return
}
}
@@ -1603,7 +1613,7 @@ export function useModuleBasicSetting(tabNum) {
// canvas.renderAll()
}
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
return
}
}
@@ -1695,7 +1705,7 @@ export function useModuleBasicSetting(tabNum) {
// canvas.renderAll()
}
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
return
}
}
@@ -1732,21 +1742,39 @@ export function useModuleBasicSetting(tabNum) {
}
//자동 모듈 설치(그리드 방식)
- const autoModuleSetup = (placementRef) => {
+ const autoModuleSetup = (type, layoutSetupRef) => {
initEvent() //마우스 이벤트 초기화
- if (checkedModule.length === 0) {
- swalFire({ text: getMessage('module.place.select.module') })
- return
+ //실패한 지붕재 배열
+ let failAutoSetupRoof = []
+
+ let checkedLayoutData
+
+ /**
+ * 자동 레이아웃일때 0이 있거나 혼합이 있는지 확인하는 로직
+ */
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ checkedLayoutData = layoutSetupRef.filter((module) => module.checked)
+ const hasZeroLength = checkedLayoutData.some((module) => module.row === 0 || module.col === 0)
+
+ if (hasZeroLength) {
+ swalFire({ text: getMessage('module.layout.setup.has.zero.value'), icon: 'warning' })
+ return
+ }
+
+ // //혼합 가능 모듈과 혼합 불가능 모듈을 선택했을때 카운트를 해서 확인
+ // const mixAsgY = checkedModule.filter((obj) => obj.mixAsgYn === 'Y')
+ // const mixAsgN = checkedModule.filter((obj) => obj.mixAsgYn === 'N')
+
+ // //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가
+ // if (mixAsgY.length > 0 && mixAsgN.length > 0) {
+ // swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
+ // return
+ // }
}
- //혼합 가능 모듈과 혼합 불가능 모듈을 선택했을때 카운트를 해서 확인
- const mixAsgY = checkedModule.filter((obj) => obj.mixAsgYn === 'Y')
- const mixAsgN = checkedModule.filter((obj) => obj.mixAsgYn === 'N')
-
- //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가
- if (mixAsgY.length > 0 && mixAsgN.length > 0) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ if (checkedModule.length === 0) {
+ swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' })
return
}
@@ -1762,26 +1790,40 @@ export function useModuleBasicSetting(tabNum) {
const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체
if (moduleSetupSurfaces.length === 0) {
- swalFire({ text: getMessage('module.place.no.surface') })
+ swalFire({ text: getMessage('module.place.no.surface'), icon: 'warning' })
return
}
//어짜피 자동으로 누르면 선택안된데도 다 날아간다
- canvas.getObjects().forEach((obj) => {
- if (obj.name === POLYGON_TYPE.MODULE) {
- canvas.remove(obj)
- }
- })
+ // canvas.getObjects().forEach((obj) => {
+ // if (obj.name === POLYGON_TYPE.MODULE) {
+ // canvas.remove(obj)
+ // }
+ // })
- notSelectedTrestlePolygons.forEach((obj) => {
+ //자동일때만 선택 안된 모듈 삭제
+ moduleSetupSurfaces.forEach((obj) => {
if (obj.modules) {
obj.modules.forEach((module) => {
canvas?.remove(module)
+ canvas?.renderAll()
})
obj.modules = []
}
})
+ if (type === MODULE_SETUP_TYPE.AUTO) {
+ notSelectedTrestlePolygons.forEach((obj) => {
+ if (obj.modules) {
+ obj.modules.forEach((module) => {
+ canvas?.remove(module)
+ canvas?.renderAll()
+ })
+ obj.modules = []
+ }
+ })
+ }
+
let moduleOptions = {
stroke: 'black',
strokeWidth: 0.3,
@@ -1820,17 +1862,123 @@ export function useModuleBasicSetting(tabNum) {
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
}
+ /**
+ * 자동 레이아웃 설치 일시 row col 초과 여부 확인
+ * 체크된 모듈중에 북면 모듈이 있으면 북면 모듈만 따로 계산하고 아니면 전체 모듈을 계산
+ * 북면 모듈이 있고 북면이 들어오면 북면의 row를 계산한다
+ *
+ * @param {*} trestleDetailData
+ * @returns
+ */
+ const checkAutoLayoutModuleSetup = (moduleSetupSurface, trestleDetailData) => {
+ //북면 모듈이 없을때
+ //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직
+ const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y')
+ const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음
+
+ //북면 모듈이 없으면
+ if (!isIncludeNorthModule) {
+ const isMultipleModules = checkedModule.length > 1 //모듈이 여러개인지 체크하고
+
+ //멀티 모듈이면 모듈밖에 내려온 정보의 maxRow 단일 모듈이면 모듈에 maxRow
+ const maxRow = isMultipleModules
+ ? trestleDetailData.moduleMaxRows
+ : trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단
+
+ //멀티 모듈이면 모듈밖에 내려온 정보의 row 합, 단일 모듈이면 모듈에 row
+ const sumRowCount = isMultipleModules
+ ? layoutSetupRef.filter((item) => item.checked).reduce((acc, cur) => acc + cur.row, 0)
+ : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열
+
+ //col는 moduleItems 배열 밖에 내려옴
+ const sumColCount = layoutSetupRef.filter((item) => item.col).some((item) => item.col > maxCol)
+
+ // 혼합일때 모듈 개별의 maxRow를 체크해서 가능여부 확인
+ const isPassedObject =
+ isMultipleModules && layoutSetupRef.find((item, index) => item.checked && item.row > trestleDetailData.module[index].mixModuleMaxRows) //체크된 배열은 checked여부로 체크해서 index와 동일함
+ //전체 카은트된 열수가 크거나 혼합카운트가 존재 하면 실패
+ if (sumRowCount > maxRow || sumColCount || isPassedObject) {
+ failAutoSetupRoof.push(moduleSetupSurface)
+ return false
+ }
+ } else {
+ const normalModule = checkedModule.filter((item) => item.northModuleYn === 'N')
+ const northModule = checkedModule.filter((item) => item.northModuleYn === 'Y')
+ const northModuleIds = northModule.map((item) => item.itemId)
+ let isPassedNormalModule = false
+
+ //만약 북면 모듈이 2개면 이 하위 로직 가져다가 쓰면됨 northModule === 만 바꾸면 될듯
+ // northModule을 배열로 만들고 include로 해서 체크 해야됨
+ if (normalModule.length > 0 && !moduleSetupSurface.isNorth) {
+ //C1C2 모듈일 경우ㅁㅁ
+ const isMultipleModules = normalModule.length > 1 //모듈이 여러개면
+ const maxRow = isMultipleModules
+ ? trestleDetailData.moduleMaxRows
+ : trestleDetailData.module.find((item) => item.moduleTpCd === normalModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단
+
+ //북면 모듈 id를 제외한 모듈의 단 체크
+ const sumRowCount = isMultipleModules
+ ? layoutSetupRef.filter((item) => item.checked && !northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0)
+ : layoutSetupRef.find((item) => item.moduleId === normalModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열
+
+ //북면 모듈 id를 제외한 모듈의 열 체크
+ const sumColCount = layoutSetupRef.filter((item) => item.col && !northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol)
+
+ // 혼합일때 모듈 개별의 row를 체크함
+ const isPassedObject =
+ isMultipleModules &&
+ layoutSetupRef.find(
+ (item, index) => item.checked && !item.moduleId.includes(northModuleIds) && item.row > trestleDetailData.module[index].mixModuleMaxRows,
+ )
+
+ // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패
+ if (sumRowCount > maxRow || sumColCount || isPassedObject) {
+ failAutoSetupRoof.push(moduleSetupSurface)
+ return false
+ } else {
+ isPassedNormalModule = true
+ }
+ }
+
+ //위에서 일반 모듈이 설치가 완료면 그냥 넘어간다
+ //일반 모듈이 pass라면 일반 모듈이 설치됨
+ //만약 일반모듈이 체크가 안되어 있으면 밑에 로직을 탐
+ if (!isPassedNormalModule) {
+ //북면 모듈이 있고 북면에 있을때
+ if (northModule.length > 0 && (moduleSetupSurface.isNorth || !moduleSetupSurface.isNorth)) {
+ //북면 모듈이 있는데 일반 모듈이 있을때 북면이 아니면 그냥 북면은 그냥 pass
+ const isMultipleModules = northModule.length > 1 //모듈이 여러개면
+ const maxRow = isMultipleModules
+ ? trestleDetailData.moduleMaxRows
+ : trestleDetailData.module.find((item) => item.moduleTpCd === northModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단
+
+ const sumRowCount = isMultipleModules
+ ? layoutSetupRef.filter((item) => northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0)
+ : layoutSetupRef.find((item) => item.moduleId === northModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열
+
+ const sumColCount = layoutSetupRef.filter((item) => item.col && northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol)
+
+ // 혼합일때 모듈 개별의 row를 체크함
+ const isPassedObject =
+ isMultipleModules &&
+ layoutSetupRef.find(
+ (item, index) =>
+ item.checked && northModuleIds.includes(item.moduleId) && item.row > trestleDetailData.module[index].mixModuleMaxRows,
+ )
+
+ // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패
+ if (sumRowCount > maxRow || sumColCount || isPassedObject) {
+ failAutoSetupRoof.push(moduleSetupSurface)
+ return false
+ }
+ }
+ }
+ }
+ return true
+ }
+
//흐름 방향이 남쪽(아래)
- const downFlowSetupModule = (
- surfaceMaxLines,
- maxLengthLine,
- moduleSetupArray,
- moduleSetupSurface,
- containsBatchObjects,
- isCenter = false,
- intvHor,
- intvVer,
- ) => {
+ const downFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => {
let setupModule = []
const trestleDetailData = moduleSetupSurface.trestleDetail
@@ -1840,8 +1988,35 @@ export function useModuleBasicSetting(tabNum) {
let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트
let isChidoriLine = false
let flowLines
+ let installedModuleMixYn
+ const isNorthSurface = moduleSetupSurface.isNorth
+ const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직
+
+ let layoutRow = 0
+ let layoutCol = 0
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ const isPassed = checkAutoLayoutModuleSetup(moduleSetupSurface, trestleDetailData)
+ if (!isPassed) {
+ return
+ }
+ }
+
+ for (let moduleIndex = 0; moduleIndex < checkedModule.length; moduleIndex++) {
+ const module = checkedModule[moduleIndex]
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT && checkedLayoutData) {
+ const layout = checkedLayoutData.find((item) => module.itemId === item.moduleId)
+ layoutRow = layout.row
+ layoutCol = layout.col
+ }
+ //혼합여부에 따라 설치 여부 결정
+ if (installedModuleMixYn && installedModuleMixYn !== module.mixAsgYn) {
+ continue
+ }
+ //북면일때
+ const isNorthModuleYn = module.northModuleYn === 'Y'
- checkedModule.forEach((module, moduleIndex) => {
const tmpModuleData = trestleDetailData.module.filter((moduleObj) => module.moduleTpCd === moduleObj.moduleTpCd)[0]
//혼합모듈일때는 mixModuleMaxRows 값이 0 이상임
// let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows
@@ -1857,18 +2032,38 @@ export function useModuleBasicSetting(tabNum) {
}
}
+ if (moduleSetupSurface.isSaleStoreNorthFlg) {
+ //북면일때
+ if (isIncludeNorthModule) {
+ if (!isNorthModuleYn && isNorthSurface) {
+ continue
+ } //흐름 방향이 북쪽(위)
+ }
+ } else {
+ if (isNorthSurface) {
+ if (!isNorthModuleYn) {
+ continue
+ }
+ }
+ }
+
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
const moduleArray = []
let calcAreaWidth = Math.abs(flowLines.right.x1 - flowLines.left.x1) //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직
let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
- let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
- let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
-
let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1
let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1)
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ calcModuleWidthCount = layoutCol > calcModuleWidthCount ? calcModuleWidthCount : layoutCol
+ calcModuleHeightCount = layoutRow
+ }
+
+ let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
+ let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
+
let calcStartPoint = flowLines.right.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬
let startPointX = flowLines.left.x1 + calcStartPoint //시작점을 만든다
@@ -1882,7 +2077,7 @@ export function useModuleBasicSetting(tabNum) {
let chidoriLength = 0
//첫번재 모듈 설치 후 두번째 모듈을 몇개까지 설치 할 수 있는지 계산
- if (moduleIndex > 0) {
+ if (installedModuleHeightCount > 0) {
// moduleMaxRows = totalModuleMaxRows - installedModuleHeightCount //두번째 모듈일때
isChidoriLine = installedModuleHeightCount % 2 != 0 ? true : false //첫번째에서 짝수에서 끝났으면 홀수는 치도리가 아님 짝수는 치도리
}
@@ -1892,12 +2087,12 @@ export function useModuleBasicSetting(tabNum) {
let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
- if (moduleIndex > 0) {
- moduleY = installedLastHeightCoord - intvVer
+ if (installedModuleHeightCount > 0) {
+ moduleY = installedLastHeightCoord
}
//첫번째는 붙여서 두번째는 마진을 주고 설치
- heightMargin = i === 0 ? 0 : intvVer * i
+ heightMargin = installedModuleHeightCount === 0 ? 0 : intvVer
for (let j = 0; j < totalModuleWidthCount; j++) {
let moduleX = startPointX + width * j + 1 //5정도 마진을 준다
@@ -1954,23 +2149,15 @@ export function useModuleBasicSetting(tabNum) {
}
if (isInstall) {
++installedModuleHeightCount
+ installedModuleMixYn = module.mixAsgYn
}
}
setupModule.push(moduleArray)
- })
+ }
}
- const topFlowSetupModule = (
- surfaceMaxLines,
- maxLengthLine,
- moduleSetupArray,
- moduleSetupSurface,
- containsBatchObjects,
- isCenter = false,
- intvHor,
- intvVer,
- ) => {
+ const topFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => {
let setupModule = []
const trestleDetailData = moduleSetupSurface.trestleDetail
@@ -1980,8 +2167,36 @@ export function useModuleBasicSetting(tabNum) {
let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트
let isChidoriLine = false
let flowLines
+ let installedModuleMixYn
+ const isNorthSurface = moduleSetupSurface.isNorth
+ const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직
+
+ let layoutRow = 0
+ let layoutCol = 0
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ const isPassed = checkAutoLayoutModuleSetup(moduleSetupSurface, trestleDetailData)
+ if (!isPassed) {
+ return
+ }
+ }
+
+ for (let moduleIndex = 0; moduleIndex < checkedModule.length; moduleIndex++) {
+ const module = checkedModule[moduleIndex]
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT && checkedLayoutData) {
+ const layout = checkedLayoutData.find((item) => module.itemId === item.moduleId)
+ layoutRow = layout.row
+ layoutCol = layout.col
+ }
+
+ //혼합여부에 따라 설치 여부 결정
+ if (installedModuleMixYn && installedModuleMixYn !== module.mixAsgYn) {
+ continue
+ }
+
+ const isNorthModuleYn = module.northModuleYn === 'Y'
- checkedModule.forEach((module, moduleIndex) => {
const tmpModuleData = trestleDetailData.module.filter((moduleObj) => module.moduleTpCd === moduleObj.moduleTpCd)[0]
//혼합모듈일때는 mixModuleMaxRows 값이 0 이상임
let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows
@@ -1997,20 +2212,45 @@ export function useModuleBasicSetting(tabNum) {
}
}
- //흐름 방향이 북쪽(위)
+ if (moduleSetupSurface.isSaleStoreNorthFlg) {
+ //북면가능 설치 대리점이면
+ //북면일때
+ if (isIncludeNorthModule) {
+ //북면 모듈이 있는지 확인하는 로직
+ if (!isNorthModuleYn && isNorthSurface) {
+ //북면 모듈이 있으면 북면 모듈만 깔고 나머지는 스킵
+ continue
+ } //흐름 방향이 북쪽(위)
+ }
+ } else {
+ // 불면설치 불가 대리점이면
+ if (isNorthSurface) {
+ //북면일때
+ if (!isNorthModuleYn) {
+ //북면 모듈이 아니면 스킵
+ continue
+ }
+ }
+ }
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
const moduleArray = []
let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직
let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
+ let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1
+ let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1)
+
+ //단수지정 자동이면
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ calcModuleWidthCount = layoutCol > calcModuleWidthCount ? calcModuleWidthCount : layoutCol
+ calcModuleHeightCount = layoutRow
+ }
+
let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
// let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 //??어쩔때는 붙고 어쩔때는 안붙고 멋대로???
let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
- let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1
- let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1)
-
let calcStartPoint = flowLines.left.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬
let startPointX = flowLines.right.x1 - calcStartPoint //시작점을 만든다
@@ -2032,11 +2272,11 @@ export function useModuleBasicSetting(tabNum) {
let isInstall = false
let moduleY = flowLines.top.y1 + height * i //탑의 y점에서부터 아래로 그려 내려간다
- if (moduleIndex > 0) {
- moduleY = installedLastHeightCoord + intvVer + 1
+ if (installedModuleHeightCount > 0) {
+ moduleY = installedLastHeightCoord
}
- heightMargin = i === 0 ? 0 : intvVer * i //모듈간에 마진이 있어 마진값도 넣음
+ heightMargin = installedModuleHeightCount === 0 ? 0 : intvVer //모듈간에 마진이 있어 마진값도 넣음
for (let j = 0; j < totalModuleWidthCount; j++) {
//모듈 열수 만큼 반복
let moduleX = startPointX - width * j - 1 //시작점에서 우 -> 좌로 그려 내려간다
@@ -2087,25 +2327,17 @@ export function useModuleBasicSetting(tabNum) {
}
if (isInstall) {
++installedModuleHeightCount
+ installedModuleMixYn = module.mixAsgYn
}
}
setupModule.push(moduleArray)
- })
+ }
}
//남, 북과 같은 로직으로 적용하려면 좌우는 열 -> 행 으로 그려야함
//변수명은 bottom 기준으로 작성하여 동일한 방향으로 진행한다
- const leftFlowSetupModule = (
- surfaceMaxLines,
- maxLengthLine,
- moduleSetupArray,
- moduleSetupSurface,
- containsBatchObjects,
- isCenter = false,
- intvHor,
- intvVer,
- ) => {
+ const leftFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => {
let setupModule = []
const trestleDetailData = moduleSetupSurface.trestleDetail //가대 상세 데이터
@@ -2115,8 +2347,36 @@ export function useModuleBasicSetting(tabNum) {
let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트
let isChidoriLine = false
let flowLines
+ let installedModuleMixYn
+ const isNorthSurface = moduleSetupSurface.isNorth
+ const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직
- checkedModule.forEach((module, moduleIndex) => {
+ let layoutRow = 0
+ let layoutCol = 0
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ const isPassed = checkAutoLayoutModuleSetup(moduleSetupSurface, trestleDetailData)
+ if (!isPassed) {
+ return
+ }
+ }
+
+ for (let moduleIndex = 0; moduleIndex < checkedModule.length; moduleIndex++) {
+ const module = checkedModule[moduleIndex]
+
+ //단수 지정이면
+ if (type === MODULE_SETUP_TYPE.LAYOUT && checkedLayoutData) {
+ const layout = checkedLayoutData.find((item) => module.itemId === item.moduleId)
+ layoutRow = layout.row
+ layoutCol = layout.col
+ }
+
+ //혼합여부에 따라 설치 여부 결정
+ if (installedModuleMixYn && installedModuleMixYn !== module.mixAsgYn) {
+ continue
+ }
+
+ const isNorthModuleYn = module.northModuleYn === 'Y'
const tmpModuleData = trestleDetailData.module.filter((moduleObj) => module.moduleTpCd === moduleObj.moduleTpCd)[0]
//혼합모듈일때는 mixModuleMaxRows 값이 0 이상임
let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows
@@ -2135,19 +2395,46 @@ export function useModuleBasicSetting(tabNum) {
}
}
+ if (moduleSetupSurface.isSaleStoreNorthFlg) {
+ //북면가능 설치 대리점이면
+ //북면일때
+ if (isIncludeNorthModule) {
+ //북면 모듈이 있는지 확인하는 로직
+ if (!isNorthModuleYn && isNorthSurface) {
+ //북면 모듈이 있으면 북면 모듈만 깔고 나머지는 스킵
+ continue
+ } //흐름 방향이 북쪽(위)
+ }
+ } else {
+ // 불면설치 불가 대리점이면
+ if (isNorthSurface) {
+ //북면일때
+ if (!isNorthModuleYn) {
+ //북면 모듈이 아니면 스킵
+ continue
+ }
+ }
+ }
+
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
const moduleArray = []
let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직
let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
+ let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
+ let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
+
+ //단수지정 자동이면
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ calcModuleWidthCount = layoutCol > calcModuleWidthCount ? calcModuleWidthCount : layoutCol
+ calcModuleHeightCount = layoutRow
+ }
+
let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
// let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
- let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
- let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
-
let calcStartPoint = flowLines.bottom.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬
let startPointX = flowLines.top.y1 + calcStartPoint //시작점을 만든다
@@ -2171,12 +2458,12 @@ export function useModuleBasicSetting(tabNum) {
let moduleY = flowLines.left.x1 + width * i + 1 //살짝 여유를 준다
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
- if (moduleIndex > 0) {
- moduleY = installedLastHeightCoord + intvHor
+ if (installedModuleHeightCount > 0) {
+ moduleY = installedLastHeightCoord
}
//첫번째는 붙여서 두번째는 마진을 주고 설치
- heightMargin = i === 0 ? 0 : intvHor * i
+ heightMargin = installedModuleHeightCount === 0 ? 0 : intvHor
for (let j = 0; j < totalModuleWidthCount; j++) {
let moduleX = startPointX + height * j + 1 //5정도 마진을 준다
@@ -2227,22 +2514,14 @@ export function useModuleBasicSetting(tabNum) {
if (isInstall) {
++installedModuleHeightCount
+ installedModuleMixYn = module.mixAsgYn
}
}
setupModule.push(moduleArray)
- })
+ }
}
- const rightFlowSetupModule = (
- surfaceMaxLines,
- maxLengthLine,
- moduleSetupArray,
- moduleSetupSurface,
- containsBatchObjects,
- isCenter = false,
- intvHor,
- intvVer,
- ) => {
+ const rightFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => {
let setupModule = []
const trestleDetailData = moduleSetupSurface.trestleDetail //가대 상세 데이터
@@ -2252,8 +2531,35 @@ export function useModuleBasicSetting(tabNum) {
let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트
let isChidoriLine = false
let flowLines
+ let installedModuleMixYn
+ const isNorthSurface = moduleSetupSurface.isNorth
+ const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직
- checkedModule.forEach((module, moduleIndex) => {
+ let layoutRow = 0
+ let layoutCol = 0
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ const isPassed = checkAutoLayoutModuleSetup(moduleSetupSurface, trestleDetailData)
+ if (!isPassed) {
+ return
+ }
+ }
+
+ for (let moduleIndex = 0; moduleIndex < checkedModule.length; moduleIndex++) {
+ const module = checkedModule[moduleIndex]
+
+ if (type === MODULE_SETUP_TYPE.LAYOUT && checkedLayoutData) {
+ const layout = checkedLayoutData.find((item) => module.itemId === item.moduleId)
+ layoutRow = layout.row
+ layoutCol = layout.col
+ }
+
+ //혼합여부에 따라 설치 여부 결정
+ if (installedModuleMixYn && installedModuleMixYn !== module.mixAsgYn) {
+ continue
+ }
+
+ const isNorthModuleYn = module.northModuleYn === 'Y'
const tmpModuleData = trestleDetailData.module.filter((moduleObj) => module.moduleTpCd === moduleObj.moduleTpCd)[0]
//혼합모듈일때는 mixModuleMaxRows 값이 0 이상임
let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows
@@ -2272,18 +2578,45 @@ export function useModuleBasicSetting(tabNum) {
}
}
+ if (moduleSetupSurface.isSaleStoreNorthFlg) {
+ //북면가능 설치 대리점이면
+ //북면일때
+ if (isIncludeNorthModule) {
+ //북면 모듈이 있는지 확인하는 로직
+ if (!isNorthModuleYn && isNorthSurface) {
+ //북면 모듈이 있으면 북면 모듈만 깔고 나머지는 스킵
+ continue
+ } //흐름 방향이 북쪽(위)
+ }
+ } else {
+ // 불면설치 불가 대리점이면
+ if (isNorthSurface) {
+ //북면일때
+ if (!isNorthModuleYn) {
+ //북면 모듈이 아니면 스킵
+ continue
+ }
+ }
+ }
+
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
const moduleArray = []
let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직
let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
+ let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
+ let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
+
+ //단수지정 자동이면
+ if (type === MODULE_SETUP_TYPE.LAYOUT) {
+ calcModuleWidthCount = layoutCol > calcModuleWidthCount ? calcModuleWidthCount : layoutCol
+ calcModuleHeightCount = layoutRow
+ }
+
let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
// let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
- let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
- let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
-
let calcStartPoint = flowLines.top.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬
let startPointX = flowLines.bottom.y2 - calcStartPoint //시작점을 만든다
@@ -2307,12 +2640,12 @@ export function useModuleBasicSetting(tabNum) {
let moduleY = flowLines.right.x1 - width * i - 1 //살짝 여유를 준다
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
- if (moduleIndex > 0) {
- moduleY = installedLastHeightCoord - intvHor
+ if (installedModuleHeightCount > 0) {
+ moduleY = installedLastHeightCoord
}
//첫번째는 붙여서 두번째는 마진을 주고 설치
- heightMargin = i === 0 ? 0 : intvHor * i
+ heightMargin = installedModuleHeightCount === 0 ? 0 : intvHor
for (let j = 0; j < totalModuleWidthCount; j++) {
let moduleX = startPointX - height * j - 1 //5정도 마진을 준다
@@ -2366,11 +2699,12 @@ export function useModuleBasicSetting(tabNum) {
if (isInstall) {
++installedModuleHeightCount
+ installedModuleMixYn = module.mixAsgYn
}
}
setupModule.push(moduleArray)
- })
+ }
}
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
@@ -2379,7 +2713,6 @@ export function useModuleBasicSetting(tabNum) {
const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
- const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
return acc.length > cur.length ? acc : cur
@@ -2400,30 +2733,30 @@ export function useModuleBasicSetting(tabNum) {
if (setupLocation === 'eaves') {
// 흐름방향이 남쪽일때
if (moduleSetupSurface.direction === 'south') {
- downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ downFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'west') {
- leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ leftFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'east') {
- rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ rightFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'north') {
- topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ topFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
} else if (setupLocation === 'ridge') {
//용마루
if (moduleSetupSurface.direction === 'south') {
- topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ topFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'west') {
- rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ rightFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'east') {
- leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ leftFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
if (moduleSetupSurface.direction === 'north') {
- downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer)
+ downFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer)
}
}
@@ -2460,6 +2793,14 @@ export function useModuleBasicSetting(tabNum) {
}
})
// calculateForApi()
+
+ /**
+ * 자동 레이아웃일떄 설치 가능한 애들은 설치 해주고 실패한 애들은 이름, 최대 설치 가능한 높이 알려줄라고
+ */
+ if (type === MODULE_SETUP_TYPE.LAYOUT && failAutoSetupRoof.length) {
+ const roofNames = failAutoSetupRoof.map((roof) => roof.roofMaterial.roofMatlNmJp).join(', ')
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.over.max.row', [roofNames]), icon: 'warning' })
+ }
}
const coordToTurfPolygon = (points) => {
@@ -2766,13 +3107,13 @@ export function useModuleBasicSetting(tabNum) {
let moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
if (isManualModuleSetup) {
if (checkedModule.length === 0) {
- swalFire({ text: getMessage('module.place.select.module') })
+ swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' })
setIsManualModuleSetup(!isManualModuleSetup)
return
}
if (checkedModule.length > 1) {
- swalFire({ text: getMessage('module.place.select.one.module') })
+ swalFire({ text: getMessage('module.place.select.one.module'), icon: 'warning' })
setIsManualModuleSetup(!isManualModuleSetup)
return
}
@@ -3085,7 +3426,7 @@ export function useModuleBasicSetting(tabNum) {
const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn
//현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능
if (checkedModule[0].mixAsgYn !== mixAsgYn) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
return
}
}
@@ -3118,7 +3459,7 @@ export function useModuleBasicSetting(tabNum) {
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
//겹치면 안됨
if (intersection) {
- swalFire({ text: getMessage('module.place.overobject') })
+ swalFire({ text: getMessage('module.place.overobject'), icon: 'warning' })
isIntersection = false
}
})
@@ -3136,10 +3477,10 @@ export function useModuleBasicSetting(tabNum) {
manualDrawModules.push(manualModule)
setModuleStatisticsData()
} else {
- swalFire({ text: getMessage('module.place.overlab') })
+ swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' })
}
} else {
- swalFire({ text: getMessage('module.place.out') })
+ swalFire({ text: getMessage('module.place.out'), icon: 'warning' })
}
}
})
@@ -3169,7 +3510,7 @@ export function useModuleBasicSetting(tabNum) {
//Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가
if (mixAsgY.length > 0 && mixAsgN.length > 0) {
- swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') })
+ swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' })
return
}
diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js
index 3d14d600..0143e92e 100644
--- a/src/hooks/module/useModuleTrestle.js
+++ b/src/hooks/module/useModuleTrestle.js
@@ -10,6 +10,7 @@ const RAFT_BASE_CODE = '203800'
const trestleReducer = (state, action) => {
switch (action.type) {
+ case 'SET_LENGTH':
case 'SET_RAFT_BASE':
case 'SET_TRESTLE_MAKER':
case 'SET_CONST_MTHD':
@@ -24,7 +25,7 @@ const trestleReducer = (state, action) => {
moduleTpCd: action.roof.module?.itemTp ?? '',
roofMatlCd: action.roof?.roofMatlCd ?? '',
hajebichi: action.roof?.hajebichi ?? 0,
- raftBaseCd: action.roof?.raftBaseCd ?? null,
+ raft: action.roof?.raft ?? null,
trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null,
constMthdCd: action.roof.trestle?.constMthdCd ?? null,
constTp: action.roof.construction?.constTp ?? null,
@@ -71,7 +72,6 @@ export function useModuleTrestle(props) {
useEffect(() => {
const raftCodeList = findCommonCode(RAFT_BASE_CODE)
-
setRaftBaseList(raftCodeList)
setTrestleList([])
setConstMthdList([])
@@ -96,11 +96,15 @@ export function useModuleTrestle(props) {
useEffect(() => {
if (trestleState) {
handleSetTrestleList()
+
if (!trestleState?.trestleMkrCd) {
setConstMthdList([])
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
+ setEavesMargin(0)
+ setRidgeMargin(0)
+ setKerabaMargin(0)
return
}
@@ -109,6 +113,9 @@ export function useModuleTrestle(props) {
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
+ setEavesMargin(0)
+ setRidgeMargin(0)
+ setKerabaMargin(0)
return
}
@@ -116,12 +123,18 @@ export function useModuleTrestle(props) {
if (!trestleState?.roofBaseCd) {
setConstructionList([])
setTrestleDetail(null)
+ setEavesMargin(0)
+ setRidgeMargin(0)
+ setKerabaMargin(0)
return
}
handleSetConstructionList()
if (!trestleState?.constTp) {
setTrestleDetail(null)
+ setEavesMargin(0)
+ setRidgeMargin(0)
+ setKerabaMargin(0)
return
}
@@ -136,7 +149,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
- raftBaseCd: trestleState?.raftBaseCd ?? '',
+ raftBaseCd: trestleState?.raft ?? '',
})
.then((res) => {
if (res?.data) setTrestleList(res.data)
@@ -152,7 +165,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
- raftBaseCd: trestleState?.raftBaseCd ?? '',
+ raftBaseCd: trestleState?.raft ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
})
.then((res) => {
@@ -169,7 +182,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
- raftBaseCd: trestleState?.raftBaseCd ?? '',
+ raftBaseCd: trestleState?.raft ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState?.constMthdCd ?? '',
})
@@ -195,7 +208,7 @@ export function useModuleTrestle(props) {
stdWindSpeed: trestleState.stdWindSpeed ?? '',
stdSnowLd: trestleState.stdSnowLd ?? '',
inclCd: trestleState.inclCd ?? '',
- raftBaseCd: trestleState.raftBaseCd ?? '',
+ raftBaseCd: trestleState.raft ?? '',
roofPitch: Math.round(trestleState.roofPitch) ?? '',
})
.then((res) => {
@@ -224,7 +237,8 @@ export function useModuleTrestle(props) {
constTp: trestleState.constTp ?? '',
mixMatlNo: trestleState.mixMatlNo ?? '',
roofPitch: trestleState.roofPitch ?? '',
- workingWidth: trestleState.workingWidth ?? '',
+ // workingWidth: trestleState.length ?? '',
+ workingWidth: lengthBase ?? '',
},
])
.then((res) => {
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js
index 7048e64e..32eef2a2 100644
--- a/src/hooks/module/useTrestle.js
+++ b/src/hooks/module/useTrestle.js
@@ -2251,7 +2251,15 @@ export const useTrestle = () => {
let halfMaxX
let halfMaxY
const { direction, trestleDetail } = surface
- const { moduleIntvlHor, moduleIntvlVer } = trestleDetail
+ let moduleIntvlHor, moduleIntvlVer
+ if (+roofSizeSet === 3) {
+ //육지붕의 경우 값 고정
+ moduleIntvlHor = 300
+ moduleIntvlVer = 100
+ } else {
+ moduleIntvlHor = trestleDetail.moduleIntvlHor
+ moduleIntvlVer = trestleDetail.moduleIntvlVer
+ }
if (direction === 'south' || direction === 'north') {
maxX = width + moduleIntvlHor / 10
diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js
index d9c2073c..8109a8bb 100644
--- a/src/hooks/roofcover/useRoofAllocationSetting.js
+++ b/src/hooks/roofcover/useRoofAllocationSetting.js
@@ -469,7 +469,7 @@ export function useRoofAllocationSetting(id) {
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
- return { ...selectedRoofMaterial, selected: roof.selected }
+ return { ...selectedRoofMaterial, selected: roof.selected, index }
}
return roof
})
diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js
index db0859cf..d53faa39 100644
--- a/src/hooks/surface/usePlacementShapeDrawing.js
+++ b/src/hooks/surface/usePlacementShapeDrawing.js
@@ -14,7 +14,7 @@ import { useMouse } from '@/hooks/useMouse'
import { useLine } from '@/hooks/useLine'
import { useTempGrid } from '@/hooks/useTempGrid'
import { useEffect, useRef } from 'react'
-import { distanceBetweenPoints } from '@/util/canvas-util'
+import { calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
import { fabric } from 'fabric'
import { calculateAngle } from '@/util/qpolygon-utils'
import {
@@ -37,12 +37,13 @@ import { useSurfaceShapeBatch } from './useSurfaceShapeBatch'
import { roofDisplaySelector } from '@/store/settingAtom'
import { useRoofFn } from '@/hooks/common/useRoofFn'
import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty'
+import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
// 배치면 그리기
export function usePlacementShapeDrawing(id) {
const canvas = useRecoilValue(canvasState)
const roofDisplay = useRecoilValue(roofDisplaySelector)
- const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } =
+ const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseLine } =
useEvent()
// const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } =
// useContext(EventContext)
@@ -118,6 +119,7 @@ export function usePlacementShapeDrawing(id) {
}, [type])
const clear = () => {
+ addCanvasMouseEventListener('mouse:move', mouseMove)
setLength1(0)
setLength2(0)
@@ -173,6 +175,80 @@ export function usePlacementShapeDrawing(id) {
}
}
+/*
+mouseMove
+ */
+ const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+ const roofAdsorptionPoints = useRef([])
+ const intersectionPoints = useRef([])
+ const { getAdsorptionPoints } = useAdsorptionPoint()
+
+ const mouseMove = (e) => {
+ removeMouseLine();
+ const pointer = canvas.getPointer(e.e)
+ const roofsPoints = roofs.map((roof) => roof.points).flat()
+ roofAdsorptionPoints.current = [...roofsPoints]
+
+ const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isFixed)
+ const otherAdsorptionPoints = []
+
+ auxiliaryLines.forEach((line1) => {
+ auxiliaryLines.forEach((line2) => {
+ if (line1 === line2) {
+ return
+ }
+
+ const intersectionPoint = calculateIntersection(line1, line2)
+ if (!intersectionPoint || intersectionPoints.current.some((point) => point.x === intersectionPoint.x && point.y === intersectionPoint.y)) {
+ return
+ }
+ otherAdsorptionPoints.push(intersectionPoint)
+ })
+ })
+
+ let innerLinePoints = []
+ canvas
+ .getObjects()
+ .filter((obj) => obj.innerLines)
+ .forEach((polygon) => {
+ polygon.innerLines.forEach((line) => {
+ innerLinePoints.push({ x: line.x1, y: line.y1 })
+ innerLinePoints.push({ x: line.x2, y: line.y2 })
+ })
+ })
+
+ const adsorptionPoints = [
+ ...getAdsorptionPoints(),
+ ...roofAdsorptionPoints.current,
+ ...otherAdsorptionPoints,
+ ...intersectionPoints.current,
+ ...innerLinePoints,
+ ]
+
+ let arrivalPoint = { x: pointer.x, y: pointer.y }
+ let adsorptionPoint = findClosestPoint(pointer, adsorptionPoints)
+
+ if (adsorptionPoint && distanceBetweenPoints(pointer, adsorptionPoint) <= adsorptionRange) {
+ arrivalPoint = { ...adsorptionPoint }
+ }
+ const horizontalLine = new fabric.Line([-1 * canvas.width, arrivalPoint.y, 2 * canvas.width, arrivalPoint.y], {
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: false,
+ name: 'mouseLine',
+ })
+
+ const verticalLine = new fabric.Line([arrivalPoint.x, -1 * canvas.height, arrivalPoint.x, 2 * canvas.height], {
+ stroke: 'red',
+ strokeWidth: 1,
+ selectable: false,
+ name: 'mouseLine',
+ })
+ canvas?.add(horizontalLine, verticalLine)
+ canvas?.renderAll()
+
+ }
+
useEffect(() => {
canvas
?.getObjects()
diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js
index 4204dc71..22aad7cf 100644
--- a/src/hooks/useCanvasEvent.js
+++ b/src/hooks/useCanvasEvent.js
@@ -4,7 +4,7 @@ import { v4 as uuidv4 } from 'uuid'
import { canvasSizeState, canvasState, canvasZoomState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
import { QPolygon } from '@/components/fabric/QPolygon'
import { fontSelector } from '@/store/fontAtom'
-import { MENU } from '@/common/common'
+import { MENU, POLYGON_TYPE } from '@/common/common'
// 캔버스에 필요한 이벤트
export function useCanvasEvent() {
@@ -204,8 +204,12 @@ export function useCanvasEvent() {
if (selected?.length > 0) {
selected.forEach((obj) => {
- if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ // if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ if (obj.type === 'QPolygon') {
obj.set({ stroke: 'red' })
+ if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ obj.set({ strokeWidth: 3 })
+ }
}
})
canvas.renderAll()
@@ -217,10 +221,13 @@ export function useCanvasEvent() {
if (deselected?.length > 0) {
deselected.forEach((obj) => {
- if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ if (obj.type === 'QPolygon') {
if (obj.name !== 'moduleSetupSurface') {
obj.set({ stroke: 'black' })
}
+ if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ obj.set({ strokeWidth: 0.3 })
+ }
}
})
}
@@ -233,16 +240,24 @@ export function useCanvasEvent() {
if (deselected?.length > 0) {
deselected.forEach((obj) => {
- if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ if (obj.type === 'QPolygon') {
obj.set({ stroke: 'black' })
+ if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ //모듈 미선택시 라인 두께 변경
+ obj.set({ strokeWidth: 0.3 })
+ }
}
})
}
if (selected?.length > 0) {
selected.forEach((obj) => {
- if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ if (obj.type === 'QPolygon') {
obj.set({ stroke: 'red' })
+ if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
+ //모듈 선택시 라인 두께 변경
+ obj.set({ strokeWidth: 3 })
+ }
}
})
}
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index f812f00e..74c03296 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -21,6 +21,7 @@ import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedM
import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController'
import { useCanvasMenu } from './common/useCanvasMenu'
import { QcastContext } from '@/app/QcastProvider'
+import { unescapeString } from '@/util/common-utils'
/**
* 플랜 처리 훅
@@ -264,7 +265,7 @@ export function usePlan(params = {}) {
objectNo,
planNo: parseInt(newPlan.planNo),
popupType: 1,
- popupStatus: sourceDegree.popupStatus,
+ popupStatus: unescapeString(sourceDegree.popupStatus),
}
console.log('🚀 ~ postObjectPlan ~ degreeData:', degreeData)
await post({ url: `/api/v1/canvas-popup-status`, data: degreeData })
diff --git a/src/locales/ja.json b/src/locales/ja.json
index 73ee56c9..35f0b757 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -3,7 +3,7 @@
"welcome": "ようこそ。 {0}さん",
"header.menus.home": "ホーム",
"header.menus.management": "見積書管理画面",
- "header.menus.management.newStuff": "新規見積登録",
+ "header.menus.management.newStuff": "新規物件登録",
"header.menus.management.detail": "物件詳細",
"header.menus.management.stuffList": "物件検索",
"header.menus.community": "コミュニティ",
@@ -97,9 +97,12 @@
"modal.module.basic.setting.module.under.roof": "屋根下地",
"modal.module.basic.setting.module.setting": "モジュールの選択",
"modal.module.basic.setting.module.placement.area": "モジュール配置領域",
+ "modal.module.basic.setting.module.placement.margin": "モジュール間の間隙",
"modal.module.basic.setting.module.placement.area.eaves": "軒側",
"modal.module.basic.setting.module.placement.area.ridge": "棟側",
"modal.module.basic.setting.module.placement.area.keraba": "けらぱ",
+ "modal.module.basic.setting.module.placement.margin.horizontal": "左右",
+ "modal.module.basic.setting.module.placement.margin.vertical": "上下",
"modal.module.basic.setting.module.hajebichi": "ハゼピッチ",
"modal.module.basic.setting.module.setting.info1": "※勾配の範囲には制限があります。屋根傾斜が2.5値未満10値を超える場合は、施工が可能かどうか施工マニュアルを確認してください。",
"modal.module.basic.setting.module.setting.info2": "※モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ずご確認ください。",
@@ -110,26 +113,27 @@
"modal.module.basic.setting.module.standard.snowfall.amount": "積雪量",
"modal.module.basic.setting.module.standard.construction": "標準施工",
"modal.module.basic.setting.module.enforce.construction": "強化施工",
- "modal.module.basic.setting.module.multiple.construction": "多設施工",
+ "modal.module.basic.setting.module.multiple.construction": "多雪施工",
"modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置",
"modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置",
"modal.module.basic.setting.module.select": "モジュール/架台選択",
- "modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error4": "施工法を選択してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})(JA)",
- "modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
- "modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
- "modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
+ "modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error4": "設置可能な施工条件がないので設置条件を変更してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})",
+ "modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
+ "modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
+ "modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
+ "modal.module.basic.settting.module.error12": "施工方法を選択してください。\n(屋根材: {0})",
"modal.module.basic.setting.module.placement": "モジュールの配置",
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
- "modal.module.basic.setting.module.placement.max.row.amount": "Max単数",
- "modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max単数",
+ "modal.module.basic.setting.module.placement.max.row.amount": "Max段数",
+ "modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max段数",
"modal.module.basic.setting.module.placement.row.amount": "段数",
"modal.module.basic.setting.module.placement.column.amount": "列数",
"modal.module.basic.setting.module.placement.do": "する",
@@ -149,9 +153,10 @@
"modal.module.basic.setting.pitch.module.column.amount": "列数",
"modal.module.basic.setting.pitch.module.column.margin": "左右間隔",
"modal.module.basic.setting.prev": "前に戻る",
- "modal.module.basic.setting.row.batch": "段・列数指定配置",
+ "modal.module.basic.setting.row.batch": "レイアウト指定",
"modal.module.basic.setting.passivity.placement": "手動配置",
"modal.module.basic.setting.auto.placement": "自動配置",
+ "modal.module.basic.setting.auto.row.batch": "自動レイアウト指定",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定",
"modal.circuit.trestle.setting": "回路設定",
"modal.circuit.trestle.setting.alloc.trestle": "架台配置",
@@ -183,7 +188,7 @@
"modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02": "シリーズを選択してください。",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num.fix": "番号確定",
"modal.circuit.trestle.setting.step.up.allocation": "昇圧設定",
- "modal.circuit.trestle.setting.step.up.allocation.serial.amount": "シリアル枚数",
+ "modal.circuit.trestle.setting.step.up.allocation.serial.amount": "直列枚数",
"modal.circuit.trestle.setting.step.up.allocation.total.amount": "総回路数",
"modal.circuit.trestle.setting.step.up.allocation.connected": "接続する",
"modal.circuit.trestle.setting.step.up.allocation.circuit.amount": "昇圧回路数",
@@ -320,7 +325,7 @@
"modal.object.setting.offset.width": "幅の出幅",
"modal.object.setting.offset.slope": "勾配",
"modal.object.setting.direction.select": "方向の選択",
- "modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。",
+ "modal.placement.surface.setting.info": "①の長さを入力後、③の長さを入力すると②の長さを自動計算します。",
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
"modal.color.picker.title": "色設定",
"modal.color.picker.default.color": "基本色",
@@ -1066,13 +1071,13 @@
"roof.line.not.found": "屋根形状がありません",
"roof.material.can.not.delete": "割り当てられた配置面があります。",
"chidory.can.not.install": "千鳥配置できない工法です。",
- "module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)",
- "module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (JA)",
+ "module.layout.setup.max.count": "モジュールの単体での最大段数は{0}、最大列数は{1}です。 (JA)",
+ "module.layout.setup.max.count.multiple": "モジュール{0}の単体での最大段数は{1}、最大列数は{2}です。 (JA)",
"roofAllocation.not.found": "割り当てる屋根がありません。 (JA)",
- "modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の最大段数、2種混合の段数を確認して下さい",
- "modal.module.basic.setting.module.placement.max.row": "最大段数",
- "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合最大段数",
+ "modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の単体での最大段数、2種混合の段数を確認して下さい",
+ "modal.module.basic.setting.module.placement.max.row": "単体で\rの最大段数",
+ "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn": "混合",
- "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)"
+ "modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。"
}
diff --git a/src/locales/ko.json b/src/locales/ko.json
index e8367328..daf9ad60 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -97,9 +97,12 @@
"modal.module.basic.setting.module.under.roof": "지붕밑바탕",
"modal.module.basic.setting.module.setting": "모듈 선택",
"modal.module.basic.setting.module.placement.area": "모듈 배치 영역",
+ "modal.module.basic.setting.module.placement.margin": "모듈 배치 간격",
"modal.module.basic.setting.module.placement.area.eaves": "처마쪽",
"modal.module.basic.setting.module.placement.area.ridge": "용마루쪽",
"modal.module.basic.setting.module.placement.area.keraba": "케라바쪽",
+ "modal.module.basic.setting.module.placement.margin.horizontal": "좌우",
+ "modal.module.basic.setting.module.placement.margin.vertical": "상하",
"modal.module.basic.setting.module.hajebichi": "망둥어 피치",
"modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.",
"modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.",
@@ -117,7 +120,7 @@
"modal.module.basic.settting.module.error1": "가대메이커를 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error2": "공법를 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error3": "지붕밑바탕을 선택해주세요.\n(지붕재: {0})",
- "modal.module.basic.settting.module.error4": "시공법을 선택해주세요.\n(지붕재: {0})",
+ "modal.module.basic.settting.module.error4": "설치 조건이 없으므로 설치 조건을 변경하십시오.\n(지붕재: {0})",
"modal.module.basic.settting.module.error5": "L 을 입력해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error6": "서까래 간격을 입력해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error7": "하제비치를 입력해주세요.\n(지붕재: {0})",
@@ -125,6 +128,7 @@
"modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
+ "modal.module.basic.settting.module.error12": "시공법을 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.setting.module.placement": "모듈 배치",
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
@@ -152,7 +156,8 @@
"modal.module.basic.setting.prev": "이전",
"modal.module.basic.setting.row.batch": "단·열수 지정 배치",
"modal.module.basic.setting.passivity.placement": "수동 배치",
- "modal.module.basic.setting.auto.placement": "설정값으로 자동 배치",
+ "modal.module.basic.setting.auto.placement": "자동 배치",
+ "modal.module.basic.setting.auto.row.batch": "자동 단·열수 지정 배치 ",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정",
"modal.circuit.trestle.setting": "회로설정",
"modal.circuit.trestle.setting.alloc.trestle": "가대할당",
@@ -1075,5 +1080,5 @@
"modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "혼합 설치 불가능한 모듈입니다.",
"modal.module.basic.setting.module.placement.mix.asg.yn": "혼합",
- "modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치"
+ "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요."
}
diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss
index bfd7b1f8..58f9a3ca 100644
--- a/src/styles/_contents.scss
+++ b/src/styles/_contents.scss
@@ -806,28 +806,28 @@
color: #45576F;
margin-left: 5px;
}
-.drag-file-box{
- padding: 10px;
- .btn-area{
- padding-bottom: 15px;
- border-bottom: 1px solid #ECF0F4;
- .file-upload{
- display: inline-block;
- height: 30px;
- background-color: #94A0AD;
- padding: 0 10px;
- border-radius: 2px;
- font-size: 13px;
- line-height: 30px;
- color: #fff;
- font-weight: 500;
- cursor: pointer;
- transition: background .15s ease-in-out;
- &:hover{
- background-color: #607F9A;
- }
+.btn-area{
+ padding-bottom: 15px;
+ border-bottom: 1px solid #ECF0F4;
+ .file-upload{
+ display: inline-block;
+ height: 30px;
+ background-color: #94A0AD;
+ padding: 0 10px;
+ border-radius: 2px;
+ font-size: 13px;
+ line-height: 30px;
+ color: #fff;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background .15s ease-in-out;
+ &:hover{
+ background-color: #607F9A;
}
}
+}
+.drag-file-box{
+ padding: 10px;
.drag-file-area{
position: relative;
margin-top: 15px;
diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss
index fef7c2fd..7b94f2b4 100644
--- a/src/styles/_modal.scss
+++ b/src/styles/_modal.scss
@@ -2363,20 +2363,6 @@ $alert-color: #101010;
}
}
-.module-area{
- display: flex;
- align-items: center;
- .module-area-title{
- flex: none;
- font-size: 12px;
- color: #fff;
- font-weight: 500;
- margin-right: 20px;
- }
- .outline-form{
- flex: 1;
- }
-}
.placement-name-guide{
font-size: 11px;
@@ -2422,4 +2408,32 @@ $alert-color: #101010;
overflow: hidden;
height: 0;
}
+}
+
+// 2025-05-07 지붕모듈
+.module-input-area{
+ display: flex;
+ align-items: center;
+ margin-top: 10px;
+ .module-area-title{
+ flex: none;
+ font-size: 12px;
+ color: #fff;
+ font-weight: 500;
+ margin-right: 20px;
+ }
+ .module-input-wrap{
+ width: 100%;
+ display: flex;
+ .outline-form{
+ width: calc(33.333% - 10px);
+ margin-right: 15px;
+ &:last-child{
+ margin-right: 0;
+ }
+ .input-grid{
+ width: 100%;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss
index ac0d2f73..ecb7f2cb 100644
--- a/src/styles/_reset.scss
+++ b/src/styles/_reset.scss
@@ -377,6 +377,7 @@ button{
font-size: 12px;
color: #fff;
line-height: 1.4;
+ text-align: left;
}
&:hover{
background-color: #2C2C2C;
@@ -1023,4 +1024,23 @@ input:checked + .slider {
// alert z-index
.swal2-container{
z-index: 120000;
+}
+
+// textarea
+.textarea-form{
+ width: 100%;
+ outline: none;
+ resize: none;
+ border: none;
+ border: 1px solid #eee;
+ min-height: 150px;
+ padding: 10px;
+ font-size: 13px;
+ color: #45576F;
+ border-radius: 2px;
+ font-family: "Noto Sans JP", sans-serif;
+ transition: border .15s ease-in-out;
+ &:focus{
+ border-color: #94a0ad;
+ }
}
\ No newline at end of file
diff --git a/src/styles/_submodal.scss b/src/styles/_submodal.scss
index de53d584..40beae5e 100644
--- a/src/styles/_submodal.scss
+++ b/src/styles/_submodal.scss
@@ -288,55 +288,56 @@
}
// 커뮤니티
-.community_detail{
- .community_detail-tit{
- font-size: 16px;
- color: #101010;
- font-weight: 600;
- padding-bottom: 14px;
- border-bottom: 2px solid #101010;
- }
- .community_detail-file-wrap{
- padding: 24px 0;
- border-bottom: 1px solid #E5E5E5;
- dt{
- font-size: 13px;
- color: #101010;
- font-weight: 500;
- margin-bottom: 15px;
- }
- dd{
- font-size: 12px;
- font-weight: 400;
- margin-bottom: 3px;
- color: #344356;
- &:last-child{
- margin-bottom: 0;
- }
- }
- }
- .community_detail-inner{
- max-height: 300px;
- overflow-y: auto;
- margin-top: 20px;
- margin-bottom: 20px;
+.community_detail-tit{
+ font-size: 16px;
+ color: #101010;
+ font-weight: 600;
+ padding-bottom: 14px;
+ border-bottom: 2px solid #101010;
+}
+.community_detail-file-wrap{
+ padding: 24px 0;
+ border-bottom: 1px solid #E5E5E5;
+ dt{
font-size: 13px;
+ color: #101010;
+ font-weight: 500;
+ }
+ dd{
+ font-size: 12px;
font-weight: 400;
- color: #45576F;
- line-height: 26px;
- word-break: keep-all;
- &::-webkit-scrollbar {
- width: 4px;
- background-color: transparent;
+ margin-bottom: 3px;
+ color: #344356;
+ &:nth-child(2){
+ margin-top: 15px;
}
- &::-webkit-scrollbar-thumb {
- background-color: #C1CCD7;
- }
- &::-webkit-scrollbar-track {
- background-color: transparent;
+ &:last-child{
+ margin-bottom: 0;
}
}
}
+.community_detail-inner{
+ max-height: 300px;
+ overflow-y: auto;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ font-size: 13px;
+ font-weight: 400;
+ color: #45576F;
+ line-height: 26px;
+ word-break: keep-all;
+ &::-webkit-scrollbar {
+ width: 4px;
+ background-color: transparent;
+ }
+ &::-webkit-scrollbar-thumb {
+ background-color: #C1CCD7;
+ }
+ &::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+}
+
// 견적 복사
.estimate-copy-info-item{
@@ -368,4 +369,117 @@
color: #999;
}
}
+}
+
+// 1:1문의
+.one-on-one{
+ .select-wrap{
+ width: 250px;
+ }
+ .input-wrap{
+ flex: 1 1 auto;
+ }
+ &.btn-area{
+ padding-bottom: 0;
+ border: none;
+ margin-left: 10px;
+ }
+ &.drag-file-box{
+ border: 1px solid #eee;
+ .drag-file-area{
+ margin-top: 0;
+ }
+ }
+}
+
+.oneonone-header-wrap{
+ padding-bottom: 14px;
+ border-bottom: 2px solid #101010;
+ .oneonone-title{
+ font-size: 16px;
+ color: #101010;
+ font-weight: 600;
+ margin-bottom: 14px;
+ }
+}
+.oneonone-infor{
+ display: flex;
+ align-items: center;
+ .profile{
+ position: relative;
+ padding-left: 26px;
+ padding-right: 8px;
+ font-size: 13px;
+ font-weight: 400;
+ color: #101010;
+ &::before{
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+ width: 24px;
+ height: 24px;
+ background: url(./../../public/static/images/sub/oneonone_profile_icon.svg)no-repeat center;
+ }
+ &::after{
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ width: 1px;
+ height: 8px;
+ background-color: #CCCCCC;
+ }
+ }
+ .date{
+ padding-left: 8px;
+ font-size: 13px;
+ font-weight: 400;
+ color: #101010;
+ }
+}
+.oneonone-detail{
+ padding: 20px;
+ border: 1px solid #101010;
+ border-top: none;
+ .community_detail-file-wrap{
+ padding-top: 0;
+ }
+ .community_detail-inner{
+ max-height: 110px;
+ margin-top: 24px;
+ margin-bottom: 0;
+ }
+}
+
+.oneonone-answer{
+ margin-top: 8px;
+ padding: 20px;
+ border: 1px solid #101010;
+ .community_detail-inner{
+ max-height: 110px;
+
+ }
+ .community_detail-file-wrap{
+ border-top: 1px solid #D4DCE7;
+ padding: 16px 0 0 0;
+ border-bottom: none;
+ }
+}
+
+.answer-title-wrap{
+ display: flex;
+ align-items: center;
+ padding-bottom: 14px;
+ border-bottom: 1px solid #D4DCE7;
+ .answer-title{
+ font-size: 14px;
+ color: #101010;
+ font-weight: 600;
+ }
+ .oneonone-infor{
+ margin-left: auto;
+ }
}
\ No newline at end of file
diff --git a/src/util/common-utils.js b/src/util/common-utils.js
index 842eace0..0a1265fe 100644
--- a/src/util/common-utils.js
+++ b/src/util/common-utils.js
@@ -145,9 +145,19 @@ export const unescapeString = (str) => {
''': "'",
}
+ /*
+ 1. 한번 변환은 {" 로 변환됨 : 에러 발생 => while 변경
+ 2. 변환할 내용이 없으면 리턴값이 undefined
+
if (regex.test(str)) {
return str.replace(regex, (matched) => chars[matched] || matched)
}
+ */
+
+ while (regex.test(str)) {
+ str = str.replace(regex, (matched) => chars[matched] || matched);
+ }
+ return str
}
export const isNullOrUndefined = (value) => {