fix: 测试清单遗留bug批量修复(15条:商品库/消费/团队/设置/消息中心/平台套图/资产库)

- R6 商品图删除不生效: 封面asset移交+绕开prefetch缓存, 前端封面缩图补删除入口
- R48 消息中心长文本与UI框错位: 胶囊单行省略+优先级标签禁压缩
- R70 账单流水筛选: 后端加ledger_type过滤, count随筛选变化, 切筛选重置页码
- R72 月限额改后不刷新: 团队页/消费页自取最新teamSettings, 两页同源
- R83/R86 平台套图提示词框加大+模型胶囊嵌入输入框(复用Pill组件)
- R96 未读角标: 修KeyTextTransform注解过滤触发MySQL 3141致接口500
- R100 工作台记录丢失: 新增GET /api/ai/tasks/workbench/ 同源恢复, 废除localStorage方案
- R104 卖点添加按钮移出输入框, 新建抽屉+编辑态统一
- R106 商品库宽屏锁5列, 10个/页铺满两行
- R108 资产删除改软删+单张删除+回收站二次确认; trash页商品/资产双分区+restore/purge端点
- R109 生成图自动入资产库(person演员立绘除外), 迁移0008存量回填, 移除全部加入资产库入口
- R65 无需改动(22268d6已修, 测旧部署所致)

验证: tsc/build/check/makemigrations --check 通过, 后端测试210/210, perf-probe PASS

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-07-02 11:30:06 +08:00
co-authored by Claude Fable 5
parent 22268d608b
commit aab4d7ea4c
28 changed files with 924 additions and 476 deletions
+28 -4
View File
@@ -154,6 +154,16 @@ export const api = {
deleteAsset(id: string) {
return request<void>(`/api/assets/${id}/`, { method: "DELETE" });
},
// R108 资产垃圾桶(与商品垃圾桶同构):已软删资产列表 / 恢复回资产库 / 彻底删除(不可恢复)
assetsTrash() {
return request<Paginated<Asset>>("/api/assets/trash/");
},
restoreAsset(id: string) {
return request<Asset>(`/api/assets/${id}/restore/`, { method: "POST" });
},
purgeAsset(id: string) {
return request<void>(`/api/assets/${id}/purge/`, { method: "DELETE" });
},
preferences() {
return request<UserPreference>("/api/auth/me/preferences/");
},
@@ -176,6 +186,10 @@ export const api = {
teamMembers() {
return request<TeamMember[]>("/api/auth/team/members/");
},
// 团队级设置读取(任意成员可读):团队页/消费页取最新月限额,避免依赖登录时的陈旧 /me/ 快照(R72)
teamSettings() {
return request<Team>("/api/auth/team/settings/");
},
// 团队级月限额持久化(超管在团队页设置 · PMC#12);monthly_credit_limit: 数值 / null(清空)
updateTeamSettings(payload: { monthly_credit_limit?: number | string | null }) {
return request<Team>("/api/auth/team/settings/", { method: "PATCH", body: JSON.stringify(payload) });
@@ -501,8 +515,7 @@ export const api = {
submitAssetReview(id: string) {
return request<{ review_status: string; review_error: string }>(`/api/assets/${id}/submit-review/`, { method: "POST" });
},
// 单图「加入资产库 / 取消加入」:置 in_library。加入 → 出现在资产库列表;取消 → 移出列表。
// 资产生成时已落库并扣费,此口只控制是否进资产库展示列表,不增删真实资产、不二次扣费。
// 置 in_library(现仅演员库「保存人物」用:立绘暂存 → 入库;R109 后图片生成成图已自动入库)
setAssetLibrary(id: string, inLibrary: boolean) {
return request<{ id: string; in_library: boolean }>(`/api/assets/${id}/set-library/`, { method: "POST", body: JSON.stringify({ in_library: inLibrary }) });
},
@@ -585,8 +598,12 @@ export const api = {
billingSummary() {
return request<BillingSummary>("/api/billing/summary/");
},
ledgers(page = 1, pageSize = 10) {
return request<{ count: number; page: number; page_size: number; results: Ledger[] }>(`/api/billing/ledgers/?page=${page}&page_size=${pageSize}`);
ledgers(page = 1, pageSize = 10, filters?: { ledger_type?: string; user?: string }) {
// 类型/成员筛选传参给后端做全量过滤(count/总页数随筛选变化 · R70)
const q = new URLSearchParams({ page: String(page), page_size: String(pageSize) });
if (filters?.ledger_type) q.set("ledger_type", filters.ledger_type);
if (filters?.user) q.set("user", filters.user);
return request<{ count: number; page: number; page_size: number; results: Ledger[] }>(`/api/billing/ledgers/?${q.toString()}`);
},
billingTrend(range?: "day" | "week" | "month") {
return request<BillingTrend>(`/api/billing/trend/${range ? `?range=${range}` : ""}`);
@@ -600,6 +617,13 @@ export const api = {
// 以便 全部/已完成/失败 三个 tab 数按真实总量算。
return request<Paginated<AITask>>("/api/ai/tasks/?page_size=200&task_type=person_image,product_image");
},
// R100:工作台生成记录(模特上身图/平台套图)——从后端持久任务拉取,与任务中心同源,
// 刷新/换浏览器不丢;按 mode(+product)过滤,前端按 batch_id 归批。
workbenchTasks(mode: "model" | "cover" | "image", productId?: string) {
const qs = new URLSearchParams({ mode });
if (productId) qs.set("product", productId);
return request<{ tasks: import("./types").WorkbenchTask[] }>(`/api/ai/tasks/workbench/?${qs.toString()}`);
},
// YYX#row22:未读生成任务汇总(导航胶囊总数 + 按商品分组角标)
aiTasksUnread() {
return request<{ total: number; by_product: Record<string, number> }>("/api/ai/tasks/unread/");