Compare commits

..

No commits in common. "a708f28c36a4d6dfc5023feed772a184e4518f0f" and "66827d4c87cf94a0fcb9bcc1ce4f1c41fce4c210" have entirely different histories.

50 changed files with 127 additions and 617 deletions

View File

@ -1,10 +1,8 @@
NEXT_PUBLIC_RUN_MODE="development"
NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
NEXT_PUBLIC_API_HOST_URL="https://dev.hanasys.jp"
NEXT_PUBLIC_API_HOST_URL="http://1.248.227.176:5000"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
@ -27,6 +25,4 @@ AWS_REGION="ap-northeast-1"
AMPLIFY_BUCKET="files.hanasys.jp"
AWS_ACCESS_KEY_ID="AKIA3K4QWLZHFZRJOM2E"
AWS_SECRET_ACCESS_KEY="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"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
S3_PROFILE="dev"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"

View File

@ -1,32 +0,0 @@
NEXT_PUBLIC_RUN_MODE="local.dev"
NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
NEXT_PUBLIC_API_HOST_URL="http://1.248.227.176:5000"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
# 테스트용
# AWS_REGION="ap-northeast-2"
# AMPLIFY_BUCKET="interplug"
# AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
# AWS_SECRET_ACCESS_KEY="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"
# NEXT_PUBLIC_AWS_S3_BASE_URL="https://interplug.s3.ap-northeast-2.amazonaws.com"
# 실제 일본 서버
AWS_REGION="ap-northeast-1"
AMPLIFY_BUCKET="files.hanasys.jp"
AWS_ACCESS_KEY_ID="AKIA3K4QWLZHFZRJOM2E"
AWS_SECRET_ACCESS_KEY="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"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
S3_PROFILE="dev"

View File

@ -1,32 +0,0 @@
NEXT_PUBLIC_RUN_MODE="local"
NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
NEXT_PUBLIC_API_HOST_URL="http://localhost:3000"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
# NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_a0FLEK6M2oTpXInK"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
# 테스트용
# AWS_REGION="ap-northeast-2"
# AMPLIFY_BUCKET="interplug"
# AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
# AWS_SECRET_ACCESS_KEY="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"
# NEXT_PUBLIC_AWS_S3_BASE_URL="https://interplug.s3.ap-northeast-2.amazonaws.com"
# 실제 일본 서버
AWS_REGION="ap-northeast-1"
AMPLIFY_BUCKET="files.hanasys.jp"
AWS_ACCESS_KEY_ID="AKIA3K4QWLZHFZRJOM2E"
AWS_SECRET_ACCESS_KEY="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"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
S3_PROFILE="dev"

View File

@ -1,5 +1,3 @@
NEXT_PUBLIC_RUN_MODE="production"
NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
@ -17,17 +15,8 @@ NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secr
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
# AWS_REGION="ap-northeast-2"
# AMPLIFY_BUCKET="interplug"
# AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
# AWS_SECRET_ACCESS_KEY="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"
# NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
# 실제 일본 서버
AWS_REGION="ap-northeast-1"
AMPLIFY_BUCKET="files.hanasys.jp"
AWS_ACCESS_KEY_ID="AKIA3K4QWLZHFZRJOM2E"
AWS_SECRET_ACCESS_KEY="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"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
S3_PROFILE="prd"
AWS_REGION="ap-northeast-2"
AMPLIFY_BUCKET="interplug"
AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
AWS_SECRET_ACCESS_KEY="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"
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"

View File

@ -6,7 +6,7 @@ module.exports = {
instances: 1,
exec_mode: 'fork',
env: {
PORT: 5010,
NODE_ENV: 'development',
},
},
],

View File

@ -1,13 +0,0 @@
module.exports = {
apps: [
{
name: 'qcast-front-local-development',
script: 'node_modules/next/dist/bin/next',
instances: 1,
exec_mode: 'fork',
env: {
PORT: 5000,
},
},
],
}

View File

@ -3,14 +3,11 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "env-cmd -f .env.localhost next dev",
"local:dev": "env-cmd -f .env.local.dev next dev",
"build": "env-cmd -f .env.production next build",
"build:dev": "env-cmd -f .env.development next build",
"build:local.dev": "env-cmd -f .env.local.dev next build",
"start:cluster1": "env-cmd -f .env.production next start -p 5000",
"start:cluster2": "env-cmd -f .env.production next start -p 5001",
"start:dev": "env-cmd -f .env.development next start -p 5010",
"dev": "next dev",
"build": "next build",
"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"
},
@ -21,12 +18,10 @@
"big.js": "^6.2.2",
"chart.js": "^4.4.6",
"dayjs": "^1.11.13",
"env-cmd": "^10.1.0",
"fabric": "^5.3.0",
"framer-motion": "^11.2.13",
"fs": "^0.0.1-security",
"iron-session": "^8.0.2",
"jimp": "^1.6.0",
"js-cookie": "^3.0.5",
"mathjs": "^13.0.2",
"mssql": "^11.0.1",

View File

@ -1,13 +0,0 @@
module.exports = {
apps: [
{
name: 'qcast-front-production-1',
script: 'node_modules/next/dist/bin/next',
instances: 1,
exec_mode: 'fork',
env: {
PORT: 5000,
},
},
],
}

View File

@ -1,13 +0,0 @@
module.exports = {
apps: [
{
name: 'qcast-front-production-2',
script: 'node_modules/next/dist/bin/next',
instances: 1,
exec_mode: 'fork',
env: {
PORT: 5001,
},
},
],
}

View File

