This commit is contained in:
hyojun.choi 2025-02-11 13:09:57 +09:00
commit 5d37f0feac
10 changed files with 71 additions and 56 deletions

View File

@ -72,10 +72,10 @@ export default async function RootLayout({ children }) {
</div> </div>
<Footer /> <Footer />
</div> </div>
<QModal />
<PopupManager />
</QcastProvider> </QcastProvider>
)} )}
<QModal />
<PopupManager />
</body> </body>
</html> </html>
</GlobalDataProvider> </GlobalDataProvider>

View File

@ -24,6 +24,7 @@ import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader' import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
import { usePlan } from '@/hooks/usePlan' import { usePlan } from '@/hooks/usePlan'
import { QcastContext } from '@/app/QcastProvider'
const ALLOCATION_TYPE = { const ALLOCATION_TYPE = {
AUTO: 'auto', AUTO: 'auto',
@ -56,6 +57,8 @@ export default function CircuitTrestleSetting({ id }) {
const { handleCanvasToPng } = useImgLoader() const { handleCanvasToPng } = useImgLoader()
const { saveCanvas } = usePlan() const { saveCanvas } = usePlan()
const { setIsGlobalLoading } = useContext(QcastContext)
const { const {
makers, makers,
setMakers, setMakers,
@ -324,6 +327,7 @@ export default function CircuitTrestleSetting({ id }) {
// () // ()
const onApply = async () => { const onApply = async () => {
setIsGlobalLoading(true)
canvas canvas
.getObjects() .getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)

View File

@ -97,6 +97,7 @@ export default function StuffQGrid(props) {
overlayNoRowsTemplate={`<span className="ag-overlay-loading-center">${getMessage('stuff.grid.noData')}</span>`} overlayNoRowsTemplate={`<span className="ag-overlay-loading-center">${getMessage('stuff.grid.noData')}</span>`}
getRowClass={getRowClass} getRowClass={getRowClass}
autoSizeAllColumns={true} autoSizeAllColumns={true}
enableCellTextSelection={true}
/> />
</div> </div>
) )

View File

@ -168,19 +168,19 @@ export const useEstimateController = (planNo) => {
if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) { if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert', icon: 'warning' })
} }
if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) { if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert', icon: 'warning' })
} }
if (isNaN(Date.parse(estimateData.estimateDate))) { if (isNaN(Date.parse(estimateData.estimateDate))) {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert', icon: 'warning' })
} }
if (estimateData.estimateType === 'YJSS') { if (estimateData.estimateType === 'YJSS') {
@ -188,7 +188,7 @@ export const useEstimateController = (planNo) => {
if (pkgAsp === '0') { if (pkgAsp === '0') {
flag = false flag = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert', icon: 'warning' })
} }
} }
@ -214,7 +214,7 @@ export const useEstimateController = (planNo) => {
if (estimateData?.northArrangement === '1') { if (estimateData?.northArrangement === '1') {
fileFlg = false fileFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert', icon: 'warning' })
} }
} }
@ -226,7 +226,7 @@ export const useEstimateController = (planNo) => {
if (estimateData.fileFlg === '0') { if (estimateData.fileFlg === '0') {
fileFlg = false fileFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert', icon: 'warning' })
} }
} }
} }
@ -244,7 +244,7 @@ export const useEstimateController = (planNo) => {
if (item.itemId === '') { if (item.itemId === '') {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert', icon: 'warning' })
} }
} }
@ -260,7 +260,7 @@ export const useEstimateController = (planNo) => {
if (item.amount < 1) { if (item.amount < 1) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert', icon: 'warning' })
} }
if (estimateData.estimateType !== 'YJSS') { if (estimateData.estimateType !== 'YJSS') {
@ -272,7 +272,7 @@ export const useEstimateController = (planNo) => {
if (item.salePrice < 1) { if (item.salePrice < 1) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert', icon: 'warning' })
} }
} }
@ -283,7 +283,7 @@ export const useEstimateController = (planNo) => {
if (isNaN(item.salePrice)) { if (isNaN(item.salePrice)) {
itemFlg = false itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert', icon: 'warning' })
} }
} }
} }
@ -301,7 +301,7 @@ export const useEstimateController = (planNo) => {
}) })
if (delCnt === estimateData.itemList.length) { if (delCnt === estimateData.itemList.length) {
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert' }) return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' })
} }
} }
@ -387,6 +387,7 @@ export const useEstimateController = (planNo) => {
estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '')
} }
return
//2. 상세데이터 저장 //2. 상세데이터 저장
try { try {
setIsGlobalLoading(true) setIsGlobalLoading(true)

View File

@ -4,6 +4,8 @@ import { useCanvas } from '../useCanvas'
import { useAxios } from '../useAxios' import { useAxios } from '../useAxios'
import { usePlan } from '../usePlan' import { usePlan } from '../usePlan'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { QcastContext } from '@/app/QcastProvider'
import { useContext } from 'react'
/** /**
* 이미지 로더 hook * 이미지 로더 hook
@ -13,7 +15,7 @@ export function useImgLoader() {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { currentCanvasPlan } = usePlan() const { currentCanvasPlan } = usePlan()
const { post } = useAxios() const { post } = useAxios()
const { setIsGlobalLoading } = useContext(QcastContext)
/** /**
* 이미지 저장 왼쪽 , 오른쪽 아래 좌표 * 이미지 저장 왼쪽 , 오른쪽 아래 좌표
* return [start, end] * return [start, end]
@ -39,48 +41,53 @@ export function useImgLoader() {
* @param {integer} type 1: 모듈만 있는 상태, 2: 가대까지 올린 상태 * @param {integer} type 1: 모듈만 있는 상태, 2: 가대까지 올린 상태
*/ */
const handleCanvasToPng = async (type) => { const handleCanvasToPng = async (type) => {
removeMouseLines() try {
removeMouseLines()
canvas.getObjects('image').forEach((obj) => { canvas.getObjects('image').forEach((obj) => {
if (obj.getSrc) { if (obj.getSrc) {
const img = new Image() const img = new Image()
img.crossOrigin = 'anonymous' img.crossOrigin = 'anonymous'
img.src = obj.getSrc() img.src = obj.getSrc()
obj.setElement(img) obj.setElement(img)
}
})
canvas.renderAll()
const formData = new FormData()
const dataUrl = canvas.toDataURL('image/png')
const blobBin = atob(dataUrl.split(',')[1])
const array = []
for (let i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i))
} }
}) const file = new Blob([new Uint8Array(array)], { type: 'image/png' })
formData.append('file', file, 'canvas.png')
formData.append('objectNo', currentCanvasPlan.objectNo)
formData.append('planNo', currentCanvasPlan.planNo)
formData.append('type', type)
// formData.append('coordinates', getImageCoordinates())
const positionObj = getImageCoordinates()
console.log('🚀 ~ handleCanvasToPng ~ positionObj:', positionObj)
formData.append('width', Math.round(positionObj[1].x - positionObj[0].x - 350))
formData.append('height', Math.round(positionObj[1].y - positionObj[0].y - 100))
formData.append('left', Math.round(positionObj[0].x))
formData.append('top', Math.round(positionObj[0].y))
console.log('🚀 ~ handleCanvasToPng ~ formData:', formData)
canvas.renderAll() // 이미지 크롭 요청
const result = await post({
url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`,
data: formData,
})
console.log('🚀 ~ handleCanvasToPng ~ result:', result)
const formData = new FormData() return result
const dataUrl = canvas.toDataURL('image/png') } catch (e) {
const blobBin = atob(dataUrl.split(',')[1]) setIsGlobalLoading(false)
const array = [] console.log('🚀 ~ handleCanvasToPng ~ e:', e)
for (let i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i))
} }
const file = new Blob([new Uint8Array(array)], { type: 'image/png' })
formData.append('file', file, 'canvas.png')
formData.append('objectNo', currentCanvasPlan.objectNo)
formData.append('planNo', currentCanvasPlan.planNo)
formData.append('type', type)
// formData.append('coordinates', getImageCoordinates())
const positionObj = getImageCoordinates()
console.log('🚀 ~ handleCanvasToPng ~ positionObj:', positionObj)
formData.append('width', Math.round(positionObj[1].x - positionObj[0].x - 350))
formData.append('height', Math.round(positionObj[1].y - positionObj[0].y - 100))
formData.append('left', Math.round(positionObj[0].x))
formData.append('top', Math.round(positionObj[0].y))
console.log('🚀 ~ handleCanvasToPng ~ formData:', formData)
// 이미지 크롭 요청
const result = await post({
url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`,
data: formData,
})
console.log('🚀 ~ handleCanvasToPng ~ result:', result)
return result
} }
/** /**

View File

@ -598,6 +598,7 @@ export const useTrestle = () => {
console.error(e) console.error(e)
// clear() // clear()
setViewCircuitNumberTexts(true) setViewCircuitNumberTexts(true)
setIsGlobalLoading(false)
return null return null
} }
} }

View File

@ -60,6 +60,7 @@ export function useEstimate() {
moveEstimate(planNo, objectNo) moveEstimate(planNo, objectNo)
}) })
.catch((error) => { .catch((error) => {
setIsGlobalLoading(false)
swalFire({ text: error.message, icon: 'error' }) swalFire({ text: error.message, icon: 'error' })
}) })
} }

View File

@ -425,7 +425,7 @@ export function usePlan(params = {}) {
await getCanvasByObjectNo(objectNo, planNo).then((res) => { await getCanvasByObjectNo(objectNo, planNo).then((res) => {
if (res.length > 0) { if (res.length > 0) {
setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus })) setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus }))
setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus }))) setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((resPlan) => resPlan.planNo === plan.planNo).canvasStatus })))
} }
}) })
} }

View File

@ -765,7 +765,7 @@
"stuff.search.grid.all": "全体", "stuff.search.grid.all": "全体",
"stuff.search.grid.selected": "選択", "stuff.search.grid.selected": "選択",
"stuff.search.grid.schSortTypeR": "最近の登録日", "stuff.search.grid.schSortTypeR": "最近の登録日",
"stuff.search.grid.schSortTypeU": "最近の修正日", "stuff.search.grid.schSortTypeU": "最近の更新日",
"stuff.windSelectPopup.title": "風速選択", "stuff.windSelectPopup.title": "風速選択",
"stuff.windSelectPopup.table.selected": "選択", "stuff.windSelectPopup.table.selected": "選択",
"stuff.windSelectPopup.table.windspeed": "風速", "stuff.windSelectPopup.table.windspeed": "風速",
@ -905,7 +905,7 @@
"estimate.detail.header.showPrice": "価格表示", "estimate.detail.header.showPrice": "価格表示",
"estimate.detail.header.unitPrice": "定価", "estimate.detail.header.unitPrice": "定価",
"estimate.detail.showPrice.pricingBtn": "Pricing", "estimate.detail.showPrice.pricingBtn": "Pricing",
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください。", "estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります. 製品を選択してPricingを進めてください.",
"estimate.detail.showPrice.description1": "製品価格OPEN", "estimate.detail.showPrice.description1": "製品価格OPEN",
"estimate.detail.showPrice.description2": "追加の変更品目", "estimate.detail.showPrice.description2": "追加の変更品目",
"estimate.detail.showPrice.description3": "添付必須", "estimate.detail.showPrice.description3": "添付必須",

View File

@ -765,7 +765,7 @@
"stuff.search.grid.all": "전체", "stuff.search.grid.all": "전체",
"stuff.search.grid.selected": "선택", "stuff.search.grid.selected": "선택",
"stuff.search.grid.schSortTypeR": "최근 등록일", "stuff.search.grid.schSortTypeR": "최근 등록일",
"stuff.search.grid.schSortTypeU": "최근 수정일", "stuff.search.grid.schSortTypeU": "최근 갱신일",
"stuff.windSelectPopup.title": "풍속선택", "stuff.windSelectPopup.title": "풍속선택",
"stuff.windSelectPopup.table.selected": "선택", "stuff.windSelectPopup.table.selected": "선택",
"stuff.windSelectPopup.table.windspeed": "풍속", "stuff.windSelectPopup.table.windspeed": "풍속",
@ -906,7 +906,7 @@
"estimate.detail.header.showPrice": "가격표시", "estimate.detail.header.showPrice": "가격표시",
"estimate.detail.header.unitPrice": "정가", "estimate.detail.header.unitPrice": "정가",
"estimate.detail.showPrice.pricingBtn": "Pricing", "estimate.detail.showPrice.pricingBtn": "Pricing",
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.", "estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. 제품 선택 후 Pricing을 진행해주세요.",
"estimate.detail.showPrice.description1": "제품 가격 OPEN", "estimate.detail.showPrice.description1": "제품 가격 OPEN",
"estimate.detail.showPrice.description2": "추가 변경 자재", "estimate.detail.showPrice.description2": "추가 변경 자재",
"estimate.detail.showPrice.description3": "첨부필수", "estimate.detail.showPrice.description3": "첨부필수",