Merge branch 'dev' of https://git.hanasys.jp/qcast3/qcast-front into feature/jaeyoung
This commit is contained in:
commit
0c67a6b212
@ -1,6 +1,8 @@
|
|||||||
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
|
NEXT_PUBLIC_API_SERVER_PATH="https://dev-api.hanasys.jp"
|
||||||
|
|
||||||
NEXT_PUBLIC_HOST_URL="http://1.248.227.176:4000"
|
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
|
||||||
|
|
||||||
|
NEXT_PUBLIC_API_HOST_URL="http://1.248.227.176:5000"
|
||||||
|
|
||||||
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
||||||
|
|
||||||
@ -9,3 +11,17 @@ NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secr
|
|||||||
|
|
||||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
|
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
|
||||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
|
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
|
||||||
|
|
||||||
|
# 테스트용
|
||||||
|
# AWS_REGION="ap-northeast-2"
|
||||||
|
# AMPLIFY_BUCKET="interplug"
|
||||||
|
# AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
|
||||||
|
# AWS_SECRET_ACCESS_KEY="NDzSvPUo4/ErpPOEs1eZAnoUBilc1FL7YaoHkqe4"
|
||||||
|
# NEXT_PUBLIC_AWS_S3_BASE_URL="https://interplug.s3.ap-northeast-2.amazonaws.com"
|
||||||
|
|
||||||
|
# 실제 일본 서버
|
||||||
|
AWS_REGION="ap-northeast-1"
|
||||||
|
AMPLIFY_BUCKET="files.hanasys.jp"
|
||||||
|
AWS_ACCESS_KEY_ID="AKIA3K4QWLZHFZRJOM2E"
|
||||||
|
AWS_SECRET_ACCESS_KEY="Cw87TjKwnTWRKgORGxYiFU6GUTgu25eUw4eLBNcA"
|
||||||
|
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
|
||||||
@ -1,6 +1,8 @@
|
|||||||
NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/"
|
NEXT_PUBLIC_API_SERVER_PATH="https://api.hanasys.jp/"
|
||||||
|
|
||||||
NEXT_PUBLIC_HOST_URL="http://1.248.227.176:4000"
|
NEXT_PUBLIC_HOST_URL="//1.248.227.176:4000"
|
||||||
|
|
||||||
|
NEXT_PUBLIC_API_HOST_URL="https://www.hanasys.jp/"
|
||||||
|
|
||||||
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
||||||
|
|
||||||
@ -11,3 +13,9 @@ NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secr
|
|||||||
# NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"
|
# NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"
|
||||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
|
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin"
|
||||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
|
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin"
|
||||||
|
|
||||||
|
AWS_REGION="ap-northeast-2"
|
||||||
|
AMPLIFY_BUCKET="interplug"
|
||||||
|
AWS_ACCESS_KEY_ID="AKIAVWMWJCUXFHEAZ4FR"
|
||||||
|
AWS_SECRET_ACCESS_KEY="NDzSvPUo4/ErpPOEs1eZAnoUBilc1FL7YaoHkqe4"
|
||||||
|
NEXT_PUBLIC_AWS_S3_BASE_URL="//files.hanasys.jp"
|
||||||
@ -12,6 +12,7 @@
|
|||||||
"serve": "node server.js"
|
"serve": "node server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@aws-sdk/client-s3": "^3.772.0",
|
||||||
"ag-grid-react": "^32.0.2",
|
"ag-grid-react": "^32.0.2",
|
||||||
"axios": "^1.7.8",
|
"axios": "^1.7.8",
|
||||||
"big.js": "^6.2.2",
|
"big.js": "^6.2.2",
|
||||||
@ -24,7 +25,7 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"mathjs": "^13.0.2",
|
"mathjs": "^13.0.2",
|
||||||
"mssql": "^11.0.1",
|
"mssql": "^11.0.1",
|
||||||
"next": "14.2.26",
|
"next": "14.2.28",
|
||||||
"next-international": "^1.2.4",
|
"next-international": "^1.2.4",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
@ -38,6 +39,7 @@
|
|||||||
"react-responsive-modal": "^6.4.2",
|
"react-responsive-modal": "^6.4.2",
|
||||||
"react-select": "^5.8.1",
|
"react-select": "^5.8.1",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
|
"sharp": "^0.33.5",
|
||||||
"sqlite": "^5.1.1",
|
"sqlite": "^5.1.1",
|
||||||
"sqlite3": "^5.1.7",
|
"sqlite3": "^5.1.7",
|
||||||
"sweetalert2": "^11.14.1",
|
"sweetalert2": "^11.14.1",
|
||||||
|
|||||||
Binary file not shown.
69
src/app/api/image/cad/route.js
Normal file
69
src/app/api/image/cad/route.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
||||||
|
|
||||||
|
const Bucket = process.env.AMPLIFY_BUCKET
|
||||||
|
const s3 = new S3Client({
|
||||||
|
region: process.env.AWS_REGION,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const uploadImage = async (file) => {
|
||||||
|
const Body = Buffer.from(await file.arrayBuffer())
|
||||||
|
const Key = `cads/${file.name}`
|
||||||
|
const ContentType = file.ContentType
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new PutObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
Body,
|
||||||
|
ContentType,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: `https://${process.env.AMPLIFY_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${Key}`,
|
||||||
|
fileName: Key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(req) {
|
||||||
|
try {
|
||||||
|
const formData = await req.formData()
|
||||||
|
const file = formData.get('file')
|
||||||
|
|
||||||
|
const result = await uploadImage(file)
|
||||||
|
|
||||||
|
return NextResponse.json(result)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return NextResponse.json({ error: 'Failed to upload image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DELETE(req) {
|
||||||
|
try {
|
||||||
|
const searchParams = req.nextUrl.searchParams
|
||||||
|
const Key = `cads/${searchParams.get('fileName')}`
|
||||||
|
console.log('🚀 ~ DELETE ~ Key:', Key)
|
||||||
|
|
||||||
|
if (!Key) {
|
||||||
|
return NextResponse.json({ error: 'fileName parameter is required' }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new DeleteObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return NextResponse.json({ message: '이미지 삭제 성공' }, { status: 200 })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('S3 Delete Error:', error)
|
||||||
|
return NextResponse.json({ error: 'Failed to delete image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
133
src/app/api/image/canvas/route.js
Normal file
133
src/app/api/image/canvas/route.js
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
const Bucket = process.env.AMPLIFY_BUCKET
|
||||||
|
const s3 = new S3Client({
|
||||||
|
region: process.env.AWS_REGION,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const checkArea = (obj) => {
|
||||||
|
const { width, height, left, top } = obj
|
||||||
|
|
||||||
|
if (left < 0 || top < 0 || width > 1600 || height > 1000) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const cropImage = async (Key, width, height, left, top) => {
|
||||||
|
try {
|
||||||
|
const checkResult = checkArea({ width, height, left, top })
|
||||||
|
|
||||||
|
// Get the image from S3
|
||||||
|
const { Body } = await s3.send(
|
||||||
|
new GetObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Convert stream to buffer
|
||||||
|
const chunks = []
|
||||||
|
for await (const chunk of Body) {
|
||||||
|
chunks.push(chunk)
|
||||||
|
}
|
||||||
|
const imageBuffer = Buffer.concat(chunks)
|
||||||
|
|
||||||
|
let processedImage
|
||||||
|
if (!checkResult) {
|
||||||
|
processedImage = await sharp(imageBuffer).toBuffer()
|
||||||
|
} else {
|
||||||
|
processedImage = await sharp(imageBuffer)
|
||||||
|
.extract({
|
||||||
|
width: parseInt(width),
|
||||||
|
height: parseInt(height),
|
||||||
|
left: parseInt(left),
|
||||||
|
top: parseInt(top),
|
||||||
|
})
|
||||||
|
.png()
|
||||||
|
.toBuffer()
|
||||||
|
}
|
||||||
|
return processedImage
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing image:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(req) {
|
||||||
|
try {
|
||||||
|
const formData = await req.formData()
|
||||||
|
const file = formData.get('file')
|
||||||
|
const objectNo = formData.get('objectNo')
|
||||||
|
const planNo = formData.get('planNo')
|
||||||
|
const type = formData.get('type')
|
||||||
|
const width = formData.get('width')
|
||||||
|
const height = formData.get('height')
|
||||||
|
const left = formData.get('left')
|
||||||
|
const top = formData.get('top')
|
||||||
|
|
||||||
|
const OriginalKey = `Drawing/${uuidv4()}`
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 원본 이미지를 우선 저장한다.
|
||||||
|
* 이미지 이름이 겹지는 현상을 방지하기 위해 uuid 를 사용한다.
|
||||||
|
*/
|
||||||
|
await s3.send(
|
||||||
|
new PutObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key: OriginalKey,
|
||||||
|
Body: Buffer.from(await file.arrayBuffer()),
|
||||||
|
ContentType: 'image/png',
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 저장된 원본 이미지를 기준으로 크롭여부를 결정하여 크롭 이미지를 저장한다.
|
||||||
|
*/
|
||||||
|
const bufferImage = await cropImage(OriginalKey, width, height, left, top)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 크롭 이미지 이름을 결정한다.
|
||||||
|
*/
|
||||||
|
const Key = `Drawing/${objectNo}_${planNo}_${type}.png`
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 크롭이 완료된 이미지를 업로드한다.
|
||||||
|
*/
|
||||||
|
await s3.send(
|
||||||
|
new PutObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
Body: bufferImage,
|
||||||
|
ContentType: 'image/png',
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 크롭이미지 저장이 완료되면 원본 이미지를 삭제한다.
|
||||||
|
*/
|
||||||
|
await s3.send(
|
||||||
|
new DeleteObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key: OriginalKey,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
filePath: `https://${process.env.AMPLIFY_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${Key}`,
|
||||||
|
fileName: Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(result)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in POST:', error)
|
||||||
|
return NextResponse.json({ error: 'Failed to process and upload image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/app/api/image/map/route.js
Normal file
78
src/app/api/image/map/route.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
||||||
|
|
||||||
|
const Bucket = process.env.AMPLIFY_BUCKET
|
||||||
|
const s3 = new S3Client({
|
||||||
|
region: process.env.AWS_REGION,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export async function GET(req) {
|
||||||
|
try {
|
||||||
|
const searchParams = req.nextUrl.searchParams
|
||||||
|
const q = searchParams.get('q')
|
||||||
|
const fileNm = searchParams.get('fileNm')
|
||||||
|
const zoom = searchParams.get('zoom')
|
||||||
|
|
||||||
|
/** 구글 맵을 이미지로 변경하기 위한 API */
|
||||||
|
const API_KEY = 'AIzaSyDO7nVR1N_D2tKy60hgGFavpLaXkHpiHpc'
|
||||||
|
const targetUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${q}&zoom=${zoom}&maptype=satellite&size=640x640&scale=1&key=${API_KEY}`
|
||||||
|
const decodeUrl = decodeURIComponent(targetUrl)
|
||||||
|
|
||||||
|
/** 구글 맵을 이미지로 변경하기 위한 API 호출 */
|
||||||
|
const response = await fetch(decodeUrl)
|
||||||
|
const data = await response.arrayBuffer()
|
||||||
|
// const buffer = Buffer.from(data)
|
||||||
|
|
||||||
|
/** 변경된 이미지를 S3에 업로드 */
|
||||||
|
const Body = Buffer.from(data)
|
||||||
|
const Key = `maps/${fileNm}`
|
||||||
|
const ContentType = 'image/png'
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new PutObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
Body,
|
||||||
|
ContentType,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
filePath: `https://${process.env.AMPLIFY_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${Key}`,
|
||||||
|
fileName: Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(result)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return NextResponse.json({ error: 'Failed to upload image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DELETE(req) {
|
||||||
|
try {
|
||||||
|
const searchParams = req.nextUrl.searchParams
|
||||||
|
const Key = `maps/${searchParams.get('fileName')}`
|
||||||
|
console.log('🚀 ~ DELETE ~ Key:', Key)
|
||||||
|
|
||||||
|
if (!Key) {
|
||||||
|
return NextResponse.json({ error: 'fileName parameter is required' }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new DeleteObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return NextResponse.json({ message: '이미지 삭제 성공' }, { status: 200 })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('S3 Delete Error:', error)
|
||||||
|
return NextResponse.json({ error: 'Failed to delete image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/app/api/image/upload/route.js
Normal file
72
src/app/api/image/upload/route.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { NextResponse } from 'next/server'
|
||||||
|
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
||||||
|
|
||||||
|
const Bucket = process.env.AMPLIFY_BUCKET
|
||||||
|
const s3 = new S3Client({
|
||||||
|
region: process.env.AWS_REGION,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const uploadImage = async (file) => {
|
||||||
|
const Body = Buffer.from(await file.arrayBuffer())
|
||||||
|
const Key = `upload/${file.name}`
|
||||||
|
const ContentType = file.ContentType
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new PutObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
Body,
|
||||||
|
ContentType,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: `https://${process.env.AMPLIFY_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${Key}`,
|
||||||
|
fileName: Key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(req) {
|
||||||
|
try {
|
||||||
|
const formData = await req.formData()
|
||||||
|
const file = formData.get('file')
|
||||||
|
|
||||||
|
const result = await uploadImage(file)
|
||||||
|
result.message = '이미지 업로드 성공'
|
||||||
|
|
||||||
|
return NextResponse.json(result)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return NextResponse.json({ error: 'Failed to upload image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DELETE(req) {
|
||||||
|
try {
|
||||||
|
const searchParams = req.nextUrl.searchParams
|
||||||
|
const fileName = searchParams.get('fileName')
|
||||||
|
|
||||||
|
if (!fileName) {
|
||||||
|
return NextResponse.json({ error: 'fileName parameter is required' }, { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const Key = `upload/${fileName}`
|
||||||
|
console.log('🚀 ~ DELETE ~ Key:', Key)
|
||||||
|
|
||||||
|
await s3.send(
|
||||||
|
new DeleteObjectCommand({
|
||||||
|
Bucket,
|
||||||
|
Key,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return NextResponse.json({ message: '이미지 삭제 성공' }, { status: 200 })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('S3 Delete Error:', error)
|
||||||
|
return NextResponse.json({ error: 'Failed to delete image' }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -60,7 +60,7 @@ export default function Estimate({}) {
|
|||||||
|
|
||||||
const [cableItemList, setCableItemList] = useState([]) //케이블 리스트
|
const [cableItemList, setCableItemList] = useState([]) //케이블 리스트
|
||||||
const [cableItem, setCableItem] = useState('') //케이블 선택값
|
const [cableItem, setCableItem] = useState('') //케이블 선택값
|
||||||
|
const [cableDbItem, setCableDbItem] = useState('') //케이블 선택값
|
||||||
const [startDate, setStartDate] = useState(new Date())
|
const [startDate, setStartDate] = useState(new Date())
|
||||||
const singleDatePickerProps = {
|
const singleDatePickerProps = {
|
||||||
startDate,
|
startDate,
|
||||||
@ -98,7 +98,7 @@ export default function Estimate({}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initEstimate = (currPid = currentPid) => {
|
const initEstimate = (currPid = currentPid) => {
|
||||||
console.log('🚀 ~ initEstimate ~ currPid:', currPid)
|
// console.log('🚀 ~ initEstimate ~ currPid:', currPid)
|
||||||
closeAll()
|
closeAll()
|
||||||
setObjectNo(objectRecoil.floorPlanObjectNo)
|
setObjectNo(objectRecoil.floorPlanObjectNo)
|
||||||
|
|
||||||
@ -117,6 +117,7 @@ export default function Estimate({}) {
|
|||||||
item.value = item.clRefChr1
|
item.value = item.clRefChr1
|
||||||
item.label = item.clRefChr2
|
item.label = item.clRefChr2
|
||||||
})
|
})
|
||||||
|
// console.log(code2)
|
||||||
setCableItemList(code2)
|
setCableItemList(code2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ export default function Estimate({}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('🚀 ~ Estimate ~ selectedPlan:', selectedPlan)
|
// console.log('🚀 ~ Estimate ~ selectedPlan:', selectedPlan)
|
||||||
if (selectedPlan) initEstimate(selectedPlan.planNo)
|
if (selectedPlan) initEstimate(selectedPlan.planNo)
|
||||||
}, [selectedPlan])
|
}, [selectedPlan])
|
||||||
|
|
||||||
@ -739,6 +740,18 @@ export default function Estimate({}) {
|
|||||||
setCableItem(value)
|
setCableItem(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 케이블 select 변경시 */
|
||||||
|
const onChangeDisplayDoubleCableItem = (value, itemList) => {
|
||||||
|
itemList.map((item, index) => {
|
||||||
|
if (item.dispCableFlg === '1' && item.itemTpCd === 'M12') {
|
||||||
|
if (value !== '') {
|
||||||
|
onChangeDisplayItem(value, item.dispOrder, index, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setCableDbItem(value)
|
||||||
|
}
|
||||||
|
|
||||||
// 아이템 자동완성 검색시 아이템 추가/변경시
|
// 아이템 자동완성 검색시 아이템 추가/변경시
|
||||||
const onChangeDisplayItem = (itemId, dispOrder, index, flag) => {
|
const onChangeDisplayItem = (itemId, dispOrder, index, flag) => {
|
||||||
const param = {
|
const param = {
|
||||||
@ -1088,15 +1101,20 @@ export default function Estimate({}) {
|
|||||||
item.showSaleTotPrice = '0'
|
item.showSaleTotPrice = '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
|
if (item.dispCableFlg === '1' ) {
|
||||||
dispCableFlgCnt++
|
dispCableFlgCnt++
|
||||||
setCableItem(item.itemId)
|
if(item.itemTpCd === 'M12') {
|
||||||
|
setCableDbItem(item.itemId)
|
||||||
|
}else{
|
||||||
|
setCableItem(item.itemId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (dispCableFlgCnt === 0) {
|
if (dispCableFlgCnt === 0) {
|
||||||
setCableItem('100038')
|
setCableItem('100038')
|
||||||
|
setCableDbItem('100037')
|
||||||
}
|
}
|
||||||
|
|
||||||
let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
||||||
@ -1159,14 +1177,20 @@ export default function Estimate({}) {
|
|||||||
dispCableFlgCnt++
|
dispCableFlgCnt++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
|
if (item.dispCableFlg === '1'){
|
||||||
setCableItem(item.itemId)
|
|
||||||
|
if(item.itemTpCd === 'M12') {
|
||||||
|
setCableDbItem(item.itemId)
|
||||||
|
}else{
|
||||||
|
setCableItem(item.itemId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (dispCableFlgCnt === 0) {
|
if (dispCableFlgCnt === 0) {
|
||||||
setCableItem('100038')
|
setCableItem('100038')
|
||||||
|
setCableDbItem('100037')
|
||||||
}
|
}
|
||||||
|
|
||||||
totals.vatPrice = totals.supplyPrice * 0.1
|
totals.vatPrice = totals.supplyPrice * 0.1
|
||||||
@ -1227,6 +1251,7 @@ export default function Estimate({}) {
|
|||||||
|
|
||||||
if (dispCableFlgCnt === 0) {
|
if (dispCableFlgCnt === 0) {
|
||||||
setCableItem('100038')
|
setCableItem('100038')
|
||||||
|
setCableDbItem('100037')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [estimateContextState?.itemList, cableItemList])
|
}, [estimateContextState?.itemList, cableItemList])
|
||||||
@ -1831,6 +1856,7 @@ export default function Estimate({}) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="product-price-wrap ml10">
|
<div className="product-price-wrap ml10">
|
||||||
|
<div className="product-price-tit">{getMessage('estimate.detail.header.singleCable')}</div>
|
||||||
<div className="select-wrap">
|
<div className="select-wrap">
|
||||||
<select
|
<select
|
||||||
className="select-light"
|
className="select-light"
|
||||||
@ -1840,11 +1866,34 @@ export default function Estimate({}) {
|
|||||||
value={cableItem}
|
value={cableItem}
|
||||||
>
|
>
|
||||||
{cableItemList.length > 0 &&
|
{cableItemList.length > 0 &&
|
||||||
cableItemList.map((row) => (
|
cableItemList.map((row) => {
|
||||||
<option key={row.clRefChr1} value={row.clRefChr1}>
|
if(!row.clRefChr2.includes('S')){
|
||||||
{row.clRefChr2}
|
return <option key={row.clRefChr1} value={row.clRefChr1}>
|
||||||
</option>
|
{row.clRefChr2}
|
||||||
))}
|
</option>
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="product-price-wrap ml10">
|
||||||
|
<div className="product-price-tit">{getMessage('estimate.detail.header.doubleCable')}</div>
|
||||||
|
<div className="select-wrap">
|
||||||
|
<select
|
||||||
|
className="select-light"
|
||||||
|
onChange={(e) => {
|
||||||
|
onChangeDisplayDoubleCableItem(e.target.value, estimateContextState.itemList)
|
||||||
|
}}
|
||||||
|
value={cableDbItem}
|
||||||
|
>
|
||||||
|
{cableItemList.length > 0 &&
|
||||||
|
cableItemList.map((row) => {
|
||||||
|
if(row.clRefChr2.includes('S')){
|
||||||
|
return <option key={row.clRefChr1} value={row.clRefChr1}>
|
||||||
|
{row.clRefChr2.replace('S','')}
|
||||||
|
</option>
|
||||||
|
}
|
||||||
|
})}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1927,7 +1976,7 @@ export default function Estimate({}) {
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={item?.dispOrder}
|
id={item?.dispOrder}
|
||||||
disabled={!!item?.paDispOrder || item.dispCableFlg === '1'}
|
disabled={!!item?.paDispOrder || item.dispCableFlg === '1X'}
|
||||||
onChange={() => onChangeSelect(item.dispOrder)}
|
onChange={() => onChangeSelect(item.dispOrder)}
|
||||||
checked={!!selection.has(item.dispOrder)}
|
checked={!!selection.has(item.dispOrder)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -120,7 +120,7 @@ export default function ImgLoad() {
|
|||||||
value={refImage ? (refImage?.name ?? '') : (currentCanvasPlan?.bgImageName ?? '')}
|
value={refImage ? (refImage?.name ?? '') : (currentCanvasPlan?.bgImageName ?? '')}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
{refImage && <button className="img-check" onClick={handleFileDelete}></button>}
|
{currentCanvasPlan?.bgImageName && <button className="img-check" onClick={handleFileDelete}></button>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -37,6 +37,7 @@ export function useCanvasPopupStatusController(param = 1) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getModuleSelection = async (popupTypeParam) => {
|
const getModuleSelection = async (popupTypeParam) => {
|
||||||
|
if (!currentCanvasPlan.objectNo || !currentCanvasPlan.planNo) return
|
||||||
const result = await promiseGet({
|
const result = await promiseGet({
|
||||||
url: `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupTypeParam}`,
|
url: `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupTypeParam}`,
|
||||||
})
|
})
|
||||||
@ -48,7 +49,7 @@ export function useCanvasPopupStatusController(param = 1) {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
return result.data
|
return result?.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +60,7 @@ export function useCanvasPopupStatusController(param = 1) {
|
|||||||
let resultData = {}
|
let resultData = {}
|
||||||
for (let i = 1; i < 3; i++) {
|
for (let i = 1; i < 3; i++) {
|
||||||
const result = await getModuleSelection(i)
|
const result = await getModuleSelection(i)
|
||||||
if (!result.objectNo) return
|
if (!result?.objectNo) return
|
||||||
if (i === 1) {
|
if (i === 1) {
|
||||||
if (result.popupStatus && unescapeString(result.popupStatus)) {
|
if (result.popupStatus && unescapeString(result.popupStatus)) {
|
||||||
const data = JSON.parse(unescapeString(result.popupStatus))
|
const data = JSON.parse(unescapeString(result.popupStatus))
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { useAxios } from '../useAxios'
|
import { useAxios } from '../useAxios'
|
||||||
@ -7,6 +7,7 @@ import { currentCanvasPlanState } from '@/store/canvasAtom'
|
|||||||
import { useCanvas } from '@/hooks/useCanvas'
|
import { useCanvas } from '@/hooks/useCanvas'
|
||||||
import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions'
|
import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions'
|
||||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
|
import { popSpinnerState } from '@/store/popupAtom'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 배경 이미지 관리
|
* 배경 이미지 관리
|
||||||
@ -15,6 +16,9 @@ import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
|||||||
* 이미지 -> 캔버스 배경에 이미지 로드
|
* 이미지 -> 캔버스 배경에 이미지 로드
|
||||||
* 주소 -> 구글 맵에서 주소 검색 후 이미지로 다운로드 받아서 캔버스 배경에 이미지 로드
|
* 주소 -> 구글 맵에서 주소 검색 후 이미지로 다운로드 받아서 캔버스 배경에 이미지 로드
|
||||||
* .dwg -> api를 통해서 .png로 변환 후 캔버스 배경에 이미지 로드
|
* .dwg -> api를 통해서 .png로 변환 후 캔버스 배경에 이미지 로드
|
||||||
|
*
|
||||||
|
* setCurrentBgImage 에 이미지를 세팅하면 도면에 배경으로 로딩된다.
|
||||||
|
* 다만 S3 Response에 aws 고유 주소가 나오는데 여기서는 cloudfront 사용을 위해서 NEXT_PUBLIC_AWS_S3_BASE_URL 도메인을 사용한다.
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
export function useRefFiles() {
|
export function useRefFiles() {
|
||||||
@ -28,7 +32,8 @@ export function useRefFiles() {
|
|||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||||
const { handleBackImageLoadToCanvas } = useCanvas()
|
const { handleBackImageLoadToCanvas } = useCanvas()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { get, post } = useAxios()
|
const { get, post, del } = useAxios()
|
||||||
|
const setPopSpinnerStore = useSetRecoilState(popSpinnerState)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (refFileMethod === '1') {
|
if (refFileMethod === '1') {
|
||||||
@ -39,6 +44,7 @@ export function useRefFiles() {
|
|||||||
}, [refFileMethod])
|
}, [refFileMethod])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 최초 input type="file" 에 대한 이벤트
|
||||||
* 파일 불러오기 버튼 컨트롤
|
* 파일 불러오기 버튼 컨트롤
|
||||||
* @param {*} file
|
* @param {*} file
|
||||||
*/
|
*/
|
||||||
@ -59,6 +65,10 @@ export function useRefFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 허용하는 파일인지 체크한다
|
||||||
|
* @param {File} file
|
||||||
|
*/
|
||||||
const refFileSetting = (file) => {
|
const refFileSetting = (file) => {
|
||||||
console.log('🚀 ~ refFileSetting ~ file:', file)
|
console.log('🚀 ~ refFileSetting ~ file:', file)
|
||||||
if (file.name.split('.').pop() === 'dwg') {
|
if (file.name.split('.').pop() === 'dwg') {
|
||||||
@ -77,34 +87,40 @@ export function useRefFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 파일 삭제
|
* 이미지 파일 삭제
|
||||||
*/
|
*/
|
||||||
const handleFileDelete = async () => {
|
const handleFileDelete = async () => {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: '삭제하시겠습니까?',
|
text: '삭제하시겠습니까?',
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
confirmFn: async () => {
|
confirmFn: async () => {
|
||||||
setRefImage(null)
|
setPopSpinnerStore(true)
|
||||||
setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: null }))
|
console.log('🚀 ~ handleFileDelete ~ handleFileDelete:', refImage)
|
||||||
|
console.log('🚀 ~ handleFileDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
|
||||||
|
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload?fileName=${currentCanvasPlan.bgImageName}` })
|
||||||
|
setCurrentBgImage(null)
|
||||||
await deleteBackGroundImage({
|
await deleteBackGroundImage({
|
||||||
objectId: currentCanvasPlan.id,
|
objectId: currentCanvasPlan.id,
|
||||||
planNo: currentCanvasPlan.planNo,
|
planNo: currentCanvasPlan.planNo,
|
||||||
})
|
})
|
||||||
|
setPopSpinnerStore(false)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 주소 삭제
|
* 주소 맵 이미지 삭제
|
||||||
*/
|
*/
|
||||||
const handleAddressDelete = async () => {
|
const handleAddressDelete = async () => {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: '삭제하시겠습니까?',
|
text: '삭제하시겠습니까?',
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
confirmFn: async () => {
|
confirmFn: async () => {
|
||||||
|
console.log('🚀 ~ handleAddressDelete ~ handleAddressDelete:', refImage)
|
||||||
|
console.log('🚀 ~ handleAddressDelete ~ currentCanvasPlan.bgImageName:', currentCanvasPlan.bgImageName)
|
||||||
|
await del({ url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?fileName=${currentCanvasPlan.bgImageName}` })
|
||||||
setMapPositionAddress('')
|
setMapPositionAddress('')
|
||||||
setCurrentBgImage(null)
|
setCurrentBgImage(null)
|
||||||
setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null }))
|
|
||||||
await deleteBackGroundImage({
|
await deleteBackGroundImage({
|
||||||
objectId: currentCanvasPlan.id,
|
objectId: currentCanvasPlan.id,
|
||||||
planNo: currentCanvasPlan.planNo,
|
planNo: currentCanvasPlan.planNo,
|
||||||
@ -114,7 +130,7 @@ export function useRefFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 주소로 구글 맵 이미지 다운로드
|
* 주소로 구글 맵 이미지 다운로드하여 캔버스 배경으로 로드
|
||||||
*/
|
*/
|
||||||
const handleMapImageDown = async () => {
|
const handleMapImageDown = async () => {
|
||||||
console.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:')
|
console.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:')
|
||||||
@ -133,15 +149,16 @@ export function useRefFiles() {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const res = await get({
|
const res = await get({
|
||||||
url: `${process.env.NEXT_PUBLIC_HOST_URL}/map/convert?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
|
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/map?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`,
|
||||||
})
|
})
|
||||||
console.log('🚀 ~ handleMapImageDown ~ res:', res)
|
console.log('🚀 ~ handleMapImageDown ~ res:', res)
|
||||||
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
|
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
|
||||||
|
|
||||||
await setBackGroundImage({
|
await setBackGroundImage({
|
||||||
objectId: currentCanvasPlan.id,
|
objectId: currentCanvasPlan.id,
|
||||||
planNo: currentCanvasPlan.planNo,
|
planNo: currentCanvasPlan.planNo,
|
||||||
imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`,
|
// imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`,
|
||||||
|
imagePath: `${res.filePath}`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,16 +166,26 @@ export function useRefFiles() {
|
|||||||
* 배경 이미지 로드를 위한 세팅
|
* 배경 이미지 로드를 위한 세팅
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentBgImage) {
|
// if (!currentBgImage) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
console.log('🚀 ~ useEffect ~ currentBgImage:', currentBgImage)
|
console.log('🚀 ~ useEffect ~ currentBgImage:', currentBgImage)
|
||||||
handleBackImageLoadToCanvas(currentBgImage)
|
if (currentBgImage) {
|
||||||
setCurrentCanvasPlan((prev) => ({
|
handleBackImageLoadToCanvas(currentBgImage)
|
||||||
...prev,
|
setCurrentCanvasPlan((prev) => ({
|
||||||
bgImageName: refImage?.name ?? null,
|
...prev,
|
||||||
mapPositionAddress: queryRef.current.value,
|
// bgImageName: refImage?.name ?? null,
|
||||||
}))
|
bgImageName: currentBgImage.split('/').pop(),
|
||||||
|
mapPositionAddress: queryRef.current.value,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
setRefImage(null)
|
||||||
|
setCurrentCanvasPlan((prev) => ({
|
||||||
|
...prev,
|
||||||
|
bgImageName: null,
|
||||||
|
mapPositionAddress: null,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}, [currentBgImage])
|
}, [currentBgImage])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,6 +193,7 @@ export function useRefFiles() {
|
|||||||
* @param {*} file
|
* @param {*} file
|
||||||
*/
|
*/
|
||||||
const handleUploadImageRefFile = async (file) => {
|
const handleUploadImageRefFile = async (file) => {
|
||||||
|
setPopSpinnerStore(true)
|
||||||
const newOption1 = settingModalFirstOptions.option1.map((option) => ({
|
const newOption1 = settingModalFirstOptions.option1.map((option) => ({
|
||||||
...option,
|
...option,
|
||||||
selected: option.column === 'imageDisplay' ? true : option.selected,
|
selected: option.column === 'imageDisplay' ? true : option.selected,
|
||||||
@ -180,20 +208,22 @@ export function useRefFiles() {
|
|||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
|
||||||
const res = await post({
|
const res = await post({
|
||||||
url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/upload`,
|
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/upload`,
|
||||||
data: formData,
|
data: formData,
|
||||||
})
|
})
|
||||||
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
|
console.log('🚀 ~ handleUploadImageRefFile ~ res:', res)
|
||||||
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`)
|
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
|
||||||
setRefImage(file)
|
setRefImage(file)
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
objectId: currentCanvasPlan.id,
|
objectId: currentCanvasPlan.id,
|
||||||
planNo: currentCanvasPlan.planNo,
|
planNo: currentCanvasPlan.planNo,
|
||||||
imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`,
|
// imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`,
|
||||||
|
imagePath: `${res.filePath}`,
|
||||||
}
|
}
|
||||||
console.log('🚀 ~ handleUploadImageRefFile ~ params:', params)
|
console.log('🚀 ~ handleUploadImageRefFile ~ params:', params)
|
||||||
await setBackGroundImage(params)
|
await setBackGroundImage(params)
|
||||||
|
setPopSpinnerStore(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,15 +234,28 @@ export function useRefFiles() {
|
|||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
|
||||||
|
/** 캐드 도면 파일 변환 */
|
||||||
const res = await post({ url: converterUrl, data: formData })
|
const res = await post({ url: converterUrl, data: formData })
|
||||||
console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
|
console.log('🚀 ~ handleUploadConvertRefFile ~ res:', res)
|
||||||
|
|
||||||
|
/** 캐드 도면 파일 업로드 */
|
||||||
const result = await post({
|
const result = await post({
|
||||||
url: `${process.env.NEXT_PUBLIC_HOST_URL}/cad/convert`,
|
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/cad`,
|
||||||
data: res,
|
data: res,
|
||||||
})
|
})
|
||||||
console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
|
console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result)
|
||||||
setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${result.filePath}`)
|
|
||||||
setRefImage(res.Files[0].FileData)
|
setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${res.fileName}`)
|
||||||
|
setRefImage(file)
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
objectId: currentCanvasPlan.id,
|
||||||
|
planNo: currentCanvasPlan.planNo,
|
||||||
|
// imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`,
|
||||||
|
imagePath: `${result.filePath}`,
|
||||||
|
}
|
||||||
|
console.log('🚀 ~ handleUploadImageRefFile ~ params:', params)
|
||||||
|
await setBackGroundImage(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -79,7 +79,8 @@ export function useImgLoader() {
|
|||||||
|
|
||||||
/** 이미지 크롭 요청 */
|
/** 이미지 크롭 요청 */
|
||||||
const result = await post({
|
const result = await post({
|
||||||
url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`,
|
// url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/image/canvas`,
|
||||||
|
url: `${process.env.NEXT_PUBLIC_API_HOST_URL}/api/image/canvas`,
|
||||||
data: formData,
|
data: formData,
|
||||||
})
|
})
|
||||||
console.log('🚀 ~ handleCanvasToPng ~ result:', result)
|
console.log('🚀 ~ handleCanvasToPng ~ result:', result)
|
||||||
|
|||||||
@ -96,6 +96,10 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
|
addDocumentEventListener('contextmenu', document, (e) => {
|
||||||
|
handleRollback()
|
||||||
|
})
|
||||||
|
|
||||||
clear()
|
clear()
|
||||||
return () => {
|
return () => {
|
||||||
initEvent()
|
initEvent()
|
||||||
@ -682,6 +686,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
if (activeElem !== length1Ref.current) {
|
if (activeElem !== length1Ref.current) {
|
||||||
@ -746,6 +751,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
|
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
@ -779,6 +785,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Down': // IE/Edge에서 사용되는 값
|
case 'Down': // IE/Edge에서 사용되는 값
|
||||||
@ -804,6 +811,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Enter': {
|
case 'Enter': {
|
||||||
@ -828,7 +836,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Down': // IE/Edge에서 사용되는 값
|
case 'Down': // IE/Edge에서 사용되는 값
|
||||||
@ -892,6 +900,12 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
isFix.current = true
|
isFix.current = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enterCheck = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
handleFix()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
points,
|
points,
|
||||||
setPoints,
|
setPoints,
|
||||||
|
|||||||
@ -92,6 +92,9 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
|
addDocumentEventListener('contextmenu', document, (e) => {
|
||||||
|
handleRollback()
|
||||||
|
})
|
||||||
clear()
|
clear()
|
||||||
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
||||||
|
|
||||||
@ -175,7 +178,7 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mouseMove
|
mouseMove
|
||||||
*/
|
*/
|
||||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
@ -184,7 +187,7 @@ mouseMove
|
|||||||
const { getAdsorptionPoints } = useAdsorptionPoint()
|
const { getAdsorptionPoints } = useAdsorptionPoint()
|
||||||
|
|
||||||
const mouseMove = (e) => {
|
const mouseMove = (e) => {
|
||||||
removeMouseLine();
|
removeMouseLine()
|
||||||
const pointer = canvas.getPointer(e.e)
|
const pointer = canvas.getPointer(e.e)
|
||||||
const roofsPoints = roofs.map((roof) => roof.points).flat()
|
const roofsPoints = roofs.map((roof) => roof.points).flat()
|
||||||
roofAdsorptionPoints.current = [...roofsPoints]
|
roofAdsorptionPoints.current = [...roofsPoints]
|
||||||
@ -246,7 +249,6 @@ mouseMove
|
|||||||
})
|
})
|
||||||
canvas?.add(horizontalLine, verticalLine)
|
canvas?.add(horizontalLine, verticalLine)
|
||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -768,6 +770,7 @@ mouseMove
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
// 포커스가 length1에 있지 않으면 length1에 포커스를 줌
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
|
|
||||||
@ -833,6 +836,7 @@ mouseMove
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
|
|
||||||
const activeElem = document.activeElement
|
const activeElem = document.activeElement
|
||||||
@ -866,6 +870,7 @@ mouseMove
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Down': // IE/Edge에서 사용되는 값
|
case 'Down': // IE/Edge에서 사용되는 값
|
||||||
@ -891,6 +896,7 @@ mouseMove
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Enter': {
|
case 'Enter': {
|
||||||
@ -915,6 +921,7 @@ mouseMove
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enterCheck(e)
|
||||||
|
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@ -979,6 +986,12 @@ mouseMove
|
|||||||
isFix.current = true
|
isFix.current = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enterCheck = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
handleFix()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
points,
|
points,
|
||||||
setPoints,
|
setPoints,
|
||||||
|
|||||||
@ -72,16 +72,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
length5 = surfaceRefs.length5.current.value
|
length5 = surfaceRefs.length5.current.value
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(' before length : ', length1, length2, length3, length4, length5)
|
|
||||||
|
|
||||||
length1 = parseFloat(length1 === undefined ? 0 : Number(length1 / 10).toFixed(1))
|
length1 = parseFloat(length1 === undefined ? 0 : Number(length1 / 10).toFixed(1))
|
||||||
length2 = parseFloat(length2 === undefined ? 0 : Number(length2 / 10).toFixed(1))
|
length2 = parseFloat(length2 === undefined ? 0 : Number(length2 / 10).toFixed(1))
|
||||||
length3 = parseFloat(length3 === undefined ? 0 : Number(length3 / 10).toFixed(1))
|
length3 = parseFloat(length3 === undefined ? 0 : Number(length3 / 10).toFixed(1))
|
||||||
length4 = parseFloat(length4 === undefined ? 0 : Number(length4 / 10).toFixed(1))
|
length4 = parseFloat(length4 === undefined ? 0 : Number(length4 / 10).toFixed(1))
|
||||||
length5 = parseFloat(length5 === undefined ? 0 : Number(length5 / 10).toFixed(1))
|
length5 = parseFloat(length5 === undefined ? 0 : Number(length5 / 10).toFixed(1))
|
||||||
|
|
||||||
console.log(' after length : ', length1, length2, length3, length4, length5)
|
|
||||||
|
|
||||||
let isDrawing = true
|
let isDrawing = true
|
||||||
let obj = null
|
let obj = null
|
||||||
let points = []
|
let points = []
|
||||||
|
|||||||
@ -346,9 +346,9 @@
|
|||||||
"modal.actual.size.setting.not.exist.size": "実際の寸法の長さを入力してください",
|
"modal.actual.size.setting.not.exist.size": "実際の寸法の長さを入力してください",
|
||||||
"modal.actual.size.setting.plane.size.length": "廊下寸法の長さ",
|
"modal.actual.size.setting.plane.size.length": "廊下寸法の長さ",
|
||||||
"modal.actual.size.setting.actual.size.length": "実寸長",
|
"modal.actual.size.setting.actual.size.length": "実寸長",
|
||||||
"plan.message.confirm.save": "プラン保存しますか??",
|
"plan.message.confirm.save": "プラン保存しますか?",
|
||||||
"plan.message.confirm.copy": "プランコピーしますか??",
|
"plan.message.confirm.copy": "プランコピーしますか?",
|
||||||
"plan.message.confirm.delete": "プラン削除しますか??",
|
"plan.message.confirm.delete": "プラン削除しますか?",
|
||||||
"plan.message.save": "保存されました。",
|
"plan.message.save": "保存されました。",
|
||||||
"plan.message.delete": "削除されました。",
|
"plan.message.delete": "削除されました。",
|
||||||
"plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は保存して移動します。",
|
"plan.message.leave": "物件状況(リスト)に移動しますか? [はい]を選択した場合は保存して移動します。",
|
||||||
@ -944,6 +944,8 @@
|
|||||||
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
|
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
|
||||||
"estimate.detail.header.showPrice": "価格表示",
|
"estimate.detail.header.showPrice": "価格表示",
|
||||||
"estimate.detail.header.unitPrice": "定価",
|
"estimate.detail.header.unitPrice": "定価",
|
||||||
|
"estimate.detail.header.singleCable": "片端ケーブル長さ",
|
||||||
|
"estimate.detail.header.doubleCable": "両端ケーブル長さ",
|
||||||
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
||||||
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください。",
|
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください。",
|
||||||
"estimate.detail.showPrice.pricingBtn.confirm": "価格登録初期化されますがよろしいですか?",
|
"estimate.detail.showPrice.pricingBtn.confirm": "価格登録初期化されますがよろしいですか?",
|
||||||
|
|||||||
@ -945,6 +945,8 @@
|
|||||||
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
|
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
|
||||||
"estimate.detail.header.showPrice": "가격표시",
|
"estimate.detail.header.showPrice": "가격표시",
|
||||||
"estimate.detail.header.unitPrice": "정가",
|
"estimate.detail.header.unitPrice": "정가",
|
||||||
|
"estimate.detail.header.singleCable": "편당케이블 길이",
|
||||||
|
"estimate.detail.header.doubleCable": "양단케이블 길이",
|
||||||
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
"estimate.detail.showPrice.pricingBtn": "Pricing",
|
||||||
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. 제품 선택 후 Pricing을 진행해주세요.",
|
"estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. 제품 선택 후 Pricing을 진행해주세요.",
|
||||||
"estimate.detail.showPrice.pricingBtn.confirm": "가격등록을 초기화 하시겠습니까?",
|
"estimate.detail.showPrice.pricingBtn.confirm": "가격등록을 초기화 하시겠습니까?",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user