- | 물건명 후리가나 |
+ {getMessage('stuff.detail.objectNameKana')} |
@@ -521,7 +515,7 @@ export default function StuffDetail() {
- 1차 판매점명 / ID
+ {getMessage('stuff.detail.saleStoreId')}
*
@@ -549,7 +543,7 @@ export default function StuffDetail() {
- 2차 판매점명 / ID
+ {getMessage('stuff.detail.otherSaleStoreId')}
|
@@ -565,6 +559,8 @@ export default function StuffDetail() {
clearable={true}
onChange={onSelectionChange2}
disabled={form.watch('saleStoreId') !== '' ? false : true}
+ onClearAll={handleClear}
+ ref={ref}
>
@@ -581,23 +577,24 @@ export default function StuffDetail() {
|
- 우편번호 *
+ {getMessage('stuff.detail.zipNo')} *
|
|
|
- 도도부현 / 주소 *
+ {getMessage('stuff.detail.prefId')}
+ *
|
@@ -620,17 +617,15 @@ export default function StuffDetail() {
|
|
- 발전량시뮬레이션지역 *
+ {getMessage('stuff.detail.areaId')} *
|
|
|
- 기준풍속 *
+ {getMessage('stuff.detail.windSpeed')} *
|
@@ -660,14 +655,14 @@ export default function StuffDetail() {
})}
- m/s이하
-
+ {getMessage('stuff.detail.windSpeedSpan')}
+
|
|
- 수직적설량 *
+ {getMessage('stuff.detail.verticalSnowCover')} *
|
|
|
- 면조도구분 *
+ {getMessage('stuff.detail.surfaceType')} *
|
@@ -702,7 +697,7 @@ export default function StuffDetail() {
-
+
@@ -710,7 +705,7 @@ export default function StuffDetail() {
|
|
- 설치높이 *
+ {getMessage('stuff.detail.installHeight')} *
|
@@ -727,25 +722,25 @@ export default function StuffDetail() {
|
- | 계약조건 |
+ {getMessage('stuff.detail.conType')} |
|
- | 메모 |
+ {getMessage('stuff.detail.remarks')} |
-
+
|
@@ -772,6 +767,21 @@ export default function StuffDetail() {
)) || (
<>
+
{objectNo.substring(0, 1) === 'R' ? (
<>
@@ -788,20 +798,26 @@ export default function StuffDetail() {
>
) : (
<>
+ {!isFormValid ? (
+
+ ) : (
+
+ )}
-
>
)}
>
)}
- {showButtonValid && }
-
+ {showAddressButtonValid && }
+ {showDesignRequestButtonValid && }
>
)
}
diff --git a/src/components/management/StuffQGrid.jsx b/src/components/management/StuffQGrid.jsx
index f9a65052..a2a47c5d 100644
--- a/src/components/management/StuffQGrid.jsx
+++ b/src/components/management/StuffQGrid.jsx
@@ -38,7 +38,7 @@ export default function StuffQGrid(props) {
flex: 1,
sortable: false,
suppressMovable: true,
- resizable: false,
+ resizable: true,
suppressSizeToFit: false,
}
}, [])
@@ -69,18 +69,12 @@ export default function StuffQGrid(props) {
props.getCellDoubleClicked(event)
}, [])
- //컨텐츠에 따라 컬럼넓이 자동조절
const autoSizeStrategy = useMemo(() => {
return {
type: 'fitCellContents',
}
}, [])
- const onGridReady = useCallback((event) => {
- // 헤더 사이즈 조정 컬럼에 width값으로 계산
- event.api.sizeColumnsToFit()
- }, [])
-
// Fetch data & update rowData state
useEffect(() => {
gridData ? setRowData(gridData) : ''
@@ -97,7 +91,6 @@ export default function StuffQGrid(props) {
물건 목록이 없습니다.'}
- // getRowStyle={getRowStyle}
getRowClass={getRowClass}
+ autoSizeAllColumns={true}
/>
)
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx
index 19981fc5..f88cf3cc 100644
--- a/src/components/management/StuffSearchCondition.jsx
+++ b/src/components/management/StuffSearchCondition.jsx
@@ -110,7 +110,6 @@ export default function StuffSearchCondition() {
//초기화 눌렀을 때 자동완성도..
const handleClear = () => {
- // console.log('ref::', ref.current.state.values)
if (ref.current.state.dropDown) {
ref.current.methods.dropDown()
} else {
diff --git a/src/components/management/popup/DesignRequestPop.jsx b/src/components/management/popup/DesignRequestPop.jsx
deleted file mode 100644
index ae7fd858..00000000
--- a/src/components/management/popup/DesignRequestPop.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import React from 'react'
-
-export default function DesignRequestPop() {
- return
-}
diff --git a/src/components/management/popup/FindAddressPop.jsx b/src/components/management/popup/FindAddressPop.jsx
index bf276218..157cccb4 100644
--- a/src/components/management/popup/FindAddressPop.jsx
+++ b/src/components/management/popup/FindAddressPop.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useRef } from 'react'
+import React, { useState } from 'react'
import { useForm } from 'react-hook-form'
import { queryStringFormatter } from '@/util/common-utils'
import { useAxios } from '@/hooks/useAxios'
@@ -6,7 +6,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
import { useRecoilValue } from 'recoil'
import FindAddressPopQGrid from './FindAddressPopQGrid'
import { useMessage } from '@/hooks/useMessage'
-
+import { isNotEmptyArray } from '@/util/common-utils'
export default function FindAddressPop(props) {
const globalLocaleState = useRecoilValue(globalLocaleStore)
@@ -14,17 +14,37 @@ export default function FindAddressPop(props) {
const { getMessage } = useMessage()
- const [prefId, setPrefId] = useState('')
- const [address1, setAddress1] = useState('')
- const [address2, setAddress2] = useState('')
- const [address3, setAddress3] = useState('')
- const gridRef = useRef()
+ const [prefId, setPrefId] = useState(null)
+ const [zipNo, setZipNo] = useState(null)
+ const [address1, setAddress1] = useState(null)
+ const [address2, setAddress2] = useState(null)
+ const [address3, setAddress3] = useState(null)
const [gridProps, setGridProps] = useState({
gridData: [],
isPageable: false,
- gridColumns: [],
+ gridColumns: [
+ {
+ field: 'address1',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address1'),
+ minWidth: 150,
+ checkboxSelection: true,
+ showDisabledCheckboxes: true,
+ },
+ {
+ field: 'address2',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address2'),
+ minWidth: 150,
+ },
+ {
+ field: 'address3',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address3'),
+ minWidth: 150,
+ },
+ ],
})
+
+ //검색필드
const formInitValue = {
zipNo: '',
}
@@ -33,38 +53,46 @@ export default function FindAddressPop(props) {
})
const form = { register, setValue, getValues, handleSubmit, resetField, control, watch }
+
//우편번호 검색
const searchPostNum = () => {
// //7830060
// //9302226
// //0790177 3개짜리
- console.log(watch('zipNo'))
const params = {
zipcode: watch('zipNo'),
}
get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => {
- console.log('우편조회 API결과:::::', res)
if (res.status === 200) {
+ if (isNotEmptyArray(res.results)) {
+ setGridProps({ ...gridProps, gridData: res.results })
+ } else {
+ setGridProps({ ...gridProps, gridData: [] })
+ }
} else {
- alert('등록된 우편번호에서 주소를 찾을 수 없습니다. 다시 입력해주세요.')
+ alert(getMessage('stuff.addressPopup.error.message1'))
+ setGridProps({ ...gridProps, gridData: [] })
}
})
}
// 주소적용 클릭
- const zipInfo = () => {
- console.log('주소적용 클릭:::::::::')
- // setAddress3('3333')
- // setAddress3('4444')
- // setAddress3('5555')
- props.zipInfo({
- zipNo: '3434343',
- address1: '3333',
- address2: '4444',
- address3: '5555',
- })
+ const applyAddress = () => {
+ // console.log('주소적용 클릭:::::::::', prefId, address1, address2, address3, zipNo)
+ if (prefId == null) {
+ alert('stuff.addressPopup.error.message2')
+ } else {
+ props.zipInfo({
+ zipNo: zipNo,
+ address1: address1,
+ address2: address2,
+ address3: address3,
+ prefId: prefId,
+ })
- props.setShowButtonValid(false)
+ //팝업닫기
+ props.setShowAddressButtonValid(false)
+ }
}
//숫자만
@@ -72,13 +100,31 @@ export default function FindAddressPop(props) {
let input = e.target
input.value = input.value.replace(/[^0-9]/g, '')
}
+
+ //그리드에서 선택한 우편정보
+ const getSelectedRowdata = (data) => {
+ if (isNotEmptyArray(data)) {
+ setAddress1(data[0].address1)
+ setAddress2(data[0].address2)
+ setAddress3(data[0].address3)
+ setPrefId(data[0].prefcode)
+ setZipNo(data[0].zipcode)
+ } else {
+ setAddress1(null)
+ setAddress2(null)
+ setAddress3(null)
+ setPrefId(null)
+ setZipNo(null)
+ }
+ }
+
return (
{getMessage('stuff.addressPopup.title')}
-
@@ -96,14 +142,14 @@ export default function FindAddressPop(props) {
-
+
- props.setShowButtonValid(false)}>
+ props.setShowAddressButtonValid(false)}>
{getMessage('stuff.addressPopup.btn1')}
-
+
{getMessage('stuff.addressPopup.btn2')}
diff --git a/src/components/management/popup/FindAddressPopQGrid.jsx b/src/components/management/popup/FindAddressPopQGrid.jsx
index f5b7c2fa..83544a5a 100644
--- a/src/components/management/popup/FindAddressPopQGrid.jsx
+++ b/src/components/management/popup/FindAddressPopQGrid.jsx
@@ -1,6 +1,66 @@
import React from 'react'
+import { useCallback, useEffect, useMemo, useState } from 'react'
+import { AgGridReact } from 'ag-grid-react'
+
+import 'ag-grid-community/styles/ag-grid.css'
+import 'ag-grid-community/styles/ag-theme-quartz.css'
export default function FindAddressPopGrid(props) {
- const { gridData, gridColumns, isPageable = true, gridRef } = props
- return
+ const { gridData, gridColumns, isPageable = true } = props
+
+ const [rowData, setRowData] = useState(null)
+
+ const [gridApi, setGridApi] = useState(null)
+
+ const [colDefs, setColDefs] = useState(gridColumns)
+
+ const defaultColDef = useMemo(() => {
+ return {
+ flex: 1,
+ minWidth: 100,
+ sortable: false,
+ suppressMovable: false,
+ resizable: false,
+ suppressSizeToFit: false,
+ }
+ }, [])
+
+ const rowBuffer = 100
+
+ useEffect(() => {
+ gridData ? setRowData(gridData) : ''
+ }, [gridData])
+
+ const rowSelection = useMemo(() => {
+ return { mode: 'singleRow', enableClickSelection: true }
+ }, [])
+
+ const onGridReady = useCallback(
+ (params) => {
+ setGridApi(params.api)
+ gridData ? setRowData(gridData) : ''
+ },
+ [gridData],
+ )
+
+ //부모로 선택한 우편정보 보내기
+ const onSelectionChanged = () => {
+ const selectedData = gridApi.getSelectedRows()
+ props.getSelectedRowdata(selectedData)
+ }
+
+ return (
+
+ )
}
diff --git a/src/components/management/popup/PlanRequestPop.jsx b/src/components/management/popup/PlanRequestPop.jsx
new file mode 100644
index 00000000..9eee76a3
--- /dev/null
+++ b/src/components/management/popup/PlanRequestPop.jsx
@@ -0,0 +1,169 @@
+import React, { useState } from 'react'
+import { useForm } from 'react-hook-form'
+import { queryStringFormatter } from '@/util/common-utils'
+import { useAxios } from '@/hooks/useAxios'
+import { globalLocaleStore } from '@/store/localeAtom'
+import { useRecoilValue } from 'recoil'
+import FindAddressPopQGrid from './FindAddressPopQGrid'
+import { useMessage } from '@/hooks/useMessage'
+import { isNotEmptyArray } from '@/util/common-utils'
+import SingleDatePicker from '@/components/common/datepicker/SingleDatePicker'
+import dayjs from 'dayjs'
+export default function PlanRequestPop(props) {
+ const globalLocaleState = useRecoilValue(globalLocaleStore)
+
+ const { get } = useAxios(globalLocaleState)
+
+ const { getMessage } = useMessage()
+ // 검색조건 달력 셋팅
+ const [startDate, setStartDate] = useState(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD'))
+ const [endDate, setEndDate] = useState(dayjs(new Date()).format('YYYY-MM-DD'))
+
+ const rangeDatePickerProps1 = {
+ startDate, //시작일
+ setStartDate,
+ }
+
+ const rangeDatePickerProps2 = {
+ startDate: endDate, //종료일
+ setStartDate: setEndDate,
+ }
+
+ const [gridProps, setGridProps] = useState({
+ gridData: [],
+ isPageable: false,
+ gridColumns: [
+ {
+ field: 'address1',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address1'),
+ minWidth: 150,
+ checkboxSelection: true,
+ showDisabledCheckboxes: true,
+ },
+ {
+ field: 'address2',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address2'),
+ minWidth: 150,
+ },
+ {
+ field: 'address3',
+ headerName: getMessage('stuff.addressPopup.gridHeader.address3'),
+ minWidth: 150,
+ },
+ ],
+ })
+
+ //검색필드
+ const formInitValue = {
+ //zipNo: '',
+ }
+
+ const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({
+ defaultValues: formInitValue,
+ })
+
+ const form = { register, setValue, getValues, handleSubmit, resetField, control, watch }
+
+ return (
+
+
+
+
+ {getMessage('stuff.planReqPopup.title')}
+ props.setShowDesignRequestButtonValid(false)}>
+ 닫기
+
+
+
+
+
+
+ )
+}
diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js
index 1d395d27..33b393b8 100644
--- a/src/hooks/object/useObjectBatch.js
+++ b/src/hooks/object/useObjectBatch.js
@@ -1,6 +1,210 @@
+'use client'
+import { useMessage } from '@/hooks/useMessage'
+import { useRecoilState, useRecoilValue } from 'recoil'
+import { canvasState } from '@/store/canvasAtom'
+import { INPUT_TYPE, BATCH_TYPE } from '@/common/common'
+import { useEvent } from '@/hooks/useEvent'
+import { polygonToTurfPolygon, rectToPolygon, pointsToTurfPolygon } from '@/util/canvas-util'
+import { useSwal } from '@/hooks/useSwal'
+import * as turf from '@turf/turf'
+
export function useObjectBatch() {
const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState)
+ const { addCanvasMouseEventListener, initEvent } = useEvent()
+ const { swalFire } = useSwal()
- const openObjectBatch = () => {}
+ const applyOpeningAndShadow = (objectPlacement, buttonAct, surfaceShapePolygons, setShowObjectSettingModal) => {
+ const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value
+ const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false
+ const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP
+ const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW
+
+ let rect, isDown, origX, origY
+ let selectedSurface
+
+ //프리입력
+ if (selectedType === INPUT_TYPE.FREE) {
+ addCanvasMouseEventListener('mouse:down', (e) => {
+ isDown = true
+ const pointer = canvas.getPointer(e.e)
+
+ surfaceShapePolygons.forEach((surface) => {
+ if (surface.inPolygon({ x: pointer.x, y: pointer.y })) {
+ selectedSurface = surface
+ }
+ })
+
+ if (!selectedSurface) {
+ swalFire({ text: '지붕안에 그려야해요', icon: 'error' })
+ initEvent() //이벤트 초기화
+ return
+ }
+
+ origX = pointer.x
+ origY = pointer.y
+
+ rect = new fabric.Rect({
+ left: origX,
+ top: origY,
+ originX: 'left',
+ originY: 'top',
+ width: 0,
+ height: 0,
+ angle: 0,
+ stroke: 'black',
+ })
+
+ //개구냐 그림자냐에 따라 변경
+ rect.set({
+ fill: buttonAct === 1 ? 'white' : 'rgba(0, 0, 0, 0.4)',
+ name: objTempName,
+ })
+
+ canvas?.add(rect)
+ })
+
+ addCanvasMouseEventListener('mouse:move', (e) => {
+ if (!isDown) return
+
+ if (selectedSurface) {
+ const pointer = canvas.getPointer(e.e)
+ const width = pointer.x - origX
+ const height = pointer.y - origY
+
+ rect.set({ width: Math.abs(width), height: Math.abs(height) })
+
+ if (width < 0) {
+ rect.set({ left: Math.abs(pointer.x) })
+ }
+ if (height < 0) {
+ rect.set({ top: Math.abs(pointer.y) })
+ }
+
+ canvas?.renderAll()
+ }
+ })
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ if (rect) {
+ const rectPolygon = pointsToTurfPolygon(rectToPolygon(rect))
+ const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
+
+ //지붕 밖으로 그렸을때
+ if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) {
+ swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
+ //일단 지워
+ deleteTempObjects(setShowObjectSettingModal)
+ return
+ }
+
+ if (!isCrossChecked) {
+ const preObjects = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW)
+ const preObjectsArray = preObjects.map((obj) => rectToPolygon(obj))
+ const isCross = preObjectsArray.some((object) => turf.booleanOverlap(pointsToTurfPolygon(object), rectPolygon))
+
+ if (isCross) {
+ swalFire({ text: '겹치기 불가요...', icon: 'error' })
+ deleteTempObjects(setShowObjectSettingModal)
+ return
+ }
+ }
+
+ isDown = false
+ rect.set({ name: objName })
+ rect.setCoords()
+ initEvent()
+ }
+ })
+ } else if (selectedType === INPUT_TYPE.DIMENSION) {
+ const width = objectPlacement.widthRef.current.value / 10
+ const height = objectPlacement.heightRef.current.value / 10
+
+ if (width === '' || height === '' || width <= 0 || height <= 0) {
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
+ return
+ }
+
+ // setShowObjectSettingModal(false) //메뉴보이고
+ addCanvasMouseEventListener('mouse:move', (e) => {
+ isDown = true
+ if (!isDown) return
+
+ canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === objTempName)) //움직일때 일단 지워가면서 움직임
+ const pointer = canvas.getPointer(e.e)
+
+ surfaceShapePolygons.forEach((surface) => {
+ if (surface.inPolygon({ x: pointer.x, y: pointer.y })) {
+ selectedSurface = surface
+ }
+ })
+
+ rect = new fabric.Rect({
+ fill: 'white',
+ stroke: 'black',
+ strokeWidth: 1,
+ width: width,
+ height: height,
+ left: pointer.x - width / 2,
+ top: pointer.y - height / 2,
+ selectable: true,
+ lockMovementX: true,
+ lockMovementY: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ })
+
+ //개구냐 그림자냐에 따라 변경
+ rect.set({
+ fill: buttonAct === 1 ? 'white' : 'rgba(0, 0, 0, 0.4)',
+ name: objTempName,
+ })
+
+ canvas?.add(rect)
+ })
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ if (rect) {
+ const rectPolygon = pointsToTurfPolygon(rectToPolygon(rect))
+ const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
+
+ //지붕 밖으로 그렸을때
+ if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) {
+ swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
+ //일단 지워
+ deleteTempObjects(setShowObjectSettingModal)
+ return
+ }
+
+ if (!isCrossChecked) {
+ const preObjects = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW)
+ const preObjectsArray = preObjects.map((obj) => rectToPolygon(obj))
+ const isCross = preObjectsArray.some((object) => turf.booleanOverlap(pointsToTurfPolygon(object), rectPolygon))
+
+ if (isCross) {
+ swalFire({ text: '겹치기 불가요...', icon: 'error' })
+ deleteTempObjects(setShowObjectSettingModal)
+ return
+ }
+ }
+
+ isDown = false
+ rect.set({ name: objName })
+ rect.setCoords()
+ initEvent()
+ }
+ })
+ }
+ }
+
+ const deleteTempObjects = (setShowObjectSettingModal) => {
+ const deleteTarget = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING_TEMP || obj.name === BATCH_TYPE.SHADOW_TEMP)
+ canvas?.remove(...deleteTarget)
+ initEvent() //이벤트 초기화
+ }
+
+ return {
+ applyOpeningAndShadow,
+ }
}
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js
index c9e898e9..bcffeba4 100644
--- a/src/hooks/surface/useSurfaceShapeBatch.js
+++ b/src/hooks/surface/useSurfaceShapeBatch.js
@@ -2,7 +2,7 @@
import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
-import { MENU } from '@/common/common'
+import { MENU, BATCH_TYPE } from '@/common/common'
import { getIntersectionPoint, setSurfaceShapePattern } from '@/util/canvas-util'
import { degreesToRadians } from '@turf/turf'
import { QPolygon } from '@/components/fabric/QPolygon'
@@ -131,23 +131,23 @@ export function useSurfaceShapeBatch() {
if (surfaceId === 1) {
if (length1 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
if (length2 === 0) {
if (length3 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
}
} else if ([2, 4].includes(surfaceId)) {
if (length1 === 0 || length2 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
} else if ([3, 5, 6, 15, 18].includes(surfaceId)) {
if (length1 === 0 || length2 === 0 || length3 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
if (surfaceId === 3 && length3 > length1) {
@@ -173,7 +173,7 @@ export function useSurfaceShapeBatch() {
}
} else if ([8, 12, 13, 16, 17].includes(surfaceId)) {
if (length1 === 0 || length2 === 0 || length3 === 0 || length4 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
@@ -201,7 +201,7 @@ export function useSurfaceShapeBatch() {
}
} else if ([7, 9, 10, 11, 14].includes(surfaceId)) {
if (length1 === 0 || length2 === 0 || length3 === 0 || length4 === 0 || length5 === 0) {
- swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' })
+ swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' })
check = false
}
if (surfaceId === 9 || surfaceId === 10 || surfaceId === 11) {
@@ -564,7 +564,27 @@ export function useSurfaceShapeBatch() {
return points
}
+
+ const deleteAllSurfacesAndObjects = () => {
+ swalFire({
+ text: '삭제 ㄱㄱ?',
+ type: 'confirm',
+ confirmFn: () => {
+ canvas?.getObjects().forEach((obj) => {
+ if (obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH || obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW) {
+ canvas?.remove(obj)
+ }
+ })
+ swalFire({ text: '삭제 완료 되었습니다.' })
+ },
+ denyFn: () => {
+ swalFire({ text: '취소되었습니다.' })
+ },
+ })
+ }
+
return {
applySurfaceShape,
+ deleteAllSurfacesAndObjects,
}
}
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index c7f6620e..427fe511 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -54,6 +54,7 @@ export function usePlan() {
'y2',
'attributes',
'stickeyPoint',
+ 'text',
])
const str = JSON.stringify(objs)
@@ -76,32 +77,49 @@ export function usePlan() {
*/
const checkModifiedCanvasPlan = () => {
removeMouseLines()
- const canvasStr = addCanvas()
- const canvasStatus = dbToCanvasFormat(canvasToDbFormat(canvasStr))
+ const canvasStatus = addCanvas()
const initPlanData = initCanvasPlans.find((plan) => plan.id === currentCanvasPlan.id)
- if (JSON.parse(canvasStr).objects.length === 0 && initPlanData === undefined) {
- // 저장 안 된 빈 캔버스
- return false
- } else if (initPlanData && canvasStatus === initPlanData.canvasStatus) {
- // 저장 되어있고 변경사항 없는 캔버스
- return false
+
+ if (!initPlanData) {
+ // 새로운 캔버스
+ return JSON.parse(canvasStatus).objects.length > 0
} else {
- return true
+ // 저장된 캔버스
+ if (canvasStatus === initPlanData.canvasStatus) {
+ return false
+ } else {
+ // 각각 object들의 id 목록을 추출하여 비교
+ const canvasObjsIds = getObjectIds(JSON.parse(canvasStatus).objects)
+ const dbObjsIds = getObjectIds(JSON.parse(initPlanData.canvasStatus).objects)
+
+ return canvasObjsIds.length !== dbObjsIds.length || !canvasObjsIds.every((id, index) => id === dbObjsIds[index])
+ }
}
}
+ const getObjectIds = (objects) => {
+ return objects
+ .filter((obj) => obj.hasOwnProperty('id'))
+ .map((obj) => obj.id)
+ .sort()
+ }
/**
* DB에 저장된 데이터를 canvas에서 사용할 수 있도록 포맷화
*/
const dbToCanvasFormat = (cs) => {
- return JSON.stringify(cs.replace(/##/g, '"').replace(/\\/g, '').slice(1, -1))
+ // return JSON.stringify(cs.replace(/##/g, '"')) //.replace(/\\/g, ''))//.slice(1, -1))
+ // JSON.stringify()를 사용하면 "가 \"로 바뀐다. 따라서, JSON.stringify를 제거
+ // canvasToDbFormat()에서 \\의 상황을 없앴으므로 replace(/\\/g, '')를 제거
+ return cs.replace(/##/g, '"')
}
/**
* canvas의 데이터를 DB에 저장할 수 있도록 포맷화
*/
const canvasToDbFormat = (cs) => {
- return JSON.stringify(cs).replace(/"/g, '##')
+ // return JSON.stringify(cs).replace(/"/g, '##')
+ // addCanvas()에서 JSON.stringify()를 거쳐서 나오는데, 또 감싸버려서 \가 \\로 된다. 따라서, JSON.stringify를 제거
+ return cs.replace(/"/g, '##')
}
/**
@@ -130,9 +148,7 @@ export function usePlan() {
setInitCanvasPlans((initCanvasPlans) =>
initCanvasPlans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)),
)
- setPlans((plans) =>
- plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)),
- )
+ setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
})
.catch((error) => {
swalFire({ text: error.message, icon: 'error' })
diff --git a/src/locales/ja.json b/src/locales/ja.json
index eddf5a2a..abdfc11c 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -383,8 +383,40 @@
"stuff.message.periodError": "最大1年間閲覧可能.",
"stuff.addressPopup.title": "郵便番号",
"stuff.addressPopup.placeholder": "郵便番号の7桁を入力してください。",
+ "stuff.addressPopup.error.message1": "登録された郵便番号に住所が見つかりません。もう一度入力してください。",
+ "stuff.addressPopup.error.message2": "住所を選択してください.",
+ "stuff.addressPopup.gridHeader.address1": "都道府県",
+ "stuff.addressPopup.gridHeader.address2": "市区町村",
+ "stuff.addressPopup.gridHeader.address3": "市区町村 以下",
"stuff.addressPopup.btn1": "閉じる",
"stuff.addressPopup.btn2": "住所適用",
+ "stuff.planReqPopup.title": "設計依頼のインポート",
+ "stuff.detail.required": "必須入力項目",
+ "stuff.detail.designNo": "設計依頼No.",
+ "stuff.detail.dispCompanyName": "担当者",
+ "stuff.detail.objectStatusId": "物品区分/物件名",
+ "stuff.detail.objectStatus0": "新築",
+ "stuff.detail.objectStatus1": "基軸",
+ "stuff.detail.objectNameKana": "商品名 ふりがな",
+ "stuff.detail.saleStoreId": "一次販売店名/ID",
+ "stuff.detail.otherSaleStoreId": "二次販売店名/ID",
+ "stuff.detail.zipNo": "郵便番号 ",
+ "stuff.detail.btn.addressPop": "住所検索",
+ "stuff.detail.btn.addressPop.guide": "※ 郵便番号7桁を入力した後、アドレス検索ボタンをクリックしてください",
+ "stuff.detail.prefId": "都道府県 / 住所 ",
+ "stuff.detail.areaId": "発電量シミュレーション地域 ",
+ "stuff.detail.windSpeed": "基準風速",
+ "stuff.detail.windSpeedSpan": "m/s以下",
+ "stuff.detail.btn.windSpeedPop": "風速選択",
+ "stuff.detail.verticalSnowCover": "垂直説説",
+ "stuff.detail.coldRegionFlg": "寒冷地対策施行",
+ "stuff.detail.surfaceType": "面調図区分",
+ "stuff.detail.saltAreaFlg": "塩害地域用アイテムの使用",
+ "stuff.detail.installHeight": "設置高さ",
+ "stuff.detail.conType": "契約条件",
+ "stuff.detail.conType0": "余剰",
+ "stuff.detail.conType1": "全量",
+ "stuff.detail.remarks": "メモ",
"length": "長さ",
"height": "高さ",
"output": "出力",
@@ -438,7 +470,7 @@
"main.popup.login.validate1": "入力したパスワードが異なります。",
"main.popup.login.validate2": "半角10文字以内で入力してください。",
"main.popup.login.success": "パスワードが変更されました。",
- "surface.shape.validate.size": "寸法を入力してください.",
+ "common.canvas.validate.size": "寸法を入力してください.",
"surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.",
"surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.",
"surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.",
diff --git a/src/locales/ko.json b/src/locales/ko.json
index ef41a4a8..3e37918b 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -387,8 +387,40 @@
"stuff.message.periodError": "최대1년 조회 가능합니다.",
"stuff.addressPopup.title": "우편번호",
"stuff.addressPopup.placeholder": "우편번호의 7자리를 입력하세요.",
+ "stuff.addressPopup.error.message1": "등록된 우편번호에서 주소를 찾을 수 없습니다. 다시 입력해주세요.",
+ "stuff.addressPopup.error.message2": "주소를 선택해주세요.",
+ "stuff.addressPopup.gridHeader.address1": "도도부현",
+ "stuff.addressPopup.gridHeader.address2": "시구정촌",
+ "stuff.addressPopup.gridHeader.address3": "시구정촌 이하",
"stuff.addressPopup.btn1": "닫기",
"stuff.addressPopup.btn2": "주소적용",
+ "stuff.planReqPopup.title": "설계의뢰 불러오기",
+ "stuff.detail.required": "필수 입력항목",
+ "stuff.detail.designNo": "설계의뢰No.",
+ "stuff.detail.dispCompanyName": "담당자",
+ "stuff.detail.objectStatusId": "물건구분/물건명",
+ "stuff.detail.objectStatus0": "신축",
+ "stuff.detail.objectStatus1": "기축",
+ "stuff.detail.objectNameKana": "물건명 후리가나",
+ "stuff.detail.saleStoreId": "1차 판매점명 / ID",
+ "stuff.detail.otherSaleStoreId": "2차 판매점명 / ID",
+ "stuff.detail.zipNo": "우편번호",
+ "stuff.detail.btn.addressPop": "주소검색",
+ "stuff.detail.btn.addressPop.guide": "※ 주소검색 버튼을 클릭한 후, 도도부현 정보를 선택해주십시오.",
+ "stuff.detail.prefId": "도도부현 / 주소",
+ "stuff.detail.areaId": "발전량시뮬레이션지역",
+ "stuff.detail.windSpeed": "기준풍속",
+ "stuff.detail.windSpeedSpan": "m/s이하",
+ "stuff.detail.btn.windSpeedPop": "풍속선택",
+ "stuff.detail.verticalSnowCover": "수직적설량",
+ "stuff.detail.coldRegionFlg": "한랭지대책시행",
+ "stuff.detail.surfaceType": "면조도구분",
+ "stuff.detail.saltAreaFlg": "염해지역용아이템사용",
+ "stuff.detail.installHeight": "설치높이",
+ "stuff.detail.conType": "계약조건",
+ "stuff.detail.conType0": "잉여",
+ "stuff.detail.conType1": "전량",
+ "stuff.detail.remarks": "메모",
"length": "길이",
"height": "높이",
"output": "출력",
@@ -442,7 +474,7 @@
"main.popup.login.validate1": "입력한 패스워드가 다릅니다.",
"main.popup.login.validate2": "반각 10자 이내로 입력해주세요.",
"main.popup.login.success": "비밀번호가 변경되었습니다.",
- "surface.shape.validate.size": "사이즈를 입력해 주세요.",
+ "common.canvas.validate.size": "사이즈를 입력해 주세요.",
"surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.",
"surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.",
"surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.",
| |