Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
yoosangwook 2024-10-17 15:47:59 +09:00
commit 878efb5df4
14 changed files with 172 additions and 52 deletions

View File

@ -75,7 +75,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
const y2 = this.top + this.height * scaleY
const dx = x2 - x1
const dy = y2 - y1
this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0))
this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1))
},
addLengthText() {
@ -150,7 +150,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
getLength() {
//10배 곱해진 값 return
return Number(this.length.toFixed(1) * 10)
return Number(this.length.toFixed(0) * 10)
},
setViewLengthText(bool) {

View File

@ -199,7 +199,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
const end = points[(i + 1) % points.length]
const dx = end.x - start.x
const dy = end.y - start.y
const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10
const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) * 10
let midPoint
@ -224,7 +224,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
const degree = (Math.atan2(dy, dx) * 180) / Math.PI
// Create new text object if it doesn't exist
const text = new fabric.Text(length.toFixed(0), {
const text = new fabric.Text(length.toString(), {
left: midPoint.x,
top: midPoint.y,
fontSize: this.fontSize,

View File

@ -13,11 +13,7 @@ export default function CanvasFrame({ plan }) {
const canvasRef = useRef(null)
const { canvas } = useCanvas('canvas')
const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu()
const currentObject = useRecoilValue(currentObjectState)
useEffect(() => {
console.log(currentObject)
}, [currentObject])
useEvent()
const loadCanvas = () => {

View File

@ -19,6 +19,7 @@ import { MENU } from '@/common/common'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
const canvasMenus = [
{ index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
@ -58,7 +59,8 @@ export default function CanvasMenu(props) {
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
const setCurrentMenu = useSetRecoilState(currentMenuState)
const setPoints = useSetRecoilState(outerLinePointsState)
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
@ -140,7 +142,8 @@ export default function CanvasMenu(props) {
}
const handleClear = () => {
setPoints([])
setOuterLinePoints([])
setPlacementPoints([])
canvas?.clear()
}

View File

@ -406,14 +406,14 @@ export default function Stuff() {
<div className="sub-table-box">
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3>물건목록</h3>
<h3>{getMessage('stuff.search.grid.title')}</h3>
<ul className="info-wrap">
<li>
전체
{getMessage('stuff.search.grid.all')}
<span>{convertNumberToPriceDecimal(totalCount)}</span>
</li>
<li>
선택
{getMessage('stuff.search.grid.selected')}
<span className="red">{convertNumberToPriceDecimal(selectedRowDataCount)}</span>
</li>
</ul>
@ -421,8 +421,8 @@ export default function Stuff() {
<div className="left-unit-box">
<div className="select-box mr5" style={{ width: '110px' }}>
<select className="select-light black" name="" id="" onChange={onChangeSortType}>
<option value="R">최근 등록일</option>
<option value="U">최근 수정일</option>
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
</select>
</div>
<div className="select-box" style={{ width: '80px' }}>

View File

@ -99,7 +99,6 @@ export default function StuffSearchCondition() {
useEffect(() => {
if (isObjectNotEmpty(sessionState)) {
// console.log(' ::::::::', sessionState)
// storeId T01 1
// get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => {
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
@ -190,7 +189,6 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
// placeholder=" "
value={stuffSearch?.code === 'E' || stuffSearch?.code === 'M' ? stuffSearch.schObjectNo : objectNo}
onChange={(e) => {
setObjectNo(e.target.value)
@ -205,7 +203,6 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
// placeholder=" "
value={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
onChange={(e) => {
setSaleStoreName(e.target.value)
@ -220,7 +217,6 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
// placeholder=" "
value={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
onChange={(e) => {
setAddress(e.target.value)
@ -237,7 +233,6 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
// placeholder=" "
value={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
onChange={(e) => {
setobjectName(e.target.value)
@ -252,7 +247,6 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
// placeholder=" "
value={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
onChange={(e) => {
setDispCompanyName(e.target.value)

View File

@ -12,6 +12,9 @@ import dayjs from 'dayjs'
import PlanRequestPopQGrid from './PlanRequestPopQGrid'
import { sessionStore } from '@/store/commonAtom'
import { planReqSearchState } from '@/store/planReqAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import Select from 'react-select'
export default function PlanRequestPop(props) {
const sessionState = useRecoilValue(sessionStore)
@ -20,6 +23,7 @@ export default function PlanRequestPop(props) {
const { get } = useAxios(globalLocaleState)
const { getMessage } = useMessage()
const ref = useRef()
//
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'))
@ -34,7 +38,6 @@ export default function PlanRequestPop(props) {
setStartDate: setEndDate,
}
const ref = useRef()
const resetPlanReqRecoil = useResetRecoilState(planReqSearchState)
const [planReqSearch, setPlanReqSearch] = useRecoilState(planReqSearchState)
@ -47,14 +50,42 @@ export default function PlanRequestPop(props) {
const [schDateGbn, setSchDateGbn] = useState('S') //(S/R)
//
const resetRecoil = () => {}
const resetRecoil = () => {
console.log('초기화')
setSchPlanReqNo('')
setSchTitle('')
setSchAddress('')
setSchSaleStoreName('')
setSchPlanReqName('')
setSchDateGbn('S')
setStartDate(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD'))
setEndDate(dayjs(new Date()).format('YYYY-MM-DD'))
setSchPlanStatCd('')
handleClear() //
resetPlanReqRecoil()
}
// ..
//
const handleClear = () => {
if (ref.current.state.dropDown) {
ref.current.methods.dropDown()
if (ref.current) {
ref.current.clearValue()
}
}
//
const onSelectionChange = (key) => {
//
console.log('E::::::::', key)
if (isObjectNotEmpty(key)) {
setSchPlanStatCd(key.value)
setPlanReqSearch({
...planReqSearch,
schPlanStatCd: key.value,
})
} else {
ref.current.state.values = []
//X
setSchPlanStatCd('')
setPlanReqSearch({ ...planReqSearch, schPlanStatCd: '' })
}
}
@ -63,6 +94,11 @@ export default function PlanRequestPop(props) {
setEndDate(planReqSearch?.schEndDt ? planReqSearch.schEndDt : dayjs(new Date()).format('YYYY-MM-DD'))
}, [planReqSearch])
//
const onSubmit = () => {
console.log('조회!!!!', planReqSearch)
}
const [gridProps, setGridProps] = useState({
gridData: [],
isPageable: false,
@ -117,6 +153,25 @@ export default function PlanRequestPop(props) {
],
})
const tempList = [
{
label: '완료',
value: 'C',
},
{
label: '저장',
value: 'I',
},
{
label: '접수',
value: 'R',
},
{
label: '제출',
value: 'S',
},
]
return (
<div className="modal-popup">
<div className="modal-dialog big">
@ -132,8 +187,12 @@ export default function PlanRequestPop(props) {
<div className="design-tit-wrap">
<h3>{getMessage('stuff.planReqPopup.popTitle')}</h3>
<div className="design-search-wrap">
<button className="btn-origin grey mr5">{getMessage('stuff.planReqPopup.btn1')}</button>
<button className="btn-origin navy ">{getMessage('stuff.planReqPopup.btn2')}</button>
<button className="btn-origin navy mr5" onClick={onSubmit}>
{getMessage('stuff.planReqPopup.btn1')}
</button>
<button className="btn-origin grey" onClick={resetRecoil}>
{getMessage('stuff.planReqPopup.btn2')}
</button>
</div>
</div>
<div className="design-request-table">
@ -223,13 +282,22 @@ export default function PlanRequestPop(props) {
</td>
<th>{getMessage('stuff.planReqPopup.search.planStatName')}</th>
<td>
<div className="select-wrap">
<select className="select-light" name="" id="">
<div className="">
{/* <select className="select-light" name="" id="" onChange={onSelectionChange}>
<option value={''}>All</option>
<option value={'SAVE'}>저장</option>
<option value={'SUBMIT'}>제출</option>
<option value={'RECEIPT'}>접수</option>
</select>
<option value={'C'}>완료</option>
<option value={'I'}>저장</option>
<option value={'R'}>접수</option>
<option value={'S'}>제출</option>
</select> */}
<Select
ref={ref}
options={tempList}
onChange={onSelectionChange}
isSearchable={false}
placeholder="선택하세요."
isClearable={true}
/>
</div>
</td>
</tr>

View File

@ -23,10 +23,11 @@ import {
outerLineLength2State,
outerLineTypeState,
} from '@/store/outerLineAtom'
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util'
import { fabric } from 'fabric'
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
import { useSwal } from '@/hooks/useSwal'
import { booleanPointInPolygon } from '@turf/turf'
// 보조선 작성
export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
@ -76,6 +77,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
useEffect(() => {
typeRef.current = type
clear()
addDocumentEventListener('keydown', document, keydown[type])
}, [type])
useEffect(() => {
@ -103,12 +106,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
}
}, [])
useEffect(() => {
clear()
addDocumentEventListener('keydown', document, keydown[type])
}, [type])
const clear = () => {
addCanvasMouseEventListener('mouse:move', mouseMove)
setLength1(0)
setLength2(0)
@ -459,8 +458,9 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
}
const mouseDown = (e) => {
addCanvasMouseEventListener('mouse:move', mouseMove)
canvas.renderAll()
const pointer = getIntersectMousePoint(e)
console.log(pointer)
mousePointerArr.current.push(pointer)
if (mousePointerArr.current.length === 2) {
@ -621,10 +621,24 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
return
}
const roofBases = canvas.getObjects().find((obj) => obj.name === 'roofBase')
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
const innerLines = [...lineHistory.current]
roofBases.innerLines = [...innerLines]
roofBases.forEach((roofBase) => {
const roofInnerLines = innerLines.filter((line) => {
const turfPolygon = polygonToTurfPolygon(roofBase)
// innerLines의 두 점이 모두 polygon 안에 있는지 확인
const inPolygon1 = booleanPointInPolygon([line.x1, line.y1], turfPolygon)
const inPolygon2 = booleanPointInPolygon([line.x2, line.y2], turfPolygon)
if (inPolygon1 && inPolygon2) {
return true
}
})
roofBase.innerLines = [...roofInnerLines]
})
setShowAuxiliaryModal(false)
}

View File

@ -95,7 +95,11 @@ export function useRoofAllocationSetting(setShowRoofAllocationSettingModal) {
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
roofBases.forEach((roofBase) => {
splitPolygonWithLines(roofBase)
try {
splitPolygonWithLines(roofBase)
} catch (e) {
return
}
roofBase.innerLines.forEach((line) => {
canvas.remove(line)

View File

@ -33,6 +33,9 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
const [type, setType] = useState(TYPES.EAVES)
const isFix = useRef(false)
const initLines = useRef([])
const buttons = [
{ id: 1, name: getMessage('eaves'), type: TYPES.EAVES },
{ id: 2, name: getMessage('gable'), type: TYPES.GABLE },
@ -52,9 +55,11 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
useEffect(() => {
addCanvasMouseEventListener('mouse:down', mouseDown)
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
canvas.remove(wallLines)
canvas?.remove(...wallLines)
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
initLines.current = outerLines.map((line) => ({ ...line }))
outerLines.forEach((outerLine, idx) => {
if (idx === 0) {
currentLineRef.current = outerLine
@ -66,6 +71,7 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
canvas?.renderAll()
return () => {
handleLineToPolygon()
canvas?.discardActiveObject()
initEvent()
}
@ -166,6 +172,14 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
}
const handleSave = () => {
isFix.current = true
handleLineToPolygon()
setShowRoofShapePassivitySettingModal(false)
}
const handleLineToPolygon = () => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
exceptObjs.forEach((obj) => {
@ -176,13 +190,26 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
hideLine(line)
})
const wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
let wall
if (isFix.current) {
wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
} else {
// 그냥 닫을 경우 처리
wall = addPolygonByLines([...initLines.current], { name: 'wallLine', fill: 'transparent', stroke: 'black' })
lines.forEach((line, idx) => {
line.attributes = initLines.current[idx].attributes
})
}
wall.lines = [...lines]
// 기존 그려진 지붕이 없다면
if (roofBases.length === 0) {
return
}
const roof = drawRoofPolygon(wall)
canvas.renderAll()
setShowRoofShapePassivitySettingModal(false)
}
return { handleSave, handleConfirm, buttons, type, setType, TYPES, offsetRef, pitchRef, handleRollback }
}

View File

@ -244,8 +244,13 @@ export function useRoofShapeSetting(setShowRoofShapeSettingModal) {
}
}
// 기존 wallLine 제거
canvas?.remove(canvas.getObjects().filter((obj) => obj.name === 'wallLine'))
// 기존 wallLine, roofBase 제거
canvas
.getObjects()
.filter((obj) => obj.name === 'wallLine' || obj.name === 'roofBase')
.forEach((line) => {
canvas.remove(line)
})
const polygon = addPolygonByLines(outerLines, { name: 'wallLine' })
polygon.lines = [...outerLines]

View File

@ -43,7 +43,6 @@ export function useEvent() {
//default Event 추가
addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent)
addCanvasMouseEventListener('mouse:out', defaultMouseOutEvent)
addDocumentEventListener('keydown', document, defaultKeyboardEvent)
addDocumentEventListener('contextmenu', document, defaultContextMenuEvent)
if (adsorptionPointAddMode) {
addCanvasMouseEventListener('mouse:down', adsorptionPointAddModeStateEvent)

View File

@ -511,6 +511,11 @@
"stuff.search.period": "期間検索",
"stuff.search.schDateTypeU": "更新日",
"stuff.search.schDateTypeR": "登録日",
"stuff.search.grid.title": "商品リスト",
"stuff.search.grid.all": "全体",
"stuff.search.grid.selected": "選択",
"stuff.search.grid.schSortTypeR": "最近の登録日",
"stuff.search.grid.schSortTypeU": "最近の更新日",
"stuff.windSelectPopup.title": "風速選択",
"stuff.windSelectPopup.table.selected": "選択",
"stuff.windSelectPopup.table.windspeed": "風速",

View File

@ -516,6 +516,11 @@
"stuff.search.period": "기간검색",
"stuff.search.schDateTypeU": "갱신일",
"stuff.search.schDateTypeR": "등록일",
"stuff.search.grid.title": "물건목록",
"stuff.search.grid.all": "전체",
"stuff.search.grid.selected": "선택",
"stuff.search.grid.schSortTypeR": "최근 등록일",
"stuff.search.grid.schSortTypeU": "최근 갱신일",
"stuff.windSelectPopup.title": "풍속선택",
"stuff.windSelectPopup.table.selected": "선택",
"stuff.windSelectPopup.table.windspeed": "풍속",