Compare commits

..

12 Commits

Author SHA1 Message Date
4aec4e389f Merge pull request '1. 첨부파일 체크 문구 변경, 2. [995] module.circuit.fix.not.same.roof.error 일어추가, zipYn: N => NO' (#67) from feature/ysCha into dev
Reviewed-on: #67
2025-05-28 11:40:31 +09:00
cd65d80cce 1. 첨부파일 체크 문구 변경, 2. [995] module.circuit.fix.not.same.roof.error 일어추가, zipYn: N => NO 2025-05-28 11:38:46 +09:00
96eb4f25ae [1046] : 【HANASYS DESIGN】グリッド線の機能追加についての要望
임의 그리드 작동 이상 수정
2025-05-28 11:30:40 +09:00
김민식
f8a46c30fa [1070] : [[도면] 신규물건 작성할 때 이전 도면값을 유지하고 있음]
[작업내용] : 도면 이동시 canvas 데이터 초기화
2025-05-28 11:17:23 +09:00
김민식
74e65ec5c6 [995] : [【HANASYS DESIGN】回路組について]
[작업내용] : 다국어 추가
2025-05-28 10:50:47 +09:00
김민식
2ee0dc45f0 [1068] : [[오류] 견적서 생성된 플랜복사 --> 복사된 플랜에서 모듈삭제 --> 견적서 진입이 됨..]
[작업내용] : 회로설정 -> 수동 할당 시 회로 및 가대 삭제
2025-05-28 10:37:02 +09:00
4e8cc409d4 #1068 [오류] 견적서 생성된 플랜복사 --> 복사된 플랜에서 모듈삭제 --> 견적서 진입이 됨.. 2025-05-28 10:26:38 +09:00
8ab41c8eda Merge pull request 'https://www.hanasys.jp/ => https://www.hanasys.jp' (#64) from feature/ysCha into dev
Reviewed-on: #64
2025-05-28 09:08:33 +09:00
7fb232d9ae https://www.hanasys.jp/ => https://www.hanasys.jp 2025-05-28 09:07:09 +09:00
3a37d637ed console 제거 2025-05-27 17:48:56 +09:00
17e88e5d3c Merge pull request '[1004] 1:1 1) 버튼 색 변경 2) 상세내용 위치 변경' (#62) from feature/ysCha into dev
Reviewed-on: #62
2025-05-27 16:55:22 +09:00
5d3a7aa9cc [1004] 1:1 1) 버튼 색 변경 2) 상세내용 위치 변경 2025-05-27 16:52:42 +09:00
12 changed files with 56 additions and 17 deletions

View File

@ -2,7 +2,7 @@ NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/"
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000" NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
NEXT_PUBLIC_API_HOST_URL="https://www.hanasys.jp/" NEXT_PUBLIC_API_HOST_URL="https://www.hanasys.jp"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="

View File

@ -73,7 +73,7 @@ export default function QnaDetailModal({ qnaNo, setOpen, qnaType }) {
<dt>{getMessage('qna.detail.sub.fileList')}</dt> <dt>{getMessage('qna.detail.sub.fileList')}</dt>
{boardDetail.listFile.map((boardFile) => ( {boardDetail.listFile.map((boardFile) => (
<dd key={boardFile.encodeFileNo}> <dd key={boardFile.encodeFileNo}>
<button type="button" className="down" onClick={() => handleFileDown(boardFile.fileNo, 'N')}> <button type="button" className="down" onClick={() => handleFileDown(boardFile.fileNo, 'NO')}>
{boardFile.srcFileNm} {boardFile.srcFileNm}
</button> </button>
</dd> </dd>

View File

@ -428,8 +428,8 @@ let fileCheck = false;
</div> </div>
<div className="footer-btn-wrap"> <div className="footer-btn-wrap">
{isBtnDisable === false && <button className="btn-origin grey mr5" onClick={handleQnaSubmit}>{getMessage("qna.reg.header.save")}</button>} {isBtnDisable === false && <button className="btn-origin navy mr5" onClick={handleQnaSubmit}>{getMessage("qna.reg.header.save")}</button>}
<button className="btn-origin navy" onClick={() => { <button className="btn-origin grey" onClick={() => {
setOpen(false) setOpen(false)
}}>{getMessage("board.sub.btn.close")}</button> }}>{getMessage("board.sub.btn.close")}</button>
</div> </div>

View File

@ -76,8 +76,12 @@ export default function CanvasFrame() {
} }
initEvent() initEvent()
}) })
} else {
setSelectedMenu(null)
} }
Object.keys(currentCanvasPlan).length > 0 && canvas && handleModuleSelectionTotal() Object.keys(currentCanvasPlan).length > 0 && canvas && handleModuleSelectionTotal()
} else {
setSelectedMenu(null)
} }
gridInit() gridInit()
} }

