Merge branch 'dev' into feature/dev-yj

This commit is contained in:
yjnoh 2025-05-26 17:34:16 +09:00
commit d886bb135f
6 changed files with 67 additions and 25 deletions

View File

@ -195,9 +195,7 @@ export default function Qna() {
)) ))
) : ( ) : (
<tr> <tr>
<td colSpan={4} className="al-c"> <td className="al-c no-data" colSpan={5}>{getMessage('common.message.no.data')}</td>
{getMessage('common.message.no.data')}
</td>
</tr> </tr>
)} )}
</tbody> </tbody>

View File

@ -27,6 +27,7 @@ export default function QnaRegModal({ setOpen, setReload, searchValue, selectPag
const qnaTypeLgCodeRef = useRef(null) const qnaTypeLgCodeRef = useRef(null)
const qnaTypeMdCodeRef = useRef(null) const qnaTypeMdCodeRef = useRef(null)
const qnaTypeSmCodeRef = useRef(null) const qnaTypeSmCodeRef = useRef(null)
const qstMail = useRef(null);
const regUserNmRef = useRef(null) const regUserNmRef = useRef(null)
const regUserTelNoRef = useRef(null) const regUserTelNoRef = useRef(null)
const titleRef = useRef(null) const titleRef = useRef(null)
@ -65,6 +66,7 @@ let fileCheck = false;
const initQnaReg = async () => { const initQnaReg = async () => {
qstMail.current.value = ''
regUserNmRef.current.value = '' regUserNmRef.current.value = ''
regUserTelNoRef.current.value = '' regUserTelNoRef.current.value = ''
qnaTypeLgCodeRef.current.setValue(); qnaTypeLgCodeRef.current.setValue();
@ -148,7 +150,7 @@ let fileCheck = false;
if(!fileCheck) return; if(!fileCheck) return;
fileUploadProps.uploadFiles.forEach((file) => { fileUploadProps.uploadFiles.forEach((file) => {
console.log("file::::::::",file) //console.log("file::::::::",file)
formData.push(file) formData.push(file)
}) })
@ -156,6 +158,16 @@ let fileCheck = false;
fileCheck = false; fileCheck = false;
} }
const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const isEmpty = (value) => {
return value === null || value === undefined || value.trim() === "";
};
const handleQnaSubmit = async () => { const handleQnaSubmit = async () => {
// //
@ -164,13 +176,22 @@ let fileCheck = false;
let regUserNm = qnaData?.regUserNm??''; let regUserNm = qnaData?.regUserNm??'';
if (regUserNm.trim().length === 0) { if (!isValidEmail(qnaData.qstMail)) {
qstMail.current.focus();
swalFire({
title: getMessage('qna.reg.alert.require.qstMail'),
icon: 'warning',
});
return;
}
regUserNmRef.current.value = '';
if (isEmpty(regUserNm)) {
regUserNmRef.current.value = '';
regUserNmRef.current.focus() regUserNmRef.current.focus()
swalFire({ swalFire({
text: getMessage('qna.reg.alert.require.regUserNm'), title: getMessage('qna.reg.alert.require.regUserNm'),
type: 'alert', icon: 'warning',
}) })
return false return false
} }
@ -178,35 +199,35 @@ let fileCheck = false;
let qnaClsLrgCd = qnaData?.qnaClsLrgCd??''; let qnaClsLrgCd = qnaData?.qnaClsLrgCd??'';
let qnaClsMidCd = qnaData?.qnaClsMidCd??''; let qnaClsMidCd = qnaData?.qnaClsMidCd??'';
if (qnaClsLrgCd.trim().length === 0 || qnaClsMidCd.trim().length === 0 ) { if (isEmpty(qnaClsLrgCd) || isEmpty(qnaClsMidCd) ) {
(qnaClsLrgCd.trim().length === 0)?qnaTypeLgCodeRef.current.focus():qnaTypeMdCodeRef.current.focus() (isEmpty(qnaClsLrgCd))?qnaTypeLgCodeRef.current.focus():qnaTypeMdCodeRef.current.focus()
swalFire({ swalFire({
text: getMessage('qna.reg.alert.select.type'), title: getMessage('qna.reg.alert.select.type'),
type: 'alert', icon: 'warning',
}) })
return false return false
} }
let title = qnaData?.title??''; let title = qnaData?.title??'';
if (title.trim().length === 0) { if (isEmpty(title)) {
titleRef.current.value = ''; titleRef.current.value = '';
titleRef.current.focus() titleRef.current.focus()
swalFire({ swalFire({
text: getMessage('qna.reg.alert.require.title'), title: getMessage('qna.reg.alert.require.title'),
type: 'alert', icon: 'warning',
}) })
return false return false
} }
//console.log("5::::",qnaData) //console.log("5::::",qnaData)
let contents = qnaData?.contents??''; let contents = qnaData?.contents??'';
if (contents.trim().length === 0) { if (isEmpty(contents)) {
contentsRef.current.value = ''; contentsRef.current.value = '';
contentsRef.current.focus() contentsRef.current.focus()
swalFire({ swalFire({
text: getMessage('qna.reg.alert.require.contents'), title: getMessage('qna.reg.alert.require.contents'),
type: 'alert', icon: 'warning',
}) })
return false return false
} }
@ -310,7 +331,13 @@ let fileCheck = false;
<th>{getMessage('qna.list.header.regNm')}</th> <th>{getMessage('qna.list.header.regNm')}</th>
<td><input type="text" className="input-light" value={sessionState?.userNm || ''} readOnly /></td> <td><input type="text" className="input-light" value={sessionState?.userNm || ''} readOnly /></td>
<th>E-Mail<span className="red">*</span></th> <th>E-Mail<span className="red">*</span></th>
<td ><input type="text" className="input-light" value={sessionState?.email || ''} readOnly /></td> <td ><input type="text" className="input-light" required
ref={qstMail}
value={qnaData?.qstMail || ''}
onChange={(e) => setQnaData({...qnaData, qstMail: e.target.value })}
onBlur={(e) => setQnaData({ ...qnaData, qstMail: e.target.value })} />
</td>
<th>{getMessage('qna.reg.header.regDt')}</th> <th>{getMessage('qna.reg.header.regDt')}</th>
<td>{dayjs(new Date()).format('YYYY-MM-DD')}</td> <td>{dayjs(new Date()).format('YYYY-MM-DD')}</td>
</tr> </tr>

View File

@ -2,7 +2,14 @@ import { useRef } from 'react'
import { useRecoilValue, useSetRecoilState } from 'recoil' import { useRecoilValue, useSetRecoilState } from 'recoil'
import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom' import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { calculateDistance, calculateDistancePoint, calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' import {
calculateDistance,
calculateDistancePoint,
calculateIntersection,
distanceBetweenPoints,
findClosestPoint,
getInterSectionLineNotOverCoordinate,
} from '@/util/canvas-util'
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint' import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
import { useDotLineGrid } from '@/hooks/useDotLineGrid' import { useDotLineGrid } from '@/hooks/useDotLineGrid'
import { useTempGrid } from '@/hooks/useTempGrid' import { useTempGrid } from '@/hooks/useTempGrid'
@ -146,7 +153,7 @@ export function useEvent() {
...innerLinePoints, ...innerLinePoints,
] ]
if (dotLineGridSetting.LINE || canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name)).length > 0) { if (dotLineGridSetting.LINE || canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name)).length > 1) {
const closestLine = getClosestLineGrid(pointer) const closestLine = getClosestLineGrid(pointer)
const horizonLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'horizontal') const horizonLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'horizontal')
@ -260,7 +267,9 @@ export function useEvent() {
arrivalPoint = guideIntersectionPoint arrivalPoint = guideIntersectionPoint
} }
} }
} catch (e) {} } catch (e) {
console.error(e)
}
const horizontalLine = new fabric.Line([-4 * canvas.width, arrivalPoint.y, 4 * canvas.width, arrivalPoint.y], { const horizontalLine = new fabric.Line([-4 * canvas.width, arrivalPoint.y, 4 * canvas.width, arrivalPoint.y], {
stroke: 'red', stroke: 'red',
@ -298,7 +307,12 @@ export function useEvent() {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
//임의 그리드 모드일 경우 //임의 그리드 모드일 경우
let pointer = { x: e.offsetX, y: e.offsetY } let originPointer = { x: e.offsetX, y: e.offsetY }
const mouseLines = canvas.getObjects().filter((obj) => obj.name === 'mouseLine')
let pointer = getInterSectionLineNotOverCoordinate(mouseLines[0], mouseLines[1]) || {
x: Math.round(originPointer.x),
y: Math.round(originPointer.y),
}
const tempGrid = new fabric.Line([-1500, pointer.y, 2500, pointer.y], { const tempGrid = new fabric.Line([-1500, pointer.y, 2500, pointer.y], {
stroke: gridColor, stroke: gridColor,

View File

@ -2,6 +2,7 @@ import { canvasState, tempGridModeState } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { gridDisplaySelector } from '@/store/settingAtom' import { gridDisplaySelector } from '@/store/settingAtom'
import { useMouse } from '@/hooks/useMouse'
const GRID_PADDING = 5 const GRID_PADDING = 5
export function useTempGrid() { export function useTempGrid() {
@ -9,10 +10,10 @@ export function useTempGrid() {
const gridColor = useRecoilValue(gridColorState) const gridColor = useRecoilValue(gridColorState)
const isGridDisplay = useRecoilValue(gridDisplaySelector) const isGridDisplay = useRecoilValue(gridDisplaySelector)
const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState) const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState)
const { getIntersectMousePoint } = useMouse()
const tempGridModeStateLeftClickEvent = (e) => { const tempGridModeStateLeftClickEvent = (e) => {
//임의 그리드 모드일 경우 //임의 그리드 모드일 경우
let pointer = canvas.getPointer(e.e) let pointer = getIntersectMousePoint(e)
const tempGrid = new fabric.Line([pointer.x, -1500, pointer.x, 2500], { const tempGrid = new fabric.Line([pointer.x, -1500, pointer.x, 2500], {
stroke: gridColor, stroke: gridColor,

View File

@ -612,6 +612,7 @@
"qna.reg.header.contents": "お問い合わせ内容", "qna.reg.header.contents": "お問い合わせ内容",
"qna.reg.header.fileList": "ファイル添付", "qna.reg.header.fileList": "ファイル添付",
"qna.reg.header.save": "保存", "qna.reg.header.save": "保存",
"qna.reg.alert.require.qstMail": "無効なメール形式です。",
"qna.reg.alert.require.regUserNm": "名前を入力してください。", "qna.reg.alert.require.regUserNm": "名前を入力してください。",
"qna.reg.alert.select.type": "お問い合わせ区分を選択してください。", "qna.reg.alert.select.type": "お問い合わせ区分を選択してください。",
"qna.reg.alert.require.title": "タイトルを入力してください。", "qna.reg.alert.require.title": "タイトルを入力してください。",

View File

@ -612,6 +612,7 @@
"qna.reg.header.contents": "문의정보", "qna.reg.header.contents": "문의정보",
"qna.reg.header.fileList": "파일첨부", "qna.reg.header.fileList": "파일첨부",
"qna.reg.header.save": "저장", "qna.reg.header.save": "저장",
"qna.reg.alert.require.qstMail": "올바르지 않은 이메일 형식입니다.",
"qna.reg.alert.require.regUserNm": "이름을 입력하세요.", "qna.reg.alert.require.regUserNm": "이름을 입력하세요.",
"qna.reg.alert.select.type": "문의구분을 선택하세요.", "qna.reg.alert.select.type": "문의구분을 선택하세요.",
"qna.reg.alert.require.title": "제목을 입력하세요.", "qna.reg.alert.require.title": "제목을 입력하세요.",