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

This commit is contained in:
yoosangwook 2024-10-24 17:30:42 +09:00
commit cc5f5f85fe
13 changed files with 330 additions and 158 deletions

View File

@ -234,6 +234,7 @@ export default function Login() {
onBlur={() => setSecFocus(false)}
/>
<button
type="button"
className={`password-hidden ${passwordVisible ? 'visible' : ''}`}
onClick={(e) => {
e.preventDefault()

View File

@ -10,6 +10,7 @@ import { useRecoilValue } from 'recoil'
import { currentObjectState } from '@/store/canvasAtom'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
export default function CanvasFrame({ plan }) {
const canvasRef = useRef(null)
@ -21,7 +22,7 @@ export default function CanvasFrame({ plan }) {
},
})
const { checkCanvasObjectEvent, checkUnsavedCanvasPlan } = usePlan()
const { canvasLoadInit } = useCanvasConfigInitialize()
const currentObject = useRecoilValue(currentObjectState)
useEvent()
@ -32,47 +33,14 @@ export default function CanvasFrame({ plan }) {
if (plan?.canvasStatus) {
canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
canvas?.renderAll() // .
canvasLoadInit() //config
})
}
}
}
useEffect(() => {
// const checkEventName = [
// 'object:modified',
// 'object:moving',
// 'object:scaling',
// 'object:rotating',
// 'object:skewing',
// 'object:resizing',
// 'object:selected',
// 'object:added',
// 'object:removed',
// ]
canvas?.off('object:added')
canvas?.off('object:modified')
canvas?.off('object:removed')
loadCanvas()
if (plan) {
canvas?.on('object:added', (e) => {
if (e?.target.name !== 'mouseLine') {
checkCanvasObjectEvent(e, plan.id)
}
})
canvas?.on('object:modified', (e) => {
if (e?.target.name !== 'mouseLine') {
checkCanvasObjectEvent(e, plan.id)
}
})
canvas?.on('object:removed', (e) => {
if (e?.target.name !== 'mouseLine') {
checkCanvasObjectEvent(e, plan.id)
}
})
}
}, [plan, canvas])
const onClickContextMenu = (index) => {}

View File

@ -69,7 +69,6 @@ export default function CanvasMenu(props) {
})
const { commonFunctions } = useCommonUtils({
canvas,
commonFunctionState,
setCommonFunctionState,
})

View File