View File

@ -50,6 +50,7 @@ import JA from '@/locales/ja.json'
import { QcastContext } from '@/app/QcastProvider' import { QcastContext } from '@/app/QcastProvider'
import { useRoofFn } from '@/hooks/common/useRoofFn' import { useRoofFn } from '@/hooks/common/useRoofFn'
import { usePolygon } from '@/hooks/usePolygon' import { usePolygon } from '@/hooks/usePolygon'
import { useTrestle } from '@/hooks/module/useTrestle'
export default function CanvasMenu(props) { export default function CanvasMenu(props) {
const { selectedMenu, setSelectedMenu } = props const { selectedMenu, setSelectedMenu } = props
const pathname = usePathname() const pathname = usePathname()
@ -67,6 +68,7 @@ export default function CanvasMenu(props) {
const globalLocale = useRecoilValue(globalLocaleStore) const globalLocale = useRecoilValue(globalLocaleStore)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { handleZoomClear, handleZoom } = useCanvasEvent() const { handleZoomClear, handleZoom } = useCanvasEvent()
const { setAllModuleSurfaceIsComplete, isAllComplete } = useTrestle()
const { handleMenu } = useMenu() const { handleMenu } = useMenu()
// const urlParams = useSearchParams() // const urlParams = useSearchParams()
const { handleEstimateSubmit, fetchSetting, estimateContextState, setEstimateContextState } = useEstimateController() const { handleEstimateSubmit, fetchSetting, estimateContextState, setEstimateContextState } = useEstimateController()
@ -194,6 +196,7 @@ export default function CanvasMenu(props) {
confirmFn: () => { confirmFn: () => {
// //
setAllModuleSurfaceIsComplete(false)
const moduleSurfacesArray = canvas const moduleSurfacesArray = canvas
.getObjects() .getObjects()
.filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name)) .filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name))
@ -233,6 +236,10 @@ export default function CanvasMenu(props) {
await reloadCanvasStatus(objectNo, pid) await reloadCanvasStatus(objectNo, pid)
break break
case 'estimate': case 'estimate':
if (!isAllComplete()) {
swalFire({ text: getMessage('estimate.menu.move.valid1') })
return
}
setIsGlobalLoading(true) setIsGlobalLoading(true)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) { if (res.status === 200) {

View File

@ -154,6 +154,7 @@ export default function CircuitTrestleSetting({ id }) {
getPcsVoltageChk(pcsVoltageChkParams).then((res) => { getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
if (res.resultCode === 'S') { if (res.resultCode === 'S') {
setTabNum(2) setTabNum(2)
setAllModuleSurfaceIsComplete(false)
} else { } else {
swalFire({ swalFire({
title: res.resultMsg, title: res.resultMsg,
@ -187,6 +188,7 @@ export default function CircuitTrestleSetting({ id }) {
}).then((res) => { }).then((res) => {
if (res?.result.resultCode === 'S' && res?.data) { if (res?.result.resultCode === 'S' && res?.data) {
setTabNum(2) setTabNum(2)
setAllModuleSurfaceIsComplete(false)
} else { } else {
swalFire({ text: getMessage('common.message.send.error') }) swalFire({ text: getMessage('common.message.send.error') })
} }
@ -286,6 +288,8 @@ export default function CircuitTrestleSetting({ id }) {
setSelectedModels(pcsItemList) setSelectedModels(pcsItemList)
getPcsVoltageChk(pcsVoltageChkParams).then((res) => { getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
setAllocationType(ALLOCATION_TYPE.PASSIVITY) setAllocationType(ALLOCATION_TYPE.PASSIVITY)
setAllModuleSurfaceIsComplete(false)
clearTrestle()
}) })
} else { } else {
swalFire({ swalFire({
@ -318,6 +322,7 @@ export default function CircuitTrestleSetting({ id }) {
} }
setAllocationType(ALLOCATION_TYPE.PASSIVITY) setAllocationType(ALLOCATION_TYPE.PASSIVITY)
clearTrestle()
} }
} }
@ -654,6 +659,7 @@ export default function CircuitTrestleSetting({ id }) {
return return
} else { } else {
setTabNum(2) setTabNum(2)
setAllModuleSurfaceIsComplete(false)
} }
}) })
} }

View File

@ -3077,6 +3077,9 @@ export const useTrestle = () => {
// 배치면 전체에 가대 설치 여부 // 배치면 전체에 가대 설치 여부
const isAllComplete = () => { const isAllComplete = () => {
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
if (surfaces.length === 0) {
return false
}
return surfaces.every((surface) => surface.isComplete) return surfaces.every((surface) => surface.isComplete)
} }

View File

@ -203,7 +203,6 @@ export function useCanvasSetting(executeEffect = true) {
return return
} }
const selectedRoofMaterial = roofMaterials[0] const selectedRoofMaterial = roofMaterials[0]
console.log('selectedRoofMaterial', selectedRoofMaterial)
if (addedRoofs.length === 0) { if (addedRoofs.length === 0) {
const newAddedRoofs = [] const newAddedRoofs = []

View File

@ -160,6 +160,7 @@ export function useEvent() {
const verticalLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'vertical') const verticalLines = canvas.getObjects().filter((obj) => ['lineGrid', 'tempGrid'].includes(obj.name) && obj.direction === 'vertical')
if (!horizonLines || !verticalLines) { if (!horizonLines || !verticalLines) {
drawMouseLine(pointer)
return return
} }
@ -183,6 +184,7 @@ export function useEvent() {
} }
if (!closestVerticalLine || !closestHorizontalLine) { if (!closestVerticalLine || !closestHorizontalLine) {
drawMouseLine(pointer)
return return
} }
@ -271,7 +273,14 @@ export function useEvent() {
console.error(e) console.error(e)
} }
const horizontalLine = new fabric.Line([-4 * canvas.width, arrivalPoint.y, 4 * canvas.width, arrivalPoint.y], { drawMouseLine(arrivalPoint)
// 캔버스를 다시 그립니다.
canvas?.renderAll()
}
const drawMouseLine = (pointer) => {
const horizontalLine = new fabric.Line([-4 * canvas.width, pointer.y, 4 * canvas.width, pointer.y], {
stroke: 'red', stroke: 'red',
strokeWidth: 1, strokeWidth: 1,
selectable: false, selectable: false,
@ -279,7 +288,7 @@ export function useEvent() {
}) })
// 세로선 // 세로선
const verticalLine = new fabric.Line([arrivalPoint.x, -4 * canvas.height, arrivalPoint.x, 4 * canvas.height], { const verticalLine = new fabric.Line([pointer.x, -4 * canvas.height, pointer.x, 4 * canvas.height], {
stroke: 'red', stroke: 'red',
strokeWidth: 1, strokeWidth: 1,
selectable: false, selectable: false,
@ -288,9 +297,6 @@ export function useEvent() {
// 선들을 캔버스에 추가합니다. // 선들을 캔버스에 추가합니다.
canvas?.add(horizontalLine, verticalLine) canvas?.add(horizontalLine, verticalLine)
// 캔버스를 다시 그립니다.
canvas?.renderAll()
} }
const removeMouseLine = () => { const removeMouseLine = () => {

View File

@ -3,9 +3,17 @@
import { useContext, useEffect, useState } from 'react' import { useContext, useEffect, useState } from 'react'
import { usePathname, useRouter } from 'next/navigation' import { usePathname, useRouter } from 'next/navigation'
import { useRecoilState, useResetRecoilState } from 'recoil' import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil'
import { canvasState, currentCanvasPlanState, plansState, canvasSettingState, currentObjectState, moduleSetupSurfaceState } from '@/store/canvasAtom' import {
canvasState,
currentCanvasPlanState,
plansState,
canvasSettingState,
currentObjectState,
moduleSetupSurfaceState,
currentMenuState,
} from '@/store/canvasAtom'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
@ -33,7 +41,7 @@ export function usePlan(params = {}) {
const { floorPlanState } = useContext(FloorPlanContext) const { floorPlanState } = useContext(FloorPlanContext)
const [selectedPlan, setSelectedPlan] = useState(null) const [selectedPlan, setSelectedPlan] = useState(null)
const setCurrentMenu = useSetRecoilState(currentMenuState)
const [canvas, setCanvas] = useRecoilState(canvasState) const [canvas, setCanvas] = useRecoilState(canvasState)
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
@ -577,8 +585,10 @@ export function usePlan(params = {}) {
* plan canvasStatus 초기화 * plan canvasStatus 초기화
*/ */
const resetCanvasStatus = () => { const resetCanvasStatus = () => {
setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: null })) setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: null, objectNo: null, planNo: null, id: null }))
setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: null }))) setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: null })))
setCurrentMenu(null)
setSelectedMenu(null)
} }
/** /**

View File

@ -956,7 +956,7 @@
"estimate.detail.dragFileGuide": "(※北面設置の場合、ファイル添付が必須です。)", "estimate.detail.dragFileGuide": "(※北面設置の場合、ファイル添付が必須です。)",
"estimate.detail.header.fileList1": "ファイル添付", "estimate.detail.header.fileList1": "ファイル添付",
"estimate.detail.fileList.btn": "ファイル選択", "estimate.detail.fileList.btn": "ファイル選択",
"estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能です。", "estimate.detail.fileList.extCheck": "画像、PDF、Excel ファイルのみ添付できます。",
"estimate.detail.header.fileList2": "添付ファイル一覧", "estimate.detail.header.fileList2": "添付ファイル一覧",
"estimate.detail.fileList2.btn.return": "復元", "estimate.detail.fileList2.btn.return": "復元",
"estimate.detail.header.specialEstimate": "見積特記事項", "estimate.detail.header.specialEstimate": "見積特記事項",
@ -1078,6 +1078,7 @@
"module.not.found": "インストールモジュールを選択してください。", "module.not.found": "インストールモジュールを選択してください。",
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。", "module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。", "module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
"construction.length.difference": "屋根面工法をすべて選択してください。", "construction.length.difference": "屋根面工法をすべて選択してください。",
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。", "menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。", "batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",

View File

@ -447,10 +447,11 @@
border-top: none; border-top: none;
.community_detail-file-wrap{ .community_detail-file-wrap{
padding-top: 0; padding-top: 0;
margin-bottom: 24px;
} }
.community_detail-inner{ .community_detail-inner{
max-height: 110px; max-height: 110px;
margin-top: 24px; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
} }
} }
@ -461,12 +462,14 @@
border: 1px solid #101010; border: 1px solid #101010;
.community_detail-inner{ .community_detail-inner{
max-height: 110px; max-height: 110px;
margin-top: 20px;
margin-bottom: 0;
} }
.community_detail-file-wrap{ .community_detail-file-wrap{
border-top: 1px solid #D4DCE7; border-top: 1px solid #D4DCE7;
padding: 16px 0 0 0; padding: 16px 0 0 0;
border-bottom: none; border-bottom: none;
margin-top: 20px;
} }
} }