dev #85

Merged
ysCha merged 24 commits from dev into dev-deploy 2025-05-29 16:45:27 +09:00
26 changed files with 274 additions and 32 deletions

View File

@ -1,8 +1,10 @@
NEXT_PUBLIC_RUN_MODE="development"
NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp" NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000" NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
NEXT_PUBLIC_API_HOST_URL="http://1.248.227.176:5000" NEXT_PUBLIC_API_HOST_URL="https://dev.hanasys.jp"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="

30
.env.local.dev Normal file
View File

@ -0,0 +1,30 @@
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"

30
.env.localhost Normal file
View File

@ -0,0 +1,30 @@
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"

View File

@ -1,3 +1,5 @@
NEXT_PUBLIC_RUN_MODE="production"
NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/" NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000" NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"

View File

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

View File

@ -0,0 +1,13 @@
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,11 +3,14 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "env-cmd -f .env.localhost next dev",
"build": "next build", "local:dev": "env-cmd -f .env.local.dev next dev",
"start:cluster1": "next start -p 5000", "build": "env-cmd -f .env.productionnext build",
"start:cluster2": "next start -p 5001", "build:dev": "env-cmd -f .env.development next build",
"start:dev": "next start -p 5010", "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",
"lint": "next lint", "lint": "next lint",
"serve": "node server.js" "serve": "node server.js"
}, },
@ -18,6 +21,7 @@
"big.js": "^6.2.2", "big.js": "^6.2.2",
"chart.js": "^4.4.6", "chart.js": "^4.4.6",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"env-cmd": "^10.1.0",
"fabric": "^5.3.0", "fabric": "^5.3.0",
"framer-motion": "^11.2.13", "framer-motion": "^11.2.13",
"fs": "^0.0.1-security", "fs": "^0.0.1-security",

13
prd1.ecosystem.config.js Normal file
View File

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

13
prd2.ecosystem.config.js Normal file
View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,13 @@
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

