feat(assets): album asset status — show current banner/cover/logo in admin branding tab

- 契约 listAlbumAssetStatus(GET /albums/{albumId}/assets):每 (kind,locale)
  最新 effective 行 + 现签 URL;权限同详情(可见即读);deleted → 404
- 服务端 AssetsService.status(createdAt,id DESC 组内取首;presignGet 现签)
- Admin 品牌资产页签改造:进入即加载现状——三种 kind 卡片(预览图/未设置
  空态/设置时间),banner 分全局/zh/en 槽位;上传成功自动刷新(替换语义)
- API 56/56、admin 87/87 + build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-23 10:51:53 +08:00
parent d678c8d38d
commit 2618ad3163
14 changed files with 711 additions and 28 deletions
+57
View File
@@ -455,6 +455,31 @@ paths:
/albums/{albumId}/assets:
parameters:
- $ref: '#/components/parameters/AlbumId'
get:
operationId: listAlbumAssetStatus
tags: [assets]
summary: 各类资产当前生效项(管理端现状展示)
description: >-
返回每个 (kind, locale) 组合的最新 effective 资产行 + 现签短期 URL
(同「替换语义」——同组再上传即整体替换)。未设置的组合不出现;
签名过期重取本端点刷新。权限同相册详情(可见即可读)。
security:
- bearerAuth: []
responses:
'200':
description: 生效资产列表(可能为空数组)。
content:
application/json:
schema:
$ref: '#/components/schemas/AssetStatusResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
description: 相册不存在(ALBUM_NOT_FOUND,含已删除)。
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
operationId: initAlbumAssetUpload
tags: [assets]
@@ -3119,6 +3144,38 @@ components:
# ── 成员 ──
AssetStatusItem:
type: object
description: 单个生效资产(管理端现状展示用)。
required: [kind, locale, url, expiresAt, contentType, createdAt]
properties:
kind:
type: string
enum: [banner, cover, logo]
locale:
type: [string, "null"]
description: 语言标签(banner 可带;null=全局)。
url:
type: string
description: 现签短期 GET URL。
expiresAt:
type: string
format: date-time
contentType:
type: string
createdAt:
type: string
format: date-time
AssetStatusResponse:
type: object
description: 各 (kind, locale) 组合最新生效资产列表。
required: [items]
properties:
items:
type: array
items:
$ref: '#/components/schemas/AssetStatusItem'
MemberAddRequest:
type: object
required: [userId]
+56 -1
View File
@@ -187,7 +187,11 @@ export interface paths {
};
cookie?: never;
};
get?: never;
/**
* 各类资产当前生效项(管理端现状展示)
* @description 返回每个 (kind, locale) 组合的最新 effective 资产行 + 现签短期 URL (同「替换语义」——同组再上传即整体替换)。未设置的组合不出现; 签名过期重取本端点刷新。权限同相册详情(可见即可读)。
*/
get: operations["listAlbumAssetStatus"];
put?: never;
/**
* 初始化资产上传
@@ -1518,6 +1522,24 @@ export interface components {
/** @description 资产 ID。 */
readonly assetId: string;
};
/** @description 单个生效资产(管理端现状展示用)。 */
AssetStatusItem: {
/** @enum {string} */
kind: "banner" | "cover" | "logo";
/** @description 语言标签(banner 可带;null=全局)。 */
locale: string | null;
/** @description 现签短期 GET URL。 */
url: string;
/** Format: date-time */
expiresAt: string;
contentType: string;
/** Format: date-time */
createdAt: string;
};
/** @description 各 (kind, locale) 组合最新生效资产列表。 */
AssetStatusResponse: {
items: components["schemas"]["AssetStatusItem"][];
};
MemberAddRequest: {
/** @description 被添加用户的 ID(须为已开通账号)。 */
userId: string;
@@ -3125,6 +3147,39 @@ export interface operations {
500: components["responses"]["InternalError"];
};
};
listAlbumAssetStatus: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 生效资产列表(可能为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AssetStatusResponse"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 相册不存在(ALBUM_NOT_FOUND,含已删除)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
};
initAlbumAssetUpload: {
parameters: {
query?: never;