素材云下载
This commit is contained in:
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.9 MiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 272 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.6 MiB |
+438
File diff suppressed because one or more lines are too long
-440
File diff suppressed because one or more lines are too long
-425
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
|
After Width: | Height: | Size: 459 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 MiB |
Vendored
+1
-1
@@ -28,7 +28,7 @@
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script type="module" crossorigin src="/assets/index-BwL6llN9.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BjRp0K8U.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-eLRg4pQk.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Generated
+94
-1
@@ -12,6 +12,7 @@
|
||||
"@types/three": "^0.184.1",
|
||||
"antd": "^6.3.7",
|
||||
"dayjs": "^1.11.20",
|
||||
"jszip": "^3.10.1",
|
||||
"plyr-react": "^6.0.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.2.5",
|
||||
@@ -2501,6 +2502,12 @@
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"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/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@@ -3083,6 +3090,12 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"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/imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
@@ -3093,6 +3106,12 @@
|
||||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
@@ -3161,6 +3180,12 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -3241,6 +3266,18 @@
|
||||
"node": ">=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/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
@@ -3265,6 +3302,15 @@
|
||||
"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/lightningcss": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||
@@ -3770,6 +3816,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"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/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@@ -4040,6 +4092,12 @@
|
||||
"node": ">= 0.8.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/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -4179,6 +4237,21 @@
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"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/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -4303,6 +4376,12 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"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/scheduler": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||
@@ -4334,6 +4413,12 @@
|
||||
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -4367,6 +4452,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"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/string-convert": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
|
||||
@@ -4659,7 +4753,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"@types/three": "^0.184.1",
|
||||
"antd": "^6.3.7",
|
||||
"dayjs": "^1.11.20",
|
||||
"jszip": "^3.10.1",
|
||||
"plyr-react": "^6.0.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.2.5",
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
uploadVideo, getCreditRatios, deleteHistory, calculateCredits
|
||||
} from '../api';
|
||||
|
||||
import { useAppStore } from '../store/useAppStore';
|
||||
|
||||
import {
|
||||
PlusOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
@@ -112,9 +114,31 @@ const AIChatPage: React.FC = () => {
|
||||
|
||||
const [inputValue, setInputValue] = useState<string>('');
|
||||
|
||||
const [mediaType, setMediaType] = useState<string>('image');
|
||||
|
||||
const [countType, setCountType] = useState<string>('请选择');
|
||||
// 从 store 读取生成配置状态
|
||||
const {
|
||||
mediaType,
|
||||
countType,
|
||||
selectedRatio,
|
||||
selectedResolution,
|
||||
width,
|
||||
height,
|
||||
videoDuration,
|
||||
videoAspectRatio,
|
||||
videoResolution,
|
||||
engineOptions,
|
||||
enginesele,
|
||||
setMediaType,
|
||||
setCountType,
|
||||
setSelectedRatio,
|
||||
setSelectedResolution,
|
||||
setWidth,
|
||||
setHeight,
|
||||
setVideoDuration,
|
||||
setVideoAspectRatio,
|
||||
setVideoResolution,
|
||||
setEngineOptions,
|
||||
setEnginesele,
|
||||
} = useAppStore();
|
||||
|
||||
const [uploading, setUploading] = useState<boolean>(false);
|
||||
|
||||
@@ -183,11 +207,6 @@ const AIChatPage: React.FC = () => {
|
||||
const [attachmentPopupMessageId, setAttachmentPopupMessageId] = useState<string | null>(null);
|
||||
const [attachmentPopupPosition, setAttachmentPopupPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
// 图片设置相关状态
|
||||
const [selectedRatio, setSelectedRatio] = useState<string>('1:1');
|
||||
const [selectedResolution, setSelectedResolution] = useState<string>('2K');
|
||||
const [width, setWidth] = useState<number>(2048);
|
||||
const [height, setHeight] = useState<number>(2048);
|
||||
const [showImageSettingsModal, setShowImageSettingsModal] = useState(false);
|
||||
const [showVideoSettingsModal, setShowVideoSettingsModal] = useState(false);
|
||||
const [ratioOptions, setRatioOptions] = useState([]);
|
||||
@@ -196,22 +215,8 @@ const AIChatPage: React.FC = () => {
|
||||
const [blindex, setBlindex] = useState<any>(0);
|
||||
const [fblindex, setFBlindex] = useState<any>(0);
|
||||
|
||||
// 视频设置相关状态
|
||||
const [videoDuration, setVideoDuration] = useState(5);
|
||||
const [videoAspectRatio, setVideoAspectRatio] = useState<string>('16:9');
|
||||
const [videoResolution, setVideoResolution] = useState<string>('720p');
|
||||
const [showEngineModal, setShowEngineModal] = useState(false);
|
||||
const [engineOptions, setEngineOptions] = useState<{
|
||||
ratios: string[];
|
||||
resolutions: string[];
|
||||
durations: number[];
|
||||
}>({
|
||||
ratios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
|
||||
resolutions: ['480p', '720p', '1080p'],
|
||||
durations: [5, 8, 10, 12, 15],
|
||||
});
|
||||
|
||||
const [enginesele, setEnginesele] = useState<any>([]);
|
||||
const [creditRatios, setCreditRatios] = useState<any[]>([]);
|
||||
const [cimage, setCimage] = useState<any[]>([]);
|
||||
const [creditCalculationData, setCreditCalculationData] = useState<any[]>([]);
|
||||
@@ -359,23 +364,33 @@ const AIChatPage: React.FC = () => {
|
||||
// 如果是视频模式,初始化视频参数选项
|
||||
if (data.engine.video && data.engine.video.length > 0) {
|
||||
const defaultEngine = data.engine.video[0];
|
||||
|
||||
// 查找用户之前选择的引擎(如果存在)
|
||||
const savedEngine = data.engine.video.find((e: any) => e.id === countType);
|
||||
const targetEngine = savedEngine || defaultEngine;
|
||||
|
||||
// 更新引擎选项为当前引擎支持的参数
|
||||
setEngineOptions({
|
||||
ratios: defaultEngine.supportedRatios || ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
|
||||
resolutions: defaultEngine.supportedResolutions || ['480p', '720p', '1080p'],
|
||||
durations: defaultEngine.supportedDurations || [5, 8, 10, 12, 15],
|
||||
ratios: targetEngine.supportedRatios || ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
|
||||
resolutions: targetEngine.supportedResolutions || ['480p', '720p', '1080p'],
|
||||
durations: targetEngine.supportedDurations || [5, 8, 10, 12, 15],
|
||||
});
|
||||
// 设置默认选中值
|
||||
if (defaultEngine.supportedRatios?.length > 0) {
|
||||
setVideoAspectRatio(defaultEngine.supportedRatios[0]);
|
||||
|
||||
// 确保视频参数在引擎支持的范围内
|
||||
if (!targetEngine.supportedRatios?.includes(videoAspectRatio)) {
|
||||
setVideoAspectRatio(targetEngine.supportedRatios?.[0] || '16:9');
|
||||
}
|
||||
if (defaultEngine.supportedResolutions?.length > 0) {
|
||||
setVideoResolution(defaultEngine.supportedResolutions[0]);
|
||||
if (!targetEngine.supportedResolutions?.includes(videoResolution)) {
|
||||
setVideoResolution(targetEngine.supportedResolutions?.[0] || '720p');
|
||||
}
|
||||
if (defaultEngine.supportedDurations?.length > 0) {
|
||||
setVideoDuration(defaultEngine.supportedDurations[0]);
|
||||
if (!targetEngine.supportedDurations?.includes(videoDuration)) {
|
||||
setVideoDuration(targetEngine.supportedDurations?.[0] || 5);
|
||||
}
|
||||
|
||||
// 如果之前没有选择过引擎(还是默认值),才设置默认引擎
|
||||
if (countType === '请选择') {
|
||||
setCountType(targetEngine.id);
|
||||
}
|
||||
// 设置默认引擎
|
||||
setCountType(defaultEngine.id);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState, useLayoutEffect, useRef, useCallback } from 'react';
|
||||
import { Button, Empty, Input, Select, Space, Typography, Tag, message, Modal, Table, DatePicker } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import JSZip from 'jszip';
|
||||
import {
|
||||
FilterOutlined,
|
||||
VideoCameraOutlined,
|
||||
@@ -601,6 +602,81 @@ const GeneratedRecord: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDownloadSelected = async () => {
|
||||
if (selectedItems.size === 0) {
|
||||
message.warning('请先选择要下载的媒体');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查下载数量限制
|
||||
if (selectedItems.size > 10) {
|
||||
message.warning('最多只能单次下载10个文件');
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedContent: any[] = [];
|
||||
recordlist.forEach((group: any) => {
|
||||
group.items.forEach((item: any) => {
|
||||
if (selectedItems.has(getItemResourceId(item))) {
|
||||
selectedContent.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const zip = new JSZip();
|
||||
const baseUrl = import.meta.env.VITE_API_BASE || "http://localhost:8000";
|
||||
const folder = zip.folder('downloads');
|
||||
let hasError = false;
|
||||
let successCount = 0;
|
||||
|
||||
message.loading({ content: '下载中,请稍候...', key: 'downloadProgress' });
|
||||
|
||||
for (const item of selectedContent) {
|
||||
const url = `${baseUrl}${item.videoUrl || item.imageUrl}`;
|
||||
const filename = ((item.videoUrl || item.imageUrl).split('/').pop() || `file_${Date.now()}`).split('?')[0];
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error('Network response was not ok');
|
||||
const blob = await response.blob();
|
||||
folder?.file(filename, blob);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
console.warn(`文件下载失败(CORS限制): ${filename},将使用备用方式下载`);
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
// Fallback: 逐个打开文件下载(不受 CORS 限制)
|
||||
message.destroy('downloadProgress');
|
||||
message.info('由于跨域限制,将逐个下载文件');
|
||||
selectedContent.forEach((item, index) => {
|
||||
setTimeout(() => {
|
||||
const url = `${baseUrl}${item.videoUrl || item.imageUrl}&download=1`;
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = '';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}, index * 500);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const zipBlob = await zip.generateAsync({ type: 'blob' });
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(zipBlob);
|
||||
link.download = `downloads_${Date.now()}.zip`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
|
||||
message.destroy('downloadProgress');
|
||||
message.success(`下载完成,共 ${successCount} 个文件`);
|
||||
};
|
||||
|
||||
|
||||
const handleBatchUploadSelected = () => {
|
||||
if (selectedItems.size === 0) {
|
||||
message.warning('请先选择要上传的媒体');
|
||||
@@ -692,7 +768,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
itemMap.set(resourceId, item);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
for (const itemId of selectedItems) {
|
||||
const item = itemMap.get(itemId);
|
||||
// 根据item是否有generatedResourceId来决定source_model
|
||||
@@ -702,7 +778,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
} else {
|
||||
sourceModel = filterType === 'project' ? 'generation_records' : 'chat_generation_tasks';
|
||||
}
|
||||
|
||||
|
||||
tasks.push({
|
||||
advertiser_ids: advertiserIds,
|
||||
resource_ids: [itemId],
|
||||
@@ -827,8 +903,8 @@ const GeneratedRecord: React.FC = () => {
|
||||
page: res.page,
|
||||
}];
|
||||
if (recordList && recordList[0].items.length > 0) {
|
||||
setRecordList(recordList);
|
||||
}else{
|
||||
setRecordList(recordList);
|
||||
} else {
|
||||
setRecordList([]);
|
||||
}
|
||||
}).catch((err) => {
|
||||
@@ -927,7 +1003,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
}, [filterType, filterMedia]);
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: 'calc(100vh - 90px)', background: '#ffffffff' , overflowY: 'auto'}} >
|
||||
<div style={{ minHeight: 'calc(100vh - 90px)', background: '#ffffffff', overflowY: 'auto' }} >
|
||||
{/* 操作栏:筛选 + 上传按钮 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
@@ -1008,6 +1084,18 @@ const GeneratedRecord: React.FC = () => {
|
||||
>
|
||||
取消选择
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleDownloadSelected()}
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
background: '#f8f9fc',
|
||||
border: '1px solid #e2e8f0',
|
||||
color: '#222222ff',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
下载{selectedItems.size}个
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleBatchUploadSelected}
|
||||
@@ -1036,9 +1124,9 @@ const GeneratedRecord: React.FC = () => {
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
批量上传
|
||||
批量操作
|
||||
</Button>
|
||||
|
||||
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1057,7 +1145,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<Typography.Text style={{ color: '#94a3b8', fontSize: 14 }}>媒体类型:</Typography.Text>
|
||||
|
||||
|
||||
<Space>
|
||||
<Button
|
||||
type={filterMedia === 'video' ? 'primary' : 'default'}
|
||||
@@ -1534,7 +1622,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
open={uploadHistoryModalVisible}
|
||||
onCancel={() => setUploadHistoryModalVisible(false)}
|
||||
footer={null}
|
||||
width={ 800 }
|
||||
width={800}
|
||||
style={{ borderRadius: 8 }}
|
||||
mask={{ closable: false }}
|
||||
>
|
||||
@@ -1638,7 +1726,7 @@ const GeneratedRecord: React.FC = () => {
|
||||
width: 180,
|
||||
render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
|
||||
|
||||
]}
|
||||
loading={uploadHistoryLoading}
|
||||
scroll={{ x: 'max-content' }}
|
||||
|
||||
@@ -15,6 +15,23 @@ interface AppState {
|
||||
records: api.GenerationRecordPageListOut;
|
||||
loading: boolean;
|
||||
|
||||
// 生成配置状态 - 页面跳转时保留,刷新时重置
|
||||
mediaType: string;
|
||||
countType: string;
|
||||
selectedRatio: string;
|
||||
selectedResolution: string;
|
||||
width: number;
|
||||
height: number;
|
||||
videoDuration: number;
|
||||
videoAspectRatio: string;
|
||||
videoResolution: string;
|
||||
engineOptions: {
|
||||
ratios: string[];
|
||||
resolutions: string[];
|
||||
durations: number[];
|
||||
};
|
||||
enginesele: any;
|
||||
|
||||
fetchProjects: () => Promise<void>;
|
||||
createProject: (name: string, industry: Industry) => Promise<Project>;
|
||||
deleteProject: (id: string) => Promise<void>;
|
||||
@@ -23,6 +40,23 @@ interface AppState {
|
||||
optimizePrompt: (projectId: string, params: OptimizeParams) => Promise<OptimizeResult>;
|
||||
generateVideo: (recordId: string, params: GenerateParams) => Promise<GenerationRecord>;
|
||||
updateRecordReferences: (recordId: string, references: MediaReference[]) => void;
|
||||
|
||||
// 生成配置状态更新方法
|
||||
setMediaType: (mediaType: string) => void;
|
||||
setCountType: (countType: string) => void;
|
||||
setImageSettings: (ratio: string, resolution: string, width: number, height: number) => void;
|
||||
setVideoSettings: (duration: number, aspectRatio: string, resolution: string) => void;
|
||||
setEngineOptions: (options: { ratios: string[]; resolutions: string[]; durations: number[] }) => void;
|
||||
// 单独的 setter 方法
|
||||
setSelectedRatio: (ratio: string) => void;
|
||||
setSelectedResolution: (resolution: string) => void;
|
||||
setWidth: (width: number) => void;
|
||||
setHeight: (height: number) => void;
|
||||
setVideoDuration: (duration: number) => void;
|
||||
setVideoAspectRatio: (aspectRatio: string) => void;
|
||||
setVideoResolution: (resolution: string) => void;
|
||||
setEnginesele: (enginesele: any) => void;
|
||||
resetGenerationConfig: () => void;
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppState>((set, get) => ({
|
||||
@@ -30,6 +64,23 @@ export const useAppStore = create<AppState>((set, get) => ({
|
||||
records: emptyRecordsPage(),
|
||||
loading: false,
|
||||
|
||||
// 生成配置状态初始值
|
||||
mediaType: 'image',
|
||||
countType: '请选择',
|
||||
selectedRatio: '1:1',
|
||||
selectedResolution: '2K',
|
||||
width: 2048,
|
||||
height: 2048,
|
||||
videoDuration: 5,
|
||||
videoAspectRatio: '16:9',
|
||||
videoResolution: '720p',
|
||||
engineOptions: {
|
||||
ratios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
|
||||
resolutions: ['480p', '720p', '1080p'],
|
||||
durations: [5, 8, 10, 12, 15],
|
||||
},
|
||||
enginesele: [],
|
||||
|
||||
fetchProjects: async () => {
|
||||
set({ loading: true });
|
||||
try {
|
||||
@@ -99,4 +150,39 @@ export const useAppStore = create<AppState>((set, get) => ({
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 生成配置状态更新方法
|
||||
setMediaType: (mediaType) => set({ mediaType }),
|
||||
setCountType: (countType) => set({ countType }),
|
||||
setImageSettings: (ratio, resolution, width, height) =>
|
||||
set({ selectedRatio: ratio, selectedResolution: resolution, width, height }),
|
||||
setVideoSettings: (duration, aspectRatio, resolution) =>
|
||||
set({ videoDuration: duration, videoAspectRatio: aspectRatio, videoResolution: resolution }),
|
||||
setEngineOptions: (options) => set({ engineOptions: options }),
|
||||
// 单独的 setter 方法
|
||||
setSelectedRatio: (ratio) => set({ selectedRatio: ratio }),
|
||||
setSelectedResolution: (resolution) => set({ selectedResolution: resolution }),
|
||||
setWidth: (width) => set({ width }),
|
||||
setHeight: (height) => set({ height }),
|
||||
setVideoDuration: (duration) => set({ videoDuration: duration }),
|
||||
setVideoAspectRatio: (aspectRatio) => set({ videoAspectRatio: aspectRatio }),
|
||||
setVideoResolution: (resolution) => set({ videoResolution: resolution }),
|
||||
setEnginesele: (enginesele) => set({ enginesele }),
|
||||
resetGenerationConfig: () => set({
|
||||
mediaType: 'image',
|
||||
countType: '请选择',
|
||||
selectedRatio: '1:1',
|
||||
selectedResolution: '2K',
|
||||
width: 2048,
|
||||
height: 2048,
|
||||
videoDuration: 5,
|
||||
videoAspectRatio: '16:9',
|
||||
videoResolution: '720p',
|
||||
engineOptions: {
|
||||
ratios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
|
||||
resolutions: ['480p', '720p', '1080p'],
|
||||
durations: [5, 8, 10, 12, 15],
|
||||
},
|
||||
enginesele: [],
|
||||
}),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user