@ -1,7 +1,9 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { useMessage } from '@/hooks/useMessage'
import { useState } from 'react'
import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { canvasState } from '@/store/canvasAtom'
export default function PlanSizeSetting(props) {
const { horizon, setHorizon, vertical, setVertical, id, pos = { x: 985, y: 180 }, setIsShow } = props
@ -9,6 +11,7 @@ export default function PlanSizeSetting(props) {
const { getMessage } = useMessage()
const [originHorizon, setOriginHorizon] = useState(horizon)
const [originVertical, setOriginVertical] = useState(vertical)
const canvas = useRecoilValue(canvasState)
return (
<WithDraggable isShow={true} pos={pos}>
@ -55,6 +58,9 @@ export default function PlanSizeSetting(props) {
setVertical(originVertical)
setIsShow(false)
closePopup(id)
canvas.setWidth(originHorizon)
canvas.setHeight(originVertical)
canvas.renderAll()
}}
>
{getMessage('modal.common.save')}

View File

@ -53,9 +53,9 @@ export default function Stuff() {
const onDoubleClick = (e) => {
let objectNo = e.target.innerText
if (objectNo.substring(0, 1) === 'R') {
router.push(`${pathname}/detail?objectNo=${objectNo.toString()}`)
router.push(`${pathname}/detail?objectNo=${objectNo.toString()}`, { scroll: false })
} else {
router.push(`${pathname}/tempdetail?objectNo=${objectNo.toString()}`)
router.push(`${pathname}/tempdetail?objectNo=${objectNo.toString()}`, { scroll: false })
}
}
@ -157,9 +157,9 @@ export default function Stuff() {
//T R
if (event.data.objectNo) {
if (event.data.objectNo.substring(0, 1) === 'R') {
router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`)
router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
} else {
router.push(`${pathname}/tempdetail?objectNo=${event.data.objectNo.toString()}`)
router.push(`${pathname}/tempdetail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
}
}
}
@ -228,6 +228,7 @@ export default function Stuff() {
// sessionState
if (stuffSearchParams?.code === 'S') {
const params = {
saleStoreId: sessionState?.storeId,
schObjectNo: stuffSearchParams?.schObjectNo,
schAddress: stuffSearchParams?.schAddress,
schObjectName: stuffSearchParams?.schObjectName,
@ -244,7 +245,7 @@ export default function Stuff() {
}
async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}`
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
await get({
url: apiUrl,
}).then((res) => {
@ -258,6 +259,7 @@ export default function Stuff() {
} else {
//
const params = {
saleStoreId: sessionState?.storeId,
schObjectNo: stuffSearchParams.schObjectNo,
schAddress: '',
schObjectName: '',
@ -274,8 +276,7 @@ export default function Stuff() {
}
async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}`
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
await get({
url: apiUrl,
}).then((res) => {
@ -297,9 +298,8 @@ export default function Stuff() {
stuffSearchParams.schSortType = defaultSortType
setPageNo(1)
//
async function fetchData() {
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
@ -329,7 +329,6 @@ export default function Stuff() {
})
setPageNo(1)
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
@ -360,7 +359,6 @@ export default function Stuff() {
setPageNo(1)
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {

View File

@ -100,13 +100,13 @@ export default function StuffDetail() {
field: 'planNo',
headerName: getMessage('stuff.detail.planGridHeader.planNo'),
width: 100,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'center' },
},
{
field: 'orderFlg',
headerName: getMessage('stuff.detail.planGridHeader.orderFlg'),
width: 80,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'center' },
cellRenderer: (params) => {
//1
let orderFlg
@ -118,13 +118,13 @@ export default function StuffDetail() {
field: 'moduleModel',
headerName: getMessage('stuff.detail.planGridHeader.moduleModel'),
flex: 1,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ },
},
{
field: 'capacity',
headerName: getMessage('stuff.detail.planGridHeader.capacity'),
width: 120,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-end' /* 우측정렬*/ },
},
{
field: 'roofMaterialIdMulti',
@ -132,17 +132,18 @@ export default function StuffDetail() {
width: 140,
wrapText: true,
autoHeight: true,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ },
cellRenderer: (params) => {
// .. ?
let origin = params.value
if (origin !== null) {
return (
<>
{origin?.split(',').map((it) => (
<>
{origin?.split('').map((it, idx) => (
<span key={idx} className="block">
{it}
<br />
</>
</span>
))}
</>
)
@ -156,17 +157,17 @@ export default function StuffDetail() {
headerName: getMessage('stuff.detail.planGridHeader.constructSpecification'),
wrapText: true,
autoHeight: true,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ },
cellRenderer: (params) => {
let origin = params.value
if (origin !== null) {
return (
<>
{origin?.split(',').map((it) => (
<>
{origin?.split('').map((it, idx) => (
<span key={idx} className="block">
{it}
<br />
</>
</span>
))}
</>
)
@ -180,17 +181,17 @@ export default function StuffDetail() {
headerName: getMessage('stuff.detail.planGridHeader.supportMethodIdMulti'),
wrapText: true,
autoHeight: true,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ },
cellRenderer: (params) => {
let origin = params.value
if (origin !== null) {
return (
<>
{origin?.split(',').map((it) => (
<>
{origin?.split('').map((it, idx) => (
<span key={idx} className="block">
{it}
<br />
</>
</span>
))}
</>
)
@ -205,17 +206,17 @@ export default function StuffDetail() {
flex: 1,
wrapText: true,
autoHeight: true,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ },
cellRenderer: (params) => {
let origin = params.value
if (origin !== null) {
return (
<>
{origin?.split(',').map((it) => (
<>
{origin?.split('').map((it, idx) => (
<span key={idx} className="block">
{it}
<br />
</>
</span>
))}
</>
)
@ -229,7 +230,7 @@ export default function StuffDetail() {
headerName: getMessage('stuff.detail.planGridHeader.management'),
width: 200,
autoHeight: true,
cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
cellStyle: { justifyContent: 'center' },
cellRenderer: () => {
return (
<div className="grid-cell-btn">
@ -266,7 +267,7 @@ export default function StuffDetail() {
setEditMode('EDIT')
if (objectNo.substring(0, 1) === 'R') {
//
// ..
setIsFormValid(true)
}
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
@ -299,6 +300,7 @@ export default function StuffDetail() {
//1 : X167 T01
//2 : 10X22, 201X112
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
// get({ url: `/api/object/saleStore/T01/list` }).then((res) => {
if (!isEmptyArray(res)) {
const firstList = res.filter((row) => row.saleStoreLevel === '1')
const otherList = res.filter((row) => row.saleStoreLevel !== '1')
@ -355,6 +357,7 @@ export default function StuffDetail() {
//1 : X167 T01
//2 : 10X22, 201X112
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
// get({ url: `/api/object/saleStore/T01/list` }).then((res) => {
if (!isEmptyArray(res)) {
const firstList = res.filter((row) => row.saleStoreLevel === '1')
const otherList = res.filter((row) => row.saleStoreLevel !== '1')
@ -363,8 +366,10 @@ export default function StuffDetail() {
//1
setOriginOtherSaleStoreList(otherList)
setOtherSaleStoreList(otherList)
// console.log('1::', firstList)
// console.log('2::', otherList)
}
console.log('상세데이타::세팅:::::', detailData)
//No.
form.setValue('planReqNo', detailData.planReqNo)
//
@ -384,14 +389,16 @@ export default function StuffDetail() {
//
form.setValue('objectNameKana', detailData.objectNameKana)
// console.log('1::', firstList)
// console.log('2::', otherList)
setSelOptions(detailData.saleStoreId)
form.setValue('saleStoreId', detailData.saleStoreId)
form.setValue('saleStoreLevel', sessionState?.storeLvl)
console.log('상세데이타::세팅:::::', detailData)
// 2 2
// 1 1 2
//1
// setSelOptions(detailData.saleStoreId)
// form.setValue('saleStoreId', detailData.saleStoreId)
// form.setValue('saleStoreLevel', sessionState?.storeLvl)
//2
console.log('2차점까지 고른경우 확인필요')
// console.log('2 ')
// setOtherSelOptions(sessionState?.storeId)
// form.setValue('saleStoreId', firstList[0].saleStoreId)
// form.setValue('otherSaleStoreId', sessionState?.storeId)
@ -454,19 +461,60 @@ export default function StuffDetail() {
//1
const onSelectionChange = (key) => {
const planReqNo = form.watch('planReqNo')
let delFlg = false
if (planReqNo !== '') {
if (confirm('stuff.detail.confirm.message1')) {
delFlg = true
} else {
delFlg = false
if (editMode === 'NEW') {
if (planReqNo !== '') {
if (confirm(getMessage('stuff.detail.confirm.message1'))) {
delFlg = true
} else {
delFlg = false
}
}
} else {
// EDIT
if (planReqNo !== null) {
if (confirm(getMessage('stuff.detail.confirm.message1'))) {
delFlg = true
} else {
delFlg = false
}
}
}
if (planReqNo !== '') {
if (delFlg) {
form.setValue('planReqNo', '')
let tempObjectNo = 'T'
if (objectNo) {
tempObjectNo = objectNo.substring(0, 1)
}
if (tempObjectNo !== 'R') {
if (planReqNo) {
if (delFlg) {
form.setValue('planReqNo', '')
if (isObjectNotEmpty(key)) {
setOtherSaleStoreList(otherSaleStoreList)
form.setValue('saleStoreId', key.saleStoreId)
form.setValue('saleStoreName', key.saleStoreName)
form.setValue('saleStoreLevel', key.saleStoreLevel)
setSelOptions(key.saleStoreId)
// 1 2 list
// 
let newOtherSaleStoreList = originOtherSaleStoreList.filter((row) => row.firstAgentId === key.saleStoreId)
setOtherSaleStoreList(newOtherSaleStoreList)
} else {
//X
setSelOptions('')
form.setValue('saleStoreId', '')
form.setValue('saleStoreName', '')
form.setValue('saleStoreLevel', '')
form.setValue('otherSaleStoreId', '')
form.setValue('otherSaleStoreName', '')
form.setValue('otherSaleStoreLevel', '')
//1 2
setOtherSaleStoreList(originOtherSaleStoreList)
handleClear()
}
}
} else {
if (isObjectNotEmpty(key)) {
setOtherSaleStoreList(otherSaleStoreList)
form.setValue('saleStoreId', key.saleStoreId)
@ -521,19 +569,47 @@ export default function StuffDetail() {
//2
const onSelectionChange2 = (key) => {
const planReqNo = form.watch('planReqNo')
let delFlg = false
if (planReqNo !== '') {
if (confirm('stuff.detail.confirm.message1')) {
delFlg = true
} else {
delFlg = false
if (editMode === 'NEW') {
if (planReqNo !== '') {
if (confirm(getMessage('stuff.detail.confirm.message1'))) {
delFlg = true
} else {
delFlg = false
}
}
} else {
//EDIT
if (planReqNo !== null) {
if (confirm(getMessage('stuff.detail.confirm.message1'))) {
delFlg = true
} else {
delFlg = false
}
}
}
if (planReqNo !== '') {
if (delFlg) {
form.setValue('planReqNo', '')
let tempObjectNo = 'T'
if (objectNo) {
tempObjectNo = objectNo.substring(0, 1)
}
if (tempObjectNo !== 'R') {
if (planReqNo) {
if (delFlg) {
form.setValue('planReqNo', '')
if (isObjectNotEmpty(key)) {
setOtherSelOptions(key.saleStoreId)
form.setValue('otherSaleStoreId', key.saleStoreId)
form.setValue('otherSaleStoreName', key.saleStoreName)
form.setValue('otherSaleStoreLevel', key.saleStoreLevel)
} else {
setOtherSelOptions('')
form.setValue('otherSaleStoreId', '')
form.setValue('otherSaleStoreName', '')
form.setValue('otherSaleStoreLevel', '')
}
}
} else {
if (isObjectNotEmpty(key)) {
setOtherSelOptions(key.saleStoreId)
form.setValue('otherSaleStoreId', key.saleStoreId)
@ -782,9 +858,9 @@ export default function StuffDetail() {
//
const onValid = async () => {
const formData = form.getValues()
// console.log(' :::', formData)
const apiUrl = '/api/object/save-object'
const params = {
planReqNo: formData.planReqNo,
saleStoreId: formData.otherSaleStoreId ? formData.otherSaleStoreId : formData.saleStoreId,
saleStoreName: formData.otherSaleStoreName ? formData.otherSaleStoreName : formData.saleStoreName,
saleStoreLevel: formData.otherSaleStoreLevel ? formData.otherSaleStoreLevel : formData.saleStoreLevel,
@ -805,11 +881,24 @@ export default function StuffDetail() {
conType: formData.conType,
coldRegionFlg: formData.coldRegionFlg === true ? '1' : '0',
saltAreaFlg: formData.saltAreaFlg === true ? '1' : '0',
remarks: formData.remarks,
tempFlg: '0',
workNo: null,
workName: null,
}
// console.log('params::', params)
console.log('REAL저장::', params)
//, 0
let snow = params.verticalSnowCover
let height = params.installHeight
if (snow === '0') {
return alert(getMessage('stuff.detail.save.valierror1'))
}
if (height === '0') {
return alert(getMessage('stuff.detail.save.valierror2'))
}
alert('작업중')
return
if (editMode === 'NEW') {
@ -832,6 +921,7 @@ export default function StuffDetail() {
const onTempSave = async () => {
const formData = form.getValues()
const params = {
planReqNo: formData.planReqNo,
saleStoreId: formData.otherSaleStoreId ? formData.otherSaleStoreId : formData.saleStoreId,
saleStoreName: formData.otherSaleStoreName ? formData.otherSaleStoreName : formData.saleStoreName,
saleStoreLevel: formData.otherSaleStoreLevel ? formData.otherSaleStoreLevel : formData.saleStoreLevel,
@ -852,6 +942,7 @@ export default function StuffDetail() {
conType: formData.conType,
coldRegionFlg: formData.coldRegionFlg === true ? '1' : '0',
saltAreaFlg: formData.saltAreaFlg === true ? '1' : '0',
remarks: formData.remarks,
tempFlg: '1',
workNo: null,
workName: null,
@ -862,7 +953,17 @@ export default function StuffDetail() {
params.saleStoreId = sessionState.storeId
params.saleStoreLevel = sessionState.storeLvl
}
console.log('임시저장파람:::', params)
//, 0
let snow = params.verticalSnowCover
let height = params.installHeight
if (snow === '0') {
return alert(getMessage('stuff.detail.save.valierror1'))
}
if (height === '0') {
return alert(getMessage('stuff.detail.save.valierror2'))
}
alert('작업중')
return
await promisePost({ url: '/api/object/save-object', data: params }).then((res) => {
@ -1028,6 +1129,7 @@ export default function StuffDetail() {
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
isClearable={sessionState?.storeLvl === '1' ? true : false}
isDisabled={sessionState?.storeLel !== '1' ? true : false}
value={saleStoreList.filter(function (option) {
return option.saleStoreId === selOptions
})}
@ -1323,7 +1425,7 @@ export default function StuffDetail() {
<div className="flx-box">
<div className="product-input-wrap mr5">
<input type="text" className="product-input" readOnly value={form.watch('planReqNo') || ''} />
{objectNo.substring(0, 1) === 'T' && form.watch('planReqNo') !== '' ? (
{objectNo.substring(0, 1) === 'T' && form.watch('planReqNo') ? (
<button
type="button"
className="product-delete"
@ -1436,6 +1538,7 @@ export default function StuffDetail() {
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
isClearable={sessionState?.storeLvl === '1' ? true : false}
isDisabled={sessionState?.storeLel !== '1' ? true : false}
value={saleStoreList.filter(function (option) {
return option.saleStoreId === selOptions
})}
@ -1742,7 +1845,7 @@ export default function StuffDetail() {
</div>
{/* 진짜R 플랜끝 */}
<div className="sub-right-footer">
<Link href="/management/stuff">
<Link href="/management/stuff" scroll={false}>
<button type="button" className="btn-origin grey mr5">
R상세: {getMessage('stuff.detail.btn.moveList')}
</button>
@ -1767,7 +1870,7 @@ export default function StuffDetail() {
TEMP상세:{getMessage('stuff.detail.btn.save')}
</Button>
)}
<Link href="/management/stuff">
<Link href="/management/stuff" scroll={false}>
<button type="button" className="btn-origin grey">
TEMP상세:{getMessage('stuff.detail.btn.moveList')}
</button>

View File

@ -128,7 +128,6 @@ export default function StuffSearchCondition() {
useEffect(() => {
if (isObjectNotEmpty(sessionState)) {
// storeId T01 1
// get({ url: `/api/object/saleStore/TEMP02/list` }).then((res) => {
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
if (!isEmptyArray(res)) {
res.map((row) => {

View File

@ -0,0 +1,32 @@
import { use, useEffect } from 'react'
import { useRecoilValue } from 'recoil'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
import { canvasState } from '@/store/canvasAtom'
import { setSurfaceShapePattern } from '@/util/canvas-util'
export function useCanvasConfigInitialize() {
const canvas = useRecoilValue(canvasState)
const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
const canvasLoadInit = () => {
roofInit() //화면표시 초기화
}
//치수표시, 화면표시, 글꼴등 초기화
const roofInit = () => {
if (canvas) {
const roofDisplay = settingModalFirstOptions.option2.filter((item) => item.selected)
canvas
.getObjects()
.filter((polygon) => polygon.name === 'roof')
.forEach((polygon) => {
setSurfaceShapePattern(polygon, roofDisplay[0].column)
})
canvas.renderAll()
}
}
return { canvasLoadInit }
}

View File

@ -2,13 +2,18 @@ import { useEffect } from 'react'
import { useRecoilValue } from 'recoil'
import { wordDisplaySelector } from '@/store/settingAtom'
import { useEvent } from '@/hooks/useEvent'
import { checkLineOrientation, getDistance } from '@/util/canvas-util'
import { checkLineOrientation, getDistance, setSurfaceShapePattern } from '@/util/canvas-util'
import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
import { fontSelector } from '@/store/fontAtom'
import { canvasState } from '@/store/canvasAtom'
export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionState }) {
export function useCommonUtils({ commonFunctionState, setCommonFunctionState }) {
const canvas = useRecoilValue(canvasState)
const wordDisplay = useRecoilValue(wordDisplaySelector)
const { addCanvasMouseEventListener, addDocumentEventListener, initEvent } = useEvent()
const dimensionSettings = useRecoilValue(dimensionLineSettingsState)
const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText'))
const commonTextFont = useRecoilValue(fontSelector('commonText'))
useEffect(() => {
initEvent()
@ -19,7 +24,7 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
} else if (commonFunctionState.distance) {
commonDistanceMode()
}
}, [commonFunctionState, dimensionSettings])
}, [commonFunctionState, dimensionSettings, commonTextFont, dimensionLineTextFont])
const commonTextMode = () => {
let textbox
@ -30,10 +35,13 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
left: pointer.x,
top: pointer.y,
width: 200,
fontSize: 14,
editable: true,
name: 'commonText',
visible: wordDisplay,
fill: commonTextFont.fontColor.value,
fontFamily: commonTextFont.fontFamily.value,
fontSize: commonTextFont.fontSize.value,
fontStyle: commonTextFont.fontWeight.value,
})
canvas?.add(textbox)
@ -187,21 +195,19 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
canvas.add(arrow1)
canvas.add(arrow2)
console.log(dimensionSettings)
// 거리 텍스트가 이미 있으면 업데이트하고, 없으면 새로 생성
distanceText = new fabric.Text(`${distance * 10} `, {
left: (p1CenterX + p2CenterX) / 2 + (lineDirection === 'horizontal' ? 0 : -15),
top: (p1CenterY + p2CenterY) / 2 + (lineDirection === 'horizontal' ? +15 : 0),
fill: dimensionSettings.fontColor,
fontSize: dimensionSettings.fontSize,
// fontFamily : dimensionSettings.font, //폰트
// fontStyle : dimensionSettings.fontStyle, //폰트스타일
fill: dimensionLineTextFont.fontColor.value,
fontSize: dimensionLineTextFont.fontSize.value,
fontFamily: dimensionLineTextFont.fontFamily.value,
fontStyle: dimensionLineTextFont.fontWeight.value,
selectable: true,
textAlign: 'center',
originX: 'center',
originY: 'center',
angle: lineDirection === 'horizontal' ? 0 : 270,
name: 'dimensionLineText',
// lockMovementX: false,
// lockMovementY: false,
})
@ -272,50 +278,70 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
addCanvasMouseEventListener('mouse:down', function (options) {
const pointer = canvas.getPointer(options.e)
let point
let cross = {}
if (points.length === 0) {
// 첫 번째 포인트는 그대로 클릭한 위치에 추가
point = new fabric.Circle({
left: pointer.x - 5, // 반지름 반영
top: pointer.y - 5, // 반지름 반영
...circleOptions,
point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], {
stroke: 'black',
strokeWidth: 1,
originX: 'center',
originY: 'center',
})
points.push(point)
canvas.add(point)
cross['x'] = parseInt(point.left.toFixed(0))
// 세로 선 생성 (십자 모양의 다른 축)
point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], {
stroke: 'black',
strokeWidth: 1,
originX: 'center',
originY: 'center',
})
cross['y'] = parseInt(point.top.toFixed(0))
canvas.add(point)
points.push(cross)
} else if (points.length === 1) {
// 두 번째 포인트는 첫 번째 포인트를 기준으로 수평 또는 수직으로만 배치
const p1 = points[0]
point = new fabric.Circle({
left: pointer.x - 5, // 반지름 반영
top: pointer.y - 5, // 반지름 반영
...circleOptions,
point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], {
stroke: 'black',
strokeWidth: 1,
originX: 'center',
originY: 'center',
})
points.push(point)
canvas.add(point)
cross['x'] = parseInt(point.left.toFixed(0))
// 세로 선 생성 (십자 모양의 다른 축)
point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], {
stroke: 'black',
strokeWidth: 1,
originX: 'center',
originY: 'center',
})
canvas.add(point)
cross['y'] = parseInt(point.top.toFixed(0))
points.push(cross)
let isParallel = false
if (points[0].x === points[1].x || points[0].y === points[1].y) {
isParallel = true
}
// 두 포인트의 중심 좌표 계산
const p2 = points[1]
const p1CenterX = p1.left + p1.radius
const p1CenterY = p1.top + p1.radius
const p2CenterX = p2.left + p2.radius
const p2CenterY = p2.top + p2.radius
const p3 = new fabric.Point(p2CenterX, p1CenterY)
const p1CenterX = p1.x
const p1CenterY = p1.y
const p2CenterX = p2.x
const p2CenterY = p2.y
// 두 포인트 간에 직선을 그림 (중심을 기준으로)
const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], lineOptions)
const line2 = new fabric.Line([p2CenterX, p2CenterY, p3.x, p3.y], lineOptions)
const line3 = new fabric.Line([p3.x, p3.y, p1CenterX, p1CenterY], lineOptions)
canvas.add(line)
canvas.add(line2)
canvas.add(line3)
const distance1 = getDistance(p1CenterX, p1CenterY, p2CenterX, p2CenterY)
const distance2 = getDistance(p2CenterX, p2CenterY, p3.x, p3.y)
const distance3 = getDistance(p3.x, p3.y, p1CenterX, p1CenterY)
// 거리 텍스트가 이미 있으면 업데이트하고, 없으면 새로 생성
distanceText = new fabric.Text(`${distance1 * 10}`, {
@ -324,18 +350,28 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
...textOptions,
})
canvas.add(distanceText)
distanceText = new fabric.Text(`${distance2 * 10}`, {
left: (p2CenterX + p3.x) / 2,
top: (p2CenterY + p3.y) / 2,
...textOptions,
})
canvas.add(distanceText)
distanceText = new fabric.Text(`${distance3 * 10}`, {
left: (p3.x + p1CenterX) / 2,
top: (p3.y + p1CenterY) / 2,
...textOptions,
})
canvas.add(distanceText)
if (!isParallel) {
const p3 = new fabric.Point(p2CenterX, p1CenterY)
const line2 = new fabric.Line([p2CenterX, p2CenterY, p3.x, p3.y], lineOptions)
const line3 = new fabric.Line([p3.x, p3.y, p1CenterX, p1CenterY], lineOptions)
canvas.add(line2)
canvas.add(line3)
const distance2 = getDistance(p2CenterX, p2CenterY, p3.x, p3.y)
const distance3 = getDistance(p3.x, p3.y, p1CenterX, p1CenterY)
distanceText = new fabric.Text(`${distance2 * 10}`, {
left: (p2CenterX + p3.x) / 2,
top: (p2CenterY + p3.y) / 2,
...textOptions,
})
canvas.add(distanceText)
distanceText = new fabric.Text(`${distance3 * 10}`, {
left: (p3.x + p1CenterX) / 2,
top: (p3.y + p1CenterY) / 2,
...textOptions,
})
canvas.add(distanceText)
}
// 거리 계산 후, 다음 측정을 위해 초기화
points = []
@ -361,7 +397,7 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS
}
}
setCommonFunctionState(tempStates)
if (setCommonFunctionState) setCommonFunctionState(tempStates)
}
return {

View File

@ -11,9 +11,35 @@ export function useFont() {
const lengthText = useRecoilValue(fontSelector('lengthText'))
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
useEffect(() => {}, [commonText])
useEffect(() => {
if (canvas) {
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
textObjs.forEach((obj) => {
obj.set({
fontFamily: commonText.fontFamily.value,
fontWeight: commonText.fontWeight.value,
fontSize: commonText.fontSize.value,
fill: commonText.fontColor.value,
})
})
canvas.renderAll()
}
}, [commonText])
useEffect(() => {}, [dimensionLineText])
useEffect(() => {
if (canvas) {
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText')
textObjs.forEach((obj) => {
obj.set({
fontFamily: dimensionLineText.fontFamily.value,
fontWeight: dimensionLineText.fontWeight.value,
fontSize: dimensionLineText.fontSize.value,
fill: dimensionLineText.fontColor.value,
})
})
canvas.renderAll()
}
}, [dimensionLineText])
useEffect(() => {
if (canvas) {

View File

@ -290,12 +290,12 @@ export function usePlan() {
addPlan(userId, objectNo, currentCanvasData())
},
denyFn: () => {
addPlan(userId, objectNo)
addPlan(userId, objectNo, '')
},
})
: addPlan(userId, objectNo)
: addPlan(userId, objectNo, '')
}
const addPlan = (userId, objectNo, canvasStatus = '') => {
const addPlan = (userId, objectNo, canvasStatus) => {
const id = uuidv4()
const newPlan = {
id: id,

View File

@ -516,6 +516,8 @@
"stuff.detail.btn.moveList": "商品リスト",
"stuff.detail.btn.save": "保存",
"stuff.detail.btn.tempSave": "一時保存",
"stuff.detail.save.valierror1": "垂直説説は0より大きい値を入力してください",
"stuff.detail.save.valierror2": "設置高さ0より大きい値を入力してください",
"stuff.planReqPopup.popTitle": "設計依頼検索",
"stuff.planReqPopup.btn1": "検索",
"stuff.planReqPopup.btn2": "初期化",

View File

@ -521,6 +521,8 @@
"stuff.detail.btn.moveList": "물건목록",
"stuff.detail.btn.save": "저장",
"stuff.detail.btn.tempSave": "임시저장",
"stuff.detail.save.valierror1": "수직적설량은 0보다 큰 값을 입력하세요",
"stuff.detail.save.valierror2": "설치높이는 0보다 큰 값을 입력하세요",
"stuff.planReqPopup.popTitle": "설계 요청 검색",
"stuff.planReqPopup.btn1": "검색",
"stuff.planReqPopup.btn2": "초기화",