Merge branch 'dev' into feature/dev-yj

This commit is contained in:
yjnoh 2025-05-12 13:49:29 +09:00
commit 4b8287579c
26 changed files with 1057 additions and 354 deletions

3
.gitmessage.txt Normal file
View File

@ -0,0 +1,3 @@
[일감번호] : [제목]
[작업내용] :

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="8.25" stroke="#101010" stroke-width="1.5"/>
<path d="M7.94995 16.5C10.0485 14.302 13.9289 14.1986 16.05 16.5M14.2455 9.75C14.2455 10.9926 13.2367 12 11.9923 12C10.7479 12 9.73912 10.9926 9.73912 9.75C9.73912 8.50736 10.7479 7.5 11.9923 7.5C13.2367 7.5 14.2455 8.50736 14.2455 9.75Z" stroke="#101010" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 474 B

View File

@ -125,6 +125,11 @@ export const TRESTLE_MATERIAL = {
BRACKET: 'bracket',
}
export const MODULE_SETUP_TYPE = {
LAYOUT: 'layout',
AUTO: 'auto',
}
export const SAVE_KEY = [
'selectable',
'name',

View File

@ -26,6 +26,7 @@ export default function QSelectBox({
targetKey = '',
showKey = '',
params = {},
tagTitle = '',
}) {
const { getMessage } = useMessage()
@ -82,6 +83,7 @@ export default function QSelectBox({
className={`sort-select ${openSelect ? 'active' : ''} ${disabled ? 'disabled' : ''}`}
ref={ref}
onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)}
title={tagTitle}
>
<p>{selected}</p>
<ul className="select-item-wrap">

View File

@ -564,6 +564,7 @@ export default function Estimate({}) {
updateList.push({
...item,
openFlg: data.data2[i].unitPrice === '0.0' ? '1' : '0',
unitOpenFlg: (showPriceCd === 'QSP_PRICE' && item.openFlg === '1') ? '1' : '0',
salePrice: data.data2[i].unitPrice === null ? '0' : data.data2[i].unitPrice,
saleTotPrice: (item.amount * data.data2[i].unitPrice).toString(),
})

View File

@ -548,13 +548,26 @@ export default function CanvasMenu(props) {
{
<div className={`vertical-horizontal ${verticalHorizontalMode ? 'on' : ''}`}>
<span>{getMessage('plan.mode.vertical.horizontal')}</span>
<button onClick={() => setVerticalHorizontalMode(!verticalHorizontalMode)}>{verticalHorizontalMode ? 'ON' : 'OFF'}</button>
<button
title={`${getMessage('plan.mode.vertical.horizontal')} ${verticalHorizontalMode ? 'ON' : 'OFF'}`}
onClick={() => setVerticalHorizontalMode(!verticalHorizontalMode)}
>
{verticalHorizontalMode ? 'ON' : 'OFF'}
</button>
</div>
}
<div className="btn-from">
<button className={`btn01 ${commonUtils.text ? 'active' : ''}`} onClick={() => commonFunctions('text')}></button>
<button className={`btn02 ${commonUtils.dimension ? 'active' : ''} `} onClick={() => commonFunctions('dimension')}></button>
<button className={`btn03 ${commonUtils.distance ? 'active' : ''} `} onClick={() => commonFunctions('distance')}></button>
<button className={`btn01 ${commonUtils.text ? 'active' : ''}`} onClick={() => commonFunctions('text')} title="文字作成"></button>
<button
className={`btn02 ${commonUtils.dimension ? 'active' : ''} `}
onClick={() => commonFunctions('dimension')}
title="寸法作成"
></button>
<button
className={`btn03 ${commonUtils.distance ? 'active' : ''} `}
onClick={() => commonFunctions('distance')}
title="定規"
></button>
</div>
{isObjectNotEmpty(selectedRoofMaterial) && addedRoofs.length > 0 && (
<div className="select-box">
@ -580,6 +593,7 @@ export default function CanvasMenu(props) {
sourceKey={'index'}
targetKey={'index'}
disabled={+basicSetting.roofSizeSet === 3}
tagTitle={'屋根材変更'}
/>
}
</div>
@ -588,9 +602,10 @@ export default function CanvasMenu(props) {
<button
className={`btn10 ${floorPlanState.refFileModalOpen && 'active'}`}
onClick={() => setFloorPlanState({ ...floorPlanState, refFileModalOpen: true })}
title="読込"
></button>
{/*<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>*/}
<button className="btn04" onClick={handlePopup}></button>
<button className="btn04" onClick={handlePopup} title="設定"></button>
</div>
<div className="size-control">
<button
@ -599,7 +614,9 @@ export default function CanvasMenu(props) {
handleZoom(false)
}}
></button>
<span onClick={handleZoomClear}>{canvasZoom}%</span>
<span onClick={handleZoomClear} title="拡大・縮小">
{canvasZoom}%
</span>
<button
className="control-btn plus"
onClick={() => {
@ -608,8 +625,8 @@ export default function CanvasMenu(props) {
></button>
</div>
<div className="btn-from">
<button className="btn08" onClick={handleSaveCanvas}></button>
<button className="btn09" onClick={handleLeaveCanvas}></button>
<button className="btn08" onClick={handleSaveCanvas} title="保存"></button>
<button className="btn09" onClick={handleLeaveCanvas} title="物件検索画面へ移動"></button>
</div>
</>
)}

View File

@ -1,4 +1,4 @@
import { POLYGON_TYPE } from '@/common/common'
import { POLYGON_TYPE, MODULE_SETUP_TYPE } from '@/common/common'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
@ -331,10 +331,13 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
<button className={`btn-frame modal mr5 ${isManualModuleLayoutSetup ? 'act' : ''}`} onClick={handleManualModuleLayoutSetup}>
{getMessage('modal.module.basic.setting.row.batch')}
</button>
<button className="btn-frame modal mr5" onClick={() => autoModuleSetup(MODULE_SETUP_TYPE.LAYOUT, layoutSetup)}>
{getMessage('modal.module.basic.setting.auto.row.batch')}
</button>
<button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}>
{getMessage('modal.module.basic.setting.passivity.placement')}
</button>
<button className="btn-frame modal act" onClick={() => autoModuleSetup()}>
<button className="btn-frame modal act mr5" onClick={() => autoModuleSetup(MODULE_SETUP_TYPE.AUTO)}>
{getMessage('modal.module.basic.setting.auto.placement')}
</button>
</>

View File

@ -37,7 +37,7 @@ const Placement = forwardRef((props, refs) => {
const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState)
const [colspan, setColspan] = useState(1)
const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState)
const moduleRowColArray = useRecoilValue(moduleRowColArrayState)
//
useEffect(() => {
@ -64,9 +64,9 @@ const Placement = forwardRef((props, refs) => {
}
}, [])
useEffect(() => {
console.log('moduleRowColArray', moduleRowColArray)
}, [moduleRowColArray])
// useEffect(() => {
// console.log('moduleRowColArray', moduleRowColArray)
// }, [moduleRowColArray])
//
useEffect(() => {
@ -110,8 +110,8 @@ const Placement = forwardRef((props, refs) => {
{ type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn'), prop: 'mixAsgYn', width: 50 },
{ type: 'text', name: ``, prop: 'rows', width: 60 },
{ type: 'text', name: `熱水`, prop: 'cols', width: 60 },
{ type: 'text', name: ``, prop: 'rows', width: 60 },
{ type: 'text', name: `列数`, prop: 'cols', width: 60 },
],
rows: [],
}
@ -330,19 +330,21 @@ const Placement = forwardRef((props, refs) => {
<th rowSpan={2} style={{ width: '22%' }}></th>
{selectedModules &&
selectedModules.itemList.map((item) => (
<th colSpan={colspan}>
// <th colSpan={colspan}>
<th>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="name">{item.itemNm}</span>
</div>
</th>
))}
{colspan > 1 && <th rowSpan={2}>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>}
</tr>
<tr>
{selectedModules.itemList.map((item) => (
<>
<th>{getMessage('modal.module.basic.setting.module.placement.max.row')}</th>
{colspan > 1 && <th>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>}
{/* {colspan > 1 && <th>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>} */}
</>
))}
</tr>
@ -356,10 +358,11 @@ const Placement = forwardRef((props, refs) => {
<span className="name">{item.addRoof?.roofMatlNmJp}</span>
</div>
</td>
{moduleRowColArray[index]?.map((item) => (
{moduleRowColArray[index]?.map((item, index2) => (
<>
<td className="al-c">{item.moduleMaxRows}</td>
{colspan > 1 && <td className="al-c">{item.mixModuleMaxRows}</td>}
{/* {colspan > 1 && <td className="al-c">{item.mixModuleMaxRows}</td>} */}
{colspan > 1 && index2 === moduleRowColArray[index].length - 1 && <td className="al-c">{item.maxRow}</td>}
</>
))}
</tr>

View File

@ -92,7 +92,7 @@ const Trestle = forwardRef((props, ref) => {
useEffect(() => {
if (raftBaseList.length > 0) {
setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null)
setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === selectedRoof?.raft) ?? null)
} else {
setSelectedRaftBase(null)
}
@ -125,6 +125,12 @@ const Trestle = forwardRef((props, ref) => {
useEffect(() => {
if (constructionList.length > 0) {
setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null)
if (constructionList.filter((construction) => construction.constPossYn === 'Y').length === 0) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error4', [selectedRoof?.nameJp]), // .
icon: 'warning',
})
}
} else {
setSelectedConstruction(null)
}
@ -143,6 +149,19 @@ const Trestle = forwardRef((props, ref) => {
return 'no-click'
}
const onChangeLength = (e) => {
setLengthBase(e)
dispatch({
type: 'SET_LENGTH',
roof: {
length: e,
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raft: selectedRaftBase?.clCode,
},
})
}
const onChangeRaftBase = (e) => {
setSelectedRaftBase(e)
dispatch({
@ -150,7 +169,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: e.clCode,
raft: e.clCode,
},
})
}
@ -162,7 +181,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: selectedRaftBase?.clCode,
raft: selectedRaftBase?.clCode,
trestleMkrCd: e.trestleMkrCd,
},
})
@ -175,7 +194,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: selectedRaftBase?.clCode,
raft: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: e.constMthdCd,
},
@ -189,7 +208,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: selectedRaftBase?.clCode,
raft: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: e.roofBaseCd,
@ -210,7 +229,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: selectedRaftBase?.clCode,
raft: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: selectedRoofBase.roofBaseCd,
@ -224,7 +243,8 @@ const Trestle = forwardRef((props, ref) => {
snowGdPossYn: constructionList[index].snowGdPossYn,
cvrYn: constructionList[index].cvrYn,
mixMatlNo: selectedModules.mixMatlNo,
workingWidth: selectedRoof?.length?.toString() ?? '',
// workingWidth: selectedRoof?.length?.toString() ?? '',
workingWidth: lengthBase,
},
})
@ -241,11 +261,12 @@ const Trestle = forwardRef((props, ref) => {
return {
...selectedRoof,
hajebichi,
lenBase: lengthBase,
length: lengthBase,
eavesMargin,
ridgeMargin,
kerabaMargin,
roofIndex: selectedRoof.index,
raft: selectedRaftBase?.clCode,
trestle: {
hajebichi: hajebichi,
length: lengthBase,
@ -282,6 +303,7 @@ const Trestle = forwardRef((props, ref) => {
ridgeMargin,
kerabaMargin,
roofIndex: roof.index,
raft: selectedRaftBase?.clCode,
trestle: {
length: lengthBase,
hajebichi: hajebichi,
@ -328,7 +350,7 @@ const Trestle = forwardRef((props, ref) => {
}
if (!roof.trestle?.roofBaseCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // .
title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // .
icon: 'warning',
})
result = false
@ -336,7 +358,7 @@ const Trestle = forwardRef((props, ref) => {
}
if (!roof.construction?.constTp) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error4', [roof.nameJp]), // .
title: getMessage('modal.module.basic.settting.module.error12', [roof.nameJp]), // .
icon: 'warning',
})
result = false
@ -354,7 +376,7 @@ const Trestle = forwardRef((props, ref) => {
}
}
if (['C', 'R'].includes(roof.raftAuth)) {
if (!roof?.raftBaseCd) {
if (!roof?.raft) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error6', [roof.nameJp]), // .
icon: 'warning',
@ -457,7 +479,7 @@ const Trestle = forwardRef((props, ref) => {
addRoof: newRoofs[index],
trestle: {
...roof.trestle,
raftBaseCd: roof.raftBaseCd,
raft: roof.raftBaseCd,
},
construction: {
// ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp),
@ -482,8 +504,6 @@ const Trestle = forwardRef((props, ref) => {
return false
}
const onMarginCheck = (target, data) => {}
useImperativeHandle(ref, () => ({
isComplete,
}))
@ -517,7 +537,7 @@ const Trestle = forwardRef((props, ref) => {
type="text"
className="input-origin block"
value={lengthBase}
onChange={(e) => setLengthBase(e.target.value)}
onChange={(e) => onChangeLength(e.target.value)}
disabled={selectedRoof.lenAuth === 'R'}
/>
</div>
@ -666,46 +686,67 @@ const Trestle = forwardRef((props, ref) => {
</div>
</div>
<div className="module-area mt10">
<div className="module-input-area">
<div className="module-area-title">{getMessage('modal.module.basic.setting.module.placement.area')}</div>
<div className="outline-form mr15">
<span>{getMessage('modal.module.basic.setting.module.placement.area.eaves')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={eavesMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
onChange={(e) => setEavesMargin(+e.target.value)}
/>
<div className="module-input-wrap">
<div className="outline-form mr15">
<span>{getMessage('modal.module.basic.setting.module.placement.area.eaves')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={eavesMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
onChange={(e) => setEavesMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form mr15">
<span>{getMessage('modal.module.basic.setting.module.placement.area.ridge')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={ridgeMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
onChange={(e) => setRidgeMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form ">
<span>{getMessage('modal.module.basic.setting.module.placement.area.keraba')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={kerabaMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
onChange={(e) => setKerabaMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form mr15">
<span>{getMessage('modal.module.basic.setting.module.placement.area.ridge')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={ridgeMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
onChange={(e) => setRidgeMargin(+e.target.value)}
/>
</div>
<div className="module-input-area">
<div className="module-area-title">{getMessage('modal.module.basic.setting.module.placement.margin')}</div>
<div className="module-input-wrap">
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.placement.margin.horizontal')}</span>
<div className="input-grid mr10">
<input type="text" className="input-origin block" defaultValue={trestleDetail?.moduleIntvlHor} readOnly />
</div>
<span className="thin">mm</span>
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form ">
<span>{getMessage('modal.module.basic.setting.module.placement.area.keraba')}</span>
<div className="input-grid mr10">
<input
type="number"
className="input-origin block"
value={kerabaMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
onChange={(e) => setKerabaMargin(+e.target.value)}
/>
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.placement.margin.vertical')}</span>
<div className="input-grid mr10">
<input type="text" className="input-origin block" defaultValue={trestleDetail?.moduleIntvlVer} readOnly />
</div>
<span className="thin">mm</span>
</div>
<span className="thin">mm</span>
</div>
</div>
</div>

View File

@ -75,19 +75,19 @@ export default function Header(props) {
userSession.storeId === 'T01'
? [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
{ id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
]
: userSession.groupId === '60000'
? [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
{ id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
]
: [
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 1, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
],
)

View File

@ -18,7 +18,7 @@ export function useMasterController() {
*/
const getRoofMaterialList = async () => {
return await get({ url: '/api/v1/master/getRoofMaterialList' }).then((res) => {
console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res)
// console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res)
return res
})
}

View File

@ -310,6 +310,7 @@ export const useEstimateController = (planNo, flag) => {
//봄 컴포넌트 제품은 0으로
item.openFlg = '0'
item.unitOpenFlg = '0'
}
}
})

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ const RAFT_BASE_CODE = '203800'
const trestleReducer = (state, action) => {
switch (action.type) {
case 'SET_LENGTH':
case 'SET_RAFT_BASE':
case 'SET_TRESTLE_MAKER':
case 'SET_CONST_MTHD':
@ -24,7 +25,7 @@ const trestleReducer = (state, action) => {
moduleTpCd: action.roof.module?.itemTp ?? '',
roofMatlCd: action.roof?.roofMatlCd ?? '',
hajebichi: action.roof?.hajebichi ?? 0,
raftBaseCd: action.roof?.raftBaseCd ?? null,
raft: action.roof?.raft ?? null,
trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null,
constMthdCd: action.roof.trestle?.constMthdCd ?? null,
constTp: action.roof.construction?.constTp ?? null,
@ -71,7 +72,6 @@ export function useModuleTrestle(props) {
useEffect(() => {
const raftCodeList = findCommonCode(RAFT_BASE_CODE)
setRaftBaseList(raftCodeList)
setTrestleList([])
setConstMthdList([])
@ -96,11 +96,15 @@ export function useModuleTrestle(props) {
useEffect(() => {
if (trestleState) {
handleSetTrestleList()
if (!trestleState?.trestleMkrCd) {
setConstMthdList([])
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
setEavesMargin(0)
setRidgeMargin(0)
setKerabaMargin(0)
return
}
@ -109,6 +113,9 @@ export function useModuleTrestle(props) {
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
setEavesMargin(0)
setRidgeMargin(0)
setKerabaMargin(0)
return
}
@ -116,12 +123,18 @@ export function useModuleTrestle(props) {
if (!trestleState?.roofBaseCd) {
setConstructionList([])
setTrestleDetail(null)
setEavesMargin(0)
setRidgeMargin(0)
setKerabaMargin(0)
return
}
handleSetConstructionList()
if (!trestleState?.constTp) {
setTrestleDetail(null)
setEavesMargin(0)
setRidgeMargin(0)
setKerabaMargin(0)
return
}
@ -136,7 +149,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
raftBaseCd: trestleState?.raft ?? '',
})
.then((res) => {
if (res?.data) setTrestleList(res.data)
@ -152,7 +165,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
raftBaseCd: trestleState?.raft ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
})
.then((res) => {
@ -169,7 +182,7 @@ export function useModuleTrestle(props) {
getTrestleList({
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
raftBaseCd: trestleState?.raft ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState?.constMthdCd ?? '',
})
@ -195,7 +208,7 @@ export function useModuleTrestle(props) {
stdWindSpeed: trestleState.stdWindSpeed ?? '',
stdSnowLd: trestleState.stdSnowLd ?? '',
inclCd: trestleState.inclCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
raftBaseCd: trestleState.raft ?? '',
roofPitch: Math.round(trestleState.roofPitch) ?? '',
})
.then((res) => {
@ -224,7 +237,8 @@ export function useModuleTrestle(props) {
constTp: trestleState.constTp ?? '',
mixMatlNo: trestleState.mixMatlNo ?? '',
roofPitch: trestleState.roofPitch ?? '',
workingWidth: trestleState.workingWidth ?? '',
// workingWidth: trestleState.length ?? '',
workingWidth: lengthBase ?? '',
},
])
.then((res) => {

View File

@ -2251,7 +2251,15 @@ export const useTrestle = () => {
let halfMaxX
let halfMaxY
const { direction, trestleDetail } = surface
const { moduleIntvlHor, moduleIntvlVer } = trestleDetail
let moduleIntvlHor, moduleIntvlVer
if (+roofSizeSet === 3) {
//육지붕의 경우 값 고정
moduleIntvlHor = 300
moduleIntvlVer = 100
} else {
moduleIntvlHor = trestleDetail.moduleIntvlHor
moduleIntvlVer = trestleDetail.moduleIntvlVer
}
if (direction === 'south' || direction === 'north') {
maxX = width + moduleIntvlHor / 10

View File

@ -469,7 +469,7 @@ export function useRoofAllocationSetting(id) {
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
return { ...selectedRoofMaterial, selected: roof.selected }
return { ...selectedRoofMaterial, selected: roof.selected, index }
}
return roof
})

View File

@ -14,7 +14,7 @@ import { useMouse } from '@/hooks/useMouse'
import { useLine } from '@/hooks/useLine'
import { useTempGrid } from '@/hooks/useTempGrid'
import { useEffect, useRef } from 'react'
import { distanceBetweenPoints } from '@/util/canvas-util'
import { calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
import { fabric } from 'fabric'
import { calculateAngle } from '@/util/qpolygon-utils'
import {
@ -37,12 +37,13 @@ import { useSurfaceShapeBatch } from './useSurfaceShapeBatch'
import { roofDisplaySelector } from '@/store/settingAtom'
import { useRoofFn } from '@/hooks/common/useRoofFn'
import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty'
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
// 배치면 그리기
export function usePlacementShapeDrawing(id) {
const canvas = useRecoilValue(canvasState)
const roofDisplay = useRecoilValue(roofDisplaySelector)
const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } =
const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseLine } =
useEvent()
// const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } =
// useContext(EventContext)
@ -118,6 +119,7 @@ export function usePlacementShapeDrawing(id) {
}, [type])
const clear = () => {
addCanvasMouseEventListener('mouse:move', mouseMove)
setLength1(0)
setLength2(0)
@ -173,6 +175,80 @@ export function usePlacementShapeDrawing(id) {
}
}
/*
mouseMove
*/
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
const roofAdsorptionPoints = useRef([])
const intersectionPoints = useRef([])
const { getAdsorptionPoints } = useAdsorptionPoint()
const mouseMove = (e) => {
removeMouseLine();
const pointer = canvas.getPointer(e.e)
const roofsPoints = roofs.map((roof) => roof.points).flat()
roofAdsorptionPoints.current = [...roofsPoints]
const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isFixed)
const otherAdsorptionPoints = []
auxiliaryLines.forEach((line1) => {
auxiliaryLines.forEach((line2) => {
if (line1 === line2) {
return
}
const intersectionPoint = calculateIntersection(line1, line2)
if (!intersectionPoint || intersectionPoints.current.some((point) => point.x === intersectionPoint.x && point.y === intersectionPoint.y)) {
return
}
otherAdsorptionPoints.push(intersectionPoint)
})
})
let innerLinePoints = []
canvas
.getObjects()
.filter((obj) => obj.innerLines)
.forEach((polygon) => {
polygon.innerLines.forEach((line) => {
innerLinePoints.push({ x: line.x1, y: line.y1 })
innerLinePoints.push({ x: line.x2, y: line.y2 })
})
})
const adsorptionPoints = [
...getAdsorptionPoints(),
...roofAdsorptionPoints.current,
...otherAdsorptionPoints,
...intersectionPoints.current,
...innerLinePoints,
]
let arrivalPoint = { x: pointer.x, y: pointer.y }
let adsorptionPoint = findClosestPoint(pointer, adsorptionPoints)
if (adsorptionPoint && distanceBetweenPoints(pointer, adsorptionPoint) <= adsorptionRange) {
arrivalPoint = { ...adsorptionPoint }
}
const horizontalLine = new fabric.Line([-1 * canvas.width, arrivalPoint.y, 2 * canvas.width, arrivalPoint.y], {
stroke: 'red',
strokeWidth: 1,
selectable: false,
name: 'mouseLine',
})
const verticalLine = new fabric.Line([arrivalPoint.x, -1 * canvas.height, arrivalPoint.x, 2 * canvas.height], {
stroke: 'red',
strokeWidth: 1,
selectable: false,
name: 'mouseLine',
})
canvas?.add(horizontalLine, verticalLine)
canvas?.renderAll()
}
useEffect(() => {
canvas
?.getObjects()

View File

@ -4,7 +4,7 @@ import { v4 as uuidv4 } from 'uuid'
import { canvasSizeState, canvasState, canvasZoomState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
import { QPolygon } from '@/components/fabric/QPolygon'
import { fontSelector } from '@/store/fontAtom'
import { MENU } from '@/common/common'
import { MENU, POLYGON_TYPE } from '@/common/common'
// 캔버스에 필요한 이벤트
export function useCanvasEvent() {
@ -204,8 +204,12 @@ export function useCanvasEvent() {
if (selected?.length > 0) {
selected.forEach((obj) => {
if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
// if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
if (obj.type === 'QPolygon') {
obj.set({ stroke: 'red' })
if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
obj.set({ strokeWidth: 3 })
}
}
})
canvas.renderAll()
@ -217,10 +221,13 @@ export function useCanvasEvent() {
if (deselected?.length > 0) {
deselected.forEach((obj) => {
if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
if (obj.type === 'QPolygon') {
if (obj.name !== 'moduleSetupSurface') {
obj.set({ stroke: 'black' })
}
if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
obj.set({ strokeWidth: 0.3 })
}
}
})
}
@ -233,16 +240,24 @@ export function useCanvasEvent() {
if (deselected?.length > 0) {
deselected.forEach((obj) => {
if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
if (obj.type === 'QPolygon') {
obj.set({ stroke: 'black' })
if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
//모듈 미선택시 라인 두께 변경
obj.set({ strokeWidth: 0.3 })
}
}
})
}
if (selected?.length > 0) {
selected.forEach((obj) => {
if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
if (obj.type === 'QPolygon') {
obj.set({ stroke: 'red' })
if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) {
//모듈 선택시 라인 두께 변경
obj.set({ strokeWidth: 3 })
}
}
})
}

View File

@ -21,6 +21,7 @@ import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedM
import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController'
import { useCanvasMenu } from './common/useCanvasMenu'
import { QcastContext } from '@/app/QcastProvider'
import { unescapeString } from '@/util/common-utils'
/**
* 플랜 처리
@ -264,7 +265,7 @@ export function usePlan(params = {}) {
objectNo,
planNo: parseInt(newPlan.planNo),
popupType: 1,
popupStatus: sourceDegree.popupStatus,
popupStatus: unescapeString(sourceDegree.popupStatus),
}
console.log('🚀 ~ postObjectPlan ~ degreeData:', degreeData)
await post({ url: `/api/v1/canvas-popup-status`, data: degreeData })

View File

@ -3,7 +3,7 @@
"welcome": "ようこそ。 {0}さん",
"header.menus.home": "ホーム",
"header.menus.management": "見積書管理画面",
"header.menus.management.newStuff": "新規見積登録",
"header.menus.management.newStuff": "新規物件登録",
"header.menus.management.detail": "物件詳細",
"header.menus.management.stuffList": "物件検索",
"header.menus.community": "コミュニティ",
@ -97,9 +97,12 @@
"modal.module.basic.setting.module.under.roof": "屋根下地",
"modal.module.basic.setting.module.setting": "モジュールの選択",
"modal.module.basic.setting.module.placement.area": "モジュール配置領域",
"modal.module.basic.setting.module.placement.margin": "モジュール間の間隙",
"modal.module.basic.setting.module.placement.area.eaves": "軒側",
"modal.module.basic.setting.module.placement.area.ridge": "棟側",
"modal.module.basic.setting.module.placement.area.keraba": "けらぱ",
"modal.module.basic.setting.module.placement.margin.horizontal": "左右",
"modal.module.basic.setting.module.placement.margin.vertical": "上下",
"modal.module.basic.setting.module.hajebichi": "ハゼピッチ",
"modal.module.basic.setting.module.setting.info1": "※勾配の範囲には制限があります。屋根傾斜が2.5値未満10値を超える場合は、施工が可能かどうか施工マニュアルを確認してください。",
"modal.module.basic.setting.module.setting.info2": "※モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ずご確認ください。",
@ -110,26 +113,27 @@
"modal.module.basic.setting.module.standard.snowfall.amount": "積雪量",
"modal.module.basic.setting.module.standard.construction": "標準施工",
"modal.module.basic.setting.module.enforce.construction": "強化施工",
"modal.module.basic.setting.module.multiple.construction": "多施工",
"modal.module.basic.setting.module.multiple.construction": "多施工",
"modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置",
"modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置",
"modal.module.basic.setting.module.select": "モジュール/架台選択",
"modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error4": "施工法を選択してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error4": "設置可能な施工条件がないので設置条件を変更してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})",
"modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
"modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
"modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})",
"modal.module.basic.settting.module.error12": "施工方法を選択してください。\n(屋根材: {0})",
"modal.module.basic.setting.module.placement": "モジュールの配置",
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
"modal.module.basic.setting.module.placement.max.row.amount": "Max数",
"modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max数",
"modal.module.basic.setting.module.placement.max.row.amount": "Max数",
"modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max数",
"modal.module.basic.setting.module.placement.row.amount": "段数",
"modal.module.basic.setting.module.placement.column.amount": "列数",
"modal.module.basic.setting.module.placement.do": "する",
@ -149,9 +153,10 @@
"modal.module.basic.setting.pitch.module.column.amount": "列数",
"modal.module.basic.setting.pitch.module.column.margin": "左右間隔",
"modal.module.basic.setting.prev": "前に戻る",
"modal.module.basic.setting.row.batch": "段・列数指定配置",
"modal.module.basic.setting.row.batch": "レイアウト指定",
"modal.module.basic.setting.passivity.placement": "手動配置",
"modal.module.basic.setting.auto.placement": "自動配置",
"modal.module.basic.setting.auto.row.batch": "自動レイアウト指定",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定",
"modal.circuit.trestle.setting": "回路設定",
"modal.circuit.trestle.setting.alloc.trestle": "架台配置",
@ -183,7 +188,7 @@
"modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02": "シリーズを選択してください。",
"modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num.fix": "番号確定",
"modal.circuit.trestle.setting.step.up.allocation": "昇圧設定",
"modal.circuit.trestle.setting.step.up.allocation.serial.amount": "シリアル枚数",
"modal.circuit.trestle.setting.step.up.allocation.serial.amount": "直列枚数",
"modal.circuit.trestle.setting.step.up.allocation.total.amount": "総回路数",
"modal.circuit.trestle.setting.step.up.allocation.connected": "接続する",
"modal.circuit.trestle.setting.step.up.allocation.circuit.amount": "昇圧回路数",
@ -320,7 +325,7 @@
"modal.object.setting.offset.width": "幅の出幅",
"modal.object.setting.offset.slope": "勾配",
"modal.object.setting.direction.select": "方向の選択",
"modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。",
"modal.placement.surface.setting.info": "①の長さを入力後、③の長さを入力すると②の長さを自動計算します。",
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
"modal.color.picker.title": "色設定",
"modal.color.picker.default.color": "基本色",
@ -1066,13 +1071,13 @@
"roof.line.not.found": "屋根形状がありません",
"roof.material.can.not.delete": "割り当てられた配置面があります。",
"chidory.can.not.install": "千鳥配置できない工法です。",
"module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)",
"module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (JA)",
"module.layout.setup.max.count": "モジュールの単体での最大段数は{0}、最大列数は{1}です。 (JA)",
"module.layout.setup.max.count.multiple": "モジュール{0}の単体での最大段数は{1}、最大列数は{2}です。 (JA)",
"roofAllocation.not.found": "割り当てる屋根がありません。 (JA)",
"modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の最大段数、2種混合の段数を確認して下さい",
"modal.module.basic.setting.module.placement.max.row": "最大段数",
"modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合最大段数",
"modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の単体での最大段数、2種混合の段数を確認して下さい",
"modal.module.basic.setting.module.placement.max.row": "単体で\rの最大段数",
"modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn": "混合",
"modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)"
"modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。"
}

View File

@ -97,9 +97,12 @@
"modal.module.basic.setting.module.under.roof": "지붕밑바탕",
"modal.module.basic.setting.module.setting": "모듈 선택",
"modal.module.basic.setting.module.placement.area": "모듈 배치 영역",
"modal.module.basic.setting.module.placement.margin": "모듈 배치 간격",
"modal.module.basic.setting.module.placement.area.eaves": "처마쪽",
"modal.module.basic.setting.module.placement.area.ridge": "용마루쪽",
"modal.module.basic.setting.module.placement.area.keraba": "케라바쪽",
"modal.module.basic.setting.module.placement.margin.horizontal": "좌우",
"modal.module.basic.setting.module.placement.margin.vertical": "상하",
"modal.module.basic.setting.module.hajebichi": "망둥어 피치",
"modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.",
"modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.",
@ -117,7 +120,7 @@
"modal.module.basic.settting.module.error1": "가대메이커를 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error2": "공법를 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error3": "지붕밑바탕을 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error4": "시공법을 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error4": "설치 조건이 없으므로 설치 조건을 변경하십시오.\n(지붕재: {0})",
"modal.module.basic.settting.module.error5": "L 을 입력해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error6": "서까래 간격을 입력해주세요.\n(지붕재: {0})",
"modal.module.basic.settting.module.error7": "하제비치를 입력해주세요.\n(지붕재: {0})",
@ -125,6 +128,7 @@
"modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
"modal.module.basic.settting.module.error12": "시공법을 선택해주세요.\n(지붕재: {0})",
"modal.module.basic.setting.module.placement": "모듈 배치",
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
@ -152,7 +156,8 @@
"modal.module.basic.setting.prev": "이전",
"modal.module.basic.setting.row.batch": "단·열수 지정 배치",
"modal.module.basic.setting.passivity.placement": "수동 배치",
"modal.module.basic.setting.auto.placement": "설정값으로 자동 배치",
"modal.module.basic.setting.auto.placement": "자동 배치",
"modal.module.basic.setting.auto.row.batch": "자동 단·열수 지정 배치 ",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정",
"modal.circuit.trestle.setting": "회로설정",
"modal.circuit.trestle.setting.alloc.trestle": "가대할당",
@ -1075,5 +1080,5 @@
"modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "혼합 설치 불가능한 모듈입니다.",
"modal.module.basic.setting.module.placement.mix.asg.yn": "혼합",
"modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치"
"modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요."
}

View File

@ -806,28 +806,28 @@
color: #45576F;
margin-left: 5px;
}
.drag-file-box{
padding: 10px;
.btn-area{
padding-bottom: 15px;
border-bottom: 1px solid #ECF0F4;
.file-upload{
display: inline-block;
height: 30px;
background-color: #94A0AD;
padding: 0 10px;
border-radius: 2px;
font-size: 13px;
line-height: 30px;
color: #fff;
font-weight: 500;
cursor: pointer;
transition: background .15s ease-in-out;
&:hover{
background-color: #607F9A;
}
.btn-area{
padding-bottom: 15px;
border-bottom: 1px solid #ECF0F4;
.file-upload{
display: inline-block;
height: 30px;
background-color: #94A0AD;
padding: 0 10px;
border-radius: 2px;
font-size: 13px;
line-height: 30px;
color: #fff;
font-weight: 500;
cursor: pointer;
transition: background .15s ease-in-out;
&:hover{
background-color: #607F9A;
}
}
}
.drag-file-box{
padding: 10px;
.drag-file-area{
position: relative;
margin-top: 15px;

View File

@ -2363,20 +2363,6 @@ $alert-color: #101010;
}
}
.module-area{
display: flex;
align-items: center;
.module-area-title{
flex: none;
font-size: 12px;
color: #fff;
font-weight: 500;
margin-right: 20px;
}
.outline-form{
flex: 1;
}
}
.placement-name-guide{
font-size: 11px;
@ -2422,4 +2408,32 @@ $alert-color: #101010;
overflow: hidden;
height: 0;
}
}
// 2025-05-07 지붕모듈
.module-input-area{
display: flex;
align-items: center;
margin-top: 10px;
.module-area-title{
flex: none;
font-size: 12px;
color: #fff;
font-weight: 500;
margin-right: 20px;
}
.module-input-wrap{
width: 100%;
display: flex;
.outline-form{
width: calc(33.333% - 10px);
margin-right: 15px;
&:last-child{
margin-right: 0;
}
.input-grid{
width: 100%;
}
}
}
}

View File

@ -377,6 +377,7 @@ button{
font-size: 12px;
color: #fff;
line-height: 1.4;
text-align: left;
}
&:hover{
background-color: #2C2C2C;
@ -1023,4 +1024,23 @@ input:checked + .slider {
// alert z-index
.swal2-container{
z-index: 120000;
}
// textarea
.textarea-form{
width: 100%;
outline: none;
resize: none;
border: none;
border: 1px solid #eee;
min-height: 150px;
padding: 10px;
font-size: 13px;
color: #45576F;
border-radius: 2px;
font-family: "Noto Sans JP", sans-serif;
transition: border .15s ease-in-out;
&:focus{
border-color: #94a0ad;
}
}

View File

@ -288,55 +288,56 @@
}
// 커뮤니티
.community_detail{
.community_detail-tit{
font-size: 16px;
color: #101010;
font-weight: 600;
padding-bottom: 14px;
border-bottom: 2px solid #101010;
}
.community_detail-file-wrap{
padding: 24px 0;
border-bottom: 1px solid #E5E5E5;
dt{
font-size: 13px;
color: #101010;
font-weight: 500;
margin-bottom: 15px;
}
dd{
font-size: 12px;
font-weight: 400;
margin-bottom: 3px;
color: #344356;
&:last-child{
margin-bottom: 0;
}
}
}
.community_detail-inner{
max-height: 300px;
overflow-y: auto;
margin-top: 20px;
margin-bottom: 20px;
.community_detail-tit{
font-size: 16px;
color: #101010;
font-weight: 600;
padding-bottom: 14px;
border-bottom: 2px solid #101010;
}
.community_detail-file-wrap{
padding: 24px 0;
border-bottom: 1px solid #E5E5E5;
dt{
font-size: 13px;
color: #101010;
font-weight: 500;
}
dd{
font-size: 12px;
font-weight: 400;
color: #45576F;
line-height: 26px;
word-break: keep-all;
&::-webkit-scrollbar {
width: 4px;
background-color: transparent;
margin-bottom: 3px;
color: #344356;
&:nth-child(2){
margin-top: 15px;
}
&::-webkit-scrollbar-thumb {
background-color: #C1CCD7;
}
&::-webkit-scrollbar-track {
background-color: transparent;
&:last-child{
margin-bottom: 0;
}
}
}
.community_detail-inner{
max-height: 300px;
overflow-y: auto;
margin-top: 20px;
margin-bottom: 20px;
font-size: 13px;
font-weight: 400;
color: #45576F;
line-height: 26px;
word-break: keep-all;
&::-webkit-scrollbar {
width: 4px;
background-color: transparent;
}
&::-webkit-scrollbar-thumb {
background-color: #C1CCD7;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
// 견적 복사
.estimate-copy-info-item{
@ -368,4 +369,117 @@
color: #999;
}
}
}
// 1:1문의
.one-on-one{
.select-wrap{
width: 250px;
}
.input-wrap{
flex: 1 1 auto;
}
&.btn-area{
padding-bottom: 0;
border: none;
margin-left: 10px;
}
&.drag-file-box{
border: 1px solid #eee;
.drag-file-area{
margin-top: 0;
}
}
}
.oneonone-header-wrap{
padding-bottom: 14px;
border-bottom: 2px solid #101010;
.oneonone-title{
font-size: 16px;
color: #101010;
font-weight: 600;
margin-bottom: 14px;
}
}
.oneonone-infor{
display: flex;
align-items: center;
.profile{
position: relative;
padding-left: 26px;
padding-right: 8px;
font-size: 13px;
font-weight: 400;
color: #101010;
&::before{
content: '';
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 24px;
height: 24px;
background: url(./../../public/static/images/sub/oneonone_profile_icon.svg)no-repeat center;
}
&::after{
content: '';
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
width: 1px;
height: 8px;
background-color: #CCCCCC;
}
}
.date{
padding-left: 8px;
font-size: 13px;
font-weight: 400;
color: #101010;
}
}
.oneonone-detail{
padding: 20px;
border: 1px solid #101010;
border-top: none;
.community_detail-file-wrap{
padding-top: 0;
}
.community_detail-inner{
max-height: 110px;
margin-top: 24px;
margin-bottom: 0;
}
}
.oneonone-answer{
margin-top: 8px;
padding: 20px;
border: 1px solid #101010;
.community_detail-inner{
max-height: 110px;
}
.community_detail-file-wrap{
border-top: 1px solid #D4DCE7;
padding: 16px 0 0 0;
border-bottom: none;
}
}
.answer-title-wrap{
display: flex;
align-items: center;
padding-bottom: 14px;
border-bottom: 1px solid #D4DCE7;
.answer-title{
font-size: 14px;
color: #101010;
font-weight: 600;
}
.oneonone-infor{
margin-left: auto;
}
}

View File

@ -145,9 +145,19 @@ export const unescapeString = (str) => {
'&#39;': "'",
}
/*
1. 한번 변환은 {&quot; 변환됨 : 에러 발생 => while 변경
2. 변환할 내용이 없으면 리턴값이 undefined
if (regex.test(str)) {
return str.replace(regex, (matched) => chars[matched] || matched)
}
*/
while (regex.test(str)) {
str = str.replace(regex, (matched) => chars[matched] || matched);
}
return str
}
export const isNullOrUndefined = (value) => {