This commit is contained in:
lzp
2026-03-18 17:25:20 +08:00
16 changed files with 323 additions and 66 deletions

173
package-lock.json generated
View File

@@ -17,6 +17,7 @@
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"fabric-with-all": "^5.3.1", "fabric-with-all": "^5.3.1",
"gsap": "^3.13.0", "gsap": "^3.13.0",
"jszip": "^3.10.1",
"md5": "^2.3.0", "md5": "^2.3.0",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"pinia": "^2.0.32", "pinia": "^2.0.32",
@@ -2435,6 +2436,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
},
"node_modules/cors": { "node_modules/cors": {
"version": "2.8.5", "version": "2.8.5",
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz", "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
@@ -4812,6 +4819,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
"license": "MIT"
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -4856,8 +4869,7 @@
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"devOptional": true
}, },
"node_modules/internal-slot": { "node_modules/internal-slot": {
"version": "1.1.0", "version": "1.1.0",
@@ -5385,8 +5397,7 @@
"node_modules/isarray": { "node_modules/isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
"dev": true
}, },
"node_modules/isexe": { "node_modules/isexe": {
"version": "2.0.0", "version": "2.0.0",
@@ -5519,6 +5530,48 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"node_modules/jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"license": "(MIT OR GPL-3.0-or-later)",
"dependencies": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"setimmediate": "^1.0.5"
}
},
"node_modules/jszip/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/jszip/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/jszip/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-5.1.0.tgz", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-5.1.0.tgz",
@@ -5573,6 +5626,15 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"license": "MIT",
"dependencies": {
"immediate": "~3.0.5"
}
},
"node_modules/lilconfig": { "node_modules/lilconfig": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz",
@@ -7408,6 +7470,12 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/parent-module": { "node_modules/parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
@@ -7790,6 +7858,12 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/property-information": { "node_modules/property-information": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
@@ -8446,6 +8520,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
"license": "MIT"
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -10230,8 +10310,7 @@
"node_modules/util-deprecate": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
"devOptional": true
}, },
"node_modules/validate-npm-package-license": { "node_modules/validate-npm-package-license": {
"version": "3.0.4", "version": "3.0.4",
@@ -12506,6 +12585,11 @@
"integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
"dev": true "dev": true
}, },
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"cors": { "cors": {
"version": "2.8.5", "version": "2.8.5",
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz", "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
@@ -14269,6 +14353,11 @@
"integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
"dev": true "dev": true
}, },
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"import-fresh": { "import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -14304,8 +14393,7 @@
"inherits": { "inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"devOptional": true
}, },
"internal-slot": { "internal-slot": {
"version": "1.1.0", "version": "1.1.0",
@@ -14660,8 +14748,7 @@
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
"dev": true
}, },
"isexe": { "isexe": {
"version": "2.0.0", "version": "2.0.0",
@@ -14771,6 +14858,46 @@
"universalify": "^2.0.0" "universalify": "^2.0.0"
} }
}, },
"jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"setimmediate": "^1.0.5"
},
"dependencies": {
"readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"kind-of": { "kind-of": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-5.1.0.tgz", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-5.1.0.tgz",
@@ -14813,6 +14940,14 @@
"type-check": "~0.4.0" "type-check": "~0.4.0"
} }
}, },
"lie": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"requires": {
"immediate": "~3.0.5"
}
},
"lilconfig": { "lilconfig": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz",
@@ -16078,6 +16213,11 @@
"aggregate-error": "^3.0.0" "aggregate-error": "^3.0.0"
} }
}, },
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"parent-module": { "parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
@@ -16341,6 +16481,11 @@
"fast-diff": "^1.1.2" "fast-diff": "^1.1.2"
} }
}, },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"property-information": { "property-information": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
@@ -16833,6 +16978,11 @@
"split-string": "^3.0.1" "split-string": "^3.0.1"
} }
}, },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
},
"shebang-command": { "shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -18176,8 +18326,7 @@
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
"devOptional": true
}, },
"validate-npm-package-license": { "validate-npm-package-license": {
"version": "3.0.4", "version": "3.0.4",

View File

@@ -22,6 +22,7 @@
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"fabric-with-all": "^5.3.1", "fabric-with-all": "^5.3.1",
"gsap": "^3.13.0", "gsap": "^3.13.0",
"jszip": "^3.10.1",
"md5": "^2.3.0", "md5": "^2.3.0",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"pinia": "^2.0.32", "pinia": "^2.0.32",

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>
@@ -81,6 +81,7 @@
import resultImage from './components/nodes/result-image.vue' import resultImage from './components/nodes/result-image.vue'
import card from './components/nodes/cards/index.vue' import card from './components/nodes/cards/index.vue'
import text from './components/nodes/text.vue' import text from './components/nodes/text.vue'
import { downImgListToZip } from '../tools/tools'
const components = { const components = {
[NODE_COMPONENT.RESULT_IMAGE]: resultImage, [NODE_COMPONENT.RESULT_IMAGE]: resultImage,
@@ -194,6 +195,20 @@
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)
let arr = stateManager.nodes.value.filter((v) => v.data.type === NODE_COMPONENT.RESULT_IMAGE)
let imgList = []
arr.forEach((v) => {
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}`})
})
})
downImgListToZip(imgList)
console.log(imgList)
return
// flowManager.exportFlow() // flowManager.exportFlow()
const str = getFlowJson() const str = getFlowJson()
stateManager.isSave.value = false stateManager.isSave.value = false
@@ -224,8 +239,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

@@ -1,3 +1,4 @@
import JSZip from 'jszip'
export const createId = (before: string = 'node') => { export const createId = (before: string = 'node') => {
const time = Date.now().toString(36) const time = Date.now().toString(36)
const random = Math.random().toString(36).substring(2, 20) const random = Math.random().toString(36).substring(2, 20)
@@ -15,4 +16,47 @@ export const downloadImage = (url: string, name: string) => {
a.download = name || 'image.png' a.download = name || 'image.png'
a.click() a.click()
}) })
} }
/** 批量下载图片 */
export const downImgListToZip = async (imagesParams) => {
const zip = new JSZip()
const promises = []
// 遍历下载每个图片
imagesParams.forEach((img, index) => {
const promise = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', img.url, true)
xhr.responseType = "blob";
xhr.onload = () => {
if (xhr.status === 200) {
const fileName = img.name
zip.file(fileName, xhr.response)
resolve('')
} else {
reject(new Error(`下载失败: ${img.url}`))
}
}
xhr.onerror = () => reject(new Error(`网络错误: ${img.url}`))
xhr.send()
})
promises.push(promise)
console.log(promises,zip)
})
// 等待所有图片下载完成
Promise.all(promises)
.then(() => zip.generateAsync({ type: 'blob' }))
.then((content) => {
// 下载zip
console.log(content)
const link = document.createElement('a')
link.href = URL.createObjectURL(content)
link.download = 'DesignFiles'
link.click()
URL.revokeObjectURL(link.href)
})
.catch((error) => console.error('下载失败:', error))
}

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: '请输入'

View File

@@ -109,7 +109,7 @@
handleSendMessage({ handleSendMessage({
text: initialData.text, text: initialData.text,
images: initialData.images, images: initialData.images,
useReport:initialData.useReport, useReport: initialData.useReport,
tempImages: initialData.tempImages tempImages: initialData.tempImages
}) })
// 更新 configParams // 更新 configParams
@@ -131,7 +131,10 @@
isPaused.value = false isPaused.value = false
isGenerating.value = true isGenerating.value = true
params.message = message.text params.message = message.text
params.useReport = message.useReport if (message.hasOwnProperty('useReport')) {
params.useReport = message.useReport
}
params.imageUrlList = message.images || [] params.imageUrlList = message.images || []
// 如果不是重新生成模式,则添加用户消息到列表 // 如果不是重新生成模式,则添加用户消息到列表
@@ -241,13 +244,11 @@
for (let event of events) { for (let event of events) {
if (!event.trim()) continue if (!event.trim()) continue
// 解析事件名称(从 event:xxx 行) const eventName = event
const eventName = .split(/\n/)
event .find((line) => line.startsWith('event:'))
.split(/\n/) ?.replace(/^event:\s*/, '')
.find((line) => line.startsWith('event:')) ?.trim()
?.replace(/^event:\s*/, '')
?.trim() || ''
if (!hasReportStarted && eventName === 'report') { if (!hasReportStarted && eventName === 'report') {
isGeneratingReport.value = true isGeneratingReport.value = true
@@ -281,7 +282,7 @@
break break
} }
if (eventName === 'todo') { if (eventName === 'todo') {
break continue
} }
let isNodeIdEvent = eventName === 'nodeId' let isNodeIdEvent = eventName === 'nodeId'
@@ -295,9 +296,10 @@
.filter((content) => content.startsWith('{') || content.startsWith('[')) .filter((content) => content.startsWith('{') || content.startsWith('['))
// console.log('dataLInes', dataLines) // console.log('dataLInes', dataLines)
if (isNodeIdEvent) { if (isNodeIdEvent) {
const versionID = event.split(/\n/) const versionID = event
.filter((line) => line.startsWith('data:')) .split(/\n/)
.map((line) => line.replace(/^data:\s*/, ''))[0] .filter((line) => line.startsWith('data:'))
.map((line) => line.replace(/^data:\s*/, ''))[0]
params.versionID = versionID params.versionID = versionID
projectStore.setProject({ nodeId: versionID }) projectStore.setProject({ nodeId: versionID })
} }

View File

@@ -37,7 +37,7 @@
<div class="left flex align-center"> <div class="left flex align-center">
<div class="agent-operate flex flex-center"> <div class="agent-operate flex flex-center">
<el-popover <el-popover
placement="top-end" placement="top"
trigger="click" trigger="click"
popper-class="agent-plus-popover" popper-class="agent-plus-popover"
> >
@@ -684,9 +684,11 @@
const payload = { const payload = {
text: inputValue.value.trim(), text: inputValue.value.trim(),
images: imageUrlList, images: imageUrlList,
useReport: reportTags.value.length > 0,
tempImages: uploadedImages.value tempImages: uploadedImages.value
} }
if (reportTags.value.length > 0) {
payload.useReport = true
}
emits('send', payload) emits('send', payload)
// 发送后清空图片列表 // 发送后清空图片列表
uploadedImages.value = [] uploadedImages.value = []
@@ -1367,7 +1369,9 @@
border: none !important; border: none !important;
padding: 0 !important; padding: 0 !important;
margin-bottom: -1rem; margin-bottom: -1rem;
pointer-events: none; width: fit-content !important;
min-width: initial !important;
//pointer-events: none;
.el-popper__arrow:before { .el-popper__arrow:before {
display: none; display: none;
} }