diff --git a/ecosystem.config.js b/ecosystem.config.js
new file mode 100644
index 00000000..295b7871
--- /dev/null
+++ b/ecosystem.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ apps: [
+ {
+ name: 'qcast-front-production',
+ script: 'npm run start:dev',
+ instance: 2,
+ exec_mode: 'cluster',
+ },
+ ],
+}
diff --git a/package.json b/package.json
index e6aabebd..d9c1af06 100644
--- a/package.json
+++ b/package.json
@@ -5,8 +5,9 @@
"scripts": {
"dev": "next dev",
"build": "next build",
- "start": "next start -p 3000",
- "start:dev": "next start -p 3001",
+ "start:cluster1": "next start -p 5000",
+ "start:cluster2": "next start -p 5001",
+ "start:dev": "next start -p 5010",
"lint": "next lint",
"serve": "node server.js"
},
diff --git a/src/common/common.js b/src/common/common.js
index d82d43f0..abda5acd 100644
--- a/src/common/common.js
+++ b/src/common/common.js
@@ -203,6 +203,7 @@ export const SAVE_KEY = [
'fontWeight',
'dormerAttributes',
'toFixed',
+ 'isSortedPoints',
]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
diff --git a/src/components/auth/AutoLogin.jsx b/src/components/auth/AutoLogin.jsx
index d400f2c4..b3dcbb6e 100644
--- a/src/components/auth/AutoLogin.jsx
+++ b/src/components/auth/AutoLogin.jsx
@@ -2,26 +2,111 @@
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
+import { setSession, login } from '@/lib/authActions'
+import { sessionStore } from '@/store/commonAtom'
+import { useRecoilState } from 'recoil'
+import { useAxios } from '@/hooks/useAxios'
+import { globalLocaleStore } from '@/store/localeAtom'
+import { useRouter } from 'next/navigation'
+
import GlobalSpinner from '@/components/common/spinner/GlobalSpinner'
-export default function AutoLoginPage() {
- const [isLoading, setIsLoading] = useState(true)
+export default function AutoLoginPage({ autoLoginParam }) {
+ const router = useRouter()
+
+ const [isLoading, setIsLoading] = useState(autoLoginParam === 'Y' ? false : true)
+ const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore)
+
+ const { promisePost } = useAxios(globalLocaleState)
const { getMessage } = useMessage()
+ const [userId, setUserId] = useState('')
+ const [sessionState, setSessionState] = useRecoilState(sessionStore)
+
+ const [idFocus, setIdFocus] = useState(false)
+
+ const loginProcess = async () => {
+ setIsLoading(true)
+ await promisePost({ url: '/api/login/v1.0/user', data: { loginId: userId } }).then((response) => {
+ setIsLoading(false)
+ if (response.data) {
+ const res = response.data
+ const result = { ...res, storeLvl: res.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' }
+ setSession(result)
+ setSessionState(result)
+ login()
+ } else {
+ alert(getMessage('login.fail'))
+ router.push('/login?autoLoginParam1=Y')
+ }
+ })
+ }
+
return (
<>
{isLoading && }
-
COPYRIGHTยฉ2024 Hanwha Japan All Rights Reserved.
diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx
index cd8b9e2b..eec45f41 100644
--- a/src/components/common/context-menu/QContextMenu.jsx
+++ b/src/components/common/context-menu/QContextMenu.jsx
@@ -6,29 +6,19 @@ import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
import { useTempGrid } from '@/hooks/useTempGrid'
import { useContextMenu } from '@/hooks/useContextMenu'
import { useEvent } from '@/hooks/useEvent'
-import { canvasState } from '@/store/canvasAtom'
+import { canvasState, currentObjectState } from '@/store/canvasAtom'
export default function QContextMenu(props) {
const canvas = useRecoilValue(canvasState)
const { contextRef, canvasProps } = props
const [contextMenu, setContextMenu] = useRecoilState(contextMenuState)
const contextMenuList = useRecoilValue(contextMenuListState)
- const activeObject = canvasProps?.getActiveObject() //์กํฐ๋ธ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ด
+ const currentObject = useRecoilValue(currentObjectState)
const { tempGridMode, setTempGridMode } = useTempGrid()
const { handleKeyup } = useContextMenu()
const { addDocumentEventListener, removeDocumentEvent } = useEvent()
// const { addDocumentEventListener, removeDocumentEvent } = useContext(EventContext)
- let contextType = ''
-
- if (activeObject) {
- if (activeObject.initOptions && activeObject.initOptions.name) {
- //์ด๊ฑด ๋ฐ๋ ๊ฐ๋ฅ์ฑ์ด ์์
- if (activeObject.initOptions?.name?.indexOf('guide') > -1) {
- contextType = 'surface' //๋ฉดํ์
- }
- }
- }
const getYPosition = (e) => {
const contextLength = contextMenuList.reduce((acc, cur, index) => {
return acc + cur.length
@@ -36,11 +26,13 @@ export default function QContextMenu(props) {
return e?.clientY - (contextLength * 25 + contextMenuList.length * 2 * 17)
}
- useEffect(() => {
- if (!contextRef.current) return
+ const handleContextMenu = (e) => {
+ // e.preventDefault() //๊ธฐ์กด contextmenu ๋ง๊ณ
+
+ if (currentObject) {
+ const isArray = currentObject.hasOwnProperty('arrayData')
+ if (isArray && currentObject.arrayData.length === 0) return
- const handleContextMenu = (e) => {
- e.preventDefault() //๊ธฐ์กด contextmenu ๋ง๊ณ
if (tempGridMode) return
const position = {
x: window.innerWidth / 2 < e.pageX ? e.pageX - 240 : e.pageX,
@@ -48,21 +40,24 @@ export default function QContextMenu(props) {
}
setContextMenu({ visible: true, ...position, currentMousePos: canvasProps.getPointer(e) })
addDocumentEventListener('keyup', document, handleKeyup)
- canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //ํ๋ฒ ๋
ธ์ถ ํ ์ด๋ฒคํธ ์ญ์
}
+ }
- const handleClick = (e) => {
- // e.preventDefault()
+ const handleClick = (e) => {
+ // e.preventDefault()
+ setContextMenu({ ...contextMenu, visible: false })
+ }
+
+ const handleOutsideClick = (e) => {
+ // e.preventDefault()
+ if (contextMenu.visible) {
setContextMenu({ ...contextMenu, visible: false })
+ removeDocumentEvent('keyup')
}
+ }
- const handleOutsideClick = (e) => {
- // e.preventDefault()
- if (contextMenu.visible) {
- setContextMenu({ ...contextMenu, visible: false })
- removeDocumentEvent('keyup')
- }
- }
+ useEffect(() => {
+ if (!contextRef.current) return
canvasProps?.upperCanvasEl.addEventListener('contextmenu', handleContextMenu)
document.addEventListener('click', handleClick)
@@ -72,43 +67,9 @@ export default function QContextMenu(props) {
removeDocumentEvent('keyup')
document.removeEventListener('click', handleClick)
document.removeEventListener('click', handleOutsideClick)
+ canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //ํ๋ฒ ๋
ธ์ถ ํ ์ด๋ฒคํธ ์ญ์
}
- }, [contextRef, contextMenuList])
-
- const handleObjectMove = () => {
- activeObject.set({
- lockMovementX: false, // X ์ถ ์ด๋ ์ ๊ธ
- lockMovementY: false, // Y ์ถ ์ด๋ ์ ๊ธ
- })
-
- canvasProps?.on('object:modified', function (e) {
- activeObject.set({
- lockMovementX: true, // X ์ถ ์ด๋ ์ ๊ธ
- lockMovementY: true, // Y ์ถ ์ด๋ ์ ๊ธ
- })
- })
- }
-
- const handleObjectDelete = () => {
- if (confirm('์ญ์ ํ์ค๊ฑฐ?')) {
- canvasProps.remove(activeObject)
- }
- }
-
- const handleObjectCopy = () => {
- activeObject.clone((cloned) => {
- cloned.set({
- left: activeObject.left + activeObject.width + 20,
- initOptions: { ...activeObject.initOptions },
- lockMovementX: true, // X ์ถ ์ด๋ ์ ๊ธ
- lockMovementY: true, // Y ์ถ ์ด๋ ์ ๊ธ
- lockRotation: true, // ํ์ ์ ๊ธ
- lockScalingX: true, // X ์ถ ํฌ๊ธฐ ์กฐ์ ์ ๊ธ
- lockScalingY: true, // Y ์ถ ํฌ๊ธฐ ์กฐ์ ์ ๊ธ
- })
- canvasProps?.add(cloned)
- })
- }
+ }, [contextRef, contextMenuList, currentObject])
return (
<>
diff --git a/src/components/common/select/QSelectBox.jsx b/src/components/common/select/QSelectBox.jsx
index f1041da3..a027cb55 100644
--- a/src/components/common/select/QSelectBox.jsx
+++ b/src/components/common/select/QSelectBox.jsx
@@ -87,7 +87,7 @@ export default function QSelectBox({
{options?.length > 0 &&
options?.map((option, index) => (
- - handleClickSelectOption(option)}>
+
- handleClickSelectOption(option)}>
))}
diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx
index a44af878..a544ced7 100644
--- a/src/components/estimate/Estimate.jsx
+++ b/src/components/estimate/Estimate.jsx
@@ -13,7 +13,7 @@ import dayjs from 'dayjs'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
import { SessionContext } from '@/app/SessionProvider'
-import Select from 'react-select'
+import Select, {components} from 'react-select'
import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid'
@@ -175,7 +175,10 @@ export default function Estimate({}) {
row.check = false
estimateOption.map((row2) => {
if (row.pkgYn === '0') {
- if (row2 === row.code) {
+ // if (row2 === row.code) {
+ // row.check = true
+ // }
+ if (row.code.split('ใ').includes(row2)) {
row.check = true
}
} else {
@@ -217,7 +220,10 @@ export default function Estimate({}) {
row.check = false
estimateOption.map((row2) => {
if (row.pkgYn === '0') {
- if (row2 === row.code) {
+ // if (row2 === row.code) {
+ // row.check = true
+ // }
+ if (row.code.split('ใ').includes(row2)) {
row.check = true
}
} else {
@@ -240,7 +246,6 @@ export default function Estimate({}) {
}
}
})
-
setSpecialNoteList(res)
setSpecialNoteFirstFlg(true)
@@ -377,8 +382,8 @@ export default function Estimate({}) {
useEffect(() => {
if (estimateContextState.estimateType !== '') {
const param = {
- saleStoreId: session.storeId,
- sapSalesStoreCd: session.custCd,
+ saleStoreId: estimateContextState.sapSaleStoreId,
+ sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
docTpCd: estimateContextState?.estimateType,
}
@@ -387,6 +392,8 @@ export default function Estimate({}) {
if (isNotEmptyArray(res?.data)) {
setStorePriceList(res.data)
}
+
+ setItemChangeYn(true)
})
if (estimateContextState.estimateType === 'YJSS') {
@@ -416,8 +423,6 @@ export default function Estimate({}) {
handlePricing('UNIT_PRICE')
}
}
-
- setItemChangeYn(true)
}
}, [estimateContextState?.estimateType])
@@ -469,6 +474,21 @@ export default function Estimate({}) {
} else {
item.check = false
}
+ } else {
+ let codes = item.code.split('ใ')
+ let flg = '0'
+ if (codes.length > 1) {
+ for (let i = 0; i < pushData.length; i++) {
+ if (codes.indexOf(pushData[i]) > -1) {
+ flg = '1'
+ }
+ }
+ if (flg === '1') {
+ item.check = true
+ } else {
+ item.check = false
+ }
+ }
}
})
@@ -481,8 +501,8 @@ export default function Estimate({}) {
//Pricing ๋ฒํผ
const handlePricing = async (showPriceCd) => {
const param = {
- saleStoreId: session.storeId,
- sapSalesStoreCd: session.custCd,
+ saleStoreId: estimateContextState.sapSaleStoreId,
+ sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
docTpCd: estimateContextState.estimateType,
priceCd: showPriceCd,
itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null),
@@ -506,7 +526,6 @@ export default function Estimate({}) {
})
}
}
-
setIsGlobalLoading(true)
await promisePost({ url: '/api/estimate/price/item-price-list', data: param }).then((res) => {
let updateList = []
@@ -1342,7 +1361,12 @@ export default function Estimate({}) {
-
+ {/*pkgRank is null, empty ์ธ ๊ฒฝ์ฐ : ์ฌ์ฉ๋ถ๊ฐ, ์ด์ ์ ๋ฑ๋ก๋ ๊ฒฝ์ฐ ์ฌ์ฉ๊ฐ๋ฅ, style๋ก ์ ์ด*/}
+ 0
+ && storePriceList[0].pkgRank !== null
+ && storePriceList[0].pkgRank !== ''
+ || estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}>
x.itemName}
+ getOptionLabel={(x) => x.itemName + " (" + x.itemNo + ")"}
getOptionValue={(x) => x.itemNo}
+ components={{
+ SingleValue:({children, ...props}) =>{
+ return (
+
+ {props.data.itemName}
+
+ )
+ }
+ }}
isClearable={false}
isDisabled={!!item?.paDispOrder}
value={displayItemList.filter(function (option) {
@@ -1880,8 +1913,17 @@ export default function Estimate({}) {
placeholder="Select"
options={cableItemList}
menuPlacement={'auto'}
- getOptionLabel={(x) => x.clRefChr3}
+ getOptionLabel={(x) => x.clRefChr3 + " (" + x.clRefChr1 + ")"}
getOptionValue={(x) => x.clRefChr1}
+ components={{
+ SingleValue:({children, ...props}) =>{
+ return (
+
+ {props.data.clRefChr3}
+
+ )
+ }
+ }}
isClearable={false}
isDisabled={true}
value={cableItemList.filter(function (option) {
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 85bb03dd..a471b5be 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -45,8 +45,11 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
options.sort = options.sort ?? true
options.parentId = options.parentId ?? null
+ this.isSortedPoints = false
+
if (!options.sort && points.length <= 8) {
points = sortedPointLessEightPoint(points)
+ this.isSortedPoints = true
} else {
let isDiagonal = false
points.forEach((point, i) => {
@@ -62,6 +65,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
if (!isDiagonal) {
points = sortedPoints(points)
+ this.isSortedPoints = true
}
}
@@ -119,10 +123,12 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.addLengthText()
this.on('moving', () => {
+ this.initLines()
this.addLengthText()
})
this.on('modified', (e) => {
+ this.initLines()
this.addLengthText()
})
@@ -136,8 +142,20 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.on('removed', () => {
// const children = getAllRelatedObjects(this.id, this.canvas)
const children = this.canvas.getObjects().filter((obj) => obj.parentId === this.id)
+
children.forEach((child) => {
this.canvas.remove(child)
+
+ //๊ทธ๋ฃน์ผ๋
+ if (child.hasOwnProperty('_objects')) {
+ child._objects.forEach((obj) => {
+ if (obj.hasOwnProperty('texts')) {
+ obj.texts.forEach((text) => {
+ this.canvas?.remove(text)
+ })
+ }
+ })
+ }
})
})
@@ -171,8 +189,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.lines = []
- this.points.forEach((point, i) => {
- const nextPoint = this.points[(i + 1) % this.points.length]
+ this.getCurrentPoints().forEach((point, i) => {
+ const nextPoint = this.getCurrentPoints()[(i + 1) % this.points.length]
const line = new QLine([point.x, point.y, nextPoint.x, nextPoint.y], {
stroke: this.stroke,
strokeWidth: this.strokeWidth,
diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
index ddce32a6..c98f686b 100644
--- a/src/components/floor-plan/CanvasFrame.jsx
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -30,11 +30,14 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import { useEvent } from '@/hooks/useEvent'
import { compasDegAtom } from '@/store/orientationAtom'
+import { hotkeyStore } from '@/store/hotkeyAtom'
+import { usePopup } from '@/hooks/usePopup'
export default function CanvasFrame() {
const canvasRef = useRef(null)
const { canvas } = useCanvas('canvas')
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
+ const { closeAll } = usePopup()
const currentMenu = useRecoilValue(currentMenuState)
const { floorPlanState } = useContext(FloorPlanContext)
const { contextMenu, handleClick } = useContextMenu()
@@ -92,6 +95,8 @@ export default function CanvasFrame() {
useEffect(() => {
setIsGlobalLoading(false)
+ // ํน์ ๋ชจ๋ฅผ ํ์
์ด ๋ ์๋ ๊ฒฝ์ฐ ๋ซ๊ณ ์์ํ๋ค.
+ closeAll()
return () => {
canvas?.clear()
@@ -110,6 +115,38 @@ export default function CanvasFrame() {
resetPcsCheckState()
}
+ /**
+ * ์บ๋ฒ์ค๊ฐ ์์ ๊ฒฝ์ฐ ํซํค ์ด๋ฒคํธ ์ฒ๋ฆฌ
+ * hotkeyStore์ ํซํค ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ถ๊ฐ
+ *
+ * const hotkeys = [
+ { key: 'c', fn: () => asdf() },
+ { key: 'v', fn: () => qwer() },
+ ]
+ setHotkeyStore(hotkeys)
+ */
+ const hotkeyState = useRecoilValue(hotkeyStore)
+ const hotkeyHandlerRef = useRef(null)
+
+ useEffect(() => {
+ hotkeyHandlerRef.current = (e) => {
+ hotkeyState.forEach((hotkey) => {
+ if (e.key === hotkey.key) {
+ hotkey.fn()
+ }
+ })
+ }
+
+ document.addEventListener('keyup', hotkeyHandlerRef.current)
+
+ return () => {
+ if (hotkeyHandlerRef.current) {
+ document.removeEventListener('keyup', hotkeyHandlerRef.current)
+ }
+ }
+ }, [hotkeyState])
+ /** ํซํค ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ */
+
return (
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
index 0d9ddc0a..a268604e 100644
--- a/src/components/floor-plan/CanvasMenu.jsx
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -634,7 +634,7 @@ export default function CanvasMenu(props) {
onClick={() => setEstimatePopupOpen(true)}
>
- {getMessage('plan.menu.estimate.docDown')}
+ {getMessage('plan.menu.estimate.docDownload')}
|