-
{{ $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 @@
+
+
+
+
+ Properties Information
+
+
+
+
+ Sofa
+
+
+ Model Name
+
+
+
+ Transform
+
+
+
+ Dimensions
+
+
+
+
+
+
\ 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;"
>
+
+

+