@ -0,0 +1,22 @@
import configDevelopment from './config.development'
import configLocal from './config.local'
import configLocalDev from './config.local.dev'
import configProduction from './config.production'
// 클라이언트에서는 이 함수를 사용하여 config 값을 참조합니다.
const Config = () => {
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

@ -0,0 +1,13 @@
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

@ -0,0 +1,13 @@
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

@ -0,0 +1,13 @@
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

@ -22,7 +22,7 @@ export function useCommonUtils() {
const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
const commonTextFont = useRecoilValue(fontSelector('commonText')) const commonTextFont = useRecoilValue(fontSelector('commonText'))
const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState) const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState)
const { addPopup, closeAll } = usePopup() const { addPopup, closeAll, targetClose } = usePopup()
const { drawDirectionArrow, addLengthText } = usePolygon() const { drawDirectionArrow, addLengthText } = usePolygon()
const { applyDormers } = useObjectBatch({}) const { applyDormers } = useObjectBatch({})
@ -38,8 +38,9 @@ export function useCommonUtils() {
const commonTextMode = () => { const commonTextMode = () => {
let textbox let textbox
closeAll()
if (commonUtils.text) { if (commonUtils.text) {
targetClose('other')
setTimeout(() => { setTimeout(() => {
commonTextKeyEvent() commonTextKeyEvent()
addCanvasMouseEventListener('mouse:down', (event) => { addCanvasMouseEventListener('mouse:down', (event) => {

View File

@ -8,6 +8,7 @@ import { useCanvas } from '@/hooks/useCanvas'
import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions' import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions'
import { settingModalFirstOptionsState } from '@/store/settingAtom' import { settingModalFirstOptionsState } from '@/store/settingAtom'
import { popSpinnerState } from '@/store/popupAtom' import { popSpinnerState } from '@/store/popupAtom'
import Config from '@/config/config.export'
/** /**
* 배경 이미지 관리 * 배경 이미지 관리
@ -97,7 +98,7 @@ export function useRefFiles() {
setPopSpinnerStore(true) setPopSpinnerStore(true)
console.log('🚀 ~ handleFileDelete ~ handleFileDelete:', refImage) console.log('🚀 ~ handleFileDelete ~ handleFileDelete:', refImage)
console.log('🚀 ~ handleFileDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName) console.log('🚀 ~ handleFileDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload?fileName=${currentCanvasPlan.bgImageName}` }) await del({ url: `${Config().baseUrl}/api/image/upload?fileName=${currentCanvasPlan.bgImageName}` })
setCurrentBgImage(null) setCurrentBgImage(null)
await deleteBackGroundImage({ await deleteBackGroundImage({
objectId: currentCanvasPlan.id, objectId: currentCanvasPlan.id,
@ -118,7 +119,7 @@ export function useRefFiles() {
confirmFn: async () => { confirmFn: async () => {
console.log('🚀 ~ handleAddressDelete ~ handleAddressDelete:', refImage) console.log('🚀 ~ handleAddressDelete ~ handleAddressDelete:', refImage)
console.log('🚀 ~ handleAddressDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName) console.log('🚀 ~ handleAddressDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?fileName=${currentCanvasPlan.bgImageName}` }) await del({ url: `${Config().baseUrl}/api/image/map?fileName=${currentCanvasPlan.bgImageName}` })
setMapPositionAddress('') setMapPositionAddress('')
setCurrentBgImage(null) setCurrentBgImage(null)
await deleteBackGroundImage({ await deleteBackGroundImage({
@ -149,7 +150,7 @@ export function useRefFiles() {
})) }))
const res = await get({ const res = await get({
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`, url: `${Config().baseUrl}/api/image/map?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
}) })
console.log('🚀 ~ handleMapImageDown ~ res:', res) console.log('🚀 ~ handleMapImageDown ~ res:', res)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`) setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
@ -208,7 +209,7 @@ export function useRefFiles() {
formData.append('file', file) formData.append('file', file)
const res = await post({ const res = await post({
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload`, url: `${Config().baseUrl}/api/image/upload`,
data: formData, data: formData,
}) })
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res) console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
@ -238,14 +239,40 @@ export function useRefFiles() {
const res = await post({ url: converterUrl, data: formData }) const res = await post({ url: converterUrl, data: formData })
console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res) 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({ const result = await post({
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/cad`, url: `${Config().baseUrl}/api/image/cad`,
data: res, data: newFormData,
}) })
console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result) console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`) // setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${result.fileName}`)
setCurrentBgImage(result.filePath)
setRefImage(file) setRefImage(file)
const params = { const params = {

View File

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

View File

@ -1100,7 +1100,7 @@ export const usePolygon = () => {
}) })
// blue로 생성된 것들은 대표라인이 될 수 없음. // blue로 생성된 것들은 대표라인이 될 수 없음.
// representLines = representLines.filter((line) => line.stroke !== 'blue') representLines = representLines.filter((line) => line.stroke !== 'blue')
// representLines중 가장 긴 line을 찾는다. // representLines중 가장 긴 line을 찾는다.
representLines.forEach((line) => { representLines.forEach((line) => {
if (!representLine) { if (!representLine) {

View File

@ -128,11 +128,17 @@ export function usePopup() {
} }
} }
const targetClose = (type) => {
popup[type] = []
setPopup({ ...popup, [type]: [] })
}
return { return {
popup, popup,
addPopup, addPopup,
closePopup, closePopup,
closePopups, closePopups,
closeAll, closeAll,
targetClose,
} }
} }

View File

@ -617,7 +617,7 @@
"qna.reg.alert.select.type": "お問い合わせ区分を選択してください。", "qna.reg.alert.select.type": "お問い合わせ区分を選択してください。",
"qna.reg.alert.require.title": "タイトルを入力してください。", "qna.reg.alert.require.title": "タイトルを入力してください。",
"qna.reg.alert.require.contents": "内容を入力してください。", "qna.reg.alert.require.contents": "内容を入力してください。",
"qna.reg.confirm.save": "1:1お問い合わせを登録しますか? <br/>Hanwha Japan 担当者にお問い合わせメールが送信されます。", "qna.reg.confirm.save": "お問い合わせを登録しますか? <br/>Hanwha Japan 担当者にお問い合わせメールが送信されます。",
"qna.reg.alert.save": "保存されました。", "qna.reg.alert.save": "保存されました。",
"qna.reg.alert.saveFail": "保存に失敗しました。", "qna.reg.alert.saveFail": "保存に失敗しました。",
"qna.list.header.regNm": "登録者", "qna.list.header.regNm": "登録者",

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: 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: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS },
{ // {
id: 2, // id: 2,
name: 'plan.menu.roof.cover.roof.shape.passivity.setting', // name: 'plan.menu.roof.cover.roof.shape.passivity.setting',
menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS, // 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: 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: 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 }, { id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN },

View File

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