3d模型3视图

This commit is contained in:
X1627315083@163.com
2026-03-18 14:51:22 +08:00
parent 78fa8d965f
commit 359766f59c
11 changed files with 82 additions and 37 deletions

View File

@@ -136,7 +136,7 @@
...data, ...data,
} }
const taskList = await currentComponent.value.api(apiData).then((rv)=>{ const taskList = await currentComponent.value.api(apiData).then((rv)=>{
return [rv] return rv
}) || [] }) || []
// const taskList = [{taskId:'123'}] // const taskList = [{taskId:'123'}]
// if (!subordNode) { // if (!subordNode) {

View File

@@ -3,16 +3,28 @@
<div class="to-3view"> <div class="to-3view">
<p class="label">3D Model</p> <p class="label">3D Model</p>
<div class="image"> <div class="image">
<img src="https://s3-alpha-sig.figma.com/img/ea2f/590e/9638f62a2fc91e31f33db0022db1642c?Expires=1773014400&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=M0B8oJJOk~dGG0aZAqOIocAp7T0LFdJ9FYmCrEZVTCRzYxM6SJRNtYMTX-rTO3Z~s14QINh~o-S41XiZnBv-0zcKjuWot~VVaNHfd0~1LesfNe2KwvCinT~72btFut1pheLnKE-wWCX5ewtonxU77bnw386YPMTqv7DBZzksf2udsJA7NmOYD6~TUG3Q2dWSt~zPH~lkaidscPqpCnCbqzljCEi4RiHY4U3A45l5XypcX2umqn1UaYUFCTqV9471J4qdB6Dg2pcKocdp-7-3s1De6Q~2SmBOrSgDQ~KEADCB2lhKfhxgWmy0lwMvhTd4l90ygVZDWZRABgjHNrGUvg__" alt=""> <img :src="data.url" alt="">
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted } from 'vue' import { reactive, useAttrs, inject, computed } from 'vue'
const data = reactive({}) const attrs = useAttrs()
const stateManager = inject('stateManager') as any
defineExpose({ data }) const data = reactive({
url: attrs.node.data.originalImage,
})
const getApiData = ()=>{
let glbUrl = null
const superiorNode = stateManager.nodes.value.filter((item:any)=>item.id === attrs.node?.data?.superiorID)[0]
const nodeData:any = superiorNode?.data?.data
glbUrl = nodeData.imageProcessTasks.filter((item:any)=>item.taskId === nodeData.selectTaskId)[0]?.glbPath
return {
glbUrl: glbUrl,
}
}
defineExpose({ data,getApiData })
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@@ -11,7 +11,7 @@
<span class="icon"> <span class="icon">
<svg-icon name="chat-compose" size="20" size-unit="px" /> <svg-icon name="chat-compose" size="20" size-unit="px" />
</span> </span>
<span class="icon" @click="onPreview(item?.url)"> <span class="icon" @click="onPreview(item)">
<svg-icon name="expand-lg" size="20" size-unit="px" /> <svg-icon name="expand-lg" size="20" size-unit="px" />
</span> </span>
<span class="icon" @click="onDownload(item?.url)"> <span class="icon" @click="onDownload(item?.url)">
@@ -177,12 +177,11 @@
} }
} }
]) ])
const onPreview = (url: string) => { const onPreview = (item: any) => {
console.log(data.superiorNodeType == NODE_DATATYPE.TO_3D_MODEL)
if(data.superiorNodeType == NODE_DATATYPE.TO_3D_MODEL){ if(data.superiorNodeType == NODE_DATATYPE.TO_3D_MODEL){
openThreeModelPreview(url) openThreeModelPreview({url:item?.glbPath,glbInfoObj:item?.glbInfoObj})
}else{ }else{
openImagePreview(url) openImagePreview(item.url)
} }
} }
const onDownload = (url: string) => { const onDownload = (url: string) => {

View File

@@ -1,11 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue"; import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
//const props = defineProps({ import { downloadImage } from '../../../../tools/tools'
//}) const props = defineProps({
config: {
type: Object,
default: () => ({})
}
})
//const emit = defineEmits([ //const emit = defineEmits([
//]) //])
let data = reactive({ let data = reactive({
}) })
const onDownload = () => {
if(props?.config?.glbPath)downloadImage(props?.config?.glbPath, 'model.glb')
}
onMounted(()=>{ onMounted(()=>{
}) })
onUnmounted(()=>{ onUnmounted(()=>{
@@ -33,15 +41,15 @@ const {} = toRefs(data);
<div class="flex"> <div class="flex">
<div> <div>
<div class="fs14 c18">X</div> <div class="fs14 c18">X</div>
<div class="fs12 c66">1.0</div> <div class="fs12 c66">{{ config?.glbInfoObj?.centroid?.[0].toFixed(2) || 0 }}</div>
</div> </div>
<div> <div>
<div class="fs14 c18">Y</div> <div class="fs14 c18">Y</div>
<div class="fs12 c66">1.0</div> <div class="fs12 c66">{{ config?.glbInfoObj?.centroid?.[1].toFixed(2) || 0 }}</div>
</div> </div>
<div> <div>
<div class="fs14 c18">Z</div> <div class="fs14 c18">Z</div>
<div class="fs12 c66">1.0</div> <div class="fs12 c66">{{ config?.glbInfoObj?.centroid?.[2].toFixed(2) || 0 }}</div>
</div> </div>
</div> </div>
<div class="fs14 c18"> <div class="fs14 c18">
@@ -50,19 +58,19 @@ const {} = toRefs(data);
<div class="flex"> <div class="flex">
<div> <div>
<div class="fs14 c18">Height</div> <div class="fs14 c18">Height</div>
<div class="fs12 c66">22</div> <div class="fs12 c66">{{ config?.glbInfoObj?.size?.[0].toFixed(2) || 0 }}</div>
</div> </div>
<div> <div>
<div class="fs14 c18">Width</div> <div class="fs14 c18">Width</div>
<div class="fs12 c66">22</div> <div class="fs12 c66">{{ config?.glbInfoObj?.size?.[1].toFixed(2) || 0 }}</div>
</div> </div>
<div> <div>
<div class="fs14 c18">Depth</div> <div class="fs14 c18">Depth</div>
<div class="fs12 c66">22</div> <div class="fs12 c66">{{ config?.glbInfoObj?.size?.[2].toFixed(2) || 0 }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="download">{{ $t('threeModel.download') }}</div> <div class="download" @click="onDownload">{{ $t('threeModel.download') }}</div>
</div> </div>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>

View File

@@ -6,9 +6,9 @@ import model from './model.vue'
import detail from './detail.vue' import detail from './detail.vue'
const props = defineProps({ const props = defineProps({
currentUrl: { currentData: {
type: String, type: Object,
default: '' default: () => ({})
} }
}) })
//const emit = defineEmits([ //const emit = defineEmits([
@@ -18,8 +18,8 @@ let data = reactive({
const modelRef = ref(null) const modelRef = ref(null)
onMounted(()=>{ onMounted(()=>{
console.log(props.currentUrl) console.log(props?.currentData?.url)
modelRef.value.open(threeGlb) if(props?.currentData?.url)modelRef.value.open(props?.currentData?.url)
}) })
onUnmounted(()=>{ onUnmounted(()=>{
}) })
@@ -32,7 +32,7 @@ const {} = toRefs(data);
<model ref="modelRef" /> <model ref="modelRef" />
</div> </div>
<div class="detailBox"> <div class="detailBox">
<detail ref="detailRef" /> <detail ref="detailRef" :config="currentData" />
</div> </div>
</div> </div>
</template> </template>

View File

@@ -58,8 +58,8 @@
/> />
<image-preview ref="imagePreviewRef" /> <image-preview ref="imagePreviewRef" />
<baseModal ref="threeModelRef"> <baseModal ref="threeModelRef">
<template v-slot="{ currentUrl }"> <template v-slot="{ currentData }">
<threeModel :currentUrl="currentUrl" /> <threeModel :currentData="currentData" />
</template> </template>
</baseModal> </baseModal>
</template> </template>
@@ -194,6 +194,9 @@
return JSON.stringify(stateManager.nodes.value) return JSON.stringify(stateManager.nodes.value)
} }
const exportFlow = () => { const exportFlow = () => {
console.log(vueFlow.value)
console.log(vueFlow.value.toImage)
return
// flowManager.exportFlow() // flowManager.exportFlow()
const str = getFlowJson() const str = getFlowJson()
stateManager.isSave.value = false stateManager.isSave.value = false
@@ -224,8 +227,8 @@
imagePreviewRef.value.open(url) imagePreviewRef.value.open(url)
} }
/** 打开3D预览 */ /** 打开3D预览 */
const openThreeModelPreview = (url: string) => { const openThreeModelPreview = (currentData) => {
threeModelRef.value.open(url) threeModelRef.value.open(currentData)
} }
provide('openImagePreview', openImagePreview) provide('openImagePreview', openImagePreview)
provide('openThreeModelPreview', openThreeModelPreview) provide('openThreeModelPreview', openThreeModelPreview)

View File

@@ -7,12 +7,14 @@
<script setup lang="ts"> <script setup lang="ts">
import FullscreenDialog from '../components/fullscreen-dialog.vue' import FullscreenDialog from '../components/fullscreen-dialog.vue'
import flowCanvas from './flow-canvas.vue' import flowCanvas from './flow-canvas.vue'
import { ref } from 'vue' import { ref, onMounted, onBeforeUnmount } from 'vue'
import { getSketchFlowCanvas, putSketchFlowCanvas } from '@/api/flow-canvas' import { getSketchFlowCanvas, putSketchFlowCanvas } from '@/api/flow-canvas'
import { useI18n } from 'vue-i18n'
const dialogVisible = ref(false) const dialogVisible = ref(false)
const config = ref({}) as any const config = ref({}) as any
const flowCanvasRef = ref<any>() const flowCanvasRef = ref<any>()
const {t:$t} = useI18n()
const open = async (options) => { const open = async (options) => {
let json = [] let json = []
await new Promise((resolve) => { await new Promise((resolve) => {
@@ -47,6 +49,21 @@
await exportFlow(str) await exportFlow(str)
dialogVisible.value = false dialogVisible.value = false
} }
const handleBeforeUnload = (event) => {
const str = flowCanvasRef.value?.getFlowJson()
if (str) {
event.preventDefault()
event.returnValue = $t('flowCanvas.confirmLeave')
return $t('flowCanvas.confirmLeave')
}
}
onMounted(() => {
// 添加事件监听
window.addEventListener('beforeunload', handleBeforeUnload)
})
onBeforeUnmount(() => {
window.removeEventListener('beforeunload', handleBeforeUnload)
})
defineExpose({ defineExpose({
open, open,
close, close,

View File

@@ -54,6 +54,10 @@ export class GenerateManager {
nodeDataItem.url = item.url nodeDataItem.url = item.url
nodeDataItem.createTime = item.createTime nodeDataItem.createTime = item.createTime
nodeDataItem.status = item.status nodeDataItem.status = item.status
if(item.glbPath){
nodeDataItem.glbPath = item.glbPath
nodeDataItem.glbInfoObj = item.glbInfoObj
}
} }
} }
}) })

View File

@@ -13,7 +13,7 @@
</div> </div>
</template> </template>
<div class="modal-box"> <div class="modal-box">
<slot v-if="currentUrl" :currentUrl="currentUrl"></slot> <slot v-if="currentData" :currentData="currentData"></slot>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
@@ -27,14 +27,14 @@
} }
}) })
const showDialog = ref(false) const showDialog = ref(false)
let currentUrl = ref('') let currentData = ref(null)
const open = (url_: any) => { const open = (data: any,) => {
currentUrl.value = url_ currentData.value = data
showDialog.value = true showDialog.value = true
} }
const close = () => { const close = () => {
showDialog.value = false showDialog.value = false
currentUrl.value = '' currentData.value = null
} }
defineExpose({ defineExpose({

View File

@@ -186,6 +186,7 @@ export default {
deleteCardConfirm: 'Are you sure you want to delete this function card?', deleteCardConfirm: 'Are you sure you want to delete this function card?',
confirm: 'Confirm', confirm: 'Confirm',
cancel: 'Cancel', cancel: 'Cancel',
confirmLeave: 'Are you sure you want to leave? You may have unsaved changes.',
}, },
assistant: { assistant: {
inputPlaceholder: 'Ask anything', inputPlaceholder: 'Ask anything',

View File

@@ -180,7 +180,8 @@ export default {
flowCanvas: { flowCanvas: {
deleteCardConfirm: '确定要删除该功能卡片吗?', deleteCardConfirm: '确定要删除该功能卡片吗?',
confirm: '确认', confirm: '确认',
cancel: '取消' cancel: '取消',
confirmLeave: '您可能有未保存的更改,确定要离开吗?',
}, },
assistant: { assistant: {
inputPlaceholder: '请输入' inputPlaceholder: '请输入'