@ -11,10 +11,9 @@ const s3 = new S3Client({
})
const uploadImage = async (file) => {
console.log('🚀 ~ uploadImage ~ file:', file)
const Body = Buffer.from(await file.arrayBuffer())
const Key = `cads/${file.name}`
const ContentType = 'image/png'
const ContentType = file.ContentType
await s3.send(
new PutObjectCommand({

View File

@ -1,8 +1,7 @@
import { NextResponse } from 'next/server'
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'
import sharp from 'sharp'
import { v4 as uuidv4 } from 'uuid'
import { Jimp } from 'jimp'
const Bucket = process.env.AMPLIFY_BUCKET
const s3 = new S3Client({
region: process.env.AWS_REGION,
@ -24,6 +23,8 @@ const checkArea = (obj) => {
const cropImage = async (Key, width, height, left, top) => {
try {
const checkResult = checkArea({ width, height, left, top })
// Get the image from S3
const { Body } = await s3.send(
new GetObjectCommand({
@ -32,45 +33,28 @@ const cropImage = async (Key, width, height, left, top) => {
}),
)
// Convert stream to buffer
const chunks = []
for await (const chunk of Body) {
chunks.push(chunk)
}
const buffer = Buffer.concat(chunks)
const imageBuffer = Buffer.concat(chunks)
const image = await Jimp.read(buffer)
image.autocrop({ tolerance: 0.0002, leaveBorder: 10 })
return await image.getBuffer('image/png')
// Convert stream to buffer
// const chunks = []
// for await (const chunk of Body) {
// chunks.push(chunk)
// }
// const imageBuffer = Buffer.concat(chunks)
// const image = await Jimp.read(Body)
// if (!checkResult) {
// processedImage = await image.toBuffer()
// }
//let processedImage
// if (!checkResult) {
// processedImage = await sharp(imageBuffer).toBuffer()
// } else {
// processedImage = await sharp(imageBuffer)
// .extract({
// width: parseInt(width),
// height: parseInt(height),
// left: parseInt(left),
// top: parseInt(top),
// })
// .png()
// .toBuffer()
// }
// return processedImage
let processedImage
if (!checkResult) {
processedImage = await sharp(imageBuffer).toBuffer()
} else {
processedImage = await sharp(imageBuffer)
.extract({
width: parseInt(width),
height: parseInt(height),
left: parseInt(left),
top: parseInt(top),
})
.png()
.toBuffer()
}
return processedImage
} catch (error) {
console.error('Error processing image:', error)
throw error
@ -112,7 +96,7 @@ export async function POST(req) {
/**
* 크롭 이미지 이름을 결정한다.
*/
const Key = `Drawing/${process.env.S3_PROFILE}/${objectNo}_${planNo}_${type}.png`
const Key = `Drawing/${objectNo}_${planNo}_${type}.png`
/**
* 크롭이 완료된 이미지를 업로드한다.

View File

@ -1,59 +0,0 @@
import { NextResponse } from 'next/server'
import { S3Client, CopyObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'
import sharp from 'sharp'
import { v4 as uuidv4 } from 'uuid'
const Bucket = process.env.AMPLIFY_BUCKET
const s3 = new S3Client({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
})
export async function POST(req) {
const { objectNo, planNo, newObjectNo, newPlanNo } = await req.json()
const responseArray = []
//견적서1 번 이미지
const isExistImage1 = await s3.send(
new GetObjectCommand({
Bucket,
Key: `Drawing/${process.env.S3_PROFILE}/${objectNo}_${planNo}_1.png`,
}),
)
//견적서2 번 이미지
const isExistImage2 = await s3.send(
new GetObjectCommand({
Bucket,
Key: `Drawing/${process.env.S3_PROFILE}/${objectNo}_${planNo}_2.png`,
}),
)
//견적서1,2 번 이미지 둘다 있어야함
if (isExistImage1.$metadata.httpStatusCode === 200 && isExistImage2.$metadata.httpStatusCode === 200) {
//견적서1 번 이미지 복사
const copyCommand = new CopyObjectCommand({
Bucket,
CopySource: encodeURI(`${Bucket}/Drawing/${process.env.S3_PROFILE}/${objectNo}_${planNo}_1.png`),
Key: `Drawing/${process.env.S3_PROFILE}/${newObjectNo}_${newPlanNo}_1.png`,
})
const response = await s3.send(copyCommand)
const copyCommand2 = new CopyObjectCommand({
Bucket,
CopySource: encodeURI(`${Bucket}/Drawing/${process.env.S3_PROFILE}/${objectNo}_${planNo}_2.png`),
Key: `Drawing/${process.env.S3_PROFILE}/${newObjectNo}_${newPlanNo}_2.png`,
})
const response2 = await s3.send(copyCommand2)
responseArray.push(response, response2)
return NextResponse.json({ message: '견적서 이미지 복사 성공', responseArray }, { status: 200 })
} else {
return NextResponse.json({ message: '견적서 이미지 복사 실패(존재하지 않는 이미지)', responseArray }, { status: 400 })
}
}

View File

@ -45,19 +45,8 @@ const FloorPlanProvider = ({ children }) => {
// const pathname = usePathname()
// const setCorrentObjectNo = useSetRecoilState(correntObjectNoState)
const searchParams = useSearchParams()
const path = usePathname()
const objectNo = searchParams.get('objectNo')
const pid = searchParams.get('pid')
useEffect(() => {
setFloorPlanState((prev) => {
return {
...prev,
objectNo,
pid,
}
})
}, [path])
// useEffect(() => {
// console.log('🚀 ~ useEffect ~ objectNo:')
// if (pathname === '/floor-plan') {

View File

@ -14,7 +14,6 @@ import { sessionStore } from '@/store/commonAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import BoardDetailModal from './community/modal/BoardDetailModal'
import Config from '@/config/config.export'
export default function MainPage() {
const [sessionState, setSessionState] = useRecoilState(sessionStore)

View File

@ -13,7 +13,6 @@ import { QcastContext } from '@/app/QcastProvider'
import { useAxios } from '@/hooks/useAxios'
import { globalLocaleStore } from '@/store/localeAtom'
import { e } from 'mathjs'
import { set } from 'react-hook-form'
export default function QnaRegModal({ setOpen, setReload, searchValue, selectPageBlock }) {
@ -25,7 +24,6 @@ export default function QnaRegModal({ setOpen, setReload, searchValue, selectPag
const [qnaData, setQnaData] = useState([])
const [closeMdFlg, setCloseMdFlg] = useState(true)
const [closeSmFlg, setCloseSmFlg] = useState(true)
const [hideSmFlg, setHideSmFlg] = useState(false)
const qnaTypeLgCodeRef = useRef(null)
const qnaTypeMdCodeRef = useRef(null)
const qnaTypeSmCodeRef = useRef(null)
@ -73,7 +71,7 @@ let fileCheck = false;
regUserTelNoRef.current.value = ''
qnaTypeLgCodeRef.current.setValue();
qnaTypeMdCodeRef.current.setValue();
qnaTypeSmCodeRef.current?.setValue();
qnaTypeSmCodeRef.current.setValue();
titleRef.current.value = ''
contentsRef.current.value = ''
@ -114,7 +112,7 @@ let fileCheck = false;
setQnaData({ ...qnaData, qnaClsLrgCd:e.clCode})
setCloseMdFlg(false)
qnaTypeMdCodeRef.current.setValue();
qnaTypeSmCodeRef.current?.setValue();
qnaTypeSmCodeRef.current.setValue();
}
}
@ -133,20 +131,10 @@ let fileCheck = false;
}
})
setQnaTypeSmCodeList(codeList)
setQnaData({ ...qnaData, qnaClsMidCd: e.clCode })
setCloseSmFlg(false)
setQnaTypeSmCodeList(codeList)
qnaTypeSmCodeRef.current?.setValue();
if(codeList.length > 0) {
setHideSmFlg(false)
}else{
setHideSmFlg(true)
}
qnaTypeSmCodeRef.current.setValue();
}
@ -405,7 +393,6 @@ let fileCheck = false;
/>
</div>
<div className="select-wrap" >
{!hideSmFlg && (
<Select name="" ref={qnaTypeSmCodeRef}
options={qnaTypeSmCodeList}
placeholder="Select"
@ -414,8 +401,8 @@ let fileCheck = false;
getOptionValue={(x) => x.clCode}
isClearable={false}
isSearchable={false}
isDisabled={closeSmFlg}
/>)}
isDisabled={closeSmFlg}
/>
</div>
</div>
<div className="input-wrap mt5">

View File

@ -154,7 +154,7 @@ export default function Estimate({}) {
useEffect(() => {
// console.log('🚀 ~ Estimate ~ selectedPlan:', selectedPlan)
if (selectedPlan) initEstimate(selectedPlan?.planNo?? currentPid)
if (selectedPlan) initEstimate(selectedPlan.planNo)
}, [selectedPlan])
useEffect(() => {
@ -1281,7 +1281,7 @@ export default function Estimate({}) {
<div className="estimate-box">
<div className="estimate-tit">{getMessage('estimate.detail.objectNo')}</div>
<div className="estimate-name">
{currentObjectNo} (Plan No: {currentPid})
{currentObjectNo} (Plan No: {planNo})
</div>
</div>
<div className="estimate-box">

View File

@ -4,7 +4,7 @@ import { useContext, useEffect, useState } from 'react'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { v4 as uuidv4 } from 'uuid'
@ -98,7 +98,7 @@ export default function CanvasMenu(props) {
const [lockButtonStyle, setLockButtonStyle] = useState('') //
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //
const resetCommonUtils = useResetRecoilState(commonUtilsState)
//
const { objectNo, pid } = floorPlanState
@ -166,7 +166,6 @@ export default function CanvasMenu(props) {
}
const onClickNav = async (menu) => {
resetCommonUtils()
switch (menu.type) {
case 'drawing':
swalFire({
@ -242,7 +241,7 @@ export default function CanvasMenu(props) {
return
}
setIsGlobalLoading(true)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan?.planNo ?? pid}/detail` }).then((res) => {
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
if (estimateDetail.estimateDate !== null) {
@ -250,7 +249,7 @@ export default function CanvasMenu(props) {
setCurrentMenu(menu.title)
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
setIsGlobalLoading(false)
router.push(`/floor-plan/estimate/5?pid=${selectedPlan?.planNo ?? pid}&objectNo=${objectNo}`)
router.push(`/floor-plan/estimate/5?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
if (pathname === '/floor-plan/estimate/5') {
setIsGlobalLoading(false)
}
@ -263,13 +262,13 @@ export default function CanvasMenu(props) {
break
case 'simulation':
setIsGlobalLoading(true)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan?.planNo ?? pid}/detail` }).then((res) => {
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
if (estimateDetail.estimateDate !== null && estimateDetail.docNo) {
setSelectedMenu(menu.type)
setCurrentMenu(menu.title)
router.push(`/floor-plan/simulator/6?pid=${selectedPlan?.planNo ?? pid}&objectNo=${objectNo}`)
router.push(`/floor-plan/simulator/6?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
if (pathname === '/floor-plan/simulator/6') {
setIsGlobalLoading(false)
}

View File

@ -5,10 +5,9 @@ import { useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage'
import useMenu from '@/hooks/common/useMenu'
import { canvasState, currentMenuState } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { useRecoilState, useRecoilValue } from 'recoil'
import { subMenusState } from '@/store/menuAtom'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import { commonUtilsState } from '@/store/commonUtilsAtom'
export default function MenuDepth01() {
const canvas = useRecoilValue(canvasState)
@ -17,10 +16,8 @@ export default function MenuDepth01() {
const { selectedMenu, setSelectedMenu } = useCanvasMenu()
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
const subMenus = useRecoilValue(subMenusState)
const resetCommonUtils = useResetRecoilState(commonUtilsState)
const onClickMenu = ({ id, menu }) => {
resetCommonUtils()
if (menu === currentMenu) {
handleMenu(selectedMenu)
} else {

View File

@ -351,7 +351,7 @@ const Placement = forwardRef((props, refs) => {
</div>
)}
{guideType === 'module' && (
<div className={`module-table-box mt10 ${!useTab ? 'hide' : ''}`}>
<div className={`module-table-box mt10 ${useTab ? 'hide' : ''}`}>
<div className="module-table-inner">
<div className="roof-module-table">
<table className="">

View File

@ -217,7 +217,7 @@ const Trestle = forwardRef((props, ref) => {
stdWindSpeed: managementState?.standardWindSpeedId ?? '',
stdSnowLd: managementState?.verticalSnowCover ?? '',
inclCd: selectedRoof?.pitch ?? 0,
roofPitch: Math.round(hajebichi ?? 0),
roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0),
},
})
}
@ -236,9 +236,9 @@ const Trestle = forwardRef((props, ref) => {
illuminationTp: managementState?.surfaceTypeValue ?? '',
instHt: managementState?.installHeight ?? '',
stdWindSpeed: managementState?.standardWindSpeedId ?? '',
stdSnowLd: managementState?.verticalSnowCover ?? '',
stdSnowLd: +managementState?.verticalSnowCover ?? '',
inclCd: selectedRoof?.pitch ?? 0,
roofPitch: Math.round(hajebichi ?? 0),
roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0),
constTp: constructionList[index].constTp,
snowGdPossYn: constructionList[index].snowGdPossYn,
cvrYn: constructionList[index].cvrYn,
@ -304,7 +304,6 @@ const Trestle = forwardRef((props, ref) => {
kerabaMargin,
roofIndex: roof.index,
raft: selectedRaftBase?.clCode,
hajebichi: hajebichi,
trestle: {
length: lengthBase,
hajebichi: hajebichi,

View File

@ -13,7 +13,7 @@ import { useRecoilState } from 'recoil'
import { makersState, modelsState, modelState, pcsCheckState, selectedMakerState, selectedModelsState, seriesState } from '@/store/circuitTrestleAtom'
import { POLYGON_TYPE } from '@/common/common'
import { useSwal } from '@/hooks/useSwal'
import { canvasState, canvasZoomState } from '@/store/canvasAtom'
import { canvasState } from '@/store/canvasAtom'
import { useTrestle } from '@/hooks/module/useTrestle'
import { selectedModuleState } from '@/store/selectedModuleOptions'
@ -25,8 +25,6 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
import { usePlan } from '@/hooks/usePlan'
import { QcastContext } from '@/app/QcastProvider'
import { fabric } from 'fabric'
import { fontSelector } from '@/store/fontAtom'
const ALLOCATION_TYPE = {
AUTO: 'auto',
@ -39,16 +37,13 @@ export default function CircuitTrestleSetting({ id }) {
const { swalFire } = useSwal()
const { saveEstimate } = useEstimate()
const canvas = useRecoilValue(canvasState)
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
const [tabNum, setTabNum] = useState(1)
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
const [circuitAllocationType, setCircuitAllocationType] = useState(1)
const { managementState, setManagementState } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState)
const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList, getPcsManualConfChk } = useMasterController()
const flowText = useRecoilValue(fontSelector('flowText'))
const lengthText = useRecoilValue(fontSelector('lengthText'))
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
// ()
const [selectedStepUpValues, setSelectedStepUpValues] = useState({})
@ -107,29 +102,6 @@ export default function CircuitTrestleSetting({ id }) {
}
}, [])
//
const beforeCapture = () => {
// setCanvasZoom(100)
const x = canvas.width / 2
const y = canvas.height / 2
canvas.zoomToPoint(new fabric.Point(x, y), 0.5)
changeFontSize('lengthText', '28')
changeFontSize('circuitNumber', '28')
changeFontSize('flowText', '28')
canvas.renderAll()
}
//
const afterCapture = () => {
setCanvasZoom(100)
canvas.set({ zoom: 1 })
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
changeFontSize('lengthText', lengthText.fontSize.value)
changeFontSize('circuitNumber', circuitNumberText.fontSize.value)
changeFontSize('flowText', flowText.fontSize.value)
canvas.renderAll()
}
//
// PCS
@ -371,7 +343,6 @@ export default function CircuitTrestleSetting({ id }) {
// ()
const onApply = async () => {
beforeCapture()
setAllModuleSurfaceIsComplete(false)
setIsGlobalLoading(true)
@ -382,9 +353,12 @@ export default function CircuitTrestleSetting({ id }) {
obj.pcses = getStepUpListData()
})
setViewCircuitNumberTexts(false)
handleCanvasToPng(1)
// result=null
setViewCircuitNumberTexts(true)
//
//
@ -400,7 +374,6 @@ export default function CircuitTrestleSetting({ id }) {
if (result) {
handleCanvasToPng(2)
afterCapture()
//
await saveEstimate(result)
} else {
@ -410,16 +383,6 @@ export default function CircuitTrestleSetting({ id }) {
// removeNotAllocationModules()
}
const changeFontSize = (name, size) => {
const textObjs = canvas?.getObjects().filter((obj) => obj.name === name)
textObjs.forEach((obj) => {
obj.set({
fontSize: size,
})
})
canvas.renderAll()
}
//
const onClickPrev = () => {
// setAllocationType(ALLOCATION_TYPE.AUTO)

View File

@ -227,7 +227,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
console.log('save Info', {
...basicSetting,
selectedRoofMaterial: {
...newAddedRoofs[0],
roofInfo,
},
})
@ -240,7 +240,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
* 선택된 지붕재 정보
*/
selectedRoofMaterial: {
...newAddedRoofs[0],
roofInfo,
},
})

View File

@ -114,7 +114,7 @@ export default function Simulator() {
setHatsudenryouPeakcutAllSnow([])
if (objectNo && pid && selectedPlan) {
fetchObjectDetail(objectNo, selectedPlan?.planNo??pid)
fetchObjectDetail(objectNo, selectedPlan.planNo)
fetchSimulatorNotice()
setPwrGnrSimType('D')
setPwrRecoil({ ...pwrRecoil, type: 'D' })

View File

@ -1,11 +0,0 @@
// local, development, production 과 관계없이 동일한 값으로 반환되는 부분은 해당 함수의 return 되는 부분만 수정하면 됩니다. (달라져야 하는 값이 아닌, 같은 값에 대해서는 local, development, production 파일을 모두 수정할 필요가 없어지게 됩니다.)
export default function getConfigs(params) {
// local, development, production 마다 달라지는 값
const { baseUrl, mode } = params
// 공통으로 반환되는 구조
return {
baseUrl,
mode,
}
}

View File

@ -1,13 +0,0 @@
import getConfigs from './config.common'
// 환경마다 달라져야 할 변수, 값들을 정의합니다. (여기는 development 환경에 맞는 값을 지정합니다.)
const baseUrl = 'https://dev.hanssys.jp'
const mode = 'development'
// 환경마다 달라져야 할 값들을 getConfig 함수에 전달합니다.
const configDevelopment = getConfigs({
baseUrl,
mode,
})
export default configDevelopment

View File

@ -1,23 +0,0 @@
import configDevelopment from './config.development'
import configLocal from './config.local'
import configLocalDev from './config.local.dev'
import configProduction from './config.production'
// 클라이언트에서는 이 함수를 사용하여 config 값을 참조합니다.
const Config = () => {
console.log('🚀 ~ Config ~ process.env.NEXT_PUBLIC_RUN_MODE:', process.env.NEXT_PUBLIC_RUN_MODE)
switch (process.env.NEXT_PUBLIC_RUN_MODE) {
case 'local':
return configLocal
case 'local.dev':
return configLocalDev
case 'development':
return configDevelopment
case 'production':
return configProduction
default:
return configLocal
}
}
export default Config

View File

@ -1,13 +0,0 @@
import getConfigs from './config.common'
// 환경마다 달라져야 할 변수, 값들을 정의합니다. (여기는 local 환경에 맞는 값을 지정합니다.)
const baseUrl = 'http://1.248.227.176:5000'
const mode = 'local.dev'
// 환경마다 달라져야 할 값들을 getConfig 함수에 전달합니다.
const configLocalDev = getConfigs({
baseUrl,
mode,
})
export default configLocalDev

View File

@ -1,13 +0,0 @@
import getConfigs from './config.common'
// 환경마다 달라져야 할 변수, 값들을 정의합니다. (여기는 local 환경에 맞는 값을 지정합니다.)
const baseUrl = 'http://localhost:3000'
const mode = 'local'
// 환경마다 달라져야 할 값들을 getConfig 함수에 전달합니다.
const configLocal = getConfigs({
baseUrl,
mode,
})
export default configLocal

View File

@ -1,13 +0,0 @@
import getConfigs from './config.common'
// 환경마다 달라져야 할 변수, 값들을 정의합니다. (여기는 production 환경에 맞는 값을 지정합니다.)
const baseUrl = 'https://www.hanasys.jp'
const mode = 'production'
// 환경마다 달라져야 할 값들을 getConfig 함수에 전달합니다.
const configProduction = getConfigs({
baseUrl,
mode,
})
export default configProduction

View File

@ -1,11 +1,11 @@
import { useEffect } from 'react'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { useRecoilState, useRecoilValue } from 'recoil'
import { wordDisplaySelector } from '@/store/settingAtom'
import { useEvent } from '@/hooks/useEvent'
import { checkLineOrientation, getDistance } from '@/util/canvas-util'
import { commonUtilsState, dimensionLineSettingsState } from '@/store/commonUtilsAtom'
import { fontSelector } from '@/store/fontAtom'
import { canvasState, currentMenuState } from '@/store/canvasAtom'
import { canvasState } from '@/store/canvasAtom'
import { v4 as uuidv4 } from 'uuid'
import { usePopup } from '@/hooks/usePopup'
import Distance from '@/components/floor-plan/modal/distance/Distance'
@ -16,33 +16,30 @@ import { BATCH_TYPE } from '@/common/common'
export function useCommonUtils() {
const canvas = useRecoilValue(canvasState)
const wordDisplay = useRecoilValue(wordDisplaySelector)
const { addCanvasMouseEventListener, addDocumentEventListener, initEvent, removeMouseEvent } = useEvent()
const { addCanvasMouseEventListener, addDocumentEventListener, initEvent } = useEvent()
const dimensionSettings = useRecoilValue(dimensionLineSettingsState)
const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText'))
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
const commonTextFont = useRecoilValue(fontSelector('commonText'))
const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState)
const { addPopup, closeAll, targetClose } = usePopup()
const { addPopup, closeAll } = usePopup()
const { drawDirectionArrow, addLengthText } = usePolygon()
const { applyDormers } = useObjectBatch({})
useEffect(() => {
commonTextMode()
if (commonUtils.dimension) {
if (commonUtils.text || !commonUtils.text) {
commonTextMode()
} else if (commonUtils.dimension) {
commonDimensionMode()
return
}
if (commonUtils.distance) {
} else if (commonUtils.distance) {
commonDistanceMode()
return
}
}, [commonUtils, dimensionSettings, commonTextFont, dimensionLineTextFont])
const commonTextMode = () => {
let textbox
closeAll()
if (commonUtils.text) {
targetClose('other')
setTimeout(() => {
commonTextKeyEvent()
addCanvasMouseEventListener('mouse:down', (event) => {
@ -74,17 +71,8 @@ export function useCommonUtils() {
})
}, 100)
} else {
removeMouseEvent('mouse:down')
const activeObject = canvas?.getActiveObject()
const commonTexts = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
if (commonTexts) {
commonTexts.forEach((text) => {
if (text.text === '') {
canvas?.remove(text)
}
})
}
/*if (activeObject && activeObject.name === 'commonText') {
if (activeObject && activeObject.name === 'commonText') {
if (activeObject && activeObject.isEditing) {
if (activeObject.text === '') {
canvas?.remove(activeObject)
@ -98,7 +86,7 @@ export function useCommonUtils() {
})
canvas.renderAll()
}
}*/
}
initEvent()
}

View File

@ -8,7 +8,6 @@ import { useCanvas } from '@/hooks/useCanvas'
import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
import { popSpinnerState } from '@/store/popupAtom'
import Config from '@/config/config.export'
/**
* 배경 이미지 관리
@ -98,7 +97,7 @@ export function useRefFiles() {
setPopSpinnerStore(true)
console.log('🚀 ~ handleFileDelete ~ handleFileDelete:', refImage)
console.log('🚀 ~ handleFileDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
await del({ url: `${Config().baseUrl}/api/image/upload?fileName=${currentCanvasPlan.bgImageName}` })
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload?fileName=${currentCanvasPlan.bgImageName}` })
setCurrentBgImage(null)
await deleteBackGroundImage({
objectId: currentCanvasPlan.id,
@ -119,7 +118,7 @@ export function useRefFiles() {
confirmFn: async () => {
console.log('🚀 ~ handleAddressDelete ~ handleAddressDelete:', refImage)
console.log('🚀 ~ handleAddressDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
await del({ url: `${Config().baseUrl}/api/image/map?fileName=${currentCanvasPlan.bgImageName}` })
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?fileName=${currentCanvasPlan.bgImageName}` })
setMapPositionAddress('')
setCurrentBgImage(null)
await deleteBackGroundImage({
@ -150,7 +149,7 @@ export function useRefFiles() {
}))
const res = await get({
url: `${Config().baseUrl}/api/image/map?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
})
console.log('🚀 ~ handleMapImageDown ~ res:', res)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
@ -209,7 +208,7 @@ export function useRefFiles() {
formData.append('file', file)
const res = await post({
url: `${Config().baseUrl}/api/image/upload`,
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload`,
data: formData,
})
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
@ -239,40 +238,14 @@ export function useRefFiles() {
const res = await post({ url: converterUrl, data: formData })
console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
// Convert Base64 to Blob
const base64Data = res.Files[0].FileData
const byteCharacters = atob(base64Data)
const byteArrays = []
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512)
const byteNumbers = new Array(slice.length)
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
const byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
const blob = new Blob(byteArrays, { type: 'image/png' })
// Create File object from Blob
const convertImg = new File([blob], res.Files[0].FileName, { type: 'image/png' })
const newFormData = new FormData()
newFormData.append('file', convertImg)
/** 캐드 도면 파일 업로드 */
const result = await post({
url: `${Config().baseUrl}/api/image/cad`,
data: newFormData,
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/cad`,
data: res,
})
console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${result.fileName}`)
// setCurrentBgImage(result.filePath)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
setRefImage(file)
const params = {

View File

@ -13,8 +13,6 @@ import { useSwal } from '@/hooks/useSwal'
// Constants
const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의
import Config from '@/config/config.export'
// Helper functions
const updateItemInList = (itemList, dispOrder, updates) => {
return itemList.map((item) => (item.dispOrder === dispOrder ? { ...item, ...updates } : item))
@ -466,13 +464,11 @@ export const useEstimateController = (planNo, flag) => {
setIsGlobalLoading(true)
await promisePost({ url: '/api/estimate/save-estimate-copy', data: params })
.then(async (res) => {
.then((res) => {
setIsGlobalLoading(false)
if (res.status === 201) {
if (isObjectNotEmpty(res.data)) {
let newObjectNo = res.data.objectNo
const copyImage = await handleEstimateImageCopy(params.objectNo, params.planNo, newObjectNo, '1')
swalFire({
text: getMessage('estimate.detail.estimateCopyPopup.copy.alertMessage'),
type: 'alert',
@ -493,27 +489,6 @@ export const useEstimateController = (planNo, flag) => {
})
}
const handleEstimateImageCopy = async (objectNo, planNo, newObjectNo, newPlanNo) => {
await promisePost({ url: `${Config().baseUrl}/api/image/estimate-image-copy`, data: { objectNo, planNo, newObjectNo, newPlanNo } }).then(
(res) => {
return res
},
)
}
const handleDeleteEstimate = async (canvasStatus) => {
try {
setIsGlobalLoading(true)
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/delete-estimate`, data: canvasStatus }).then((res) => {
if (res.status === 201) {
}
})
} catch (e) {
console.error('error::::::::::::', e.response.data.message)
}
setIsGlobalLoading(false)
}
/**
* 전각20자 (반각40자)
*/
@ -534,7 +509,5 @@ export const useEstimateController = (planNo, flag) => {
fetchSetting,
handleEstimateFileDownload,
handleEstimateCopy,
handleDeleteEstimate,
handleEstimateImageCopy,
}
}

View File

@ -5,7 +5,6 @@ import { usePlan } from '../usePlan'
import { POLYGON_TYPE } from '@/common/common'
import { QcastContext } from '@/app/QcastProvider'
import { useContext } from 'react'
import Config from '@/config/config.export'
/**
* 이미지 로더 hook
@ -81,7 +80,7 @@ export function useImgLoader() {
/** 이미지 크롭 요청 */
const result = await post({
// url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/image/canvas`,
url: `${Config().baseUrl}/api/image/canvas`,
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/canvas`,
data: formData,
})
console.log('🚀 ~ handleCanvasToPng ~ result:', result)

View File

@ -661,7 +661,7 @@ export function useModuleBasicSetting(tabNum) {
//가운데 가운데
if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) {
tempModule.top = holdCellCenterY - toFixedWithoutRounding(height / 2, 2)
tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2)
}
if (isChidori) {

View File

@ -209,7 +209,7 @@ export function useModuleTrestle(props) {
stdSnowLd: trestleState.stdSnowLd ?? '',
inclCd: trestleState.inclCd ?? '',
raftBaseCd: trestleState.raft ?? '',
roofPitch: trestleState.hajebichi ? trestleState.hajebichi : (trestleState.roofPitch ?? ''),
roofPitch: Math.round(trestleState.roofPitch) ?? '',
})
.then((res) => {
if (res?.data) setConstructionList(res.data)
@ -236,7 +236,7 @@ export function useModuleTrestle(props) {
inclCd: trestleState.inclCd ?? '',
constTp: trestleState.constTp ?? '',
mixMatlNo: trestleState.mixMatlNo ?? '',
roofPitch: trestleState.hajebichi ? trestleState.hajebichi : (trestleState.roofPitch ?? ''),
roofPitch: trestleState.roofPitch ?? '',
// workingWidth: trestleState.length ?? '',
workingWidth: lengthBase ?? '',
},

View File

@ -1627,8 +1627,6 @@ export const useTrestle = () => {
// 랙 없음의 지지금구를 그린다.
const drawBracketWithOutRack = (module, rackIntvlPct, count, l, direction, moduleIntvlHor, moduleIntvlVer) => {
const { leftFindModuleList, rightFindModuleList, centerFindModuleList } = module
rackIntvlPct = rackIntvlPct === 0 ? 1 : rackIntvlPct // 0인 경우 1로 변경
rackIntvlPct = 100 / rackIntvlPct // 퍼센트로 변경
let { width, height, left, top } = module
let startPointX
@ -1643,14 +1641,14 @@ export const useTrestle = () => {
break
} else if (direction === 'east') {
startPointX = left + width
startPointY = top + height - height / rackIntvlPct - 10
startPointY = top + height - height / rackIntvlPct
break
} else if (direction === 'west') {
startPointX = left
startPointY = top + height / rackIntvlPct
break
} else if (direction === 'north') {
startPointX = left + width - width / rackIntvlPct - 10
startPointX = left + width - width / rackIntvlPct
startPointY = top
break
}
@ -1659,7 +1657,7 @@ export const useTrestle = () => {
case 'R': {
// 오른쪽부분 시작 점
if (direction === 'south') {
startPointX = left + width - width / rackIntvlPct - 10
startPointX = left + width - width / rackIntvlPct
startPointY = top + height / 2 + height / 2
break
} else if (direction === 'east') {
@ -1668,7 +1666,7 @@ export const useTrestle = () => {
break
} else if (direction === 'west') {
startPointX = left
startPointY = top + height - height / rackIntvlPct - 10
startPointY = top + height - height / rackIntvlPct
break
} else if (direction === 'north') {
startPointX = left + width / rackIntvlPct

View File

@ -498,26 +498,11 @@ export function useCanvasSetting(executeEffect = true) {
roofSeq: 0,
roofMatlCd:
params.roofsData.roofMatlCd === null || params.roofsData.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : params.roofsData.roofMatlCd,
roofWidth:
params.selectedRoofMaterial.width === null || params.selectedRoofMaterial.width === undefined
? !params.selectedRoofMaterial.widBase
? 0
: Number(params.roofsData.widBase)
: Number(params.selectedRoofMaterial.width),
roofHeight:
params.selectedRoofMaterial.height === null || params.selectedRoofMaterial.height === undefined
? !params.selectedRoofMaterial.lenBase
? 0
: Number(params.selectedRoofMaterial.lenBase)
: Number(params.roofsData.roofHeight),
roofWidth: params.roofsData.roofWidth === null || params.roofsData.roofWidth === undefined ? 0 : params.roofsData.roofWidth,
roofHeight: params.roofsData.roofHeight === null || params.roofsData.roofHeight === undefined ? 0 : params.roofsData.roofHeight,
roofHajebichi:
params.selectedRoofMaterial.hajebichi === null || params.selectedRoofMaterial.hajebichi === undefined
? 0
: Number(params.selectedRoofMaterial.hajebichi),
roofGap:
params.selectedRoofMaterial.raft === null || params.selectedRoofMaterial.raft === undefined
? params.selectedRoofMaterial.raftBaseCd
: params.roofsData.raft,
params.roofsData.roofHajebichi === null || params.roofsData.roofHajebichi === undefined ? 0 : params.roofsData.roofHajebichi,
roofGap: params.roofsData.roofGap === null || params.roofsData.roofGap === undefined ? 'HEI_455' : params.roofsData.roofGap,
roofLayout: params.roofsData.roofLayout === null || params.roofsData.roofLayout === undefined ? 'P' : params.roofsData.roofLayout,
roofPitch: params.roofsData.roofPitch === null || params.roofsData.roofPitch === undefined ? 0 : params.roofsData.roofPitch,
roofAngle: params.roofsData.roofAngle === null || params.roofsData.roofAngle === undefined ? 0 : params.roofsData.roofAngle,

View File

@ -212,6 +212,7 @@ export function useRoofAllocationSetting(id) {
}
await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => {
swalFire({ text: getMessage(res.returnMessage) })
setIsGlobalLoading(false)
})
@ -314,8 +315,7 @@ export function useRoofAllocationSetting(id) {
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
drawDirectionArrow(currentObject)
modifyModuleSelectionData()
// closeAll()
closePopup(id)
closeAll()
basicSettingSave()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
}

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react'
import { useRef } from 'react'
import { useRecoilValue, useSetRecoilState } from 'recoil'
import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom'
import { fabric } from 'fabric'
@ -15,8 +15,7 @@ import { useDotLineGrid } from '@/hooks/useDotLineGrid'
import { useTempGrid } from '@/hooks/useTempGrid'
import { gridColorState } from '@/store/gridAtom'
import { gridDisplaySelector } from '@/store/settingAtom'
import { MENU, POLYGON_TYPE } from '@/common/common'
import useMenu from '@/hooks/common/useMenu'
import { POLYGON_TYPE } from '@/common/common'
export function useEvent() {
const canvas = useRecoilValue(canvasState)
@ -26,7 +25,6 @@ export function useEvent() {
const setCanvasZoom = useSetRecoilState(canvasZoomState)
const gridColor = useRecoilValue(gridColorState)
const isGridDisplay = useRecoilValue(gridDisplaySelector)
const zoom = useRecoilValue(canvasZoomState)
const { adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, getAdsorptionPoints, adsorptionPointAddModeStateEvent } = useAdsorptionPoint()
const { dotLineGridSetting, interval, getClosestLineGrid } = useDotLineGrid()
@ -61,13 +59,6 @@ export function useEvent() {
addDefaultEvent()
}
useEffect(() => {
const whiteMenus = [MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH, MENU.BATCH_CANVAS.OBJECT_BATCH, MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING]
if (canvas && !whiteMenus.includes(currentMenu)) {
addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent)
}
}, [zoom])
const addDefaultEvent = () => {
//default Event 추가
addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent)
@ -289,7 +280,7 @@ export function useEvent() {
}
const drawMouseLine = (pointer) => {
const horizontalLine = new fabric.Line([-2 * canvas.width, pointer.y, 2 * canvas.width, pointer.y], {
const horizontalLine = new fabric.Line([-4 * canvas.width, pointer.y, 4 * canvas.width, pointer.y], {
stroke: 'red',
strokeWidth: 1,
selectable: false,
@ -297,7 +288,7 @@ export function useEvent() {
})
// 세로선
const verticalLine = new fabric.Line([pointer.x, -2 * canvas.height, pointer.x, 2 * canvas.height], {
const verticalLine = new fabric.Line([pointer.x, -4 * canvas.height, pointer.x, 4 * canvas.height], {
stroke: 'red',
strokeWidth: 1,
selectable: false,
@ -401,7 +392,7 @@ export function useEvent() {
const removeMouseEvent = (type) => {
mouseEventListeners.current = mouseEventListeners.current.filter((event) => {
if (event.eventType === type) {
canvas?.off(type, event.handler)
canvas.off(type, event.handler)
return false
}
return true

View File

@ -159,6 +159,5 @@ export const useLine = () => {
addPitchText,
removePitchText,
addPitchTextsByOuterLines,
getLengthByLine,
}
}

View File

@ -30,7 +30,6 @@ import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusCon
import { useCanvasMenu } from './common/useCanvasMenu'
import { QcastContext } from '@/app/QcastProvider'
import { unescapeString } from '@/util/common-utils'
import { useTrestle } from '@/hooks/module/useTrestle'
/**
* 플랜 처리
@ -55,7 +54,7 @@ export function usePlan(params = {}) {
const { getMessage } = useMessage()
const { get, post, promisePost, promisePut, promiseDel, promiseGet } = useAxios()
const { setEstimateContextState, handleDeleteEstimate, handleEstimateImageCopy } = useEstimateController()
const { setEstimateContextState } = useEstimateController()
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
@ -79,7 +78,6 @@ export function usePlan(params = {}) {
const resetCurrentObject = useResetRecoilState(currentObjectState)
//선택된 모듈 배치면 초기화
const resetModuleSetupSurface = useResetRecoilState(moduleSetupSurfaceState)
const { isAllComplete } = useTrestle()
/**
* 마우스 포인터의 가이드라인 제거
@ -174,11 +172,7 @@ export function usePlan(params = {}) {
*/
const saveCanvas = async (saveAlert = true) => {
const canvasStatus = currentCanvasData('save')
const result = await putCanvasStatus(canvasStatus, saveAlert)
//캔버스 저장 완료 후
if (result && !isAllComplete()) {
handleDeleteEstimate(currentCanvasPlan)
}
await putCanvasStatus(canvasStatus, saveAlert)
}
/**
@ -307,9 +301,6 @@ export function usePlan(params = {}) {
setModuleSelectionDataStore(copyData)
if (copyData.module) setSelectedModules(copyData.module)
setSelectedMenu(currentSelectedMenu)
//이미지 복사
handleEstimateImageCopy(planData.objectNo, planData.planNo, planData.objectNo, newPlan.planNo)
} else {
setSelectedMenu('placement')
}
@ -327,24 +318,20 @@ export function usePlan(params = {}) {
* @param {boolean} saveAlert - 저장 완료 알림 표시 여부
*/
const putCanvasStatus = async (canvasStatus, saveAlert = true) => {
let rtn = false
const planData = {
id: currentCanvasPlan.id,
bgImageName: currentCanvasPlan?.bgImageName ?? null,
mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null,
canvasStatus: canvasToDbFormat(canvasStatus),
}
await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
.then((res) => {
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
if (saveAlert) swalFire({ text: getMessage('plan.message.save') })
rtn = true
})
.catch((error) => {
swalFire({ text: error.message, icon: 'error' })
})
return rtn
}
/**
@ -615,10 +602,8 @@ export function usePlan(params = {}) {
if (pathname === '/floor-plan/estimate/5' || pathname === '/floor-plan/simulator/6') {
await getCanvasByObjectNo(objectNo, planNo).then((res) => {
if (res.length > 0) {
// setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus }))
// setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((resPlan) => resPlan.planNo === plan.planNo).canvasStatus })))
setCurrentCanvasPlan(res.find((plan) => plan.planNo === planNo))
setPlans(res)
setCurrentCanvasPlan((prev) => ({ ...prev, 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

@ -15,7 +15,6 @@ import { flowDisplaySelector } from '@/store/settingAtom'
import { fontSelector } from '@/store/fontAtom'
import { QLine } from '@/components/fabric/QLine'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
import { useLine } from '@/hooks/useLine'
export const usePolygon = () => {
const canvas = useRecoilValue(canvasState)
@ -25,8 +24,6 @@ export const usePolygon = () => {
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const pitchText = useRecoilValue(pitchTextSelector)
const { getLengthByLine } = useLine()
const addPolygon = (points, options, isAddCanvas = true) => {
const polygon = new QPolygon(points, {
...options,
@ -1096,37 +1093,25 @@ export const usePolygon = () => {
})
if (startFlag && endFlag) {
if (!representLines.includes(line) && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
if (!representLines.includes(line)) {
representLines.push(line)
}
}
})
// blue로 생성된 것들은 대표라인이 될 수 없음.
// representLines = representLines.filter((line) => line.stroke !== 'blue')
// representLines중 가장 긴 line을 찾는다.
representLines.forEach((line) => {
if (!representLine) {
representLine = line
} else {
if (getLengthByLine(representLine) < getLengthByLine(line)) {
if (representLine.length < line.length) {
representLine = line
}
}
})
if (!representLine) {
representLines = representLines.filter((line) => line.stroke !== 'blue')
representLines.forEach((line) => {
if (!representLine) {
representLine = line
} else {
if (representLine.length < line.length) {
representLine = line
}
}
})
}
const direction = polygon.direction ?? representLine?.direction ?? ''
const direction = polygon.direction ?? representLine?.direction
const polygonDirection = polygon.direction
switch (direction) {
@ -1193,7 +1178,7 @@ export const usePolygon = () => {
})
canvas.add(roof)
addLengthText(roof)
// addLengthText(roof)
canvas.remove(polygon)
canvas.renderAll()
})

View File

@ -1,7 +1,5 @@
import { useRecoilState, useResetRecoilState } from 'recoil'
import { useRecoilState } from 'recoil'
import { contextPopupState, popupState } from '@/store/popupAtom'
import { useEffect } from 'react'
import { commonUtilsState } from '@/store/commonUtilsAtom'
/**
* 팝업 관리
@ -130,17 +128,11 @@ export function usePopup() {
}
}
const targetClose = (type) => {
popup[type] = []
setPopup({ ...popup, [type]: [] })
}
return {
popup,
addPopup,
closePopup,
closePopups,
closeAll,
targetClose,
}
}

View File

@ -617,7 +617,7 @@
"qna.reg.alert.select.type": "お問い合わせ区分を選択してください。",
"qna.reg.alert.require.title": "タイトルを入力してください。",
"qna.reg.alert.require.contents": "内容を入力してください。",
"qna.reg.confirm.save": "お問い合わせを登録しますか? <br/>Hanwha Japan 担当者にお問い合わせメールが送信されます。",
"qna.reg.confirm.save": "1:1お問い合わせを登録しますか? <br/>Hanwha Japan 担当者にお問い合わせメールが送信されます。",
"qna.reg.alert.save": "保存されました。",
"qna.reg.alert.saveFail": "保存に失敗しました。",
"qna.list.header.regNm": "登録者",
@ -666,9 +666,9 @@
"join.sub1.title": "販売代理店情報",
"join.sub1.comment": "※登録される販売店の会社名を入力してください。 2次店は「○○販売株式会社2次店××設備株式会社」でご記入ください。",
"join.sub1.storeQcastNm": "販売代理店名",
"join.sub1.storeQcastNm_placeholder": "ハンファジャパン株式会社",
"join.sub1.storeQcastNm_placeholder": "株式会社エネルギーギアソリューションアンサービス(2次点山口周期販売有限会社",
"join.sub1.storeQcastNmKana": "販売代理店名フリガナ",
"join.sub1.storeQcastNmKana_placeholder": "ハンファジャパンカブシキカイシャ",
"join.sub1.storeQcastNmKana_placeholder": "株式会社エネルギーギアソリューション",
"join.sub1.postCd": "郵便番号",
"join.sub1.postCd_placeholder": "数字7桁",
"join.sub1.addr": "住所",
@ -681,7 +681,7 @@
"join.sub2.title": "担当者情報",
"join.sub2.userNm": "担当者名",
"join.sub2.userNmKana": "担当者名ふりがな",
"join.sub2.userId": "ユーザーID",
"join.sub2.userId": "申請ID",
"join.sub2.email": "メールアドレス",
"join.sub2.telNo": "電話番号",
"join.sub2.telNo_placeholder": "00 0000 0000",
@ -689,12 +689,12 @@
"join.sub2.fax_placeholder": "00 0000 0000",
"join.sub2.category": "部署名",
"join.btn.login_page": "ログイン画面に移動",
"join.btn.approval_request": "ID申請",
"join.btn.approval_request": "ID承認要求",
"join.complete.title": "HANASYS設計ログインID発行申請完了",
"join.complete.contents": "※申請したIDが承認されると、担当者情報に入力したEメールアドレスにログイン関連案内メールが送信されます。",
"join.complete.email_comment": "担当者のメールアドレス",
"join.validation.check1": "{0}形式を確認してください。",
"join.complete.save.confirm": "ID申請を完了後は申請情報の修正が出来ません。申請しますか?",
"join.complete.save.confirm": "ハンファジャパンの担当者にID承認が要求された場合、これ以上情報を修正することはできません。申請しますか?",
"stuff.gridHeader.lastEditDatetime": "更新日時",
"stuff.gridHeader.objectNo": "物件番号",
"stuff.gridHeader.planTotCnt": "プラン数",

View File

@ -666,9 +666,9 @@
"join.sub1.title": "판매대리점 정보",
"join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)",
"join.sub1.storeQcastNm": "판매대리점명",
"join.sub1.storeQcastNm_placeholder": "한화재팬 주식회사",
"join.sub1.storeQcastNm_placeholder": "주식회사 에너지 기어 솔루션 앤 서비스 (2차점: 야마구치 주기 판매 유한회사)",
"join.sub1.storeQcastNmKana": "판매대리점명 후리가나",
"join.sub1.storeQcastNmKana_placeholder": "한화재팬 카부시키 카이샤",
"join.sub1.storeQcastNmKana_placeholder": "주식회사 에너지 기어 솔루션",
"join.sub1.postCd": "우편번호",
"join.sub1.postCd_placeholder": "숫자 7자리",
"join.sub1.addr": "주소",
@ -681,7 +681,7 @@
"join.sub2.title": "담당자 정보",
"join.sub2.userNm": "담당자명",
"join.sub2.userNmKana": "담당자명 후리가나",
"join.sub2.userId": "사용자 ID",
"join.sub2.userId": "신청 ID",
"join.sub2.email": "이메일 주소",
"join.sub2.telNo": "전화번호",
"join.sub2.telNo_placeholder": "00 0000 0000",

View File

@ -37,11 +37,11 @@ export const subMenusState = atom({
// 지붕덮개
{ id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE },
{ id: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS },
// {
// id: 2,
// name: 'plan.menu.roof.cover.roof.shape.passivity.setting',
// menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS,
// },
{
id: 2,
name: 'plan.menu.roof.cover.roof.shape.passivity.setting',
menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS,
},
{ id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING },
{ id: 4, name: 'plan.menu.roof.cover.eaves.kerava.edit', menu: MENU.ROOF_COVERING.EAVES_KERAVA_EDIT },
{ id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN },

View File

@ -1,2 +0,0 @@
var exec = require('child_process').exec
exec('yarn start:cluster1', { windowsHide: true })

View File

@ -1,2 +0,0 @@
var exec = require('child_process').exec
exec('yarn start:cluster2', { windowsHide: true })

View File

@ -1,2 +0,0 @@
var exec = require('child_process').exec
exec('yarn start:dev', { windowsHide: true })

View File

@ -1,2 +1,2 @@
var exec = require('child_process').exec
exec('yarn local:dev -p 5000', { windowsHide: true })
exec('yarn dev -p 5000', { windowsHide: true })