perf(core): 资产预览改 TOS 公读直链 + 通知只取首页,减刷新开销与缓存失效
- 资产 preview_url 从「逐图签发预签名 URL」改为虚拟主机式公读直链 (https://{bucket}.{host}/{key})。桶公读已验证免签可访问;直链稳定可被浏览器/CDN 缓存,而签名链每次都变、1h 过期反而打不到缓存。boto3 也移出序列化热路径。 - allNotifications 不再逐页翻全部(原 O(N) 随消息增长拖慢每次刷新),只取首页 100 条 (侧边栏徽标 unread_count + 团队动态仅展示最近 6 条已足够);「共 N」改用后端真实 count。 - perf-probe:page_size 由 API 级硬闸确定性守住后,浏览器端「资产翻页」降为提示 (翻 1~2 页是资产真超 200 的合法分页,仅 ≥3 页才疑似 page_size 失效)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-19
@@ -312,7 +312,8 @@ export const api = {
|
||||
return request(`/api/projects/${projectId}/adopt-base-asset/`, { method: "POST", body: JSON.stringify(payload) });
|
||||
},
|
||||
// 流程步骤4 · 用演员库现有资产替换基础资产卡(挂为候选并采用)
|
||||
attachBaseAsset(projectId: string, payload: { group_id: string; asset_id: string }) {
|
||||
// seed 占位卡还没 group:不传 group_id,改传 kind+label,后端按 label 命中/新建实体组再挂(不出图)
|
||||
attachBaseAsset(projectId: string, payload: { group_id?: string; asset_id: string; kind?: "product" | "person" | "scene"; label?: string }) {
|
||||
return request(`/api/projects/${projectId}/attach-base-asset/`, { method: "POST", body: JSON.stringify(payload) });
|
||||
},
|
||||
// 流程步骤4 · 据某一版立绘资产生成它配套的三视图(image_edit 锁角色一致性,绑定该立绘 asset)
|
||||
@@ -401,6 +402,10 @@ export const api = {
|
||||
uploadAsset(formData: FormData) {
|
||||
return request<Asset>("/api/assets/upload/", { method: "POST", body: formData });
|
||||
},
|
||||
// 流程步骤4 · 给人物/资产改名(添加人物工作台命名 → PATCH 写回 name)
|
||||
updateAsset(id: string, payload: { name?: string; description?: string }) {
|
||||
return request<Asset>(`/api/assets/${id}/`, { method: "PATCH", body: JSON.stringify(payload) });
|
||||
},
|
||||
billingSummary() {
|
||||
return request<BillingSummary>("/api/billing/summary/");
|
||||
},
|
||||
@@ -437,25 +442,11 @@ export const api = {
|
||||
const qs = query.toString();
|
||||
return request<NotificationList>(`/api/ops/notifications/${qs ? `?${qs}` : ""}`);
|
||||
},
|
||||
// 跟着 next 把所有消息取全(给侧边栏徽标 + 团队动态用,不参与收件箱滚动渲染),与 allAssets 同套路
|
||||
// 侧边栏徽标(unread_count)+ 团队动态(只展示最近 6 条)用。只取第 1 页 100 条即足够,
|
||||
// count 用后端真实总数(给「共 N」显示),不再随消息增长逐页翻全部(原来 O(N) 拖慢每次刷新)。
|
||||
// 注:不参与收件箱滚动渲染——收件箱走 listNotifications 自己的服务端分页。
|
||||
async allNotifications(): Promise<NotificationList> {
|
||||
// 首页拿计数,剩余页并行(原串行逐页:消息多时侧边栏徽标加载也拖慢整页)
|
||||
const SIZE = 100;
|
||||
const first = await request<NotificationList>(`/api/ops/notifications/?page_size=${SIZE}`);
|
||||
const out: Notification[] = [...first.results];
|
||||
const pageSize = first.results.length || SIZE;
|
||||
const totalPages = pageSize > 0 ? Math.ceil((first.count || out.length) / pageSize) : 1;
|
||||
if (totalPages > 1) {
|
||||
const rest = await Promise.all(
|
||||
Array.from({ length: totalPages - 1 }, (_, i) =>
|
||||
request<NotificationList>(`/api/ops/notifications/?page_size=${SIZE}&page=${i + 2}`)
|
||||
.then((p) => p.results)
|
||||
.catch(() => [] as Notification[])
|
||||
)
|
||||
);
|
||||
rest.forEach((r) => out.push(...r));
|
||||
}
|
||||
return { count: out.length, next: null, previous: null, results: out, unread_count: first.unread_count, type_counts: first.type_counts };
|
||||
return request<NotificationList>(`/api/ops/notifications/?page_size=100`);
|
||||
},
|
||||
markAllNotificationsRead() {
|
||||
return request<{ updated: number; unread_count: number }>("/api/ops/notifications/mark-all-read/", {
|
||||
|
||||
Reference in New Issue
Block a user