From 2f74996d48b08859169998dfe6ce13d7e1831fe1 Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Tue, 10 Mar 2026 09:35:40 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E7=A7=AF=E5=88=86=E5=8F=98=E4=B8=BA?= =?UTF-8?q?=E5=8F=AF=E6=8E=A7=E8=83=8C=E6=99=AF=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Canvas/components/fullscreen-dialog.vue | 1 + src/components/MyInfo.vue | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Canvas/components/fullscreen-dialog.vue b/src/components/Canvas/components/fullscreen-dialog.vue index cca3d74..2d39dc9 100644 --- a/src/components/Canvas/components/fullscreen-dialog.vue +++ b/src/components/Canvas/components/fullscreen-dialog.vue @@ -69,6 +69,7 @@ position: absolute; top: 3rem; right: 3rem; + --bgColor: #fff; } > .close-btn { cursor: pointer; diff --git a/src/components/MyInfo.vue b/src/components/MyInfo.vue index d763bdb..6f5bf75 100644 --- a/src/components/MyInfo.vue +++ b/src/components/MyInfo.vue @@ -72,9 +72,9 @@ min-width: 18rem; height: 4.3rem; margin-right: 1rem; - background-color: rgba(255, 252, 244, 1); border: 1px solid #ffcf90; border-radius: 0.8rem; + background-color: var(--bgColor, rgba(255, 252, 244, 1)); > .credits { flex: 1; font-size: 1.3rem; From d8f974834474bdf28d3c8de6e4e35f05492d67d9 Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Tue, 10 Mar 2026 09:38:51 +0800 Subject: [PATCH 2/8] fix --- src/components/Canvas/components/fullscreen-dialog.vue | 2 +- src/components/MyInfo.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Canvas/components/fullscreen-dialog.vue b/src/components/Canvas/components/fullscreen-dialog.vue index 2d39dc9..ae94f3b 100644 --- a/src/components/Canvas/components/fullscreen-dialog.vue +++ b/src/components/Canvas/components/fullscreen-dialog.vue @@ -69,7 +69,7 @@ position: absolute; top: 3rem; right: 3rem; - --bgColor: #fff; + --my-info-bgColor: #fff; } > .close-btn { cursor: pointer; diff --git a/src/components/MyInfo.vue b/src/components/MyInfo.vue index 6f5bf75..0d7a345 100644 --- a/src/components/MyInfo.vue +++ b/src/components/MyInfo.vue @@ -74,7 +74,7 @@ margin-right: 1rem; border: 1px solid #ffcf90; border-radius: 0.8rem; - background-color: var(--bgColor, rgba(255, 252, 244, 1)); + background-color: var(--my-info-bgColor, rgba(255, 252, 244, 1)); > .credits { flex: 1; font-size: 1.3rem; From 12e14c56970bf716d487c8d2bdbed88b5dc37196 Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Tue, 10 Mar 2026 10:16:19 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=BC=95=E5=85=A5three.js=20=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E9=80=9A=E7=94=A8=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 12 +++++ package.json | 1 + .../Canvas/FlowCanvas/flow-canvas.vue | 4 ++ .../Canvas/components/base-modal.vue | 51 +++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 src/components/Canvas/components/base-modal.vue diff --git a/package-lock.json b/package-lock.json index 8e9f9b4..2f7bd38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "pinia": "^2.0.32", "pinia-persistedstate-plugin": "^0.1.0", "pinia-plugin-persistedstate": "^3.1.0", + "three": "^0.148.0", "vue": "^3.2.47", "vue-draggable-plus": "^0.6.1", "vue-i18n": "^11.2.8", @@ -8556,6 +8557,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/three": { + "version": "0.148.0", + "resolved": "https://registry.npmmirror.com/three/-/three-0.148.0.tgz", + "integrity": "sha512-8uzVV+qhTPi0bOFs/3te3RW6hb3urL8jYEl6irjCWo/l6sr8MPNMcClFev/MMYeIxr0gmDcoXTy/8LXh/LXkfw==", + "license": "MIT" + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz", @@ -16065,6 +16072,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "three": { + "version": "0.148.0", + "resolved": "https://registry.npmmirror.com/three/-/three-0.148.0.tgz", + "integrity": "sha512-8uzVV+qhTPi0bOFs/3te3RW6hb3urL8jYEl6irjCWo/l6sr8MPNMcClFev/MMYeIxr0gmDcoXTy/8LXh/LXkfw==" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz", diff --git a/package.json b/package.json index a89a047..c003462 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "pinia": "^2.0.32", "pinia-persistedstate-plugin": "^0.1.0", "pinia-plugin-persistedstate": "^3.1.0", + "three": "^0.148.0", "vue": "^3.2.47", "vue-draggable-plus": "^0.6.1", "vue-i18n": "^11.2.8", diff --git a/src/components/Canvas/FlowCanvas/flow-canvas.vue b/src/components/Canvas/FlowCanvas/flow-canvas.vue index 76c3450..fd24821 100644 --- a/src/components/Canvas/FlowCanvas/flow-canvas.vue +++ b/src/components/Canvas/FlowCanvas/flow-canvas.vue @@ -53,6 +53,9 @@ @home="() => fitView({ maxZoom: 1 })" /> + + + + + From e934d77f95cb982f65c16410fd7f8ceb4212fd11 Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Tue, 10 Mar 2026 16:28:11 +0800 Subject: [PATCH 4/8] =?UTF-8?q?bugfix:=20=E8=BE=93=E5=85=A5=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E4=BC=9A=E6=90=BA=E5=B8=A6=E6=8A=A5=E5=91=8A=E6=A0=87?= =?UTF-8?q?=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/agent.ts | 23 ++++++++------------- src/stores/agent.ts | 25 ++++++++++------------- src/views/home/agent/components/Agent.vue | 16 ++++++++------- src/views/home/components/Input.vue | 11 +++++----- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/api/agent.ts b/src/api/agent.ts index 5646e63..257e01e 100644 --- a/src/api/agent.ts +++ b/src/api/agent.ts @@ -8,15 +8,10 @@ export interface AgentParamsType { imageUrlList?: string[] // 图片URL列表 configParams: Record // 其他配置参数 token: string + needSuggestion?: boolean + useReport: bolean } -export const fetchAgentReply = (data: AgentParamsType): Promise => { - return request({ - url: '/api/ai-design/chat', - method: 'get', - data, - meta: { responseAll: true } - }) -} +export const chatUrl = '/api/ai-design/chat' export interface CreateProjectParamsType { type: string @@ -33,11 +28,11 @@ export const createProject = (data: CreateProjectParamsType): Promise => { * @param data 获取项目信息参数 * @param data.id 项目id * @returns 获取项目信息 -*/ + */ export const getProjectInfo = (data) => { return request({ url: `/api/project/${data.id}`, - method: 'get', + method: 'get' }) } @@ -47,7 +42,7 @@ export const getProjectInfo = (data) => { * @param params.page 页码 * @param params.size 每页数量 * @returns 获取项目版本列表 -*/ + */ export const getProjectList = (params) => { return request({ url: `/api/project/list`, @@ -66,7 +61,7 @@ export const getProjectList = (params) => { * @param data.style 项目风格 * @param data.temperature 项目温度 * @returns 修改项目信息 -*/ + */ export const updateProject = (id: string, data: Object) => { return request({ url: `/api/project/${id}`, @@ -78,10 +73,10 @@ export const updateProject = (id: string, data: Object) => { * 删除项目 * @param id 项目id * @returns 删除项目 -*/ + */ export const deleteProject = (id: string) => { return request({ url: `/api/project/${id}`, - method: 'delete', + method: 'delete' }) } diff --git a/src/stores/agent.ts b/src/stores/agent.ts index 658e586..34c458e 100644 --- a/src/stores/agent.ts +++ b/src/stores/agent.ts @@ -7,23 +7,20 @@ import MyEvent from '@/utils/myEvent' // Agent 项目初始数据 store +type InitialProjectData = { + text: string + images: Array<{ url: string; name: string }> + type: string + area: string + style: string + useReport:boolean + needSuggestion:boolean +} export const useAgentStore = defineStore('agent', () => { - const initialProjectData = ref<{ - text: string - images: Array<{ url: string; name: string }> - type: string - area: string - style: string - } | null>(null) + const initialProjectData = ref(null) // 保存项目初始数据 - const setInitialProjectData = (data: { - text: string - images: Array<{ url: string; name: string }> - type: string - area: string - style: string - }) => { + const setInitialProjectData = (data: InitialProjectData) => { initialProjectData.value = data } diff --git a/src/views/home/agent/components/Agent.vue b/src/views/home/agent/components/Agent.vue index cfacb7b..733e5c7 100644 --- a/src/views/home/agent/components/Agent.vue +++ b/src/views/home/agent/components/Agent.vue @@ -24,10 +24,9 @@ import { ref, reactive, computed, onUnmounted, onMounted, nextTick, watch } from 'vue' import List from './List.vue' import Input from '../../components/Input.vue' - import { fetchAgentReply } from '@/api/agent' + import { chatUrl } from '@/api/agent' import type { AgentParamsType } from '@/api/agent' - import { useUserInfoStore, useProjectStore } from '@/stores' - import { useAgentStore } from '@/stores/agent' + import { useUserInfoStore, useProjectStore, useAgentStore } from '@/stores' const userStore = useUserInfoStore() const agentStore = useAgentStore() @@ -54,6 +53,8 @@ message: '', token: userStore.state.token, versionID: '', + needSuggestion: false, + useReport: false, configParams: { type: '', region: '', @@ -99,6 +100,8 @@ style: initialData.style, temperature: 0.7 } + params.needSuggestion = initialData.needSuggestion || false + params.useReport = initialData.useReport handleSendMessage({ text: initialData.text, images: initialData.images, @@ -158,7 +161,7 @@ configParams: JSON.stringify(params.configParams) }) const BASEURL = import.meta.env.VITE_APP_URL - const response = await fetch(`${BASEURL}/api/ai-design/chat?${urlParams.toString()}`, { + const response = await fetch(`${BASEURL}${chatUrl}?${urlParams.toString()}`, { method: 'GET', signal: abortController.signal }) @@ -221,7 +224,7 @@ } buffer += decoder.decode(value, { stream: true }) - + // 优先按空行拆分事件块(SSE标准) let events = buffer.split(/\n\n/) buffer = events.pop() // 保留不完整块 @@ -469,11 +472,10 @@ // 延迟设置新数据,确保 UI 有时间响应清空操作 nextTick(() => { - messageList.value = [...ancestorsList, ...currentList] params.versionID = current?.id sketchList.value = imgList - console.log('11111111111111',params.versionID); + console.log('11111111111111', params.versionID) }) } diff --git a/src/views/home/components/Input.vue b/src/views/home/components/Input.vue index 0640ebd..f0529eb 100644 --- a/src/views/home/components/Input.vue +++ b/src/views/home/components/Input.vue @@ -20,7 +20,6 @@
-
{{ $t('Input.placeholder') }}
@@ -506,8 +505,9 @@ let node: Node | null while ((node = walker.nextNode())) { - if (node.parentElement?.classList.contains('custom-placeholder')) continue - if (node.parentElement?.classList.contains('editor-tag')) continue + // 使用 closest() 检查当前节点的祖先元素是否包含需要排除的 class + if (node.parentElement?.closest('.custom-placeholder')) continue + if (node.parentElement?.closest('.editor-tag')) continue text += node.textContent } @@ -732,14 +732,15 @@ ) const handleCreateProject = async () => { - // 这里可以添加创建项目的逻辑 if (!inputValue.value.trim()) { return } + const params = { type: typeValue.value, area: areaValue.value, style: styleValue.value, + useReport: reportTags.value.length > 0, temperature: 0.7 } const projectres = await createProject(params) @@ -1035,7 +1036,7 @@ min-height: 5rem; line-height: 1.4rem; } - .editor-placeholder{ + .editor-placeholder { font-family: 'Regular'; font-size: 1.4rem; padding: 0; From 5a07a6fa9f746e7a176f9eccbca9767115d40aaa Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Tue, 10 Mar 2026 16:57:04 +0800 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=8E=86=E5=8F=B2=E8=8E=B7=E5=8F=96=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/home/agent/components/Agent.vue | 19 +++++++++-------- src/views/home/agent/components/Preview.vue | 23 ++++++++++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/views/home/agent/components/Agent.vue b/src/views/home/agent/components/Agent.vue index 733e5c7..89c9edf 100644 --- a/src/views/home/agent/components/Agent.vue +++ b/src/views/home/agent/components/Agent.vue @@ -374,9 +374,9 @@ while (i < dialogue.length) { const item = dialogue[i] - if (item.image_url) { - existingImgList.push(item.image_url) - } + // if (item.image_url) { + // existingImgList.push(item.image_url) + // } if (item.role === 'user') { // user 角色直接添加 @@ -394,9 +394,9 @@ // 继续往后找连续的 assistant 消息 let j = i + 1 while (j < dialogue.length && dialogue[j].role === 'assistant') { - if (dialogue[j].image_url) { - existingImgList.push(dialogue[j].image_url) - } + // if (dialogue[j].image_url) { + // existingImgList.push(dialogue[j].image_url) + // } combinedContent += dialogue[j].content || '' j++ } @@ -428,6 +428,7 @@ const setChatInfo = (info) => { const initialData = agentStore.getInitialProjectData if (isGenerating.value || initialData) return + console.log('info0----', info) const data = info.conversation let project = info.project @@ -451,11 +452,12 @@ const { ancestors, current } = data - const imgList = [] + let imgList = [] const ancestorsList = [] let ancestorsIdCounter = 1 if (ancestors) { ancestors.forEach((item) => { + imgList = imgList.concat(current.sketchIDAndUrl) const list = processDialogue(item.dialogue, 0, imgList) // 重新设置 id list.forEach((el) => { @@ -465,7 +467,7 @@ }) } const currentList = processDialogue(current?.dialogue, 0, imgList) - // 重新设置 id + imgList = imgList.concat(current.sketchIDAndUrl) currentList.forEach((el, index) => { el.id = index + 1 + ancestorsList.length }) @@ -475,7 +477,6 @@ messageList.value = [...ancestorsList, ...currentList] params.versionID = current?.id sketchList.value = imgList - console.log('11111111111111', params.versionID) }) } diff --git a/src/views/home/agent/components/Preview.vue b/src/views/home/agent/components/Preview.vue index 2743d80..628976a 100644 --- a/src/views/home/agent/components/Preview.vue +++ b/src/views/home/agent/components/Preview.vue @@ -10,7 +10,10 @@ :key="'sketch-item-' + index" > -
+
Edit
@@ -124,6 +127,9 @@ import Menu from './Menu.vue' import LoadingImg from '@/assets/images/sketch-loading.gif' import reportNull from '@/assets/images/reportNull.png' + import myEvent from '@/utils/myEvent' + import { useProjectStore } from '@/stores' + const projectStore = useProjectStore() // 存储每个图片的加载状态 const loadedStatus = reactive>({}) @@ -146,12 +152,19 @@ // 获取当前显示的图片源 const getImageSrc = (item: string, index: number) => { - return loadedStatus[index] ? item : LoadingImg + if (typeof item === 'string') { + return loadedStatus[index] ? item : LoadingImg + } + if (typeof item === 'object') { + return Object.values(item)[0] + } } - const handleClickEdit = () => { - // 编辑按钮点击逻辑 - console.log('Edit button clicked') + const handleClickEdit = (item: string) => { + const url = Object.values(item)[0] + const imgId = Object.keys(item)[0] + const nodeId = projectStore.state.nodeId + myEvent.emit('openFlowCanvas', { url, imgId, nodeId }) } const handleClickMenu = () => { // 菜单按钮点击逻辑 From e47eb010fb80120ff02508fe89f917a68a24398d Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Tue, 10 Mar 2026 16:59:18 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E6=8E=A5=E5=85=A53d=20=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=94=BB=E5=B8=83=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- src/api/flow-canvas.ts | 54 +++++ .../components/tools/threeModel/detail.vue | 123 ++++++++++++ .../components/tools/threeModel/index.vue | 49 +++++ .../components/tools/threeModel/model.vue | 188 ++++++++++++++++++ .../components/tools/threeModel/threeTool.ts | 125 ++++++++++++ .../Canvas/FlowCanvas/flow-canvas.vue | 58 ++++-- .../Canvas/components/base-modal.vue | 22 +- 8 files changed, 599 insertions(+), 22 deletions(-) create mode 100644 src/api/flow-canvas.ts create mode 100644 src/components/Canvas/FlowCanvas/components/tools/threeModel/detail.vue create mode 100644 src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue create mode 100644 src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue create mode 100644 src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts diff --git a/.env.development b/.env.development index f844c2d..8eca712 100644 --- a/.env.development +++ b/.env.development @@ -1,5 +1,5 @@ # VITE_APP_URL = http://192.168.31.82:8771 VITE_APP_URL = http://18.167.251.121:10015 # VITE_APP_URL = http://192.168.31.118:8080 -# VITE_APP_URL = http://192.168.31.82:8755 +VITE_APP_URL = http://192.168.31.82:8755 VITE_GOOGLE_CLIENT_ID = 216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com diff --git a/src/api/flow-canvas.ts b/src/api/flow-canvas.ts new file mode 100644 index 0000000..062708d --- /dev/null +++ b/src/api/flow-canvas.ts @@ -0,0 +1,54 @@ +import request from '@/utils/request' + +/** + * 获取sketch的画布详情 + * @param data 获取sketch的画布详情的参数 + * @param data.id sketch id + * @returns 获取sketch的画布详情 + */ +export interface getSketchFlowCanvasData { + id: string +} +export const getSketchFlowCanvas = (data:getSketchFlowCanvasData) => { + return request({ + url: `/api/canvas/detail/${data.id}`, + method: 'get', + }) +} + +/** + * 保存或者更新sketch的画布详情 + * @param data 获取sketch的画布详情的参数 + * @param data.id sketch id + * @param data.canvasData sketch id + * @returns 获取sketch的画布详情 + */ +export interface saveSketchFlowCanvasData { + id?: string + canvasData: string +} +export const putSketchFlowCanvas = (data:saveSketchFlowCanvasData) => { + return request({ + url: `/api/canvas/detail/${data.id}`, + method: 'put', + data: data.canvasData + }) +} + +/** + * 删除sketch和画布详情 + * @param data 删除sketch的画布详情的参数 + * @param data.id sketch id + * @param data.versionNodeId 节点id + * @returns 获取sketch的画布详情 + */ +export interface deleteSketchFlowCanvasData { + id?: string + versionNodeId?: string +} +export const deleteSketchFlowCanvas = (data:deleteSketchFlowCanvasData) => { + return request({ + url: `/api/canvas/detail/${data.versionNodeId}/${data.id}`, + method: 'delete', + }) +} diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/detail.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/detail.vue new file mode 100644 index 0000000..d828c77 --- /dev/null +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/detail.vue @@ -0,0 +1,123 @@ + + + \ No newline at end of file diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue new file mode 100644 index 0000000..7f12bfa --- /dev/null +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue new file mode 100644 index 0000000..bdab5fa --- /dev/null +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue @@ -0,0 +1,188 @@ + + + \ No newline at end of file diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts new file mode 100644 index 0000000..2236ced --- /dev/null +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts @@ -0,0 +1,125 @@ +import * as THREE from 'three'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' + +export const initThree = (threeDom)=>{ + const scene = new THREE.Scene(); + const group = new THREE.Group() + scene.add(group) + + //创建相机对象 + // this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); + const camera = new THREE.PerspectiveCamera(45, threeDom.offsetWidth / threeDom.offsetHeight, 0.1, 10000); + camera.position.set(0, 90, 6); //设置相机位置 + camera.lookAt(scene.position); //设置相机方向(指向的场景对象) + /** + * 创建渲染器对象 + */ + let width = threeDom.offsetWidth; //窗口宽度 + let height = threeDom.offsetHeight; //窗口高度 + const renderer = new THREE.WebGLRenderer({ + antialias: true, + logarithmicDepthBuffer: true,//深度缓存 防止模型闪烁重影 + }); + + renderer.toneMapping = THREE.ACESFilmicToneMapping;//设置色调 + renderer.toneMappingExposure = 1.3; + + renderer.shadowMap.enabled = true; + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(width, height); //设置渲染区域尺寸 + renderer.setClearColor(0xffffff, 1); //设置背景颜色 + threeDom.innerHTML = ''; + threeDom.appendChild(renderer.domElement); + + // 设置渲染器大小 + //环境光 + let ambient = new THREE.AmbientLight(0xffffff,.8); + scene.add(ambient); + let controls = new OrbitControls(camera,renderer.domElement)//监听鼠标、键盘事件; + // controls.minDistance = 500; // 设置相机与焦点的最小距离 + // controls.maxDistance = 4000; // 设置相机与焦点的最大距离 + controls.mouseButtons = { + // LEFT:THREE.MOUSE.PAN, // 左键 拖动(默认旋转:ROTATE) + LEFT:THREE.MOUSE.ROTATE, // 左键 拖动(默认旋转:ROTATE) + MIDDLE:THREE.MOUSE.DOLLY, // 滑轮 缩放 + RIGHT:THREE.MOUSE.PAN // 右键 旋转(默认拖动:PAN) + // RIGHT:THREE.MOUSE.ROTAafTE // 右键 旋转(默认拖动:PAN) + } + /** + * 光源设置 + */ + //点光源 + /** + * AmbientLight 环境光 + PointLight 点光源 + DirectionalLight 平行光,比如太阳光 + SpotLight 聚光源 + */ + const pointLight = new THREE.DirectionalLight(0xffffff,.5); + pointLight.intensity = 1.2 + pointLight.castShadow = true//开启阴影 + pointLight.shadow.mapSize = new THREE.Vector2(width, height) + scene.add(pointLight); //点光源添加到场景中 + // pointLight.position.set(400, 200, 300); //点光源位置 + pointLight.position.y = 400; + pointLight.position.z = 200; + pointLight.position.x = 200; + let floorGeometry = new THREE.PlaneGeometry(5000, 3000)//地板大小 + let floorMaterial = new THREE.MeshPhongMaterial({ color: "#7e7ab0", }) + let floorMesh = new THREE.Mesh(floorGeometry, floorMaterial); + floorMesh.rotation.x = -0.5 * Math.PI; + floorMesh.receiveShadow = true; + floorMesh.position.y = -0.001; + // scene.add(floorMesh); + const textureLoader = new THREE.TextureLoader(); + // const texture = textureLoader.load('/3dModel/sketch-thick.jpg'); + scene.background = new THREE.Color("#fff"); + return {scene,group,camera,renderer,ambient,controls,pointLight} +} +export const clearModel = (group,scene)=>{ + const oldGroup:any = group.value; + group.value = new THREE.Group(); + scene.value.add(group.value); + scene.value.remove(oldGroup); +} + + +export const addModel = async ( + url:any, + controls:OrbitControls, + camera:THREE.PerspectiveCamera, + pointLight:THREE.DirectionalLight, + group:THREE.Group, + load:any)=>{ + await new Promise((resolve, reject) => { + var fbxLoader = new GLTFLoader(); + let drac = new DRACOLoader() + drac.setDecoderPath('/draco/') + fbxLoader.setDRACOLoader(drac) + // fbxLoader.load('/3dModel/222/1111.glb', + fbxLoader.load(url, + + (obj:any) => { + let scene = obj.scene; + var box = new THREE.Box3().setFromObject(scene); + var center = box.getCenter(new THREE.Vector3()); + controls.value.target.copy(center); + // controls.autoRotate = true + camera.value.position.y = center.y; + camera.value.position.z = 1000; + pointLight.value.position.y = 250; + pointLight.value.position.z = 1250; + group.value.add(scene); + resolve('') + },(xhr:any) => { // 加载进度回调 + const percent = xhr.total == 0?100:(xhr.loaded / xhr.total * 100).toFixed(2); + load.value.progress = percent + // updateProgressBar(Number(percent)); + },(error:any) => { // 加载失败回调 + console.error('模型加载失败:', error); + reject('') + }) + }) +} \ No newline at end of file diff --git a/src/components/Canvas/FlowCanvas/flow-canvas.vue b/src/components/Canvas/FlowCanvas/flow-canvas.vue index fd24821..56a7893 100644 --- a/src/components/Canvas/FlowCanvas/flow-canvas.vue +++ b/src/components/Canvas/FlowCanvas/flow-canvas.vue @@ -53,8 +53,8 @@ @home="() => fitView({ maxZoom: 1 })" /> - - + + @@ -68,11 +68,16 @@ import zoom from '../components/zoom.vue' import imagePreview from '../components/image-preview.vue' import baseModal from '../components/base-modal.vue' + // 工具 + import threeModel from './components/tools/threeModel/index.vue' // 节点 import node from './components/node.vue' import resultImage from './components/nodes/result-image.vue' import card from './components/nodes/cards/index.vue' import text from './components/nodes/text.vue' + + // 接口 + import { getSketchFlowCanvas, putSketchFlowCanvas } from '@/api/flow-canvas' const components = { [NODE_COMPONENT.RESULT_IMAGE]: resultImage, [NODE_COMPONENT.CARD]: card, @@ -166,16 +171,25 @@ // 导出流程 const exportFlow = () => { // flowManager.exportFlow() + const str = JSON.stringify(stateManager.nodes.value) const json = JSON.parse(str) - localStorage.setItem('flow_json', str) + putSketchFlowCanvas({ + id: props.config.id || '==========', + canvasData: str + }).then((res) => { + if (res) { + console.log(res) + } + }) + // localStorage.setItem('flow_json', str) } // 导入流程 - const importFlow = async () => { + const importFlow = async (json) => { try { stateManager.nodes.value = [] await nextTick() - const json = JSON.parse(localStorage.getItem('flow_json') || '[]') + // const json = JSON.parse(localStorage.getItem('flow_json') || '[]') stateManager.nodes.value = json setTimeout(() => { nextTick(() => { @@ -188,24 +202,42 @@ } const imagePreviewRef = ref() + const threeModelRef = ref() /** 打开图片预览 */ const openImagePreview = (url: string) => { imagePreviewRef.value.open(url) } provide('openImagePreview', openImagePreview) - onMounted(() => { + onMounted(async () => { // window['vueFlow'] = vueFlow // window['nodes'] = nodes - nodeManager.createResultNode({ - data: { - disableDelete: true, - isHeader: false, - data: { - url: props.config.url + let json = [] + await new Promise((resolve) => { + getSketchFlowCanvas({ id: props.config.id || '==========' }).then((res) => { + if (res) { + console.log(res) + json = res.data } - } + resolve(true) + }).catch(() => { + resolve(true) + }) }) + if(json.length > 0){ + importFlow(json) + }else{ + nodeManager.createResultNode({ + data: { + disableDelete: true, + isHeader: false, + data: { + url: props.config.url + } + } + }) + } + }) onBeforeMount(() => { eventManager.removeEvents() // 移除事件 diff --git a/src/components/Canvas/components/base-modal.vue b/src/components/Canvas/components/base-modal.vue index ba6e67d..0ce7ed6 100644 --- a/src/components/Canvas/components/base-modal.vue +++ b/src/components/Canvas/components/base-modal.vue @@ -4,8 +4,8 @@ v-model="showDialog" align-center :show-close="false" - width="70vw" - style="border-radius: 20px; padding: 0; --el-dialog-padding-primary: 0" + :width="modalWidth" + style="border-radius: 2.9rem; padding: 0; --el-dialog-padding-primary: 0;background-color: #f7f7f7;" >
@@ -146,7 +149,7 @@