调整画布保存机制,把保存画布接口放到状态管理中,完善toRealStyle提示词
This commit is contained in:
@@ -11,10 +11,14 @@
|
||||
<svg-icon :name="v.icon" :size="v.iconSize" />
|
||||
</span>
|
||||
</template>
|
||||
<button class="export" @click="emit('export')">
|
||||
<span class="icon"><svg-icon name="export" size="11" /></span>
|
||||
<span class="text">Export</span>
|
||||
</button>
|
||||
<div>
|
||||
<button class="export" @click="emit('export')">
|
||||
<span class="icon"><svg-icon name="export" size="11" /></span>
|
||||
<span class="text">Export</span>
|
||||
</button>
|
||||
<div v-loading="true" class="mask" v-if="downloadData.status == 'loading'"></div>
|
||||
</div>
|
||||
|
||||
<!-- <button class="import" @click="emit('import')">
|
||||
<span class="text">Import</span>
|
||||
</button> -->
|
||||
@@ -26,7 +30,8 @@
|
||||
import { TOOLS } from '../manager/ToolManager'
|
||||
const props = defineProps({
|
||||
zoom: { default: 1, type: Number },
|
||||
step: { default: 0.1, type: Number }
|
||||
step: { default: 0.1, type: Number },
|
||||
downloadData: { default: {}, type: Object }
|
||||
})
|
||||
const emit = defineEmits(['export', 'import'])
|
||||
const stateManager = inject('stateManager') as any
|
||||
@@ -109,8 +114,21 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
> button {
|
||||
width: 10rem;
|
||||
> div{
|
||||
position: relative;
|
||||
> .mask{
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
zoom: .6;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
button {
|
||||
// width: 10rem;
|
||||
padding: 0 2.4rem;
|
||||
height: 3rem;
|
||||
border-radius: 0.4rem;
|
||||
border: none;
|
||||
@@ -118,12 +136,15 @@
|
||||
color: #fff;
|
||||
font-size: 1.1rem;
|
||||
display: flex;
|
||||
gap: 0.8rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.8rem;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -155,12 +155,6 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
stateManager.recordState()
|
||||
// } else {
|
||||
// subordNode.data.data.url =
|
||||
// 'https://s3-alpha-sig.figma.com/img/8ce2/f1a4/12b93da90e5f17109e7430f14837fd14?Expires=1773619200&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=kmLsTFtXJqfvuxj6husWlDkRDMOIRDjzUUjb7zh79GkBKihUHc0f59k5OAImHTPdaiEREUCCpn~8sQ-si5lenuauJpApCmAU~NsxjfQhuh9m5O~GiHenr2fKu0DIJ75-oCE3859fyxoSFXQgZ9PRmeb98kikMR6uRX9nI5TPUHgKO8ZgkhDBTW~iyaDT~1ybnoK7elPa6T2VzfO-bpIyY-MZ71VRq3RxwmZRxduqHEb3Dh-jjrHyh2SoQsHmUjSJOf-uYilfvpGUResZAjAq8ZVLEjvhzKC2bmCNZIp3RmhYO8ctU7pd5t91J6Xaa6jBLtGfMxbqIm652EC79K0RoA__'
|
||||
// setTimeout(() => stateManager.recordState())
|
||||
// }
|
||||
}
|
||||
//删除功能卡片
|
||||
const onDeleteClick = ()=>{
|
||||
|
||||
@@ -28,23 +28,23 @@
|
||||
const shortcutList = ref([
|
||||
{
|
||||
label: 'Change the...',
|
||||
value: 'Change the...'
|
||||
value: 'Change the style to a realistic design. '
|
||||
},
|
||||
{
|
||||
label: 'Bright Colors...',
|
||||
value: 'Bright Colors...'
|
||||
value: 'Bright colors with modern patterns, change the style to a realistic furniture design. '
|
||||
},
|
||||
{
|
||||
label: 'Make the...',
|
||||
value: 'Make the...'
|
||||
value: 'Make the structure more refined and balanced, change the style to a realistic furniture style. '
|
||||
},
|
||||
{
|
||||
label: 'Imagine...',
|
||||
value: 'Imagine...'
|
||||
value: 'Imagine this furniture with detailed fabric textures, change the style to a realistic design. '
|
||||
},
|
||||
{
|
||||
label: 'Wood Materials with...',
|
||||
value: 'Wood Materials with...'
|
||||
value: 'Wood materials with natural oak texture and soft fabric, change the style to a realistic furniture design.'
|
||||
}
|
||||
])
|
||||
const modeList = ref([
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
item.scale.x = -item.scale.x
|
||||
})
|
||||
stateManager.recordState()
|
||||
stateManager.exportFlow(stateManager.saveCanvasTimeInterval)
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -174,6 +175,7 @@
|
||||
item.scale.y = -item.scale.y
|
||||
})
|
||||
stateManager.recordState()
|
||||
stateManager.exportFlow(stateManager.saveCanvasTimeInterval)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</template>
|
||||
</VueFlow>
|
||||
</div>
|
||||
<header-tools @export="exportFlow" @import="importFlow" />
|
||||
<header-tools @export="exportFlow" @import="importFlow" :downloadData="downloadData" />
|
||||
<zoom
|
||||
:zoom="stateManager.zoom.value"
|
||||
:step="0.1"
|
||||
@@ -107,9 +107,8 @@
|
||||
|
||||
const vueFlow = ref<any>()
|
||||
const nodeTypes = ref([NODE_TYPE.INPUT, NODE_TYPE.SECONDARY, NODE_TYPE.OUTPUT, NODE_TYPE.ALONE])
|
||||
|
||||
// 状态管理器
|
||||
const stateManager = new StateManager({ vueFlow })
|
||||
const stateManager = new StateManager({ vueFlow,sketchId:props.config.imgId })
|
||||
provide('stateManager', stateManager)
|
||||
|
||||
// 事件管理器
|
||||
@@ -191,29 +190,34 @@
|
||||
}
|
||||
// 导出流程
|
||||
const getFlowJson = () => {
|
||||
if(!stateManager.isSave.value)return ''
|
||||
return JSON.stringify(stateManager.nodes.value)
|
||||
}
|
||||
const exportFlow = () => {
|
||||
const downloadData = ref<any>({
|
||||
amount: 0,
|
||||
progress: 0,
|
||||
status: 'success',//success
|
||||
})
|
||||
const exportFlow = async () => {
|
||||
// console.log(vueFlow.value)
|
||||
// console.log(vueFlow.value.toImage)
|
||||
let arr = stateManager.nodes.value.filter((v) => v.data.type === NODE_COMPONENT.RESULT_IMAGE)
|
||||
let imgList = []
|
||||
arr.forEach((v) => {
|
||||
arr.forEach((v,i) => {
|
||||
v.data.data.imageProcessTasks.forEach((item,index) => {
|
||||
let url = item.url
|
||||
let name = url?.split(".").pop().split("?").shift();
|
||||
imgList.push({url:url,name:`${v.data.type}${index == 0?'':index}.${name}`})
|
||||
imgList.push({url:url,name:`${v.data.type}${i}-${index == 0?'':index}.${name}`})
|
||||
})
|
||||
})
|
||||
downImgListToZip(imgList)
|
||||
console.log(imgList)
|
||||
downloadData.value.amount = imgList.length
|
||||
downloadData.value.status = 'loading'
|
||||
await downImgListToZip(imgList,(progress)=>{
|
||||
downloadData.value.progress = progress
|
||||
if(progress == downloadData.value.amount){
|
||||
downloadData.value.status = 'success'
|
||||
}
|
||||
})
|
||||
return
|
||||
// flowManager.exportFlow()
|
||||
const str = getFlowJson()
|
||||
stateManager.isSave.value = false
|
||||
emit('exportFlow', str)
|
||||
// localStorage.setItem('flow_json', str)
|
||||
}
|
||||
// 导入流程
|
||||
const importFlow = async (json) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<fullscreen-dialog v-model="dialogVisible" @close="close" hide-destroy>
|
||||
<flow-canvas ref="flowCanvasRef" :config="config" @exportFlow="exportFlow" />
|
||||
<flow-canvas ref="flowCanvasRef" :config="config" />
|
||||
</fullscreen-dialog>
|
||||
</template>
|
||||
|
||||
@@ -31,22 +31,7 @@
|
||||
config.value.json = json
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const exportFlow = async (str) => {
|
||||
if(!config.value.imgId || !str)return
|
||||
await new Promise((resolve) => {
|
||||
putSketchFlowCanvas({
|
||||
id: config.value.imgId,
|
||||
canvasData: str },true).then(() => {
|
||||
resolve(true)
|
||||
}).catch(() => {
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const close = async () => {
|
||||
const str = flowCanvasRef.value?.getFlowJson()
|
||||
await exportFlow(str)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
const handleBeforeUnload = (event) => {
|
||||
@@ -67,7 +52,6 @@
|
||||
defineExpose({
|
||||
open,
|
||||
close,
|
||||
exportFlow
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -38,6 +38,7 @@ export class EventManager {
|
||||
}
|
||||
})
|
||||
this.stateManager.recordState()
|
||||
this.stateManager.exportFlow(this.stateManager.saveCanvasTimeInterval)
|
||||
}
|
||||
/** 处理点击 */
|
||||
handleClick(event: any) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { ref, computed } from "vue";
|
||||
import { NODE_TYPE, NODE_DATATYPE } from '../tools/index.d'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import i18n from '@/lang'
|
||||
import { putSketchFlowCanvas } from '@/api/flow-canvas'
|
||||
|
||||
const t = i18n.global.t
|
||||
|
||||
export interface NodesItem {
|
||||
@@ -37,8 +39,12 @@ export class StateManager {
|
||||
toolManager: any
|
||||
generateManager: any
|
||||
|
||||
// 是否有数据没保存
|
||||
isSave: any
|
||||
// 保存画布数据定时器
|
||||
saveCanvasTime: any
|
||||
// 保存画布数据定时器时间间隔
|
||||
saveCanvasTimeInterval: any
|
||||
// 打开画布线稿id
|
||||
sketchId: any
|
||||
// 设置管理器
|
||||
setManager(options) {
|
||||
options.eventManager && (this.eventManager = options.eventManager)
|
||||
@@ -57,7 +63,10 @@ export class StateManager {
|
||||
this.mxHistory = ref(50)
|
||||
this.historyList = ref([])
|
||||
this.historyIndex = ref(0)
|
||||
this.isSave = ref(false)
|
||||
|
||||
this.sketchId = options.sketchId
|
||||
this.saveCanvasTimeInterval = 6000
|
||||
this.saveCanvasTime = null
|
||||
|
||||
this.activeNodeID = ref("")
|
||||
this.nodes = ref<NodesItem[]>([]);
|
||||
@@ -100,8 +109,6 @@ export class StateManager {
|
||||
})
|
||||
return arr
|
||||
})
|
||||
window.nodes = this.nodes
|
||||
window.aaa = this
|
||||
|
||||
}
|
||||
/** 设置激活节点 */
|
||||
@@ -110,6 +117,7 @@ export class StateManager {
|
||||
addNode(node: NodesItem) {
|
||||
this.nodes.value.push(node);
|
||||
this.recordState()
|
||||
this.exportFlow()
|
||||
}
|
||||
/** 删除节点 */
|
||||
async deleteNode(id: string, { isElMessageBox } = { isElMessageBox: false }) {
|
||||
@@ -136,6 +144,7 @@ export class StateManager {
|
||||
if (!deletePromise) return console.log('删除操作被取消')
|
||||
this.nodes.value = this.nodes.value.filter((node: NodesItem) => node.id !== id)
|
||||
this.recordState()
|
||||
this.exportFlow()
|
||||
}
|
||||
/** 获取节点 */
|
||||
getNodeById(id: string) { return this.nodes.value.find((node: NodesItem) => node.id === id) }
|
||||
@@ -176,8 +185,22 @@ export class StateManager {
|
||||
const size = this.historyList.value.length - this.mxHistory.value
|
||||
if (size > 0) this.historyList.value.splice(0, size)
|
||||
this.historyIndex.value = this.historyList.value.length - 1
|
||||
|
||||
this.isSave.value = true
|
||||
}
|
||||
/** 画布数据存储 */
|
||||
async exportFlow (time:number = 0){
|
||||
if(!this.sketchId)return
|
||||
clearTimeout(this.saveCanvasTime)
|
||||
await new Promise((resolve) => {
|
||||
this.saveCanvasTime = setTimeout(()=>{
|
||||
putSketchFlowCanvas({
|
||||
id: this.sketchId,
|
||||
canvasData: JSON.stringify(this.nodes.value) }).then(() => {
|
||||
resolve(true)
|
||||
}).catch(() => {
|
||||
resolve(true)
|
||||
})
|
||||
},time)
|
||||
})
|
||||
}
|
||||
/** 撤回状态 */
|
||||
undoState() {
|
||||
@@ -186,6 +209,7 @@ export class StateManager {
|
||||
if (!state) return
|
||||
this.historyIndex.value = index
|
||||
this.nodes.value = JSON.parse(state.nodes)
|
||||
this.exportFlow(this.saveCanvasTimeInterval)
|
||||
}
|
||||
/** 重做状态 */
|
||||
redoState() {
|
||||
@@ -194,6 +218,7 @@ export class StateManager {
|
||||
if (!state) return
|
||||
this.historyIndex.value = index
|
||||
this.nodes.value = JSON.parse(state.nodes)
|
||||
this.exportFlow(this.saveCanvasTimeInterval)
|
||||
}
|
||||
|
||||
/** 显示指定子节点和父节点连接线,隐藏父节点和其他子节点链接线, */
|
||||
@@ -211,7 +236,7 @@ export class StateManager {
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.isSave.value = false
|
||||
clearTimeout(this.saveCanvasTime)
|
||||
this.historyList.value = []
|
||||
this.historyIndex.value = 0
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@ export const downloadImage = (url: string, name: string) => {
|
||||
}
|
||||
|
||||
/** 批量下载图片 */
|
||||
export const downImgListToZip = async (imagesParams) => {
|
||||
export const downImgListToZip = async (imagesParams,callback) => {
|
||||
const zip = new JSZip()
|
||||
const promises = []
|
||||
// 遍历下载每个图片
|
||||
let progress = 0
|
||||
imagesParams.forEach((img, index) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
@@ -32,18 +33,17 @@ export const downImgListToZip = async (imagesParams) => {
|
||||
if (xhr.status === 200) {
|
||||
const fileName = img.name
|
||||
zip.file(fileName, xhr.response)
|
||||
progress++
|
||||
callback(progress)
|
||||
resolve('')
|
||||
} else {
|
||||
reject(new Error(`下载失败: ${img.url}`))
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = () => reject(new Error(`网络错误: ${img.url}`))
|
||||
xhr.send()
|
||||
})
|
||||
|
||||
promises.push(promise)
|
||||
console.log(promises,zip)
|
||||
})
|
||||
|
||||
// 等待所有图片下载完成
|
||||
@@ -56,7 +56,7 @@ export const downImgListToZip = async (imagesParams) => {
|
||||
link.href = URL.createObjectURL(content)
|
||||
link.download = 'DesignFiles'
|
||||
link.click()
|
||||
URL.revokeObjectURL(link.href)
|
||||
// URL.revokeObjectURL(link.href)
|
||||
})
|
||||
.catch((error) => console.error('下载失败:', error))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user