fix: 修复图片创作删除与垃圾桶预览

This commit is contained in:
hh
2026-07-16 23:24:44 +08:00
parent 5fc316112c
commit 81fdb02517
7 changed files with 172 additions and 9 deletions
+2 -1
View File
@@ -27,6 +27,7 @@ import type {
LoginSession,
Invitation,
ImageConversation,
ImageConversationTrash,
ImageConversationTask,
ModelConfig,
ModelEntity,
@@ -730,7 +731,7 @@ export const api = {
return request<Paginated<ImageConversation>>(`/api/ai/image-conversations/?${params.toString()}`);
},
conversationsTrash(mode: "image" | "model" | "cover" = "image") {
return request<Paginated<ImageConversation>>(`/api/ai/image-conversations/trash/?mode=${mode}&page_size=100`);
return request<Paginated<ImageConversationTrash>>(`/api/ai/image-conversations/trash/?mode=${mode}&page_size=100`);
},
createConversation(payload: { mode?: "image" | "model" | "cover"; title?: string; product?: string | null }) {
return request<ImageConversation>("/api/ai/image-conversations/", { method: "POST", body: JSON.stringify(payload) });
+29 -3
View File
@@ -738,6 +738,8 @@ export function ImageWorkbenchPage({
// 重命名:正在改名的对话 id + 草稿
const [renamingId, setRenamingId] = useState("");
const [renameDraft, setRenameDraft] = useState("");
// 整条对话删除独立确认,不与单图/批次删除状态耦合。
const [pendingDeleteConversation, setPendingDeleteConversation] = useState<ImageConversation | null>(null);
// 参考图:支持多张(可多选 / 多次追加),逐张可移除。提交时上传成 Asset 作生成参考。
const [refImages, setRefImages] = useState<{ name: string; url: string; file: File }[]>([]);
const refInputRef = useRef<HTMLInputElement | null>(null);
@@ -1050,8 +1052,16 @@ export function ImageWorkbenchPage({
try { await api.renameConversation(convId, title); } catch { void loadConversations(); }
}
// 删除对话(软删):从列表移除;删的是当前对话则切到剩下第一条或清空
// 删除对话(软删):接口成功后再从列表移除删的是当前对话则切到剩下第一条或清空
async function handleDeleteConversation(convId: string) {
try {
await api.deleteConversation(convId);
setConvError("");
} catch (error) {
setConvError(error instanceof Error ? error.message : "删除对话失败,请稍后重试");
void loadConversations();
return;
}
const remaining = conversations.filter((c) => c.id !== convId);
setConversations(remaining);
if (convId === activeConvId) {
@@ -1061,7 +1071,13 @@ export function ImageWorkbenchPage({
if (nextActive) void loadConvBatches(nextActive);
else setBatches([]);
}
try { await api.deleteConversation(convId); } catch { void loadConversations(); }
}
async function confirmDeleteConversation() {
const target = pendingDeleteConversation;
setPendingDeleteConversation(null);
if (!target) return;
await handleDeleteConversation(target.id);
}
// 列表加载:image 模式才用对话(model/cover 走商品空间布局)。
@@ -1682,7 +1698,7 @@ export function ImageWorkbenchPage({
<button
type="button"
title="删除对话"
onClick={(e) => { e.stopPropagation(); handleDeleteConversation(conv.id); }}
onClick={(e) => { e.stopPropagation(); setPendingDeleteConversation(conv); }}
>
<Trash2 size={12} />
</button>
@@ -1823,6 +1839,16 @@ export function ImageWorkbenchPage({
</div>
</div>
</section>
<ConfirmModal
open={!!pendingDeleteConversation}
title="删除当前对话"
subtitle="// DELETE"
icon={<Trash2 size={16} />}
detail="删除后可在垃圾桶恢复,是否需要删除?"
confirmText="删除"
onCancel={() => setPendingDeleteConversation(null)}
onConfirm={confirmDeleteConversation}
/>
{/* R108/R109:删除二次确认 —— 单张 / 整批共用,确认后软删进垃圾桶 */}
<ConfirmModal
open={!!confirmDel}
+4 -3
View File
@@ -3,7 +3,7 @@ import type { CSSProperties } from "react";
import { api } from "../api";
import { ConfirmModal } from "../components/overlays";
import type { NavigateFn } from "./route-config";
import type { Asset, FreeVideoTask, ImageConversation, ImageExceptionBatchTrash, ModelEntity, Product, Project } from "../types";
import type { Asset, FreeVideoTask, ImageConversationTrash, ImageExceptionBatchTrash, ModelEntity, Product, Project } from "../types";
import "../trash-page.css";
type TrashKind = "product" | "asset" | "model" | "image" | "imageExceptionBatch" | "freeVideo" | "project";
@@ -73,12 +73,13 @@ const rowsFromModels = (items: ModelEntity[]): TrashRow[] =>
cover: m.portrait || m.triview || ""
}));
const rowsFromConversations = (items: ImageConversation[]): TrashRow[] =>
const rowsFromConversations = (items: ImageConversationTrash[]): TrashRow[] =>
items.map((c) => ({
id: c.id,
kind: "image",
title: c.title || "未命名图片创作",
subtitle: `${c.task_count || 0} 个生成任务${dateOf(c.updated_at) ? ` · 删除于 ${dateOf(c.updated_at)}` : ""}`
subtitle: `${c.task_count || 0} 个生成任务${dateOf(c.updated_at) ? ` · 删除于 ${dateOf(c.updated_at)}` : ""}`,
cover: c.cover_preview_url || ""
}));
const IMAGE_MODE_LABEL: Record<ImageExceptionBatchTrash["mode"], string> = {
+5
View File
@@ -659,6 +659,11 @@ export type ImageConversation = {
updated_at: string;
};
// 垃圾桶专用:对话可含多个批次/资产,cover 只选一张用于列表展示。
export type ImageConversationTrash = ImageConversation & {
cover_preview_url: string;
};
// 工作台生成记录(R100):模特上身图/平台套图页从后端持久任务拉取(与任务中心同源),
// 按 batch_id 归批还原批次流;assets 只含存活成图(软删的图已被后端过滤)。
export type WorkbenchTask = {