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

This commit is contained in:
김민식 2025-02-05 20:21:52 +09:00
commit 41e936b7c6
6 changed files with 201 additions and 156 deletions

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { getDegreeByChon } from '@/util/canvas-util' import { getDegreeByChon } from '@/util/canvas-util'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { basicSettingState } from '@/store/settingAtom' import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
// 회로 및 가대설정 // 회로 및 가대설정
@ -15,6 +15,7 @@ export const useTrestle = () => {
const { getQuotationItem } = useMasterController() const { getQuotationItem } = useMasterController()
const currentAngleType = useRecoilValue(currentAngleTypeSelector) const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
const isTrestleDisplay = useRecoilValue(trestleDisplaySelector)
const { swalFire } = useSwal() const { swalFire } = useSwal()
const apply = () => { const apply = () => {
try { try {
@ -135,6 +136,7 @@ export const useTrestle = () => {
selectable: false, selectable: false,
surfaceId: surface.id, surfaceId: surface.id,
parentId: module.id, parentId: module.id,
visible: isTrestleDisplay,
}) })
canvas.add(eaveBar) canvas.add(eaveBar)
canvas.renderAll() canvas.renderAll()
@ -165,6 +167,7 @@ export const useTrestle = () => {
selectable: false, selectable: false,
surfaceId: surface.id, surfaceId: surface.id,
parentId: module.id, parentId: module.id,
visible: isTrestleDisplay,
}) })
canvas.add(halfEaveBar) canvas.add(halfEaveBar)
canvas.renderAll() canvas.renderAll()
@ -193,6 +196,7 @@ export const useTrestle = () => {
strokeWidth: 4, strokeWidth: 4,
selectable: false, selectable: false,
parentId: module.id, parentId: module.id,
visible: isTrestleDisplay,
}) })
canvas.add(halfEaveBar) canvas.add(halfEaveBar)
canvas.renderAll() canvas.renderAll()
@ -918,7 +922,7 @@ export const useTrestle = () => {
offsetX: 0, offsetX: 0,
offsetY: 0, offsetY: 0,
}, },
visible: isTrestleDisplay,
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
supFitQty, supFitQty,
@ -952,6 +956,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen,
@ -992,6 +997,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen: rackLength, rackLen: rackLength,
@ -1022,6 +1028,7 @@ export const useTrestle = () => {
surfaceId: surface.id, surfaceId: surface.id,
strokeWidth: 4, strokeWidth: 4,
selectable: false, selectable: false,
visible: isTrestleDisplay,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen,
@ -1062,6 +1069,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen: rackLength, rackLen: rackLength,
@ -1090,6 +1098,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
strokeWidth: 4, strokeWidth: 4,
selectable: false, selectable: false,
supFitQty, supFitQty,
@ -1130,6 +1139,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
supFitQty, supFitQty,
supFitIntvlPct, supFitIntvlPct,
rackLen, rackLen,
@ -1158,6 +1168,7 @@ export const useTrestle = () => {
}, },
parentId: module.id, parentId: module.id,
surfaceId: surface.id, surfaceId: surface.id,
visible: isTrestleDisplay,
strokeWidth: 4, strokeWidth: 4,
selectable: false, selectable: false,
supFitQty, supFitQty,
@ -1209,6 +1220,7 @@ export const useTrestle = () => {
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
parentId: rack.parentId, parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id, surfaceId: surface.id,
width: bracketLength, width: bracketLength,
height: bracketLength, height: bracketLength,
@ -1228,6 +1240,7 @@ export const useTrestle = () => {
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
parentId: rack.parentId, parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id, surfaceId: surface.id,
width: bracketLength, width: bracketLength,
height: bracketLength, height: bracketLength,
@ -1246,6 +1259,7 @@ export const useTrestle = () => {
top: y2 - bracketLength / 3, top: y2 - bracketLength / 3,
fill: 'green', fill: 'green',
parentId: rack.parentId, parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id, surfaceId: surface.id,
name: 'bracket', name: 'bracket',
width: bracketLength, width: bracketLength,
@ -1266,6 +1280,7 @@ export const useTrestle = () => {
fill: 'green', fill: 'green',
name: 'bracket', name: 'bracket',
parentId: rack.parentId, parentId: rack.parentId,
visible: isTrestleDisplay,
surfaceId: surface.id, surfaceId: surface.id,
width: bracketLength, width: bracketLength,
height: bracketLength, height: bracketLength,
@ -1431,6 +1446,7 @@ export const useTrestle = () => {
width: 10, width: 10,
height: 10, height: 10,
selectable: false, selectable: false,
visible: isTrestleDisplay,
}) })
canvas.add(bracket) canvas.add(bracket)
canvas.renderAll() canvas.renderAll()

View File

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

View File

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