Merge branch 'dev' of ssh://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev

This commit is contained in:
yjnoh 2025-02-06 17:46:07 +09:00
commit 17d34bb036
32 changed files with 939 additions and 643 deletions

View File

@ -1,10 +1,11 @@
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
NEXT_PUBLIC_HOST_URL="http://localhost:4000"
NEXT_PUBLIC_HOST_URL="http://1.248.227.176:4000"
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_bV5zuYMyyIYFlOb3"
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
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"

View File

@ -1,10 +1,11 @@
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
NEXT_PUBLIC_HOST_URL="http://localhost:4000"
NEXT_PUBLIC_HOST_URL="http://1.248.227.176:4000"
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_bV5zuYMyyIYFlOb3"
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"

View File

@ -1,21 +1,27 @@
'use client'
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import GlobalSpinner from '@/components/common/spinner/GlobalSpinner'
export default function AutoLoginPage() {
const [isLoading, setIsLoading] = useState(true)
const { getMessage } = useMessage()
return (
<div className="login-input-frame">
<div className="login-frame-tit ">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
</div>
<div className="login-input-wrap">
<div className="login-area id" style={{ fontWeight: 'bolder' }}>
{getMessage('login.auto.page.text')}
<>
{isLoading && <GlobalSpinner />}
<div className="login-input-frame">
<div className="login-frame-tit ">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
</div>
<div className="login-input-wrap">
<div className="login-area id" style={{ fontWeight: 'bolder' }}>
{getMessage('login.auto.page.text')}
</div>
</div>
</div>
</div>
</>
)
}

View File

