fix(ads): 轮播图裂图修复——广告现签 TTL 24h + 失败节流重拉

根因:广告图现签 900s(照片域 TTL),观众长留直播页超时后重拉 403。
广告为匿名公开内容,短轮换无安全收益——专属 AD_SIGNED_URL_TTL_SECONDS=24h;
另加兜底:img error → 页面层 60s 冷却重拉广告列表换新签名 URL。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-29 11:27:06 +08:00
parent 8741bded7f
commit 744d45cc61
5 changed files with 65 additions and 10 deletions
@@ -25,7 +25,7 @@
// 脏数据整页失败);defaultLocale 翻译条目缺失属装配异常 → 5xx 兜底。
import { HttpStatus, Inject, Injectable } from '@nestjs/common';
import type { components } from '@photo/contracts';
import { ErrorCodes } from '@photo/contracts';
import { AD_SIGNED_URL_TTL_SECONDS, ErrorCodes } from '@photo/contracts';
import { ApiException } from '../api-exception';
import { ALBUM_LOCALES, type AlbumLocale } from '../albums/dto';
import { validationFailed } from '../albums/support';
@@ -322,11 +322,16 @@ export class PublicOvService {
(r) =>
r.albumIds === null || (r.albumIds as string[]).includes(album.albumId),
);
const ttl = signedUrlTtlSeconds();
// 广告现签 TTL 用专属常量(24h)而非照片域的 SIGNED_URL_TTL_SECONDS(900s):
// 观众在图片直播页停留常超 15 分钟,短 TTL 会使轮播图在长会话中裂图;
// 广告为匿名公开内容(任何持 token 访客可见),短轮换无安全收益。
const items = await Promise.all(
visible.map(async (r) => ({
adId: r.adId,
imageUrl: await this.storage.presignGet(r.imageObjectKey, ttl),
imageUrl: await this.storage.presignGet(
r.imageObjectKey,
AD_SIGNED_URL_TTL_SECONDS,
),
linkUrl: r.linkUrl,
})),
);