@ -10,14 +10,15 @@ import { useMessage } from '@/hooks/useMessage'
import { globalLocaleStore } from '@/store/localeAtom'
import { sessionStore } from '@/store/commonAtom'
import { useRouter } from 'next/navigation'
import Cookies from 'js-cookie'
import { useSearchParams } from 'next/navigation'
import GlobalSpinner from '@/components/common/spinner/GlobalSpinner'
import Cookies from 'js-cookie'
import AutoLogin from './AutoLogin'
export default function Login() {
const [isLoading, setIsLoading] = useState(false)
//
const initParams = useSearchParams()
const autoLoginParam = initParams.get('autoLoginParam1')
@ -35,11 +36,13 @@ export default function Login() {
}, [])
const autoLoginProcess = async (autoLoginParam) => {
setIsLoading(true)
await promisePost({ url: '/api/login/v1.0/user/login/autoLoginDecryptData', data: { loginId: autoLoginParam } })
.then((res) => {
if (res) {
if (res.data) {
post({ url: '/api/login/v1.0/user', data: { loginId: res.data } }).then((response) => {
setIsLoading(false)
if (response) {
const result = { ...response, storeLvl: response.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' }
setSession(result)
@ -53,6 +56,7 @@ export default function Login() {
}
})
.catch((error) => {
setIsLoading(false)
router.push('/login')
})
}
@ -93,9 +97,11 @@ export default function Login() {
loginId: formData.get('id'),
pwd: formData.get('password'),
}
setIsLoading(true)
await promisePost({ url: '/api/login/v1.0/login', data: param })
.then((res) => {
if (res) {
setIsLoading(false)
if (res.data.result.resultCode === 'S') {
setSession(res.data.data)
setSessionState(res.data.data)
@ -105,7 +111,6 @@ export default function Login() {
} else {
Cookies.remove('chkLoginId')
}
// router.push('/')
login()
} else {
alert(res.data.result.resultMsg)
@ -113,6 +118,7 @@ export default function Login() {
}
})
.catch((error) => {
setIsLoading(false)
alert(error.response.data.message)
})
}
@ -123,12 +129,14 @@ export default function Login() {
loginId: checkId,
email: checkEmail,
}
setIsLoading(true)
await promisePatch({
url: '/api/login/v1.0/user/init-password',
data: param,
})
.then((res) => {
if (res) {
setIsLoading(false)
if (res.data.result.resultCode == 'S') {
alert(getMessage('login.init_password.complete_message'))
setCheckId('')
@ -140,36 +148,135 @@ export default function Login() {
}
})
.catch((error) => {
setIsLoading(false)
alert(error.response.data.message)
})
}
return (
<div className="login-wrap">
<div className="login-inner">
<Link href={'/login'} className="login-logo">
<Image src="/static/images/main/login-logo.svg" alt="react" width={236} height={43} styles={{ width: '236px', height: '43px' }} priority />
</Link>
{!autoLoginParam && passwordReset === 1 && (
<>
<div className="login-input-frame">
<form onSubmit={loginProcess} className="space-y-6">
<div className="login-frame-tit">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
<>
{isLoading && <GlobalSpinner />}
<div className="login-wrap">
<div className="login-inner">
<Link href={'/login'} className="login-logo">
<Image
src="/static/images/main/login-logo.svg"
alt="react"
width={236}
height={43}
styles={{ width: '236px', height: '43px' }}
priority
/>
</Link>
{!autoLoginParam && passwordReset === 1 && (
<>
<div className="login-input-frame">
<form onSubmit={loginProcess} className="space-y-6">
<div className="login-frame-tit">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
</div>
<div className="login-input-wrap">
<div className={`login-area id ${idFocus ? 'focus' : ''}`}>
<input
type="text"
className="login-input"
id="userId"
name="id"
required
value={userId}
placeholder={getMessage('login.id.placeholder')}
onChange={(e) => {
setUserId(e.target.value)
}}
onFocus={() => setIdFocus(true)}
onBlur={() => setIdFocus(false)}
/>
<button
type="button"
className="id-delete"
onClick={(e) => {
setUserId('')
}}
></button>
</div>
<div className={`login-area password ${secFocus ? 'focus' : ''}`}>
<input
type={passwordVisible ? 'text' : 'password'}
className="login-input"
id="password"
name="password"
required
autoComplete="current-password"
placeholder={getMessage('login.password.placeholder')}
onChange={(e) => {
setPasswordVisible(passwordVisible)
}}
onFocus={() => setSecFocus(true)}
onBlur={() => setSecFocus(false)}
/>
<button
type="button"
className={`password-hidden ${passwordVisible ? 'visible' : ''}`}
onClick={(e) => {
e.preventDefault()
setPasswordVisible(!passwordVisible)
}}
></button>
</div>
<div className="d-check-box login">
<input
type="checkbox"
id="ch01"
name="chkLoginId"
checked={chkLoginId}
onChange={(e) => {
setChkLoginId(e.target.checked)
}}
/>
<label htmlFor="ch01">{getMessage('login.id.save')}</label>
</div>
<div className="login-btn-box">
<button type="submit" className="login-btn">
{getMessage('login')}
</button>
</div>
<div className="reset-password">
<button type="button" onClick={() => setPasswordReset(2)}>
{getMessage('login.init_password.btn')}
</button>
</div>
</div>
</form>
</div>
<div className="login-guide-wrap">
<span></span>
{getMessage('login.guide.text')}
<br />
{getMessage('login.guide.sub1')} <Link href={'../join'}>{getMessage('login.guide.join.btn')}</Link>
{getMessage('login.guide.sub2')}
</div>
</>
)}
{!autoLoginParam && passwordReset === 2 && (
<>
<div className="login-input-frame">
<div className="login-frame-tit pw-reset">
<span>{getMessage('login.init_password.title')}</span>
{getMessage('login.init_password.sub_title')}
</div>
<div className="login-input-wrap">
<div className={`login-area id ${idFocus ? 'focus' : ''}`}>
<input
type="text"
className="login-input"
id="userId"
name="id"
id="checkId"
name="checkId"
value={checkId}
required
value={userId}
placeholder={getMessage('login.id.placeholder')}
className="login-input"
placeholder={getMessage('login.init_password.id.placeholder')}
onChange={(e) => {
setUserId(e.target.value)
setCheckId(e.target.value)
}}
onFocus={() => setIdFocus(true)}
onBlur={() => setIdFocus(false)}
@ -177,146 +284,58 @@ export default function Login() {
<button
type="button"
className="id-delete"
onClick={(e) => {
setUserId('')
onClick={() => {
setCheckId('')
}}
></button>
</div>
<div className={`login-area password ${secFocus ? 'focus' : ''}`}>
<div className={`login-area email ${secFocus ? 'focus' : ''}`}>
<input
type={passwordVisible ? 'text' : 'password'}
className="login-input"
id="password"
name="password"
id="checkEmail"
name="checkEmail"
type="email"
required
autoComplete="current-password"
placeholder={getMessage('login.password.placeholder')}
className="login-input"
value={checkEmail}
onChange={(e) => {
setPasswordVisible(passwordVisible)
setCheckEmail(e.target.value)
}}
placeholder={getMessage('login.init_password.email.placeholder')}
onFocus={() => setSecFocus(true)}
onBlur={() => setSecFocus(false)}
/>
<button
type="button"
className={`password-hidden ${passwordVisible ? 'visible' : ''}`}
onClick={(e) => {
e.preventDefault()
setPasswordVisible(!passwordVisible)
className="id-delete"
onClick={() => {
setCheckEmail('')
}}
></button>
</div>
<div className="d-check-box login">
<input
type="checkbox"
id="ch01"
name="chkLoginId"
checked={chkLoginId}
onChange={(e) => {
setChkLoginId(e.target.checked)
<div className="pwreset-btn-box">
<button
type="button"
className="login-btn light mr5"
onClick={() => {
setPasswordReset(1)
setCheckEmail('')
setCheckId('')
}}
/>
<label htmlFor="ch01">{getMessage('login.id.save')}</label>
</div>
<div className="login-btn-box">
<button type="submit" className="login-btn">
{getMessage('login')}
>
{getMessage('login.init_password.btn.back')}
</button>
</div>
<div className="reset-password">
<button type="button" onClick={() => setPasswordReset(2)}>
<button type="button" className="login-btn" onClick={initPasswordProcess}>
{getMessage('login.init_password.btn')}
</button>
</div>
</div>
</form>
</div>
<div className="login-guide-wrap">
<span></span>
{getMessage('login.guide.text')}
<br />
{getMessage('login.guide.sub1')} <Link href={'../join'}>{getMessage('login.guide.join.btn')}</Link>
{getMessage('login.guide.sub2')}
</div>
</>
)}
{!autoLoginParam && passwordReset === 2 && (
<>
<div className="login-input-frame">
<div className="login-frame-tit pw-reset">
<span>{getMessage('login.init_password.title')}</span>
{getMessage('login.init_password.sub_title')}
</div>
<div className="login-input-wrap">
<div className={`login-area id ${idFocus ? 'focus' : ''}`}>
<input
type="text"
id="checkId"
name="checkId"
value={checkId}
required
className="login-input"
placeholder={getMessage('login.init_password.id.placeholder')}
onChange={(e) => {
setCheckId(e.target.value)
}}
onFocus={() => setIdFocus(true)}
onBlur={() => setIdFocus(false)}
/>
<button
type="button"
className="id-delete"
onClick={() => {
setCheckId('')
}}
></button>
</div>
<div className={`login-area email ${secFocus ? 'focus' : ''}`}>
<input
id="checkEmail"
name="checkEmail"
type="email"
required
className="login-input"
value={checkEmail}
onChange={(e) => {
setCheckEmail(e.target.value)
}}
placeholder={getMessage('login.init_password.email.placeholder')}
onFocus={() => setSecFocus(true)}
onBlur={() => setSecFocus(false)}
/>
<button
type="button"
className="id-delete"
onClick={() => {
setCheckEmail('')
}}
></button>
</div>
<div className="pwreset-btn-box">
<button
type="button"
className="login-btn light mr5"
onClick={() => {
setPasswordReset(1)
setCheckEmail('')
setCheckId('')
}}
>
{getMessage('login.init_password.btn.back')}
</button>
<button type="button" className="login-btn" onClick={initPasswordProcess}>
{getMessage('login.init_password.btn')}
</button>
</div>
</div>
</div>
</>
)}
{autoLoginParam && <AutoLogin />}
</>
)}
{autoLoginParam && <AutoLogin />}
</div>
<div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div>
</div>
<div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div>
</div>
</>
)
}

View File

@ -1188,7 +1188,7 @@ export default function Estimate({}) {
<input
type="text"
className="input-light"
value={estimateContextState?.charger}
value={estimateContextState?.charger || ''}
onBlur={handleBlurCharger}
onChange={handleBlurCharger}
/>
@ -1206,7 +1206,7 @@ export default function Estimate({}) {
<input
type="text"
className="input-light"
value={estimateContextState?.objectName}
value={estimateContextState?.objectName || ''}
onBlur={handleBlurObjectName}
onChange={handleBlurObjectName}
/>
@ -1297,13 +1297,13 @@ export default function Estimate({}) {
//
let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('、')
return (
<div className={`form-flex-wrap ${style}`} key={`roof_${row}`}>
<div className={`form-flex-wrap ${style}`} key={`roof_${index}_${row}`}>
<div className="input-wrap mr5" style={{ width: '610px' }}>
<input type="text" className="input-light" value={roofList} readOnly />
<input type="text" className="input-light" value={roofList || ''} readOnly />
</div>
{constructSpecificationMulti ? (
<div className="input-wrap" style={{ width: '200px' }}>
<input type="text" className="input-light" value={constructSpecificationMulti[index]} readOnly />
<input type="text" className="input-light" value={constructSpecificationMulti[index] || ''} readOnly />
</div>
) : null}
</div>
@ -1316,7 +1316,6 @@ export default function Estimate({}) {
<th>{getMessage('estimate.detail.remarks')}</th>
<td colSpan={3}>
<div className="input-wrap">
{/* <input type="text" className="input-light" defaultValue={estimateContextState?.remarks || ''} onBlur={handleBlurRemarks} /> */}
<input
type="text"
className="input-light"

View File

@ -42,7 +42,9 @@ export default function CanvasLayout({ children }) {
{index !== 0 && (
<i
className="close"
onClick={(e) =>
onClick={(e) => {
// handleCurrentPlan
e.stopPropagation()
swalFire({
text: `Plan ${plan.planNo} ` + getMessage('plan.message.confirm.delete'),
type: 'confirm',
@ -50,7 +52,7 @@ export default function CanvasLayout({ children }) {
handleDeletePlan(e, plan)
},
})
}
}}
></i>
)}
</button>

View File

@ -112,7 +112,7 @@ export default function CanvasMenu(props) {
const params = {
objectNo: objectNo,
planNo: pid,
planNo: selectedPlan.planNo,
schDownload: donwloadType,
schDrawingFlg: drawingFlg,
pwrGnrSimType: pwrGnrSimTypeRecoil.type,
@ -156,6 +156,7 @@ export default function CanvasMenu(props) {
text: getMessage('stuff.detail.move.confirmMsg'),
type: 'confirm',
confirmFn: () => {
setIsGlobalLoading(true)
router.push(`/management/stuff/detail?objectNo=${objectNo}`, { scroll: false })
},
})
@ -172,38 +173,51 @@ export default function CanvasMenu(props) {
setType('surface')
break
case 4:
if (!checkMenuAndCanvasState()) {
swalFire({ text: getMessage('menu.validation.canvas.roof') })
return
console.log('🚀 ~ onClickNav ~ menu:', menu)
console.log('🚀 ~ onClickNav ~ menuNumber:', menuNumber)
if (menuNumber < menu.index) {
if (!checkMenuAndCanvasState()) {
swalFire({ text: getMessage('menu.validation.canvas.roof') })
return
} else {
setType('module')
}
} else {
setType('module')
router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`)
}
break
case 5:
// let pid = urlParams.get('pid')
setIsGlobalLoading(true)
// (useEstimateController.js) setIsGlobalLoading(false)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
// if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
if (estimateDetail.estimateDate !== null) {
setMenuNumber(menu.index)
setCurrentMenu(menu.title)
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
router.push(`/floor-plan/estimate/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
} else {
setIsGlobalLoading(false)
swalFire({ text: getMessage('estimate.menu.move.valid1') })
}
}
})
break
case 6:
setIsGlobalLoading(true)
// (Simulator.jsx) setIsGlobalLoading(false)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
if (estimateDetail.tempFlg === '0') {
if (estimateDetail.estimateDate !== null) {
setMenuNumber(menu.index)
setCurrentMenu(menu.title)
router.push(`/floor-plan/simulator/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
} else {
setIsGlobalLoading(false)
swalFire({ text: getMessage('simulator.menu.move.valid1') })
}
}
@ -215,9 +229,10 @@ export default function CanvasMenu(props) {
setMenuNumber(menu.index)
setCurrentMenu(menu.title)
}
if (pathname !== '/floor-plan') {
if (menu.index !== 0) {
// if (menu.index !== 0 ) {
// or ..
if (menu.index !== 0 && menu.index !== 5 && menu.index !== 6) {
router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`)
}
}
@ -257,7 +272,7 @@ export default function CanvasMenu(props) {
// (btn08)
const handleSaveCanvas = async () => {
await saveCanvas()
await saveCanvas(true)
}
//
@ -312,15 +327,15 @@ export default function CanvasMenu(props) {
confirmFn: async () => {
setIsGlobalLoading(true)
const params = {
objectNo: objectNo,
planNo: pid,
objectNo: estimateRecoilState.objectNo,
planNo: estimateRecoilState.planNo,
userId: sessionState.userId,
}
try {
await promisePost({ url: '/api/estimate/reset-estimate', data: params }).then((res) => {
if (res.status === 201) {
swalFire({ text: getMessage('estimate.detail.reset.alertMsg'), type: 'alert' })
fetchSetting(objectNo, pid, 'R')
fetchSetting(estimateRecoilState.objectNo, estimateRecoilState.planNo, 'R')
}
})
} catch (error) {
@ -359,9 +374,14 @@ export default function CanvasMenu(props) {
}, [basicSetting])*/
const checkMenuState = (menu) => {
return (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2)
return (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && [1, 2].includes(menu.index))
}
/**
* 모듈, 회로 구성 이전 메뉴에서 메뉴 클릭으로 넘어올때
* 지붕면 할당이 끝난 지붕이 하나라도 있는지 체크
* @returns {boolean}
*/
const checkMenuAndCanvasState = () => {
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
//
@ -372,40 +392,109 @@ export default function CanvasMenu(props) {
useEffect(() => {
if (isObjectNotEmpty(estimateRecoilState)) {
if (estimateRecoilState?.createUser === 'T01') {
if (sessionState.userId !== 'T01') {
setButtonStyle1('none')
setButtonStyle2('none')
setButtonStyle3('none')
setButtonStyle4('none')
setButtonStyle5('none')
}
} else {
if (estimateRecoilState?.tempFlg === '1') {
setButtonStyle1('none')
setButtonStyle2('')
setButtonStyle3('none')
setButtonStyle4('none')
setButtonStyle5('none')
} else {
if (estimateRecoilState?.tempFlg === '0' && estimateRecoilState?.lockFlg === '0') {
setButtonStyle1('')
setButtonStyle2('')
setButtonStyle3('')
setButtonStyle4('')
setButtonStyle5('')
const { createUser, tempFlg, lockFlg } = estimateRecoilState
if (createUser && tempFlg && lockFlg) {
if (createUser === 'T01') {
if (sessionState.storeId !== 'T01') {
setAllButtonStyles('none')
} else {
setButtonStyle1('')
setButtonStyle2('none')
setButtonStyle3('none')
setButtonStyle4('')
setButtonStyle5('')
handleButtonStyles(tempFlg, lockFlg)
}
} else {
handleButtonStyles(tempFlg, lockFlg)
}
}
}
}, [estimateRecoilState])
const setAllButtonStyles = (style) => {
setButtonStyle1(style)
setButtonStyle2(style)
setButtonStyle3(style)
setButtonStyle4(style)
setButtonStyle5(style)
}
const handleButtonStyles = (tempFlg, lockFlg) => {
if (tempFlg === '1') {
setAllButtonStyles('none')
setButtonStyle2('')
} else if (tempFlg === '0' && lockFlg === '0') {
setAllButtonStyles('')
} else {
setButtonStyle1('')
setButtonStyle2('none')
setButtonStyle3('none')
setButtonStyle4('')
setButtonStyle5('')
}
}
// useEffect(() => {
// if (isObjectNotEmpty(estimateRecoilState)) {
// if (estimateRecoilState?.createUser && estimateRecoilState?.tempFlg && estimateRecoilState.lockFlg) {
// if (estimateRecoilState?.createUser === 'T01') {
// if (sessionState.storeId !== 'T01') {
// setButtonStyle1('none')
// setButtonStyle2('none')
// setButtonStyle3('none')
// setButtonStyle4('none')
// setButtonStyle5('none')
// } else {
// if (estimateRecoilState?.tempFlg === '1') {
// setButtonStyle1('none')
// setButtonStyle2('')
// setButtonStyle3('none')
// setButtonStyle4('none')
// setButtonStyle5('none')
// } else {
// if (estimateRecoilState?.tempFlg === '0' && estimateRecoilState?.lockFlg === '0') {
// setButtonStyle1('')
// setButtonStyle2('')
// setButtonStyle3('')
// setButtonStyle4('')
// setButtonStyle5('')
// } else {
// setButtonStyle1('')
// setButtonStyle2('none')
// setButtonStyle3('none')
// setButtonStyle4('')
// setButtonStyle5('')
// }
// }
// }
// } else {
// if (isObjectNotEmpty(estimateRecoilState)) {
// if (estimateRecoilState?.tempFlg && estimateRecoilState.lockFlg) {
// if (estimateRecoilState?.tempFlg === '1') {
// setButtonStyle1('none')
// setButtonStyle2('')
// setButtonStyle3('none')
// setButtonStyle4('none')
// setButtonStyle5('none')
// } else {
// if (estimateRecoilState?.tempFlg === '0' && estimateRecoilState?.lockFlg === '0') {
// setButtonStyle1('')
// setButtonStyle2('')
// setButtonStyle3('')
// setButtonStyle4('')
// setButtonStyle5('')
// } else {
// setButtonStyle1('')
// setButtonStyle2('none')
// setButtonStyle3('none')
// setButtonStyle4('')
// setButtonStyle5('')
// }
// }
// }
// }
// }
// }
// }
// }, [estimateRecoilState])
/**
* 견적서 잠금 / 해제
* lockFlg : 0 잠금해제상태 / 1 잠금상태
@ -415,7 +504,6 @@ export default function CanvasMenu(props) {
*/
const handleEstimateLockController = (estimateRecoilState) => {
swalFire({
// text: estimateRecoilState.lockFlg === '0' ? getMessage('estimate.detail.lock.alertMsg') : getMessage('estimate.detail.unlock.alertMsg'),
html: estimateRecoilState.lockFlg === '0' ? getMessage('estimate.detail.lock.alertMsg') : getMessage('estimate.detail.unlock.alertMsg'),
confirmButtonText: estimateRecoilState.lockFlg === '1' ? getMessage('estimate.detail.unlock.confirmBtnName') : '',
type: 'confirm',
@ -431,37 +519,49 @@ export default function CanvasMenu(props) {
await promisePost({ url: '/api/estimate/save-estimate-lock', data: params }).then((res) => {
if (res.status === 201) {
estimateRecoilState.lockFlg = estimateRecoilState.lockFlg === '0' ? '1' : '0'
if (estimateRecoilState?.createUser === 'T01') {
if (sessionState.userId !== 'T01') {
setButtonStyle1('none')
setButtonStyle2('none')
setButtonStyle3('none')
setButtonStyle4('none')
setButtonStyle5('none')
}
} else {
if (estimateRecoilState?.tempFlg === '1') {
setButtonStyle1('none')
setButtonStyle2('')
setButtonStyle3('none')
setButtonStyle4('none')
setButtonStyle5('none')
} else {
if (estimateRecoilState?.tempFlg === '0' && estimateRecoilState?.lockFlg === '0') {
setButtonStyle1('')
setButtonStyle2('')
setButtonStyle3('')
setButtonStyle4('')
setButtonStyle5('')
const { createUser, tempFlg, lockFlg } = estimateRecoilState
if (createUser && tempFlg && lockFlg) {
if (createUser === 'T01') {
if (sessionState.storeId !== 'T01') {
setAllButtonStyles('none')
} else {
setButtonStyle1('')
setButtonStyle2('none')
setButtonStyle3('none')
setButtonStyle4('')
setButtonStyle5('')
handleButtonStyles(tempFlg, lockFlg)
}
} else {
handleButtonStyles(tempFlg, lockFlg)
}
}
// if (estimateRecoilState?.createUser === 'T01') {
// if (sessionState.storeId !== 'T01') {
// setButtonStyle1('none')
// setButtonStyle2('none')
// setButtonStyle3('none')
// setButtonStyle4('none')
// setButtonStyle5('none')
// }
// } else {
// if (estimateRecoilState?.tempFlg === '1') {
// setButtonStyle1('none')
// setButtonStyle2('')
// setButtonStyle3('none')
// setButtonStyle4('none')
// setButtonStyle5('none')
// } else {
// if (estimateRecoilState?.tempFlg === '0' && estimateRecoilState?.lockFlg === '0') {
// setButtonStyle1('')
// setButtonStyle2('')
// setButtonStyle3('')
// setButtonStyle4('')
// setButtonStyle5('')
// } else {
// setButtonStyle1('')
// setButtonStyle2('none')
// setButtonStyle3('none')
// setButtonStyle4('')
// setButtonStyle5('')
// }
// }
// }
}
setIsGlobalLoading(false)
})
@ -493,7 +593,7 @@ export default function CanvasMenu(props) {
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
onClick={() => {
if (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) return
if (menuNumber === 4 && menu.index === 2) return
if (menuNumber === 4 && [1, 2].includes(menu.index)) return
onClickNav(menu)
}}
>
@ -572,20 +672,17 @@ export default function CanvasMenu(props) {
{menuNumber === 5 && (
<>
<div className="ico-btn-from">
{/* <button className="btn-frame gray ico-flx" onClick={() => setEstimatePopupOpen(true)}> */}
<button type="button" style={{ display: buttonStyle1 }} className="btn-frame gray ico-flx" onClick={() => setEstimatePopupOpen(true)}>
<span className="ico ico01"></span>
<span className="name">{getMessage('plan.menu.estimate.docDown')}</span>
</button>
<button type="button" style={{ display: buttonStyle2 }} className="btn-frame gray ico-flx" onClick={handleEstimateSubmit}>
{/* <button type="button" style={{ display: buttonStyle }} className="btn-frame gray ico-flx" onClick={handleEstimateSubmit}> */}
<span className="ico ico02"></span>
<span className="name">{getMessage('plan.menu.estimate.save')}</span>
</button>
<button
type="button"
style={{ display: buttonStyle3 }}
// style={{ display: buttonStyle }}
className="btn-frame gray ico-flx"
onClick={() => {
handleEstimateReset()
@ -599,7 +696,6 @@ export default function CanvasMenu(props) {
<button
type="button"
style={{ display: buttonStyle4 }}
// style={{ display: buttonStyle }}
className="btn-frame gray ico-flx"
onClick={() => {
setEstimateCopyPopupOpen(true)
@ -612,10 +708,8 @@ export default function CanvasMenu(props) {
<button
type="button"
style={{ display: buttonStyle5 }}
// style={{ display: buttonStyle }}
className="btn-frame gray ico-flx"
onClick={() => {
//
handleEstimateLockController(estimateRecoilState)
}}
>

View File

@ -26,7 +26,7 @@ export default function MenuDepth01() {
useEffect(() => {
handleMenu(type)
canvas.discardActiveObject()
canvas?.discardActiveObject()
}, [currentMenu])
return (
<div className="canvas-depth2-inner">

View File

@ -30,7 +30,7 @@ const ALLOCATION_TYPE = {
export default function CircuitTrestleSetting({ id }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const { apply } = useTrestle()
const { apply, setViewCircuitNumberTexts } = useTrestle()
const { swalFire } = useSwal()
const { saveEstimate } = useEstimate()
const canvas = useRecoilValue(canvasState)
@ -94,14 +94,14 @@ export default function CircuitTrestleSetting({ id }) {
// PCS
getPcsAutoRecommendList(params).then((res) => {
if (res.data?.pcsItemList) {
const itemList = models.filter((model) => {
return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
})
const selectedModels = itemList.map((model) => {
return {
...model,
id: uuidv4(),
isUsed: false,
let pcsItemList = []
res.data?.pcsItemList.forEach((item) => {
if (models.map((model) => model.itemId).includes(item.itemId)) {
pcsItemList.push({
...item,
id: uuidv4(),
isUsed: false,
})
}
})
//
@ -112,7 +112,7 @@ export default function CircuitTrestleSetting({ id }) {
pcsItemList: getPcsItemList(),
}
//
setSelectedModels(selectedModels)
setSelectedModels(pcsItemList)
//
getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
if (res.resultCode === 'S') {
@ -205,24 +205,26 @@ export default function CircuitTrestleSetting({ id }) {
const getRoofSurfaceList = () => {
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
return roofSurfaceList.map((obj) => {
return {
roofSurfaceId: obj.id,
roofSurface: canvas
.getObjects()
.filter((o) => o.id === obj.parentId)[0]
.directionText.replace(/[0-9]/g, ''),
roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
moduleList: getModuleList(obj).map((module) => {
return {
itemId: module.moduleInfo.itemId,
circuit: module.circuitNumber ? module.circuitNumber : null,
pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
uniqueId: module.id ? module.id : null,
}
}),
}
})
return roofSurfaceList
.map((obj) => {
return {
roofSurfaceId: obj.id,
roofSurface: canvas
.getObjects()
.filter((o) => o.id === obj.parentId)[0]
.directionText.replace(/[0-9]/g, ''),
roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
moduleList: getModuleList(obj).map((module) => {
return {
itemId: module.moduleInfo.itemId,
circuit: module.circuitNumber ? module.circuitNumber : null,
pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
uniqueId: module.id ? module.id : null,
}
}),
}
})
.filter((surface) => surface.moduleList.length > 0)
}
//
@ -338,7 +340,18 @@ export default function CircuitTrestleSetting({ id }) {
const params = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(),
roofSurfaceList: getRoofSurfaceList().map((surface) => {
console.log(surface.moduleList)
return {
...surface,
moduleList: surface.moduleList.map((module) => {
return {
itemId: module.itemId,
uniqueId: module.uniqueId,
}
}),
}
}),
pcsItemList: getPcsItemList(),
}
@ -348,19 +361,34 @@ export default function CircuitTrestleSetting({ id }) {
const itemList = models.filter((model) => {
return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
})
const selectedModels = itemList.map((model) => {
return {
...model,
id: uuidv4(),
let pcsItemList = []
let pcsObj = {}
models.forEach((model) => {
pcsObj[model.itemId] = model
})
res.data?.pcsItemList.forEach((item) => {
if (pcsObj[item.itemId]) {
pcsItemList.push({
...pcsObj[item.itemId],
isUsed: false,
id: uuidv4(),
})
}
})
const pcsVoltageChkParams = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(),
pcsItemList: getPcsItemList(),
pcsItemList: pcsItemList.map((item) => {
return {
itemId: item.itemId,
pcsMkrCd: item.pcsMkrCd,
pcsSerCd: item.pcsSerCd,
}
}),
}
setSelectedModels(selectedModels)
setSelectedModels(pcsItemList)
getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
})
@ -422,11 +450,18 @@ export default function CircuitTrestleSetting({ id }) {
obj.pcses = getStepUpListData()
})
setViewCircuitNumberTexts(false)
//TODO :
const result = await apply()
if (result) {
// TODO :
setViewCircuitNumberTexts(true)
await saveEstimate(result)
}
removeNotAllocationModules()
// removeNotAllocationModules()
}
const removeNotAllocationModules = () => {
@ -536,37 +571,21 @@ export default function CircuitTrestleSetting({ id }) {
//
const handleClose = () => {
swalFire({
title: '변경사항을 저장하시겠습니까?',
//text: ' .',
type: 'confirm',
confirmButtonText: '저장',
cancelButtonText: '취소',
icon: 'warning',
confirmFn: async () => {
//
await onApply()
closePopup(id)
},
denyFn: () => {
//
const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
canvas.remove(...circuitTexts)
// //
const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
canvas.remove(...circuitTexts)
//
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE)
.forEach((obj) => {
obj.circuit = null
obj.pcsItemId = null
obj.circuitNumber = null
})
//
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE)
.forEach((obj) => {
obj.circuit = null
obj.pcsItemId = null
obj.circuitNumber = null
})
canvas.renderAll()
closePopup(id)
},
})
canvas.renderAll()
closePopup(id)
}
return (
@ -592,7 +611,7 @@ export default function CircuitTrestleSetting({ id }) {
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
<div className="grid-btn-wrap">
<button className="btn-frame modal mr5" onClick={() => onAutoRecommend()}>
<button className="btn-frame modal mr5 act" onClick={() => onAutoRecommend()}>
{getMessage('modal.circuit.trestle.setting.circuit.allocation.auto')}
</button>
<button className="btn-frame modal act" onClick={() => onPassivityAllocation()}>
@ -602,7 +621,7 @@ export default function CircuitTrestleSetting({ id }) {
)}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
<div className="grid-btn-wrap">
<button className="btn-frame modal mr5" onClick={() => onClickPrev()}>
<button className="btn-frame modal mr5 " onClick={() => onClickPrev()}>
{getMessage('modal.common.prev')}
</button>
<button className="btn-frame modal act" onClick={() => setTabNum(2)}>

View File

@ -91,7 +91,6 @@ export default function PowerConditionalSelect(props) {
}
const onCheckSeries = (data) => {
console.log('data', data)
const copySeries = series.map((s) => {
return {
...s,
@ -99,12 +98,10 @@ export default function PowerConditionalSelect(props) {
}
})
setSeries(copySeries)
console.log('copySeries', copySeries)
handleSetmodels(copySeries.filter((s) => s.selected))
}
const handleSetmodels = (selectedSeries) => {
console.log('series', selectedSeries)
if (selectedSeries.length === 0) {
setModels([])
setSelectedModels([])
@ -149,7 +146,7 @@ export default function PowerConditionalSelect(props) {
return
}
setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4() }])
setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }])
setSelectedRow(null)
}
@ -160,10 +157,10 @@ export default function PowerConditionalSelect(props) {
const onChangeMaker = (option) => {
if (option) {
setModels([])
setSelectedModels([])
setSelectedMaker(option)
getPcsMakerList(option).then((res) => {
console.log('getPcsMakerList(series)', res.data)
setSeries(
res.data.map((series) => {
return { ...series, selected: false }

View File

@ -12,6 +12,7 @@ import { useMasterController } from '@/hooks/common/useMasterController'
import { v4 as uuidv4 } from 'uuid'
import { globalLocaleStore } from '@/store/localeAtom'
import { POLYGON_TYPE } from '@/common/common'
import { circuitNumDisplaySelector } from '@/store/settingAtom'
export default function StepUp(props) {
const {
@ -32,7 +33,7 @@ export default function StepUp(props) {
const [moduleTabs, setModuleTabs] = useState({})
const [arrayLength, setArrayLength] = useState(3) //module-table-inner
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()
const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk, getPcsConnOptionItemList } = useMasterController()
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const canvas = useRecoilValue(canvasState)
const selectedModules = useRecoilValue(selectedModuleState)
@ -43,7 +44,7 @@ export default function StepUp(props) {
//
const [selectedValues, setSelectedValues] = useState({})
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
// useCanvasPopupStatusController(6)
// const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore)
// if (Object.keys(canvasPopupStatusState[6]).length !== 0) {
@ -51,20 +52,19 @@ export default function StepUp(props) {
// }
useEffect(() => {
// PCS
console.log(allocationType)
if (allocationType === 'auto') {
fetchStepUpData()
// PCS
fetchAutoStepUpData()
} else {
// 1-1 2-2
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
.map((module) => module.circuitNumber)
// PCS
fetchPassiStepUpData()
}
}, [])
// PCS
const fetchStepUpData = async () => {
// PCS
const fetchAutoStepUpData = async () => {
try {
const params = {
...props.getOptYn(), // Y/N
@ -106,6 +106,89 @@ export default function StepUp(props) {
}
}
// PCS
const fetchPassiStepUpData = async () => {
try {
// 1-1 2-2
// canvas
// .getObjects()
// .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
// .map((module) => module.circuitNumber)
//
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
// PCS
const pcsSummary = {}
// PCS
modules.forEach((module) => {
if (!module.circuit || !module.pcsItemId) return
if (!pcsSummary[module.pcsItemId]) {
pcsSummary[module.pcsItemId] = {
circuits: {},
totalModules: 0,
}
}
const circuitNumber = module.circuitNumber
if (!pcsSummary[module.pcsItemId].circuits[circuitNumber]) {
pcsSummary[module.pcsItemId].circuits[circuitNumber] = 0
}
pcsSummary[module.pcsItemId].circuits[circuitNumber]++
pcsSummary[module.pcsItemId].totalModules++
})
const params = {
useModuleItemList: props.getUseModuleItemList(),
pcsItemList: getSelectedPcsItemList(),
}
// PCS
getPcsConnOptionItemList(params).then((res) => {
if (res?.result.code === 200 && res?.data) {
// PCS serQtyList
const pcsItemListWithSerQty = res.data.pcsItemList.map((pcsItem) => {
const pcsData = pcsSummary[pcsItem.itemId] || { circuits: {}, totalModules: 0 }
const circuitCounts = Object.values(pcsData.circuits)
return {
...pcsItem,
serQtyList: [
{
//
serQty: circuitCounts.length > 0 ? Math.max(...circuitCounts) : 0,
//
paralQty: Object.keys(pcsData.circuits).length || 0,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: props.getRoofSurfaceList(),
},
],
}
})
// Update res.data with modified pcsItemList
res.data.pcsItemList = pcsItemListWithSerQty
setSelectedModels(pcsItemListWithSerQty)
const dataArray = Array.isArray(res.data) ? res.data : [res.data]
const stepUpListData = formatStepUpListData(dataArray)
// PCS SET
setStepUpListData(stepUpListData)
// PCS
const formattedOptCodes = formatOptionCodes(res.data.optionList)
setOptCodes(formattedOptCodes)
setSeletedOption(formattedOptCodes[0])
}
})
} catch (error) {
console.error('Error fetching step up data:', error)
}
}
// PCS
const formatOptionCodes = (optionList = []) => {
return optionList?.map((opt) => ({
@ -124,40 +207,6 @@ export default function StepUp(props) {
selectedPcsItem: formatPcsItemList(stepUps.pcsItemList),
}))
// selectedValues
const initialSelectedValues = {}
formattedData.forEach((stepUp) => {
stepUp.pcsItemList.forEach((pcsItem, pcsIdx) => {
const pcsKey = `${pcsItem.goodsNo}_${pcsIdx}`
// (rmdYn === 'Y')
const recommendedRow = pcsItem.serQtyList.find((item) => item.rmdYn === 'Y')
if (recommendedRow) {
const selectionData = {
stepUpId: pcsItem.goodsNo,
pcsInfo: {
itemId: pcsItem.itemId,
goodsNo: pcsItem.goodsNo,
pcsMkrCd: pcsItem.pcsMkrCd,
pcsSerCd: pcsItem.pcsSerCd,
},
allocation: {
serQty: recommendedRow.serQty,
paralQty: recommendedRow.paralQty,
},
}
initialSelectedValues[pcsItem.goodsNo] = {
...initialSelectedValues[pcsItem.goodsNo],
[pcsKey]: selectionData,
}
}
})
})
// selectedValues
setSelectedValues(initialSelectedValues)
return formattedData
}
@ -239,8 +288,12 @@ export default function StepUp(props) {
//
const handleRowClick = (mainIdx, subIdx) => {
//
if (allocationType !== 'auto') return
let tempStepUpListData = [...stepUpListData]
let selectedData = {}
tempStepUpListData[0].pcsItemList[mainIdx].serQtyList.forEach((item, index) => {
if (index === subIdx) {
selectedData = item
@ -323,6 +376,7 @@ export default function StepUp(props) {
name: 'circuitNumber',
parentId: targetModule.id,
circuitInfo: module.pcsItemId,
visible: isDisplayCircuitNumber,
})
targetModule.circuit = moduleCircuitText
targetModule.pcsItemId = module.pcsItemId
@ -399,7 +453,7 @@ export default function StepUp(props) {
key={`row-${serQtyIdx}`}
className={`${item.selected ? 'on' : ''}`}
onClick={() => handleRowClick(idx, serQtyIdx)}
style={{ cursor: 'pointer' }}
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
>
<td className="al-r">{item.serQty}</td>
<td className="al-r">{item.paralQty}</td>

View File

@ -7,6 +7,7 @@ import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { circuitNumDisplaySelector } from '@/store/settingAtom'
import { useContext, useEffect, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
@ -29,6 +30,7 @@ export default function PassivityCircuitAllocation(props) {
const [targetModules, setTargetModules] = useState([])
const { setModuleStatisticsData } = useModule()
const { getPcsManualConfChk } = useMasterController()
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
useEffect(() => {
console.log('header, rows', header, rows)
@ -79,36 +81,36 @@ export default function PassivityCircuitAllocation(props) {
const setSurfaceInfo = () => {
const surfaces = canvas.getObjects().filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name)
// setHeaders([header[0], { name: '', prop: 'circuit' }, ...header.slice(1)])
setRows(
rows.map((row) => {
return {
...row,
circuit: '',
}
}),
)
let totals = {}
// setRows(
// rows.map((row) => {
// return {
// ...row,
// circuit: '',
// }
// }),
// )
// let totals = {}
rows.forEach((row) => {
if (header.length === 4) {
if (!totals[header[2].prop]) totals[header[2].prop] = 0
totals[header[2].prop] += +row[header[2].prop]
} else if (header.length === 5) {
if (!totals[header[2].prop]) totals[header[2].prop] = 0
totals[header[2].prop] += +row[header[2].prop]
if (!totals[header[3].prop]) totals[header[3].prop] = 0
totals[header[3]] += +row[header[3]]
}
})
setFooter([
...['합계', ''],
...Object.keys(totals).map((key) => {
return totals[key]
}),
Object.keys(totals).reduce((acc, key) => {
return acc + totals[key]
}, 0),
])
// rows.forEach((row) => {
// if (header.length === 4) {
// if (!totals[header[2].prop]) totals[header[2].prop] = 0
// totals[header[2].prop] += +row[header[2].prop]
// } else if (header.length === 5) {
// if (!totals[header[2].prop]) totals[header[2].prop] = 0
// totals[header[2].prop] += +row[header[2].prop]
// if (!totals[header[3].prop]) totals[header[3].prop] = 0
// totals[header[3]] += +row[header[3]]
// }
// })
// setFooter([
// ...['', ''],
// ...Object.keys(totals).map((key) => {
// return totals[key]
// }),
// Object.keys(totals).reduce((acc, key) => {
// return acc + totals[key]
// }, 0),
// ])
// let totalWpout = 0
// const rows = surfaces.map((surface) => {
// let wpOut = 0
@ -215,6 +217,7 @@ export default function PassivityCircuitAllocation(props) {
name: 'circuitNumber',
parentId: obj.id,
circuitInfo: selectedPcs,
visible: isDisplayCircuitNumber,
})
obj.set({
strokeWidth: 0.3,
@ -226,10 +229,23 @@ export default function PassivityCircuitAllocation(props) {
setSelectedPcs(tempSelectedPcs)
canvas.add(moduleCircuitText)
})
console.log('🚀 ~ handleCircuitNumberFix ~ selectedModels:', selectedModels)
// let pcsList = [...selectedModels.map((model) => ({ ...model }))]
let pcsList = JSON.parse(JSON.stringify(selectedModels))
pcsList = pcsList.map((model) => {
console.log('🚀 ~ handleCircuitNumberFix ~ pcsList:', pcsList)
if (model.id === selectedPcs.id) {
model.isUsed = true
}
return model
})
console.log('🚀 ~ handleCircuitNumberFix ~ pcsList:', pcsList)
const roofSurfaceList = canvas
.getObjects()
.filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name)
.filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0)
.map((surface) => {
return {
roofSurfaceId: surface.id,
@ -246,45 +262,25 @@ export default function PassivityCircuitAllocation(props) {
})
console.log('uniqueCircuitNumbers', uniqueCircuitNumbers)
const usedPcses = selectedModels.filter((model) => model.isUsed)
const pcsItemList =
usedPcses.length === 0
? [
{
pcsMkrCd: selectedPcs.pcsMkrCd,
pcsSerCd: selectedPcs.pcsSerCd,
itemId: selectedPcs.itemId,
itemNm: selectedPcs.itemNm,
goodsNo: selectedPcs.goodsNo,
serQtyList: [
{
serQty: targetModules.length,
paralQty: uniqueCircuitNumbers.length,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: roofSurfaceList,
},
],
},
]
: selectedModels.map((model, index) => {
return {
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
itemId: model.itemId,
itemNm: model.itemNm,
goodsNo: model.goodsNo,
serQtyList: [
{
serQty: targetModules.length,
paralQty: uniqueCircuitNumbers.length,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: roofSurfaceList,
},
],
}
})
const usedPcses = pcsList.filter((model) => model.isUsed)
const pcsItemList = usedPcses.map((model, index) => {
return {
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
itemId: model.itemId,
itemNm: model.itemNm,
goodsNo: model.goodsNo,
serQtyList: [
{
serQty: targetModules.length,
paralQty: uniqueCircuitNumbers.length,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: roofSurfaceList,
},
],
}
})
const params = {
...getApiProps(),
@ -318,17 +314,15 @@ export default function PassivityCircuitAllocation(props) {
return
}
setSelectedModels(
selectedModels.map((model) => {
return { ...model, isUsed: model.id === selectedPcs.id ? true : model.isUsed }
}),
)
setSelectedModels(pcsList)
setTargetModules([])
setCircuitNumber(+circuitNumber + 1)
setModuleStatisticsData()
})
}
console.log('🚀 ~ handleCircuitNumberFix ~ selectedModels:', selectedModels)
console.log('🚀 ~ handleCircuitNumberFix ~ selectedModels:', selectedModels)
const getCircuitNumber = () => {
if (selectedModels.length === 1) {

View File

@ -1,10 +1,12 @@
'use client'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
import { useRecoilValue, useResetRecoilState } from 'recoil'
import { useModule } from '@/hooks/module/useModule'
import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit'
export default function PanelBatchStatistics() {
const { getMessage } = useMessage()
@ -14,6 +16,11 @@ export default function PanelBatchStatistics() {
y: 30,
})
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const { setModuleStatisticsData } = useModule()
useEffect(() => {
setModuleStatisticsData()
}, [])
return (
<WithDraggable isShow={true} handle=".penal-wrap" pos={pos}>

View File

@ -116,22 +116,25 @@ export default function ContextRoofAllocationSetting(props) {
)}
</div>
</div>
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('slope')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangePitch(e, index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
{roof.raftAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
{raftCodes.length > 0 && (
<div className="grid-select">
<QSelectBox
options={raftCodes}
value={roof}
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
/>
</div>
)}
</div>
<span className="absol">{pitchText}</span>
</div>
</div>
)}
{(roof.widAuth || roof.lenAuth) && (
<>
{roof.widAuth && (
@ -139,7 +142,15 @@ export default function ContextRoofAllocationSetting(props) {
<div className="flex-ment">
<span>W</span>
<div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
<input
type="text"
className="input-origin block"
defaultValue={roof.width}
readOnly={roof.widAuth === 'R'}
onChange={(e) => {
handleChangeInput(e, 'width', index)
}}
/>
</div>
</div>
</div>
@ -148,44 +159,15 @@ export default function ContextRoofAllocationSetting(props) {
<div className="block-box">
<div className="flex-ment">
<span>L</span>
<div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
</div>
</div>
</div>
)}
</>
)}
{(roof.raftAuth || roof.roofPchAuth) && (
<>
{roof.raftAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
{raftCodes.length > 0 && (
<div className="grid-select">
<QSelectBox
options={raftCodes}
value={roof}
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
/>
</div>
)}
</div>
</div>
)}
{roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
defaultValue={roof.length}
readOnly={roof.lenAuth === 'R'}
onChange={(e) => {
handleChangeInput(e, 'length', index)
}}
/>
</div>
</div>
@ -193,6 +175,39 @@ export default function ContextRoofAllocationSetting(props) {
)}
</>
)}
{roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
onChange={(e) => handleChangeInput(e, 'hajebichi', index)}
/>
</div>
</div>
</div>
)}
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('slope')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
handleChangePitch(e, index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
</div>
<span className="absol">{pitchText}</span>
</div>
</div>
<div className="block-box">
<div className="icon-btn-wrap">
<button

View File

@ -33,7 +33,6 @@ export default function RoofAllocationSetting(props) {
handleChangeLayout,
currentRoofList,
handleChangeInput,
handleChangePitch,
} = useRoofAllocationSetting(id)
const pitchText = useRecoilValue(pitchTextSelector)
const { findCommonCode } = useCommonCode()
@ -118,22 +117,27 @@ export default function RoofAllocationSetting(props) {
)}
</div>
</div>
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('slope')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangePitch(e, index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
{roof.raftAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
{raftCodes.length > 0 && (
<div className="grid-select">
<QSelectBox
options={raftCodes}
value={roof}
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
onChange={(e) => handleChangeRaft(e, index)}
/>
</div>
)}
</div>
<span className="absol">{pitchText}</span>
</div>
</div>
)}
{(roof.widAuth || roof.lenAuth) && (
<>
{roof.widAuth && (
@ -170,45 +174,38 @@ export default function RoofAllocationSetting(props) {
)}
</>
)}
{(roof.raftAuth || roof.roofPchAuth) && (
<>
{roof.raftAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
{raftCodes.length > 0 && (
<div className="grid-select">
<QSelectBox
options={raftCodes}
value={roof}
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
onChange={(e) => handleChangeRaft(e, index)}
/>
</div>
)}
</div>
{roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => handleChangeInput(e, 'hajebichi', index)}
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
/>
</div>
)}
{roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => handleChangeInput(e, 'hajebichi', index)}
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
/>
</div>
</div>
</div>
)}
</>
</div>
</div>
)}
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('slope')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangePitch(e, index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
</div>
<span className="absol">{pitchText}</span>
</div>
</div>
<div className="block-box">
<div className="icon-btn-wrap">
<button

View File

@ -176,7 +176,6 @@ export default function Simulator() {
const [content, setContent] = useState('')
const fetchSimulatorNotice = async () => {
setIsGlobalLoading(true)
get({ url: '/api/pwrGnrSimulation/guideInfo' }).then((res) => {
if (res.data) {
setContent(res.data.replaceAll('\n', '<br/>'))
@ -184,7 +183,6 @@ export default function Simulator() {
setContent(getMessage('common.message.no.data'))
}
})
setIsGlobalLoading(false)
}
// , list type

View File

@ -241,6 +241,18 @@ export function useMasterController() {
return await put({ url: '/api/object/update-object-date', data: params })
}
/**
* PCS 접속함 옵션 목록 조회
* @param {사용된 모듈 아이템 목록} useModuleItemList
* @param {PCS 제품 목록} pcsItemList
* @returns
*/
const getPcsConnOptionItemList = async (params = null) => {
return await post({ url: '/api/v1/master/getPcsConnOptionItemList', data: params }).then((res) => {
return res
})
}
return {
getRoofMaterialList,
getModuleTypeItemList,
@ -255,5 +267,6 @@ export function useMasterController() {
getPcsVoltageStepUpList,
updateObjectDate,
getQuotationItem,
getPcsConnOptionItemList,
}
}

View File

@ -66,15 +66,20 @@ export function useRefFiles() {
}
const refFileSetting = (file) => {
if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
// setRefImage(file)
file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file)
console.log('🚀 ~ refFileSetting ~ file:', file)
if (file.name.split('.').pop() === 'dwg') {
handleUploadConvertRefFile(file)
} else {
swalFire({
text: '이미지가 아닙니다.',
type: 'alert',
icon: 'error',
})
if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) {
// file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file)
handleUploadImageRefFile(file)
} else {
swalFire({
text: '이미지가 아닙니다.',
type: 'alert',
icon: 'error',
})
}
}
}
/**
@ -121,14 +126,13 @@ export function useRefFiles() {
}
const res = await get({
url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
url: `${process.env.NEXT_PUBLIC_HOST_URL}/map/convert?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
})
console.log('🚀 ~ handleMapImageDown ~ res:', res)
const file = await readImage(res.fileNm)
console.log('🚀 ~ handleMapImageDown ~ file:', file)
setCurrentBgImage(file)
// handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`)
// setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value }))
// const file = await readImage(res.fileNm)
// console.log('🚀 ~ handleMapImageDown ~ file:', file)
// setCurrentBgImage(file)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
}
/**
@ -158,7 +162,6 @@ export function useRefFiles() {
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
// const image = await readImage(res.filePath)
// console.log('🚀 ~ handleUploadImageRefFile ~ file:', image)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
setRefImage(file)
}
@ -171,15 +174,21 @@ export function useRefFiles() {
const formData = new FormData()
formData.append('file', file)
await promisePost({ url: converterUrl, data: formData })
.then((res) => {
convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData)
swalFire({ text: '파일 변환 성공' })
setRefImage(res.data.Files[0].FileData)
})
.catch((err) => {
swalFire({ text: '파일 변환 실패', icon: 'error' })
})
const res = await post({ url: converterUrl, data: formData })
console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
const result = await post({ url: `${process.env.NEXT_PUBLIC_HOST_URL}/cad/convert`, data: res })
console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${result.filePath}`)
setRefImage(res.Files[0].FileData)
// await promisePost({ url: converterUrl, data: formData })
// .then((res) => {
// convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData)
// swalFire({ text: '파일 변환 성공' })
// setRefImage(res.data.Files[0].FileData)
// })
// .catch((err) => {
// swalFire({ text: '파일 변환 실패', icon: 'error' })
// })
}
/**

View File

@ -16,7 +16,9 @@ export function useRoof() {
.filter((polygon) => polygon.name === 'roof')
.forEach((polygon) => {
if (allocDisplay) {
setSurfaceShapePattern(polygon, roofDisplay.column)
if (polygon.roofMaterial) {
setSurfaceShapePattern(polygon, roofDisplay.column, false, polygon.roofMaterial, true)
}
} else {
polygon.set('fill', null)
}

View File

@ -311,7 +311,10 @@ export function useModule() {
canvas.renderAll()
},
})
} else {
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
}
setModuleStatisticsData()
}
const moduleMultiCopy = (type, length, direction) => {
@ -385,6 +388,9 @@ export function useModule() {
canvas.renderAll()
},
})
} else {
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
setModuleStatisticsData()
}
}
@ -500,6 +506,7 @@ export function useModule() {
},
})
}
setModuleStatisticsData()
}
const moduleRowRemove = (type) => {
@ -615,6 +622,7 @@ export function useModule() {
},
})
}
setModuleStatisticsData()
}
const moduleColumnInsert = (type) => {
@ -710,6 +718,7 @@ export function useModule() {
},
})
}
setModuleStatisticsData()
}
const muduleRowInsert = (type) => {
@ -807,6 +816,7 @@ export function useModule() {
},
})
}
setModuleStatisticsData()
}
const alignModule = (type, surfaceArray) => {
@ -879,6 +889,7 @@ export function useModule() {
surface.set({ modules: modules })
canvas.remove(activeModule)
canvas.renderAll()
setModuleStatisticsData()
}
const moduleRoofRemove = (surfaceArray) => {
@ -961,10 +972,11 @@ export function useModule() {
}
const setModuleStatisticsData = () => {
if (selectedModules?.length === 0) return
const tempHeader = [
{ name: getMessage('simulator.table.sub1'), prop: 'name' },
{ name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
...selectedModules.itemList.map((module) => {
...selectedModules?.itemList?.map((module) => {
return {
name: module.itemNm,
prop: module.itemId,

View File

@ -5,7 +5,7 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { getDegreeByChon } from '@/util/canvas-util'
import { v4 as uuidv4 } from 'uuid'
import { useMasterController } from '@/hooks/common/useMasterController'
import { basicSettingState } from '@/store/settingAtom'
import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom'
import { useSwal } from '@/hooks/useSwal'
// 회로 및 가대설정
@ -15,8 +15,14 @@ export const useTrestle = () => {
const { getQuotationItem } = useMasterController()
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
const isTrestleDisplay = useRecoilValue(trestleDisplaySelector)
const { swalFire } = useSwal()
const apply = () => {
const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
if (notAllocationModules.length > 0) {
swalFire({ text: '回路番号が設定されていないモジュールがあります。 番号を設定しなおすか、 パネルを削除してください。', icon: 'error' })
return null
}
try {
//처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함.
// exposedBottomPoints는 노출 최하면 들의 centerPoint 배열.
@ -51,7 +57,7 @@ export const useTrestle = () => {
let { rackQty, rackIntvlPct, rackYn, cvrPlvrYn } = surface.trestleDetail
if (!rack) {
//25/01/16 기준 랙이 없는 경우는 그냥 안그려준다.
//25/02/06 가대없음의 경우 랙정보가 없음
return
}
@ -104,8 +110,6 @@ export const useTrestle = () => {
leftExposedHalfTopModules.length > 0 ||
rightExposedHalfTopPoints.length > 0
console.log('isChidory', isChidory)
if (plvrYn === 'N' && isChidory) {
alert('치조불가공법입니다.')
clear()
@ -135,6 +139,7 @@ export const useTrestle = () => {
selectable: false,
surfaceId: surface.id,
parentId: module.id,
visible: isTrestleDisplay,
})
canvas.add(eaveBar)
canvas.renderAll()
@ -165,6 +170,7 @@ export const useTrestle = () => {
selectable: false,
surfaceId: surface.id,
parentId: module.id,
visible: isTrestleDisplay,
})
canvas.add(halfEaveBar)
canvas.renderAll()
@ -193,6 +199,7 @@ export const useTrestle = () => {
strokeWidth: 4,
selectable: false,
parentId: module.id,
visible: isTrestleDisplay,
})
canvas.add(halfEaveBar)
canvas.renderAll()
@ -615,7 +622,21 @@ export const useTrestle = () => {
}
}
})
const params = { trestles: surfaces.map((surface) => surface.quotationParam), pcses }
const allModules = surfaces.map((surface) => surface.modules).flat()
// 모듈 파라미터 생성
const modules = getModulesParam(allModules)
const trestles = []
//가대 파라미터 생성
surfaces.forEach((surface) => {
if (surface.quotationParam) {
trestles.push(surface.quotationParam)
}
})
// trestles 배열에서 null인 경우 제거
const params = { trestles, pcses, modules }
//견적서 itemList 조회
const { data: itemList, data2, result } = await getQuotationItem(params)
@ -918,7 +939,7 @@ export const useTrestle = () => {
offsetX: 0,
offsetY: 0,
},
visible: isTrestleDisplay,
parentId: module.id,
surfaceId: surface.id,
supFitQty,
@ -952,6 +973,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@ -992,6 +1014,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen: rackLength,
@ -1022,6 +1045,7 @@ export const useTrestle = () => {
surfaceId: surface.id,
strokeWidth: 4,
selectable: false,
visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@ -1062,6 +1086,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen: rackLength,
@ -1090,6 +1115,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
strokeWidth: 4,
selectable: false,
supFitQty,
@ -1130,6 +1156,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty,
supFitIntvlPct,
rackLen,
@ -1158,6 +1185,7 @@ export const useTrestle = () => {
},
parentId: module.id,
surfaceId: surface.id,
visible: isTrestleDisplay,
strokeWidth: 4,
selectable: false,
supFitQty,
@ -1209,6 +1237,7 @@ export const useTrestle = () => {
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@ -1228,6 +1257,7 @@ export const useTrestle = () => {
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@ -1246,6 +1276,7 @@ export const useTrestle = () => {
top: y2 - bracketLength / 3,
fill: 'green',
parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id,
name: 'bracket',
width: bracketLength,
@ -1266,6 +1297,7 @@ export const useTrestle = () => {
fill: 'green',
name: 'bracket',
parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id,
width: bracketLength,
height: bracketLength,
@ -1431,6 +1463,7 @@ export const useTrestle = () => {
width: 10,
height: 10,
selectable: false,
visible: isTrestleDisplay,
})
canvas.add(bracket)
canvas.renderAll()
@ -1867,7 +1900,7 @@ export const useTrestle = () => {
cvrYn: moduleSelection.construction.setupCover ? 'Y' : 'N',
snowGdYn: moduleSelection.construction.setupSnowCover ? 'Y' : 'N',
plvrYn: cvrPlvrYn,
modules: getModules(surface),
// modules: getModules(surface), // 2025-02-06 api 수정
trestleMkrCd,
constMthdCd,
roofBaseCd,
@ -1879,10 +1912,9 @@ export const useTrestle = () => {
}
}
const getModules = (surface) => {
const { modules } = surface
const params = modules.map((module, index) => {
// 전체 모듈 파라미터 생성
const getModulesParam = (allModules) => {
const params = allModules.map((module, index) => {
return {
moduleTpCd: module.moduleInfo.itemTp,
moduleItemId: module.moduleInfo.itemId,
@ -2200,5 +2232,15 @@ export const useTrestle = () => {
})
}
return { apply, getTrestleParams, clear }
// 전모듈 의 회로번호 visible false 처리
// 가대 설치 전 필요
const setViewCircuitNumberTexts = (visible) => {
const circuitNumberTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
circuitNumberTexts.forEach((text) => {
text.visible = visible
})
canvas.renderAll()
}
return { apply, getTrestleParams, clear, setViewCircuitNumberTexts }
}

View File

@ -727,7 +727,7 @@ export function useCanvasSetting() {
for (let i = 0; i < option1.length; i++) {
switch (option1[i].column) {
case 'allocDisplay': //할당 표시
optionName = ['1']
optionName = []
break
case 'outlineDisplay': //외벽선 표시
optionName = ['outerLine', POLYGON_TYPE.WALL]
@ -742,19 +742,20 @@ export function useCanvasSetting() {
optionName = ['commonText']
break
case 'circuitNumDisplay': //회로번호 표시
optionName = ['7']
optionName = ['circuitNumber']
break
case 'flowDisplay': //흐름방향 표시
optionName = ['arrow', 'flowText']
break
case 'trestleDisplay': //가대 표시
optionName = ['8']
optionName = ['rack', 'smartRack', 'bracket', 'eaveBar', 'halfEaveBar']
break
case 'imageDisplay': //이미지 표시
optionName = ['9']
break
case 'totalDisplay': //집계표 표시
optionName = ['10']
// 작업할 필요 없음
optionName = []
break
}
// 표시 선택 상태(true/false)

View File

@ -445,9 +445,9 @@ export function useRoofAllocationSetting(id) {
setCurrentRoofList(newRoofList)
}
const handleChangeInput = (e, type, index) => {
const handleChangeInput = (e, type = '', index) => {
const value = e.target.value
if (type === 'pitch') {
/*if (type === 'pitch') {
// type이 pitch인 경우 소수점 1자리까지만 입력 가능
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
@ -481,7 +481,7 @@ export function useRoofAllocationSetting(id) {
}
return
}
}*/
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {

View File

@ -203,6 +203,20 @@ export function useRoofShapePassivitySetting(id) {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
let checkedAllSetting = true
lines.forEach((line) => {
if (!line.attributes) {
checkedAllSetting = false
}
})
if (!checkedAllSetting) {
swalFire({ text: '설정이 완료되지 않은 외벽선이 있습니다.', icon: 'warning' })
return
}
exceptObjs.forEach((obj) => {
canvas.remove(obj)
})

View File

@ -7,11 +7,13 @@ import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
import { usePlan } from '@/hooks/usePlan'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { QcastContext } from '@/app/QcastProvider'
import { currentCanvasPlanState } from '@/store/canvasAtom'
import { loginUserStore } from '@/store/commonAtom'
export function useEstimate() {
const { managementStateLoaded } = useContext(GlobalDataContext)
const { setIsGlobalLoading } = useContext(QcastContext)
const router = useRouter()
const loginUserState = useRecoilValue(loginUserStore)
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
@ -24,6 +26,9 @@ export function useEstimate() {
* 도면 견적서 저장
*/
const saveEstimate = async (estimateParam) => {
// 로딩 임시 주석
// setIsGlobalLoading(true)
const userId = loginUserState.userId
const saleStoreId = managementStateLoaded.saleStoreId
const objectNo = currentCanvasPlan.objectNo
@ -54,7 +59,7 @@ export function useEstimate() {
await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData })
.then(async () => {
// 견적서 저장이 완료되면 캔버스 저장 후 견적서 페이지로 이동
await saveCanvas()
await saveCanvas(false)
moveEstimate(planNo, objectNo)
})
.catch((error) => {

View File

@ -11,10 +11,10 @@ export function useMouse() {
const mouseLines = canvas.getObjects().filter((obj) => obj.name === 'mouseLine')
if (mouseLines.length < 2) {
return pointer
return { x: Math.round(pointer.x), y: Math.round(pointer.y) }
}
return getInterSectionLineNotOverCoordinate(mouseLines[0], mouseLines[1]) || pointer
return getInterSectionLineNotOverCoordinate(mouseLines[0], mouseLines[1]) || { x: Math.round(pointer.x), y: Math.round(pointer.y) }
}
return {

View File

@ -120,9 +120,9 @@ export function usePlan(params = {}) {
/**
* 페이지 캔버스를 저장
*/
const saveCanvas = async () => {
const saveCanvas = async (saveAlert = true) => {
const canvasStatus = currentCanvasData('save')
await putCanvasStatus(canvasStatus)
await putCanvasStatus(canvasStatus, saveAlert)
}
/**
@ -192,7 +192,7 @@ export function usePlan(params = {}) {
/**
* id에 해당하는 canvas 데이터를 수정
*/
const putCanvasStatus = async (canvasStatus) => {
const putCanvasStatus = async (canvasStatus, saveAlert = true) => {
const planData = {
id: currentCanvasPlan.id,
bgImageName: currentCanvasPlan?.bgImageName ?? null,
@ -202,7 +202,7 @@ export function usePlan(params = {}) {
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)))
swalFire({ text: getMessage('plan.message.save') })
if (saveAlert) swalFire({ text: getMessage('plan.message.save') })
})
.catch((error) => {
swalFire({ text: error.message, icon: 'error' })
@ -238,7 +238,9 @@ export function usePlan(params = {}) {
if (res.status === 200) {
const estimateDetail = res.data
if (pathname === '/floor-plan/estimate/5') {
if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
// 견적서 이동 조건 수정
// if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) {
if (estimateDetail.estimateDate !== null) {
res.data.resetFlag = 'N'
if (res.data.itemList.length > 0) {
@ -263,7 +265,7 @@ export function usePlan(params = {}) {
}
} else {
// 발전시뮬레이션
if (estimateDetail.tempFlg === '0') {
if (estimateDetail.estimateDate !== null) {
setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId))
setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId })))
} else {
@ -281,7 +283,7 @@ export function usePlan(params = {}) {
})
} else {
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
await saveCanvas()
await saveCanvas(true)
}
setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId))
setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId })))
@ -314,7 +316,7 @@ export function usePlan(params = {}) {
*/
const handleAddPlan = async (userId, objectNo) => {
if (currentCanvasPlan?.id) {
await saveCanvas()
await saveCanvas(true)
}
JSON.parse(currentCanvasData()).objects.length > 0
? swalFire({

View File

@ -61,12 +61,18 @@ export const usePolygon = () => {
let left, top
if (line.direction === 'left' || line.direction === 'right') {
if (line.direction === 'right') {
left = (x1 + x2) / 2
top = (y1 + y2) / 2 + 10
} else if (line.direction === 'top' || line.direction === 'bottom') {
} else if (line.direction === 'top') {
left = (x1 + x2) / 2 + 10
top = (y1 + y2) / 2
} else if (line.direction === 'left') {
left = (x1 + x2) / 2
top = (y1 + y2) / 2 - 30
} else if (line.direction === 'bottom') {
left = (x1 + x2) / 2 - 50
top = (y1 + y2) / 2
}
const minX = line.left

View File

@ -16,9 +16,7 @@ export async function getSession() {
let session
session = await getIronSession(cookies(), sessionOptions)
console.log('session:', session)
if (!session.isLoggedIn) {
// session.isLoggedIn = defaultSession.isLoggedIn
session.isLoggedIn = false
}
@ -27,10 +25,6 @@ export async function getSession() {
export async function checkSession() {
const session = await getSession()
// if (!session.isLoggedIn) {
// redirect('/login')
// }
return session.isLoggedIn
}
@ -54,7 +48,6 @@ export async function setSession(data) {
session.pwdInitYn = data.pwdInitYn
session.custCd = data.custCd
session.isLoggedIn = true
// console.log('session:', session)
await session.save()
}
@ -64,31 +57,33 @@ export async function login() {
if (session) {
redirect('/')
}
// const userId = formData.get('id')
// const password = formData.get('password')
// console.log('id:', userId)
// console.log('password:', password)
// // const loginUser = await getUserByIdAndPassword({ userId, password })
// const loginUser = {
// id: 1,
// userId: 'test123',
// name: 'jinsoo Kim',
// email: 'jinsoo.kim@example.com',
// }
// if (!loginUser) {
// throw Error('Wrong Credentials!')
// }
// session.name = loginUser.name
// session.userId = loginUser.userId
// session.email = loginUser.email
// session.isLoggedIn = true
// console.log('session:', session)
// await session.save()
// redirect('/')
}
export const customSetMenuNumber = async ({ objectNo, pid, menuNum, callback = () => {} }) => {
let db = null
if (!db) {
db = await open({
filename: 'qcast3.global.sqlite',
driver: sqlite3.Database,
})
}
const chkSql = `SELECT menu_num FROM current_menu WHERE object_no = ? AND pid = ?`
const prevMenuNum = await getInstance().get(chkSql, objectNo, pid)
if (prevMenuNum) {
if (prevMenuNum > menuNum) {
callback()
} else {
const sql = `UPDATE current_menu SET menu_num = ? WHERE object_no = ? AND pid = ?`
await getInstance().run(sql, menuNum, objectNo, pid)
setMenuNumber(menuNum)
}
} else {
const sql = `INSERT INTO current_menu (object_no, pid, menu_num) VALUES (?, ?, ?)`
await getInstance().run(sql, objectNo, pid, menuNum)
setMenuNumber(menuNum)
}
}

View File

@ -72,16 +72,7 @@ const writeImage = async (fileName, file) => {
}
const readImage = async (fileName) => {
// const file = await fs.readFile(`${FILE_PATH}/${fileName}`)
const file = await fs.readFile(`${process.env.NEXT_PUBLIC_HOST_URL}${fileName}`)
// .then((res) => {
// console.log('readImage-then', res)
// })
// .catch((e) => {
// console.log('readImage-catch', e)
// })
console.log('🚀 ~ readImage ~ file:', file)
return file
}
@ -89,7 +80,7 @@ const removeImage = async (fileName) => {
try {
await fs.rm(`${FILE_PATH}/${fileName}.png`)
} catch (e) {
console.log(e)
// Error handling without console.log
}
}

View File

@ -64,11 +64,11 @@ export const subMenusState = atom({
name: 'plan.menu.module.circuit.setting.circuit.trestle.setting',
menu: MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING,
},
{
id: 2,
name: 'plan.menu.module.circuit.setting.plan.orientation',
menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
},
// {
// id: 2,
// name: 'plan.menu.module.circuit.setting.plan.orientation',
// menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
// },
],
},
})

View File

@ -235,6 +235,7 @@ export default function offsetPolygon(vertices, offset) {
const arcSegments = 0
const originPolygon = new QPolygon(vertices, { fontSize: 0 })
originPolygon.setViewLengthText(false)
if (offset > 0) {
let result = createMarginPolygon(polygon, offset, arcSegments).vertices