2026-09-17 17:04:12 +08:00
|
|
|
|
openapi: 3.1.0
|
|
|
|
|
|
info:
|
|
|
|
|
|
title: photo-live
|
|
|
|
|
|
version: 0.1.0
|
|
|
|
|
|
license:
|
|
|
|
|
|
name: UNLICENSED
|
|
|
|
|
|
identifier: UNLICENSED
|
|
|
|
|
|
description: |
|
|
|
|
|
|
photo-live 直播相册系统 API 契约(单一事实来源)。
|
|
|
|
|
|
|
|
|
|
|
|
- 类型经 `openapi-typescript` 生成并提交入库(`src/generated/openapi.d.ts`),
|
|
|
|
|
|
三端(services/api、apps/admin、apps/viewer)直接消费生成类型,不自行跑 gen。
|
|
|
|
|
|
- 错误响应使用稳定 `code`(见 `components.schemas.Error` 的枚举,与
|
|
|
|
|
|
`src/errors.ts` 的 `ErrorCodes` 一一对应),客户端按 code 映射多语言文案,
|
|
|
|
|
|
`message` 仅供诊断。
|
|
|
|
|
|
- 列表接口统一游标分页,元信息见 `components.schemas.CursorPageMeta`。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- 业务端点一律 Bearer 认证;`/public/**` 匿名访问(`security: []`)。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- `/internal/**` 为服务间同步接口(P2):HMAC 签名鉴权
|
|
|
|
|
|
(`X-Sync-Signature`/`X-Sync-Timestamp`,见 [internal] tag 描述),
|
|
|
|
|
|
OpenAPI 无对应标准 scheme 故同样标注 `security: []`,但匿名不可访问。
|
|
|
|
|
|
- WebSocket 实时消息契约不经 OpenAPI 生成,单独维护于
|
|
|
|
|
|
`src/realtime.ts`(判别联合 + 心跳常量),与生成类型同属单一事实来源。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- 状态码通用映射:401 → AUTH_TOKEN_EXPIRED、500 → INTERNAL_ERROR;
|
|
|
|
|
|
其余状态码对应的 code 在各响应的 description 中标注。
|
|
|
|
|
|
- 多语言内容按「请求 locale → 相册 defaultLocale」回退解析为单语言对象,
|
|
|
|
|
|
响应携带 `resolvedLocale` 供界面判断实际语言。
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
|
|
|
|
|
servers:
|
|
|
|
|
|
- url: /v1
|
|
|
|
|
|
|
|
|
|
|
|
tags:
|
|
|
|
|
|
- name: auth
|
|
|
|
|
|
description: 密码登录会话(签发、滑动续期、退出)
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- name: albums
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 相册创建、列表、详情、配置与水印版本管理(工作人员)
|
2026-09-18 08:23:59 +08:00
|
|
|
|
- name: assets
|
|
|
|
|
|
description: 相册宣传图/封面/Logo 资产直传(创建者或管理员)
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- name: members
|
|
|
|
|
|
description: 相册成员管理(创建者或管理员)
|
|
|
|
|
|
- name: categories
|
|
|
|
|
|
description: 相册分类管理(创建者或管理员)
|
|
|
|
|
|
- name: uploads
|
|
|
|
|
|
description: 直传任务初始化、授权续签、完成核验与会话记录
|
|
|
|
|
|
- name: photos
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 照片可见性调整(单项与批量)与软删除(工作人员)
|
2026-09-18 08:23:59 +08:00
|
|
|
|
- name: admin
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 管理辅助查询与账号治理(用户管理、相册交接、用户同步、用量统计)
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- name: public
|
|
|
|
|
|
description: 观众匿名只读(相册信息与公开照片)
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- name: interactions
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 观众匿名互动与下载(点赞批次、浏览上报、照片下载;ov 域部署,路径前缀不变、域名区分)
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- name: internal
|
|
|
|
|
|
description: |
|
2026-09-18 16:19:02 +08:00
|
|
|
|
服务间内部接口(cn↔ov 同步 + ov 紧急停用通道),HMAC 鉴权,不对匿名
|
|
|
|
|
|
开放。共用签名规则:
|
2026-09-18 13:34:35 +08:00
|
|
|
|
`X-Sync-Signature` = hex(HMAC-SHA256(原始请求体, SYNC_INTERNAL_KEY)),
|
|
|
|
|
|
`X-Sync-Timestamp` = Unix 秒(与服务端时差 ±300s 内有效,防重放);
|
|
|
|
|
|
签名缺失/不符或时间戳超窗一律拒绝。OpenAPI 无 HMAC 标准 scheme,
|
|
|
|
|
|
故下列操作 `security` 标注为 `[]`(无标准认证要求),鉴权由服务端强制执行。
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
|
|
|
|
|
paths:
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ─────────────────────────── auth ───────────────────────────
|
|
|
|
|
|
|
2026-09-17 17:04:12 +08:00
|
|
|
|
/auth/password:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: loginWithPassword
|
|
|
|
|
|
tags: [auth]
|
|
|
|
|
|
summary: 密码登录
|
|
|
|
|
|
description: 校验账号密码,签发会话令牌。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/LoginRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 登录成功,返回会话令牌与过期时间。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/LoginResponse'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED,经全局校验管道)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'401':
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 账号或密码错误(AUTH_INVALID_CREDENTIALS)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 21:17:16 +08:00
|
|
|
|
'429':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
登录失败次数过多(AUTH_RATE_LIMITED,Task 13 契约修订)。
|
|
|
|
|
|
同账号+来源 IP 在窗口期内连续失败达到阈值后锁定一段时间。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
|
|
|
|
|
/auth/refresh:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: refreshSession
|
|
|
|
|
|
tags: [auth]
|
|
|
|
|
|
summary: 会话滑动续期
|
|
|
|
|
|
description: 携带有效 Bearer 令牌滑动续期,返回新的过期时间。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 续期成功。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/RefreshResponse'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED,经全局校验管道)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
|
|
|
|
|
/auth/logout:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: logout
|
|
|
|
|
|
tags: [auth]
|
|
|
|
|
|
summary: 退出登录
|
|
|
|
|
|
description: 使当前 Bearer 令牌失效。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'204':
|
|
|
|
|
|
description: 已退出,无响应体。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体不可解析(VALIDATION_FAILED,经全局校验管道)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
2026-09-19 00:59:39 +08:00
|
|
|
|
/auth/password-change:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: changePassword
|
|
|
|
|
|
tags: [auth]
|
|
|
|
|
|
summary: 修改密码
|
|
|
|
|
|
description: |
|
|
|
|
|
|
已认证用户修改自身密码:校验旧密码,成功后更新密码哈希并撤销该用户
|
|
|
|
|
|
除当前会话外的全部其他会话(当前会话保持有效,无需重新登录)。
|
|
|
|
|
|
P3 Task 3 契约增补(需求 4.1「支持修改密码」,P1 契约缺口补齐)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PasswordChangeRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'204':
|
|
|
|
|
|
description: 修改成功,无响应体;当前会话保留,其他会话已撤销。
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED,经全局校验管道)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
description: 旧密码错误(AUTH_INVALID_CREDENTIALS)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ─────────────────────────── albums ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/albums:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: createAlbum
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 创建相册
|
|
|
|
|
|
description: |
|
|
|
|
|
|
创建相册并写入多语言内容;创建者自动成为 owner 成员。
|
|
|
|
|
|
初始默认值:uploadEnabled/publicEnabled/downloadEnabled=true、
|
|
|
|
|
|
originalDownloadEnabled=false、status=active、watermarkVersion=0。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumCreateRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'201':
|
|
|
|
|
|
description: 相册已创建(新相册 categories 为空数组)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Album'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listAlbums
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 相册列表
|
|
|
|
|
|
description: 当前用户可见(参与)的相册列表;管理员可见全部。按创建时间倒序。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页条数。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 相册列表页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getAlbum
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 相册详情
|
|
|
|
|
|
description: 相册完整配置、多语言内容与分类列表。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 相册详情。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Album'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户非成员不可见(ALBUM_NOT_FOUND,避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
patch:
|
|
|
|
|
|
operationId: updateAlbum
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 更新相册配置
|
|
|
|
|
|
description: |
|
|
|
|
|
|
部分更新:仅提交的字段被修改,各开关互相独立。
|
|
|
|
|
|
translations 为全量替换(须包含 defaultLocale 对应条目)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumUpdateRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 更新后的相册详情。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Album'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可修改(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/albums/{albumId}/watermark-jobs:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: createWatermarkJob
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 保存水印配置并发起历史重生成
|
|
|
|
|
|
description: |
|
|
|
|
|
|
保存新的水印配置版本(configVersion 递增)并创建历史照片重生成任务
|
|
|
|
|
|
(A18/A20)。仅创建者或管理员可操作。语义约定:
|
|
|
|
|
|
新照片发布默认套用最新版本;历史照片重生成须显式经本端点发起;
|
|
|
|
|
|
任务为原子切换——全部照片处理完成前旧浏览图保持可用(失败照片保留
|
|
|
|
|
|
旧图,任务可重试);原图(original)永不覆盖。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkConfig'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'202':
|
|
|
|
|
|
description: 配置已保存、重生成任务已受理(异步执行,进度经 GET 查询)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkJobCreated'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;opacity/scalePercent/fontSize 越界等)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可管理水印(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getWatermarkJobs
|
|
|
|
|
|
tags: [albums]
|
|
|
|
|
|
summary: 水印配置版本与重生成任务状态
|
|
|
|
|
|
description: |
|
|
|
|
|
|
当前生效配置(current,从未配置为 null)与历史任务列表(创建时间倒序)。
|
|
|
|
|
|
任务进度(progress/total/failed)供前端轮询;state=failed 的任务可经
|
|
|
|
|
|
POST 重新发起(按照片粒度幂等续跑)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 当前配置与任务列表。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkJobsStatus'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可查看(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-18 08:23:59 +08:00
|
|
|
|
# ─────────────────────────── assets ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}/assets:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: initAlbumAssetUpload
|
|
|
|
|
|
tags: [assets]
|
|
|
|
|
|
summary: 初始化资产上传
|
|
|
|
|
|
description: |
|
|
|
|
|
|
为相册宣传图/封面/Logo 创建上传会话,返回 staging 对象的临时直传凭证
|
|
|
|
|
|
(凭证结构与照片直传同形)。无 clientTaskId 幂等键:assetId 即一次性会话,
|
|
|
|
|
|
失败重试重新初始化即可。替换语义:同一 (kind, locale) 再次上传→新行生效,
|
|
|
|
|
|
旧行保留作历史(P1b 无删除端点);公开相册响应始终取该 kind 最新生效行
|
|
|
|
|
|
(P1a 公开服务已按 latest 实现)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AssetInitRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'201':
|
|
|
|
|
|
description: 资产上传会话已创建。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AssetInitResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED):文件超过大小限额或类型不接受。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可管理资产(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}/assets/{assetId}/complete:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
- $ref: '#/components/parameters/AssetId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: completeAlbumAssetUpload
|
|
|
|
|
|
tags: [assets]
|
|
|
|
|
|
summary: 完成资产上传核验
|
|
|
|
|
|
description: |
|
|
|
|
|
|
核验 staging 对象(存在性、字节数与可用完整性信息)后将资产挂到相册生效,
|
|
|
|
|
|
并返回短期签名访问 URL。幂等:已核验通过的资产重复调用返回 200
|
|
|
|
|
|
(URL 重新现签,本端点即签名刷新入口)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 核验通过,资产已生效。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AssetCompleteResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
核验失败(UPLOAD_VERIFY_FAILED):对象缺失、字节数与申明不符
|
|
|
|
|
|
或完整性信息不可用。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 资产不存在或无权操作(AUTH_FORBIDDEN,不区分以避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ─────────────────────────── members ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}/members:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: addAlbumMember
|
|
|
|
|
|
tags: [members]
|
|
|
|
|
|
summary: 添加相册成员
|
|
|
|
|
|
description: 将已开通的同事添加为协作者;仅创建者或管理员可操作。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/MemberAddRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'201':
|
|
|
|
|
|
description: 成员已添加。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Member'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可管理成员(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'409':
|
|
|
|
|
|
description: 该用户已是相册成员(MEMBER_CONFLICT)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listAlbumMembers
|
|
|
|
|
|
tags: [members]
|
|
|
|
|
|
summary: 相册成员列表
|
|
|
|
|
|
description: 相册全部成员(含 owner)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页条数。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 成员列表页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/MemberList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}/members/{userId}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
- $ref: '#/components/parameters/UserId'
|
|
|
|
|
|
delete:
|
|
|
|
|
|
operationId: removeAlbumMember
|
|
|
|
|
|
tags: [members]
|
|
|
|
|
|
summary: 移除相册成员
|
|
|
|
|
|
description: |
|
|
|
|
|
|
移除协作者;仅创建者或管理员可操作。不能移除创建者(403)。
|
|
|
|
|
|
目标成员不存在时幂等返回 204。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'204':
|
|
|
|
|
|
description: 已移除,无响应体。
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无管理权限,或试图移除创建者(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────── categories ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/albums/{albumId}/categories:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: createCategory
|
|
|
|
|
|
tags: [categories]
|
|
|
|
|
|
summary: 创建分类
|
|
|
|
|
|
description: 在相册下创建分类;仅创建者或管理员可操作。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/CategoryCreateRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'201':
|
|
|
|
|
|
description: 分类已创建。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Category'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可管理分类(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
/categories/{categoryId}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/CategoryId'
|
|
|
|
|
|
patch:
|
|
|
|
|
|
operationId: updateCategory
|
|
|
|
|
|
tags: [categories]
|
|
|
|
|
|
summary: 更新分类
|
|
|
|
|
|
description: 部分更新;translations 为全量替换。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/CategoryUpdateRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 更新后的分类。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Category'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无所属相册的管理权限(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 分类不存在,或所属相册不存在/不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
delete:
|
|
|
|
|
|
operationId: deleteCategory
|
|
|
|
|
|
tags: [categories]
|
|
|
|
|
|
summary: 删除分类
|
|
|
|
|
|
description: 删除分类(分类下仍有照片时是否允许删除由服务端策略决定,400 拒绝)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'204':
|
|
|
|
|
|
description: 已删除,无响应体。
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无所属相册的管理权限(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 分类不存在,或所属相册不存在/不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────── uploads ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/uploads:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: initUpload
|
|
|
|
|
|
tags: [uploads]
|
|
|
|
|
|
summary: 初始化上传任务
|
|
|
|
|
|
description: |
|
|
|
|
|
|
幂等初始化:预创建上传会话与照片 ID,返回 staging 对象的临时直传凭证。
|
|
|
|
|
|
相同 clientTaskId 且参数一致时返回原会话,不重复创建照片;
|
|
|
|
|
|
参数不一致时返回 409(UPLOAD_SESSION_CONFLICT)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadInitRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'201':
|
|
|
|
|
|
description: 上传会话已创建(幂等重复调用返回原会话)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadInitResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED):文件超过大小限额或类型不接受。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无该相册的上传权限(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'409':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册已关闭上传(ALBUM_UPLOAD_DISABLED),或同 clientTaskId 已存在
|
|
|
|
|
|
且参数不一致(UPLOAD_SESSION_CONFLICT)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listUploads
|
|
|
|
|
|
tags: [uploads]
|
|
|
|
|
|
summary: 上传会话记录
|
|
|
|
|
|
description: 当前用户的上传会话历史(新在前),用于任务队列恢复与状态展示。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页条数。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 会话记录列表页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadSessionList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
/uploads/{uploadId}/renew:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/UploadId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: renewUploadCredential
|
|
|
|
|
|
tags: [uploads]
|
|
|
|
|
|
summary: 续签上传凭证
|
|
|
|
|
|
description: 为仍处于 pending 状态的会话重新签发直传凭证(结构同初始化响应)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 新凭证已签发(credential 为新值,其余字段回显原会话)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadInitResponse'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'409':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册已关闭上传(ALBUM_UPLOAD_DISABLED),或会话状态不允许续签
|
|
|
|
|
|
(已完成/取消/过期,UPLOAD_SESSION_CONFLICT)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
/uploads/{uploadId}/complete:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/UploadId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: completeUpload
|
|
|
|
|
|
tags: [uploads]
|
|
|
|
|
|
summary: 完成核验
|
|
|
|
|
|
description: |
|
|
|
|
|
|
核验 staging 对象(存在性、字节数与可用完整性信息)后进入处理流水线。
|
|
|
|
|
|
幂等:核验通过的会话重复调用返回相同结果。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 核验通过,照片进入处理流水线。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadCompleteResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
核验失败(UPLOAD_VERIFY_FAILED):对象缺失、字节数与申明不符
|
|
|
|
|
|
或完整性信息不可用。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'409':
|
|
|
|
|
|
description: 会话状态不允许完成(已取消或已过期,UPLOAD_SESSION_CONFLICT)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────── photos ───────────────────────────
|
|
|
|
|
|
|
2026-09-18 08:23:59 +08:00
|
|
|
|
/albums/{albumId}/photos:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listAlbumPhotos
|
|
|
|
|
|
tags: [photos]
|
|
|
|
|
|
summary: 管理端照片列表
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册照片管理列表(区别于公开列表):全部状态可见(unpublished/published/
|
|
|
|
|
|
hidden/deleted),条目含 uploader 脱敏信息。按 uploadedAt 与 ID 稳定倒序
|
|
|
|
|
|
游标分页。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- name: visibility
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 可见性过滤;缺省为全部状态。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoVisibility'
|
|
|
|
|
|
- name: categoryId
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 分类 ID 过滤。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页条数。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 管理照片列表页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminPhotoList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可访问管理列表(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/albums/{albumId}/photos/hide-batch:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: hidePhotosBatch
|
|
|
|
|
|
tags: [photos]
|
|
|
|
|
|
summary: 批量隐藏照片
|
|
|
|
|
|
description: |
|
|
|
|
|
|
批量将 published 照片置为 hidden(A16)。逐项返回结果:不存在、已删除
|
|
|
|
|
|
或状态不可切换单项 ok=false 并携带 code,不影响其余项(部分成功语义)。
|
|
|
|
|
|
单批上限 200(minItems/maxItems)。权限与 403/404 语义同管理照片列表
|
|
|
|
|
|
(仅创建者或管理员;ALBUM_NOT_FOUND 防枚举)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoHideBatchRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 批量处理结果(逐项;单项失败不影响其余项)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/BatchHideResult'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;photoIds 空/超 200/含空串)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅创建者或管理员可管理照片(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
/photos/{photoId}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/PhotoId'
|
|
|
|
|
|
patch:
|
|
|
|
|
|
operationId: updatePhoto
|
|
|
|
|
|
tags: [photos]
|
|
|
|
|
|
summary: 调整照片可见性
|
|
|
|
|
|
description: 在 hidden 与 published 间切换(隐藏/恢复发布);按相册角色与上传人共同判定权限。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoVisibilityUpdateRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 更新后的照片记录。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoRecord'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED,visibility 取值非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无该照片的管理权限(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 照片不存在(PHOTO_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
delete:
|
|
|
|
|
|
operationId: deletePhoto
|
|
|
|
|
|
tags: [photos]
|
|
|
|
|
|
summary: 软删除照片
|
|
|
|
|
|
description: 标记 deleted(软删除),公开端点即刻不可见;物理删除走独立运维流程。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'204':
|
|
|
|
|
|
description: 已软删除,无响应体。
|
|
|
|
|
|
'401':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 无该照片的管理权限(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 照片不存在(PHOTO_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
2026-09-18 08:23:59 +08:00
|
|
|
|
# ─────────────────────────── admin ───────────────────────────
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/admin/albums/{albumId}/transfer:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: transferAlbum
|
2026-09-18 08:23:59 +08:00
|
|
|
|
tags: [admin]
|
2026-09-20 15:56:38 +08:00
|
|
|
|
summary: 相册负责人交接
|
2026-09-18 08:23:59 +08:00
|
|
|
|
description: |
|
2026-09-20 15:56:38 +08:00
|
|
|
|
将相册 owner 移交给目标用户(A17)。仅 admin 可操作(负责人交接为
|
|
|
|
|
|
组织级治理动作,区别于相册级配置修改)。keepAsCollaborator=true 时
|
|
|
|
|
|
原 owner 转为 collaborator 成员,否则原 owner 移出成员表。历史上传人
|
|
|
|
|
|
不变(photos.uploaderId 不动);审计 album.transfer。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
2026-09-20 15:56:38 +08:00
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumTransferRequest'
|
2026-09-18 08:23:59 +08:00
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 交接后的相册详情(ownerId 已变更)。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
$ref: '#/components/schemas/Album'
|
2026-09-18 08:23:59 +08:00
|
|
|
|
'400':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
参数校验失败(VALIDATION_FAILED;targetUserId 非法,或目标账号
|
|
|
|
|
|
不可被指定为 owner——不存在/停用/待激活/锁定)。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
2026-09-20 15:56:38 +08:00
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可交接相册负责人(AUTH_FORBIDDEN)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/admin/users:
|
2026-09-17 17:31:11 +08:00
|
|
|
|
get:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
operationId: listAdminUsers
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 用户查询与管理列表
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: |
|
2026-09-20 15:56:38 +08:00
|
|
|
|
双模式统一端点(P4a 决策:与 P1b 账号前缀查询合一,响应统一
|
|
|
|
|
|
AdminUserList——条目为 AdminUser 字段超集,管理端 UI 按场景裁剪展示):
|
|
|
|
|
|
· 前缀模式(提供 accountPrefix):邀请协作者前置查询,沿用 P1b 语义
|
|
|
|
|
|
——大小写敏感前缀匹配(服务端按二进制校对执行 LIKE prefix%)、
|
|
|
|
|
|
仅「激活资格」用户(credentialStatus=active 且 sourceStatus≠disabled
|
|
|
|
|
|
且 !localLocked,与成员添加的目标校验一致)、account 升序;
|
|
|
|
|
|
访问策略沿用 P1b 决策:任何已认证工作人员可用(邀请发起方不限于
|
|
|
|
|
|
创建者/管理员,泄露面为已认证内部人员,风险可接受)。
|
|
|
|
|
|
· 管理列表模式(未提供 accountPrefix):全量用户治理列表(游标分页,
|
|
|
|
|
|
按 createdAt 与 ID 稳定倒序),可选 query/status 过滤(不做全文
|
|
|
|
|
|
搜索);仅 admin 可用(非 admin 403)。
|
|
|
|
|
|
两模式响应形状一致(AdminUserList);前缀模式小上限即取即用,
|
|
|
|
|
|
hasMore/nextCursor 同样按游标语义填充。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
2026-09-17 17:31:11 +08:00
|
|
|
|
parameters:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
- name: accountPrefix
|
2026-09-17 17:31:11 +08:00
|
|
|
|
in: query
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 账号前缀(≥2 字符以防过宽匹配;提供即进入前缀模式)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
2026-09-20 15:56:38 +08:00
|
|
|
|
minLength: 2
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
- name: query
|
2026-09-18 17:05:56 +08:00
|
|
|
|
in: query
|
|
|
|
|
|
description: |
|
2026-09-20 15:56:38 +08:00
|
|
|
|
管理列表过滤:账号或展示名前缀(大小写敏感二进制前缀匹配,同
|
|
|
|
|
|
accountPrefix 规则;不做全文搜索)。
|
2026-09-18 17:05:56 +08:00
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
2026-09-20 15:56:38 +08:00
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
- name: status
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 管理列表过滤:治理状态单值归类(归类优先级见 AdminUserStatusFilter)。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminUserStatusFilter'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 每页条数。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
2026-09-20 15:56:38 +08:00
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
2026-09-17 17:31:11 +08:00
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 用户列表页(前缀模式无匹配为空数组)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
$ref: '#/components/schemas/AdminUserList'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'400':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
查询参数校验失败(VALIDATION_FAILED;accountPrefix/query 长度非法、
|
|
|
|
|
|
status 取值非法、cursor/limit 非法)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-20 15:56:38 +08:00
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 管理列表模式仅 admin 可用(AUTH_FORBIDDEN)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/admin/users/{userId}:
|
2026-09-17 17:31:11 +08:00
|
|
|
|
parameters:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
- $ref: '#/components/parameters/UserId'
|
|
|
|
|
|
patch:
|
|
|
|
|
|
operationId: updateAdminUser
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 更新用户治理属性
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: |
|
2026-09-20 15:56:38 +08:00
|
|
|
|
部分更新 role/localLocked/displayName;仅 admin。sourceStatus 只读
|
|
|
|
|
|
(上游状态仅由同步任务维护,本地不越权改写——技术方案 3.1A 红线,
|
|
|
|
|
|
需求侧只读展示)。localLocked 置 true 等价停用(撤销该用户全部会话);
|
|
|
|
|
|
置 false 仅解除本地锁定,不改变上游停用状态。审计全程。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminUserUpdateRequest'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 更新后的用户条目。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
$ref: '#/components/schemas/AdminUser'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;role 取值非法、displayName 长度非法、空请求体)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可管理用户(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
'404':
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 目标用户不存在(NOT_FOUND)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
'500':
|
2026-09-17 18:06:54 +08:00
|
|
|
|
$ref: '#/components/responses/InternalError'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/admin/users/{userId}/reset-password:
|
2026-09-18 13:34:35 +08:00
|
|
|
|
parameters:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
- $ref: '#/components/parameters/UserId'
|
2026-09-18 13:34:35 +08:00
|
|
|
|
post:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
operationId: resetAdminUserPassword
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 管理员重置用户密码
|
2026-09-18 13:34:35 +08:00
|
|
|
|
description: |
|
2026-09-20 15:56:38 +08:00
|
|
|
|
仅 admin。body 可选 newPassword(8-128):缺省由服务端生成随机密码
|
|
|
|
|
|
(e2e 两种路径均覆盖)。重置成功后撤销该目标用户全部既有会话(须
|
|
|
|
|
|
重新登录);新密码仅在响应中返回一次(不入库明文、不留日志),管理
|
|
|
|
|
|
端一次性展示转交。审计全程。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminPasswordResetRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 重置成功(newPassword 为请求指定或服务端生成)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminPasswordResetResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;newPassword 长度非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可重置密码(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 目标用户不存在(NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/users/{userId}/activate:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/UserId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: activateAdminUser
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 激活待激活用户
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。credentialStatus pending→active(闭环用户同步创建的待激活
|
|
|
|
|
|
账号,§10 语义)。激活本身不出凭据:初始密码经 reset-password 出具
|
|
|
|
|
|
(推荐流程 activate → reset-password 生成一次性初始密码 → 用户登录)。
|
|
|
|
|
|
幂等:对已是 active 的用户重复激活返回当前条目。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 激活后的用户条目(credentialStatus=active)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminUser'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可激活用户(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 目标用户不存在(NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/users/{userId}/deactivate:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/UserId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: deactivateAdminUser
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 停用用户
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。localLocked=true 并撤销该用户全部会话(既有令牌即刻 401)。
|
|
|
|
|
|
上游状态不动(sourceStatus 保持;上游恢复 active 不解除本地锁定——
|
|
|
|
|
|
本地锁定独立,技术方案 3.1A)。重新启用经 PATCH localLocked=false。
|
|
|
|
|
|
审计全程。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 停用后的用户条目(localLocked=true)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminUser'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可停用用户(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 目标用户不存在(NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/user-sync/status:
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getUserSyncStatus
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 用户同步状态
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。同步引擎当前状态、最近批次计数与源水位(A29)。当前为 mock
|
|
|
|
|
|
源(G4:真实接口到位后仅替换 provider,契约不变)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 同步状态。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncStatus'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可查看同步状态(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/user-sync/runs:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页条数。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
default: 20
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listUserSyncRuns
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 同步运行历史
|
|
|
|
|
|
description: 仅 admin。历史批次列表(startedAt 与 ID 稳定倒序游标分页)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 运行历史页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncRunList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED;cursor/limit 非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可查看运行历史(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: triggerUserSyncRun
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 手动触发同步补拉
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。手动发起一次同步(与定时调度共用互斥锁;已有批次运行中时
|
|
|
|
|
|
不重复执行,返回进行中批次的 runId)。202 表示已受理,异步执行,
|
|
|
|
|
|
结果经 status/runs 端点查询。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'202':
|
|
|
|
|
|
description: 已受理(或复用进行中批次)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncRunCreated'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可手动触发(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/user-sync/errors:
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listUserSyncErrors
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 同步失败明细
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。单批次失败行明细(state=partial/failed 批次的坏行记录,
|
|
|
|
|
|
其余行照常应用的证据链);runId 必填。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- name: runId
|
|
|
|
|
|
in: query
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 批次 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 失败明细(createdAt 倒序;无失败为空数组)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncErrorList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED;runId 缺失)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可查看失败明细(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/usage/summary:
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getUsageSummary
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 用量汇总与阈值告警
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。按相册聚合存储用量(原图 + 变体,实时 SUM——P1 规模够用;
|
|
|
|
|
|
P5 接 OSS 用量 API/物化视图,登记偏差)、当前阈值与告警列表
|
|
|
|
|
|
(A23 后台侧;告警接收人通知渠道 P5)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 用量汇总。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageSummary'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可查看用量(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/admin/usage/thresholds:
|
|
|
|
|
|
put:
|
|
|
|
|
|
operationId: updateUsageThresholds
|
|
|
|
|
|
tags: [admin]
|
|
|
|
|
|
summary: 更新用量阈值
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅 admin。部分更新:缺省字段保持不变,显式 null 清除该阈值(清除后
|
|
|
|
|
|
对应告警维度停用)。修改后即刻重新评估(超阈产生新告警、阈值上调将
|
|
|
|
|
|
已回落旧告警标记 resolvedAt)。
|
|
|
|
|
|
security:
|
|
|
|
|
|
- bearerAuth: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageThresholdsUpdate'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 更新后的阈值。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageThresholds'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;负值或非整数)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'401':
|
|
|
|
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 仅 admin 可更新阈值(AUTH_FORBIDDEN)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────── public ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/public/albums/{token}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getPublicAlbum
|
|
|
|
|
|
tags: [public]
|
|
|
|
|
|
summary: 公开相册信息
|
|
|
|
|
|
description: |
|
|
|
|
|
|
观众页入口:按「请求 locale → defaultLocale」回退解析为单语言对象。
|
|
|
|
|
|
publicToken 不可枚举,但持有链接者均可访问。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/LocaleQuery'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 相册公开信息。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicAlbum'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED;locale 取值不支持时不报错,按 defaultLocale 回退)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在或未公开(ALBUM_NOT_PUBLIC,不区分以避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/public/albums/{token}/photos:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: listPublicPhotos
|
|
|
|
|
|
tags: [public]
|
|
|
|
|
|
summary: 公开照片列表
|
|
|
|
|
|
description: |
|
|
|
|
|
|
仅返回公开相册中 published 的照片,按 publishedAt 与 ID 稳定倒序游标分页。
|
|
|
|
|
|
签名 URL 为短期凭证,过期后凭同一入口刷新。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- name: category
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 分类 ID 过滤(来自 PublicAlbum.categories 的 id)。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
- name: sort
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: |
|
|
|
|
|
|
排序模式:latest=发布时间倒序(缺省);hot=点赞数倒序(photoId 倒序
|
|
|
|
|
|
决胜,短期快照语义——服务端约 30s 缓冲,窗口内顺序不随点赞变化,
|
|
|
|
|
|
技术实施方案 §7)。hot 仅 ov 部署实现;cn 部署不感知该参数(固定
|
|
|
|
|
|
latest 语义)。ov 部署对非法取值返回 400 VALIDATION_FAILED。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
enum: [latest, hot]
|
|
|
|
|
|
default: latest
|
|
|
|
|
|
- $ref: '#/components/parameters/LocaleQuery'
|
|
|
|
|
|
- $ref: '#/components/parameters/CursorQuery'
|
|
|
|
|
|
- name: limit
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 每页张数(技术实施方案 §7 建议 30-60)。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 60
|
|
|
|
|
|
default: 30
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 公开照片列表页。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicPhotoList'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(category/cursor/limit;locale 取值不支持时不报错,按 defaultLocale 回退)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在或未公开(ALBUM_NOT_PUBLIC,不区分以避免枚举)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/public/albums/{token}/photos/{photoId}:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
- $ref: '#/components/parameters/PhotoId'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: getPublicPhoto
|
|
|
|
|
|
tags: [public]
|
|
|
|
|
|
summary: 公开单图
|
|
|
|
|
|
description: |
|
|
|
|
|
|
深度链接定位单图,同时作为签名 URL 过期后的刷新入口。
|
|
|
|
|
|
服务端校验相册与照片归属;隐藏/删除后的旧链接返回 404。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 单图信息(含新签名的 thumb/browse URL)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicPhotoDetail'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
|
|
|
|
|
|
不属于该相册(PHOTO_NOT_PUBLIC)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────── interactions ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/public/albums/{token}/photos/{photoId}/likes:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
- $ref: '#/components/parameters/PhotoId'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: likePhotoBatch
|
|
|
|
|
|
tags: [interactions]
|
|
|
|
|
|
summary: 点赞批次上报
|
|
|
|
|
|
description: |
|
|
|
|
|
|
匿名点赞批次(ov 域部署;路径前缀与 cn 相同,按部署域名区分)。
|
|
|
|
|
|
客户端将短时间内的多次点击合并为批次提交,delta 为本批新增点赞数。
|
|
|
|
|
|
|
|
|
|
|
|
- 幂等:同一 (photoId, sessionId, batchId) 重复提交返回已确认结果
|
|
|
|
|
|
(batchAccepted=true、total 为权威累计值),不重复加计;失败重试
|
|
|
|
|
|
必须复用同一 batchId。
|
|
|
|
|
|
- 窗口外过期批次(LIKE_BATCH_WINDOW_HOURS,默认 24h,清理任务保留窗口)
|
|
|
|
|
|
拒绝重放:不加计,返回当前权威 total(batchAccepted=false),
|
|
|
|
|
|
客户端据此校准本地乐观计数。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- 基础限速:sessionId+来源 IP 滑窗,超限 429(RATE_LIMITED)。
|
|
|
|
|
|
- 相册非公开/紧急停用 404(ALBUM_NOT_PUBLIC);照片不存在、未发布、
|
|
|
|
|
|
不属于该相册或相册非公开 404(PHOTO_NOT_PUBLIC)。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/LikeBatchRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
本批处理结果(含被拒绝的过期批次——拒绝也返回 200 与权威 total,
|
|
|
|
|
|
语义由 batchAccepted 表达,避免客户端把重放当失败重试)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/LikeBatchResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;delta 越界 1..20 或字段长度非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
|
|
|
|
|
|
不属于该相册(PHOTO_NOT_PUBLIC)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'429':
|
|
|
|
|
|
description: 基础限速触发(RATE_LIMITED;sessionId+IP 滑窗)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/public/albums/{token}/visits:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: reportAlbumVisit
|
|
|
|
|
|
tags: [interactions]
|
|
|
|
|
|
summary: 浏览上报
|
|
|
|
|
|
description: |
|
|
|
|
|
|
匿名浏览上报(ov 域部署)。仅由客户端显式调用:页面可见且相册信息
|
|
|
|
|
|
加载成功后上报一次(列表/图片/WS 等接口调用一律不触发计数)。
|
|
|
|
|
|
|
|
|
|
|
|
- requestId 为上报幂等键(建议 UUID),counted 确认前跨刷新/重试持久复用;
|
2026-09-18 18:14:01 +08:00
|
|
|
|
重复 requestId 幂等重放:counted 回显该 requestId 首次处理的结局
|
|
|
|
|
|
(确认响应丢失后重试仍见 true),viewCount 恒为当前权威值,不重复计数。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- 去重窗口(VISIT_WINDOW_MINUTES,默认 30 分钟,D07)内同一 visitorId
|
|
|
|
|
|
不重复计数;窗口过后再上报按新访次计数。
|
|
|
|
|
|
- 过期 requestId(VISIT_REQUEST_TTL_MINUTES,默认 35 分钟)拒绝重放
|
2026-09-18 18:14:01 +08:00
|
|
|
|
(counted=false,无论原结局),不得重新加计。
|
|
|
|
|
|
- 基础限速:visitorId+来源 IP 固定窗(VISIT_WINDOW_REQUESTS,默认
|
|
|
|
|
|
60/窗),超限 429(RATE_LIMITED);去重本身为主缓解。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
- 相册非公开/紧急停用 404(ALBUM_NOT_PUBLIC)。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/VisitReportRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 上报结果(窗口内重复/重复 requestId/过期重放均 200 + counted=false)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/VisitReportResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 参数校验失败(VALIDATION_FAILED;visitorId/requestId 长度非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册不存在或未公开(ALBUM_NOT_PUBLIC)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'429':
|
|
|
|
|
|
description: 基础限速触发(RATE_LIMITED;visitorId 滑窗)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
/public/albums/{token}/photos/{photoId}/download:
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- $ref: '#/components/parameters/AlbumPublicToken'
|
|
|
|
|
|
- $ref: '#/components/parameters/PhotoId'
|
|
|
|
|
|
get:
|
|
|
|
|
|
operationId: downloadPublicPhoto
|
|
|
|
|
|
tags: [interactions]
|
|
|
|
|
|
summary: 公开照片下载
|
|
|
|
|
|
description: |
|
|
|
|
|
|
匿名下载(ov 域部署,观众动作端点故归 interactions)。按相册两级下载
|
|
|
|
|
|
开关校验(A18):variant=browse 需 downloadEnabled;variant=original
|
|
|
|
|
|
需 originalDownloadEnabled(在 downloadEnabled 基础上的更高级开关,
|
|
|
|
|
|
两者均开才可下载原图)。对应级别开关关闭 → 403 DOWNLOAD_DISABLED;
|
|
|
|
|
|
相册/照片不可见 404(ALBUM_NOT_PUBLIC/PHOTO_NOT_PUBLIC,不区分枚举)。
|
|
|
|
|
|
URL 为短期签名凭证,禁止持久保存/写入分享链接,过期经本端点刷新;
|
|
|
|
|
|
服务端日志不记完整签名 URL。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
parameters:
|
|
|
|
|
|
- name: variant
|
|
|
|
|
|
in: query
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 下载版本。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/DownloadVariant'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 下载凭证(短期签名 URL)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicPhotoDownload'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 查询参数校验失败(VALIDATION_FAILED;variant 缺失或取值非法)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'403':
|
|
|
|
|
|
description: 相册下载开关关闭(DOWNLOAD_DISABLED;对应 variant 所需级别的开关未开)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
|
|
|
|
|
|
不属于该相册(PHOTO_NOT_PUBLIC)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-18 13:34:35 +08:00
|
|
|
|
# ─────────────────────────── internal ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/internal/sync/content-batches:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: syncContentBatches
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 内容事件批量推送
|
|
|
|
|
|
description: |
|
|
|
|
|
|
cn→ov 方向:cn outbox 未投递事件批量推送(默认每 2s 一批、单批
|
|
|
|
|
|
SYNC_BATCH_SIZE 条;priority=high 的下线/隐藏/删除类事件即时单发)。
|
|
|
|
|
|
ov 侧语义:eventId 幂等(重复推送忽略)、entityVersion 单调
|
|
|
|
|
|
(旧版本忽略)、tombstone 墓碑优先(副本删除且不被旧事件复活)、
|
|
|
|
|
|
依赖缺失暂存待补。acceptedEventIds 为本批受理(含幂等重复)的事件 ID,
|
|
|
|
|
|
applied 为实际应用(新版本生效)条数。鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/ContentBatchRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 本批受理结果。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/ContentBatchResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/internal/sync/stat-snapshots:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: syncStatSnapshots
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 统计快照回传
|
|
|
|
|
|
description: |
|
|
|
|
|
|
ov→cn 方向:ov 侧聚合的统计快照(likes/views 权威累计值,默认每 60s
|
|
|
|
|
|
增量回传)。cn 按 statVersion 单调替换副本列(仅更高版本替换、
|
|
|
|
|
|
绝不相加),重复回传幂等。kind=likes 时 photoId 必填(照片点赞数);
|
|
|
|
|
|
kind=views 为相册级浏览数(无 photoId)。鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/StatSnapshotRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 回传受理结果。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/StatSnapshotResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/internal/sync/reconcile:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: syncReconcile
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 缺失事件对账
|
|
|
|
|
|
description: |
|
|
|
|
|
|
ov 侧按 sync_state 水位向 cn 请求指定实体类型在 sinceVersion 之后
|
|
|
|
|
|
的事件清单(albumId 可选过滤;中断恢复=水位重放)。cn 返回按版本
|
|
|
|
|
|
升序的事件数组,ov 重放补漏;全量快照(bootstrap)的事件本体也经
|
|
|
|
|
|
本通道分批拉取。鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/ReconcileRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 缺失事件清单(按 entityVersion 升序)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/ReconcileResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/internal/sync/bootstrap:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: syncBootstrap
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 全量快照引导
|
|
|
|
|
|
description: |
|
|
|
|
|
|
ov 冷启动或新建副本时请求 cn 生成当前全量快照事件序列
|
|
|
|
|
|
(album → categories → assets → photos,含各实体当前 entityVersion)。
|
|
|
|
|
|
本端点仅返回事件计数 eventCount 与快照水位 watermark;事件本体经
|
|
|
|
|
|
对账通道(/internal/sync/reconcile)以 watermark 为起点分批拉取。
|
|
|
|
|
|
albumId 缺省表示全部相册。鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/BootstrapRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 快照规模与水位。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/BootstrapResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-18 16:18:31 +08:00
|
|
|
|
/internal/sync/digest:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: syncDigest
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 每相册实体计数摘要
|
|
|
|
|
|
description: |
|
|
|
|
|
|
cn 侧权威计数(P2 Task 4):每相册 {categoryCount, publishedPhotoCount,
|
|
|
|
|
|
photoCount, assetCount}。ov 对账调度定期拉取并与副本计数比对——不一致
|
|
|
|
|
|
的相册触发该相册 bootstrap(当前状态快照重发,含分类全量清单整体替换),
|
|
|
|
|
|
收敛错过的墓碑与漏掉的事件。albumId 缺省表示全部相册。鉴权见 [internal]
|
|
|
|
|
|
tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/DigestRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 每相册计数摘要(albumId 升序)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/DigestResponse'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-18 16:19:02 +08:00
|
|
|
|
/internal/emergency/disable:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: emergencyDisable
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 海外紧急停用相册(ov 域)
|
|
|
|
|
|
description: |
|
|
|
|
|
|
ov 侧独立于同步链路的紧急停用入口:直接置 albums_ov.emergency_disabled
|
|
|
|
|
|
=true(ov 本地写,不经同步版本链——后续任何同步事件不得解除,恢复仅经
|
|
|
|
|
|
/internal/emergency/enable 显式操作)。停用相册在 ov 公开 API/WS 侧按
|
|
|
|
|
|
404 ALBUM_NOT_PUBLIC 语义处理;cn 侧不感知(同步照常)。albumToken 与
|
|
|
|
|
|
albumId 二选一(都缺省 400)。审计:ov 侧结构化日志以 audit=emergency
|
|
|
|
|
|
字段标记(P2 决策:不做独立文件通道,P5 运维按字段路由聚合)。
|
|
|
|
|
|
鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/EmergencyDisableRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 已停用(幂等:重复停用返回同一结果)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/EmergencyStatus'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED;含 albumToken/albumId 均缺省)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册副本不存在(ALBUM_NOT_FOUND——ov 尚未同步该相册)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
|
|
|
|
|
/internal/emergency/enable:
|
|
|
|
|
|
post:
|
|
|
|
|
|
operationId: emergencyEnable
|
|
|
|
|
|
tags: [internal]
|
|
|
|
|
|
summary: 解除海外紧急停用(ov 域,显式唯一恢复通道)
|
|
|
|
|
|
description: |
|
|
|
|
|
|
唯一能清除 albums_ov.emergency_disabled 的入口(显式操作,任何同步
|
|
|
|
|
|
事件都不会代为解除)。albumToken 与 albumId 二选一(都缺省 400)。
|
|
|
|
|
|
审计同 disable(audit=emergency 字段)。鉴权见 [internal] tag 描述。
|
|
|
|
|
|
security: []
|
|
|
|
|
|
requestBody:
|
|
|
|
|
|
required: true
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/EmergencyEnableRequest'
|
|
|
|
|
|
responses:
|
|
|
|
|
|
'200':
|
|
|
|
|
|
description: 已恢复(幂等:重复启用返回同一结果)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/EmergencyStatus'
|
|
|
|
|
|
'400':
|
|
|
|
|
|
description: 请求体校验失败(VALIDATION_FAILED;含 albumToken/albumId 均缺省)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'404':
|
|
|
|
|
|
description: 相册副本不存在(ALBUM_NOT_FOUND)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
'500':
|
|
|
|
|
|
$ref: '#/components/responses/InternalError'
|
|
|
|
|
|
|
2026-09-17 17:04:12 +08:00
|
|
|
|
components:
|
|
|
|
|
|
securitySchemes:
|
|
|
|
|
|
bearerAuth:
|
|
|
|
|
|
type: http
|
|
|
|
|
|
scheme: bearer
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
parameters:
|
|
|
|
|
|
AlbumId:
|
|
|
|
|
|
name: albumId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 相册 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
UserId:
|
|
|
|
|
|
name: userId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 用户 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
CategoryId:
|
|
|
|
|
|
name: categoryId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 分类 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
2026-09-18 08:23:59 +08:00
|
|
|
|
AssetId:
|
|
|
|
|
|
name: assetId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 相册资产 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
2026-09-17 17:31:11 +08:00
|
|
|
|
UploadId:
|
|
|
|
|
|
name: uploadId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 上传会话 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
PhotoId:
|
|
|
|
|
|
name: photoId
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
AlbumPublicToken:
|
|
|
|
|
|
name: token
|
|
|
|
|
|
in: path
|
|
|
|
|
|
required: true
|
|
|
|
|
|
description: 相册公开令牌(不可枚举,持有即可访问)。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
CursorQuery:
|
|
|
|
|
|
name: cursor
|
|
|
|
|
|
in: query
|
|
|
|
|
|
description: 分页游标(上一页响应的 nextCursor)。
|
|
|
|
|
|
schema:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
maxLength: 512
|
2026-09-17 17:31:11 +08:00
|
|
|
|
LocaleQuery:
|
|
|
|
|
|
name: locale
|
|
|
|
|
|
in: query
|
2026-09-17 18:11:21 +08:00
|
|
|
|
description: 请求语言;缺省或取值不支持时按相册 defaultLocale 回退(不报 400,响应 resolvedLocale 指示实际返回语言)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
|
2026-09-17 18:06:54 +08:00
|
|
|
|
responses:
|
|
|
|
|
|
Unauthorized:
|
|
|
|
|
|
description: 未认证:令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
InternalError:
|
|
|
|
|
|
description: 服务器内部错误(INTERNAL_ERROR)。
|
|
|
|
|
|
content:
|
|
|
|
|
|
application/json:
|
|
|
|
|
|
schema:
|
|
|
|
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
|
|
|
2026-09-17 17:04:12 +08:00
|
|
|
|
schemas:
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ── 通用 ──
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
ErrorCode:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: |
|
|
|
|
|
|
稳定错误码(服务器生成,与 src/errors.ts 的 ErrorCodes 一一对应,
|
|
|
|
|
|
1:1 类型守护见 __tests__/events.test.ts);P4a 起供批量逐项结果等
|
|
|
|
|
|
内嵌失败原因复用。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- AUTH_INVALID_CREDENTIALS
|
|
|
|
|
|
- AUTH_TOKEN_EXPIRED
|
|
|
|
|
|
- AUTH_RATE_LIMITED
|
|
|
|
|
|
- RATE_LIMITED
|
|
|
|
|
|
- AUTH_FORBIDDEN
|
|
|
|
|
|
- NOT_FOUND
|
|
|
|
|
|
- ALBUM_NOT_FOUND
|
|
|
|
|
|
- ALBUM_NOT_PUBLIC
|
|
|
|
|
|
- ALBUM_UPLOAD_DISABLED
|
|
|
|
|
|
- MEMBER_CONFLICT
|
|
|
|
|
|
- UPLOAD_SESSION_CONFLICT
|
|
|
|
|
|
- UPLOAD_VERIFY_FAILED
|
|
|
|
|
|
- PHOTO_NOT_FOUND
|
|
|
|
|
|
- PHOTO_NOT_PUBLIC
|
|
|
|
|
|
- DOWNLOAD_DISABLED
|
|
|
|
|
|
- VALIDATION_FAILED
|
|
|
|
|
|
- SYNC_AUTH_FAILED
|
|
|
|
|
|
- INTERNAL_ERROR
|
|
|
|
|
|
|
2026-09-17 17:04:12 +08:00
|
|
|
|
Error:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [code, message, requestId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
code:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
$ref: '#/components/schemas/ErrorCode'
|
2026-09-17 17:04:12 +08:00
|
|
|
|
message:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 服务器生成的可读消息(诊断用,不作为客户端展示文案依据)。
|
|
|
|
|
|
requestId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 请求追踪 ID。
|
|
|
|
|
|
|
|
|
|
|
|
CursorPageMeta:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [nextCursor, hasMore]
|
2026-09-17 18:06:54 +08:00
|
|
|
|
description: 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。不变式:hasMore=true 当且仅当 nextCursor≠null,两者必须成对填充。
|
2026-09-17 17:04:12 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
nextCursor:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 下一页游标;null 表示没有更多数据。
|
|
|
|
|
|
hasMore:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 是否还有下一页。
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
Locale:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: P1a 支持的语言。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- zh-CN
|
|
|
|
|
|
- en
|
|
|
|
|
|
|
|
|
|
|
|
# ── 认证 ──
|
|
|
|
|
|
|
2026-09-17 17:04:12 +08:00
|
|
|
|
LoginRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [account, password]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
account:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 账号(用户名或邮箱)。
|
|
|
|
|
|
password:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 密码。
|
|
|
|
|
|
LoginResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [sessionToken, expiresAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
sessionToken:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 会话令牌(Bearer)。
|
|
|
|
|
|
expiresAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 会话过期时间。
|
|
|
|
|
|
RefreshResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [expiresAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
expiresAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 续期后的过期时间。
|
2026-09-19 00:59:39 +08:00
|
|
|
|
PasswordChangeRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 修改密码请求(P3 Task 3 契约增补)。
|
|
|
|
|
|
required: [oldPassword, newPassword]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
oldPassword:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 当前密码。
|
|
|
|
|
|
newPassword:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 8
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 新密码(至少 8 位)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
# ── 相册 ──
|
|
|
|
|
|
|
|
|
|
|
|
AlbumTranslation:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [locale, title]
|
|
|
|
|
|
description: 相册多语言条目(创建/更新与响应共用;未填的可选字段存储为 null)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
locale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
title:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
minLength: 1
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 相册标题。
|
|
|
|
|
|
description:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 相册描述。
|
|
|
|
|
|
venue:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 场地名称。
|
|
|
|
|
|
address:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 场地地址。
|
|
|
|
|
|
|
|
|
|
|
|
AlbumCreateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [translations, defaultLocale, startAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
description: 多语言内容;必须包含 defaultLocale 对应条目。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumTranslation'
|
|
|
|
|
|
defaultLocale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
startAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动开始时间(UTC 存储,展示按 timezone)。
|
|
|
|
|
|
endAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动结束时间;null 或缺省表示未定。
|
|
|
|
|
|
timezone:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
default: Asia/Shanghai
|
|
|
|
|
|
description: 活动 IANA 时区。
|
|
|
|
|
|
examples:
|
|
|
|
|
|
- Asia/Shanghai
|
|
|
|
|
|
downloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
default: true
|
|
|
|
|
|
description: 允许下载浏览版本。
|
|
|
|
|
|
originalDownloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
default: false
|
|
|
|
|
|
description: 允许下载原图。
|
|
|
|
|
|
|
|
|
|
|
|
AlbumUpdateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
minProperties: 1
|
|
|
|
|
|
description: 部分更新:仅提交的字段被修改,各开关互相独立;endAt 传 null 清除。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
description: 全量替换多语言内容;须包含 defaultLocale 对应条目。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumTranslation'
|
|
|
|
|
|
defaultLocale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
startAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动开始时间。
|
|
|
|
|
|
endAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动结束时间;null 清除。
|
|
|
|
|
|
timezone:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 活动 IANA 时区。
|
|
|
|
|
|
uploadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 是否允许新上传任务。
|
|
|
|
|
|
publicEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 是否公开可见。
|
|
|
|
|
|
downloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 允许下载浏览版本。
|
|
|
|
|
|
originalDownloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 允许下载原图。
|
|
|
|
|
|
|
|
|
|
|
|
AlbumSummary:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 相册列表条目(完整开关与多语言标题,管理列表无需二次请求详情)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- id
|
|
|
|
|
|
- publicToken
|
|
|
|
|
|
- ownerId
|
|
|
|
|
|
- status
|
|
|
|
|
|
- defaultLocale
|
|
|
|
|
|
- timezone
|
|
|
|
|
|
- startAt
|
|
|
|
|
|
- endAt
|
|
|
|
|
|
- uploadEnabled
|
|
|
|
|
|
- publicEnabled
|
|
|
|
|
|
- downloadEnabled
|
|
|
|
|
|
- originalDownloadEnabled
|
|
|
|
|
|
- watermarkVersion
|
|
|
|
|
|
- translations
|
|
|
|
|
|
- createdAt
|
|
|
|
|
|
- updatedAt
|
2026-09-18 18:45:43 +08:00
|
|
|
|
- statsSyncedAt
|
2026-09-17 17:31:11 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 相册 ID。
|
|
|
|
|
|
publicToken:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
2026-09-17 18:06:54 +08:00
|
|
|
|
pattern: '^[0-9a-z]{20,32}$'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 公开访问令牌(不可枚举)。
|
|
|
|
|
|
ownerId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 创建者用户 ID。
|
|
|
|
|
|
status:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
default: active
|
2026-09-17 18:06:54 +08:00
|
|
|
|
description: 相册状态;offline 表示下线(停止公开访问与新授权签发)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
enum:
|
|
|
|
|
|
- active
|
2026-09-17 18:06:54 +08:00
|
|
|
|
- offline
|
2026-09-17 17:31:11 +08:00
|
|
|
|
defaultLocale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
timezone:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 活动 IANA 时区。
|
|
|
|
|
|
startAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动开始时间。
|
|
|
|
|
|
endAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 活动结束时间;null 表示未定。
|
|
|
|
|
|
uploadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 是否允许新上传任务。
|
|
|
|
|
|
publicEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 是否公开可见。
|
|
|
|
|
|
downloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 允许下载浏览版本。
|
|
|
|
|
|
originalDownloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 允许下载原图。
|
|
|
|
|
|
watermarkVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
default: 0
|
|
|
|
|
|
description: 当前水印配置版本。
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 各语言内容。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumTranslation'
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 创建时间。
|
|
|
|
|
|
updatedAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 最近更新时间。
|
2026-09-18 18:45:43 +08:00
|
|
|
|
statsSyncedAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
|
|
|
|
|
统计副本最近同步时间(P2 A27:ov→cn 统计快照在本相册的应用时刻);
|
|
|
|
|
|
null 表示尚无回传应用(viewCountReplica 副本位仍为初始 0)。照片级
|
|
|
|
|
|
点赞副本(PhotoRecord.likeCount)的同步时间不经相册行表达。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
AlbumList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumSummary'
|
|
|
|
|
|
|
|
|
|
|
|
Album:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/AlbumSummary'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [categories]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
categories:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 相册分类(按 sortOrder 升序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/Category'
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
# ── 水印(P4a) ──
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkConfig:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
水印配置(P4a A18,创建请求与当前配置响应共用)。enabled=false 表示
|
|
|
|
|
|
关闭水印(新照片不加水印),其余字段此时被忽略;可选字段缺省用服务端
|
|
|
|
|
|
默认值。
|
|
|
|
|
|
required: [enabled]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
enabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 是否开启浏览图水印。
|
|
|
|
|
|
position:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 水印位置;缺省服务端默认。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- topLeft
|
|
|
|
|
|
- topRight
|
|
|
|
|
|
- bottomLeft
|
|
|
|
|
|
- bottomRight
|
|
|
|
|
|
- center
|
|
|
|
|
|
opacity:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
maximum: 100
|
|
|
|
|
|
description: 不透明度百分比。
|
|
|
|
|
|
scalePercent:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 5
|
|
|
|
|
|
maximum: 50
|
|
|
|
|
|
description: 水印尺寸相对浏览图宽度的百分比。
|
|
|
|
|
|
text:
|
|
|
|
|
|
description: 文字水印参数;缺省不绘制文字。
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/WatermarkTextConfig'
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkTextConfig:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 文字水印参数(SVG 渲染实现,Task 3 登记)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
content:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
description: 文字内容。
|
|
|
|
|
|
fontSize:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 8
|
|
|
|
|
|
maximum: 72
|
|
|
|
|
|
description: 字号(像素)。
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkJobCreated:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 重生成任务受理结果;configVersion 为本次保存的配置版本。
|
|
|
|
|
|
required: [jobId, configVersion]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
jobId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 重生成任务 ID。
|
|
|
|
|
|
configVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 本次保存的水印配置版本(新照片即刻套用)。
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkJobState:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 重生成任务状态;failed 可重新发起(按照片粒度幂等续跑)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- pending
|
|
|
|
|
|
- running
|
|
|
|
|
|
- done
|
|
|
|
|
|
- failed
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkJob:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 历史重生成任务条目(进度供前端轮询)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- jobId
|
|
|
|
|
|
- configVersion
|
|
|
|
|
|
- state
|
|
|
|
|
|
- progress
|
|
|
|
|
|
- total
|
|
|
|
|
|
- failed
|
|
|
|
|
|
- createdAt
|
|
|
|
|
|
properties:
|
|
|
|
|
|
jobId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 任务 ID。
|
|
|
|
|
|
configVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 目标配置版本。
|
|
|
|
|
|
state:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkJobState'
|
|
|
|
|
|
progress:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 已处理张数(含失败)。
|
|
|
|
|
|
total:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 待处理总张数。
|
|
|
|
|
|
failed:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 失败张数。
|
|
|
|
|
|
errorCode:
|
|
|
|
|
|
description: 任务失败原因(state=failed 时必有)。
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/ErrorCode'
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 任务创建时间。
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkCurrent:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 当前生效的水印配置。
|
|
|
|
|
|
required: [configVersion, config]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
configVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 当前配置版本(同 AlbumSummary.watermarkVersion)。
|
|
|
|
|
|
config:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkConfig'
|
|
|
|
|
|
|
|
|
|
|
|
WatermarkJobsStatus:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 水印配置与任务状态;current 从未配置为 null(watermarkVersion=0)。
|
|
|
|
|
|
required: [current, jobs]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
current:
|
|
|
|
|
|
description: 当前生效配置;从未配置为 null。
|
|
|
|
|
|
anyOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/WatermarkCurrent'
|
|
|
|
|
|
- type: 'null'
|
|
|
|
|
|
jobs:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 历史任务(创建时间倒序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/WatermarkJob'
|
|
|
|
|
|
|
2026-09-18 08:23:59 +08:00
|
|
|
|
# ── 资产 ──
|
|
|
|
|
|
|
|
|
|
|
|
AssetKind:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: |
|
|
|
|
|
|
相册资产类型(技术实施方案 §4 album_assets.kind)。banner 为观众页宣传图
|
|
|
|
|
|
(PublicAlbum.banner,P1b 消费方);cover/logo 建表与上传链路就绪,展示
|
|
|
|
|
|
消费随后续阶段。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- banner
|
|
|
|
|
|
- cover
|
|
|
|
|
|
- logo
|
|
|
|
|
|
|
|
|
|
|
|
AssetInitRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
资产上传初始化请求;大小与类型白名单与照片直传一致(UPLOAD_MAX_BYTES
|
|
|
|
|
|
环境策略,逐请求惰性读取)。locale 为可选语言维度:同一 (kind, locale)
|
|
|
|
|
|
的再次上传即替换(新行生效);语言无关的资产(如 logo)可不传。
|
|
|
|
|
|
required: [kind, filename, bytes, contentType]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
kind:
|
|
|
|
|
|
$ref: '#/components/schemas/AssetKind'
|
|
|
|
|
|
locale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
filename:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
maxLength: 255
|
|
|
|
|
|
description: 原始文件名(仅元数据,不作对象唯一标识)。
|
|
|
|
|
|
bytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 申明文件字节数;完成核验时逐一比对。
|
|
|
|
|
|
contentType:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
enum: [image/jpeg, image/png, image/heic]
|
|
|
|
|
|
description: MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。
|
|
|
|
|
|
|
|
|
|
|
|
AssetInitResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [assetId, objectKey, credential]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
assetId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 资产 ID(完成核验的寻址凭据,一次性会话)。
|
|
|
|
|
|
objectKey:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: staging 对象键(photo-live/{env}/albums/{albumId}/assets/{assetId}.{ext})。
|
|
|
|
|
|
credential:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadCredential'
|
|
|
|
|
|
|
|
|
|
|
|
AssetCompleteResponse:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/SignedUrl'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [assetId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
assetId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 资产 ID。
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ── 成员 ──
|
|
|
|
|
|
|
|
|
|
|
|
MemberAddRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [userId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
userId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 被添加用户的 ID(须为已开通账号)。
|
|
|
|
|
|
role:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
default: collaborator
|
|
|
|
|
|
description: 成员角色;P1a 仅协作者(owner 由创建流程产生)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- collaborator
|
|
|
|
|
|
|
|
|
|
|
|
Member:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [userId, account, displayName, role, status]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
userId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 用户 ID。
|
|
|
|
|
|
account:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 登录账号。
|
|
|
|
|
|
displayName:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 展示姓名(来自用户资料同步)。
|
|
|
|
|
|
role:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 相册角色。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- owner
|
|
|
|
|
|
- collaborator
|
|
|
|
|
|
status:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 成员状态;P1a 仅 active,预留扩展。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- active
|
|
|
|
|
|
|
|
|
|
|
|
MemberList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/Member'
|
|
|
|
|
|
|
|
|
|
|
|
# ── 分类 ──
|
|
|
|
|
|
|
|
|
|
|
|
CategoryTranslation:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [locale, name]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
locale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
name:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
minLength: 1
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 分类名称。
|
|
|
|
|
|
|
|
|
|
|
|
CategoryCreateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [translations]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
sortOrder:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
default: 0
|
|
|
|
|
|
description: 排序序号(升序)。
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
description: 分类多语言名称。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/CategoryTranslation'
|
|
|
|
|
|
|
|
|
|
|
|
CategoryUpdateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
minProperties: 1
|
|
|
|
|
|
description: 部分更新;translations 为全量替换。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
sortOrder:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
description: 排序序号(升序)。
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
description: 全量替换多语言名称。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/CategoryTranslation'
|
|
|
|
|
|
|
|
|
|
|
|
Category:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [id, albumId, sortOrder, translations]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 分类 ID。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 所属相册 ID。
|
|
|
|
|
|
sortOrder:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
description: 排序序号(升序)。
|
|
|
|
|
|
translations:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 各语言名称。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/CategoryTranslation'
|
|
|
|
|
|
|
|
|
|
|
|
# ── 上传 ──
|
|
|
|
|
|
|
|
|
|
|
|
UploadSessionState:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
上传会话状态(服务端视角;本地任务状态见技术实施方案 §5.5)。
|
|
|
|
|
|
会话没有 failed 状态:完成核验失败属于单次请求错误(UPLOAD_VERIFY_FAILED),
|
|
|
|
|
|
会话保持 pending 可重试;cancelled 为用户主动取消;
|
|
|
|
|
|
expired 为超过 expiresAt 未完成(核验时推导或由补偿扫描落定)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
enum:
|
|
|
|
|
|
- pending
|
|
|
|
|
|
- confirmed
|
|
|
|
|
|
- cancelled
|
|
|
|
|
|
- expired
|
|
|
|
|
|
|
|
|
|
|
|
PhotoProcessingState:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 照片服务端处理状态(技术实施方案 §5.5「服务端处理」链路)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- pending_upload
|
|
|
|
|
|
- uploaded
|
|
|
|
|
|
- processing
|
|
|
|
|
|
- ready
|
|
|
|
|
|
- processing_failed
|
|
|
|
|
|
|
|
|
|
|
|
PhotoVisibility:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 照片对外可见性(技术实施方案 §5.5「对外可见性」;deleted 为软删除)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- unpublished
|
|
|
|
|
|
- published
|
|
|
|
|
|
- hidden
|
|
|
|
|
|
- deleted
|
|
|
|
|
|
|
|
|
|
|
|
UploadInitRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [albumId, clientTaskId, filename, bytes, contentType]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 目标相册 ID。
|
|
|
|
|
|
categoryId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 目标分类 ID;缺省为相册默认分类。
|
|
|
|
|
|
clientTaskId:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
maxLength: 128
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 客户端任务幂等键;同一任务的重试必须复用(会话与照片 ID 均复用)。
|
|
|
|
|
|
filename:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
maxLength: 255
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 原始文件名(仅元数据,不作对象唯一标识)。
|
|
|
|
|
|
bytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 申明文件字节数;完成核验时逐一比对。
|
|
|
|
|
|
contentType:
|
|
|
|
|
|
type: string
|
2026-09-17 18:06:54 +08:00
|
|
|
|
enum: [image/jpeg, image/png, image/heic]
|
|
|
|
|
|
description: MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。
|
2026-09-19 00:59:39 +08:00
|
|
|
|
sourceDeviceId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 8
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
description: |
|
|
|
|
|
|
客户端首次生成并持久化的设备标识;服务端历史返回用于区分上传来源
|
|
|
|
|
|
(A19)。可选;同一 clientTaskId 幂等重放时保留首次落库的值。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
UploadCredential:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: staging 对象的临时直传凭证;仅可写入指定 objectKey,不可访问 originals/variants。
|
|
|
|
|
|
required: [mode, url, method, headers, expiresAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
mode:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
default: presigned
|
|
|
|
|
|
description: 凭证模式;P1a 仅预签名 URL,预留 STS 扩展。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- presigned
|
|
|
|
|
|
url:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 预签名上传 URL。
|
|
|
|
|
|
method:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传 HTTP 方法。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- PUT
|
|
|
|
|
|
headers:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传时必须携带的请求头(如 Content-Type)。
|
|
|
|
|
|
additionalProperties:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
expiresAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 凭证过期时间;过期后续签(renew)再重试。
|
|
|
|
|
|
|
|
|
|
|
|
UploadInitResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [uploadId, photoId, objectKey, credential]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
uploadId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传会话 ID。
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 预创建的照片 ID(重试复用,不重复建照片)。
|
|
|
|
|
|
objectKey:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: staging 对象键(photo-live/{env}/staging/{uploadId}/{photoId}.{ext})。
|
|
|
|
|
|
credential:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadCredential'
|
|
|
|
|
|
|
|
|
|
|
|
UploadCompleteResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [photoId, processingState]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
processingState:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoProcessingState'
|
|
|
|
|
|
|
|
|
|
|
|
UploadSessionPhoto:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [photoId, processingState, visibility]
|
|
|
|
|
|
description: 会话关联照片的当前状态(会话记录内嵌,客户端据此展示服务端进度)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
processingState:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoProcessingState'
|
|
|
|
|
|
visibility:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoVisibility'
|
|
|
|
|
|
|
|
|
|
|
|
UploadSessionRecord:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required:
|
|
|
|
|
|
- uploadId
|
|
|
|
|
|
- albumId
|
|
|
|
|
|
- clientTaskId
|
|
|
|
|
|
- state
|
|
|
|
|
|
- expectedBytes
|
|
|
|
|
|
- contentType
|
|
|
|
|
|
- createdAt
|
|
|
|
|
|
- photo
|
|
|
|
|
|
properties:
|
|
|
|
|
|
uploadId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传会话 ID。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 目标相册 ID。
|
|
|
|
|
|
clientTaskId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 客户端任务幂等键。
|
|
|
|
|
|
state:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadSessionState'
|
|
|
|
|
|
expectedBytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 申明文件字节数。
|
|
|
|
|
|
contentType:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 申明 MIME 类型。
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 会话创建时间。
|
2026-09-19 00:59:39 +08:00
|
|
|
|
sourceDeviceId:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
|
|
|
|
|
发起该上传的设备标识(客户端首次生成并持久化;init 时未携带为 null)。
|
|
|
|
|
|
P3 Task 3 契约增补(A19 设备来源语义)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
photo:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadSessionPhoto'
|
|
|
|
|
|
|
|
|
|
|
|
UploadSessionList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/UploadSessionRecord'
|
|
|
|
|
|
|
|
|
|
|
|
# ── 照片(管理端) ──
|
|
|
|
|
|
|
|
|
|
|
|
PhotoVisibilityUpdateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
required: [visibility]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
visibility:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 目标可见性;仅允许 hidden 与 published 间切换。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- hidden
|
|
|
|
|
|
- published
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
PhotoHideBatchRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 批量隐藏请求(P4a A16);逐项处理,部分成功。
|
|
|
|
|
|
required: [photoIds]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoIds:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
maxItems: 200
|
|
|
|
|
|
description: 目标照片 ID 列表(单批上限 200,执行注意约定)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
|
|
|
|
|
|
BatchHideItem:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 单项隐藏结果;ok=false 时 code 说明原因(如 PHOTO_NOT_PUBLIC/PHOTO_NOT_FOUND)。
|
|
|
|
|
|
required: [photoId, ok]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
ok:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 本项是否隐藏成功。
|
|
|
|
|
|
code:
|
|
|
|
|
|
description: 失败原因错误码(ok=false 时必有)。
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/ErrorCode'
|
|
|
|
|
|
|
|
|
|
|
|
BatchHideResult:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 批量隐藏结果;results 与请求 photoIds 同序逐项对应。
|
|
|
|
|
|
required: [results]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
results:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 逐项结果(与请求同序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/BatchHideItem'
|
|
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
PhotoRecord:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 管理端照片记录(技术实施方案 §4 photos 表字段)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- photoId
|
|
|
|
|
|
- albumId
|
|
|
|
|
|
- categoryId
|
|
|
|
|
|
- uploaderId
|
|
|
|
|
|
- visibility
|
|
|
|
|
|
- processingState
|
|
|
|
|
|
- bytes
|
|
|
|
|
|
- width
|
|
|
|
|
|
- height
|
|
|
|
|
|
- shotAt
|
|
|
|
|
|
- uploadedAt
|
|
|
|
|
|
- publishedAt
|
|
|
|
|
|
- likeCount
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 所属相册 ID。
|
|
|
|
|
|
categoryId:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 分类 ID;null 表示未分类。
|
|
|
|
|
|
uploaderId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传人用户 ID。
|
|
|
|
|
|
visibility:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoVisibility'
|
|
|
|
|
|
processingState:
|
|
|
|
|
|
$ref: '#/components/schemas/PhotoProcessingState'
|
|
|
|
|
|
bytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 原图字节数。
|
|
|
|
|
|
width:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 原图宽度(像素);处理前为 null。
|
|
|
|
|
|
height:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 原图高度(像素);处理前为 null。
|
|
|
|
|
|
shotAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 拍摄时间(EXIF);无有效值时为 null。
|
|
|
|
|
|
uploadedAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传完成时间。
|
|
|
|
|
|
publishedAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 发布时间;未发布为 null。
|
|
|
|
|
|
likeCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 累计点赞数。
|
|
|
|
|
|
|
2026-09-18 08:23:59 +08:00
|
|
|
|
AdminPhotoUploader:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 管理列表条目内嵌的上传人脱敏信息(不含邮箱、手机等凭据字段)。
|
|
|
|
|
|
required: [userId, account, displayName]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
userId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上传人用户 ID(与 PhotoRecord.uploaderId 一致)。
|
|
|
|
|
|
account:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 登录账号。
|
|
|
|
|
|
displayName:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 展示姓名(来自用户资料)。
|
|
|
|
|
|
|
|
|
|
|
|
AdminPhoto:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/PhotoRecord'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [uploader]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
uploader:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminPhotoUploader'
|
|
|
|
|
|
|
|
|
|
|
|
AdminPhotoList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminPhoto'
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
# ── 管理辅助与账号治理(P4a) ──
|
|
|
|
|
|
|
|
|
|
|
|
AlbumTransferRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 相册负责人交接请求(A17)。
|
|
|
|
|
|
required: [targetUserId, keepAsCollaborator]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
targetUserId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
description: 新 owner 用户 ID(须为可被指定为 owner 的账号,见端点 400 说明)。
|
|
|
|
|
|
keepAsCollaborator:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 原 owner 是否保留为 collaborator;false 时移出成员表。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
AdminUser:
|
2026-09-18 08:23:59 +08:00
|
|
|
|
type: object
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
用户治理条目(P4a;不含邮箱/手机/密码等凭据字段)。sourceStatus 只读
|
|
|
|
|
|
展示(上游状态仅同步任务维护)。id 用于邀请协作者
|
|
|
|
|
|
(POST /albums/{albumId}/members 的 userId)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- id
|
|
|
|
|
|
- account
|
|
|
|
|
|
- displayName
|
|
|
|
|
|
- role
|
|
|
|
|
|
- sourceStatus
|
|
|
|
|
|
- localLocked
|
|
|
|
|
|
- credentialStatus
|
|
|
|
|
|
- createdAt
|
2026-09-18 08:23:59 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 用户 ID。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
account:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 登录账号。
|
|
|
|
|
|
displayName:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 展示姓名。
|
2026-09-20 15:56:38 +08:00
|
|
|
|
role:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 公司角色(staff/admin;相册角色另表)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- staff
|
|
|
|
|
|
- admin
|
|
|
|
|
|
sourceStatus:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 来源状态:local=本地创建;active/disabled=同步源状态(P4a 同步)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- local
|
|
|
|
|
|
- active
|
|
|
|
|
|
- disabled
|
|
|
|
|
|
localLocked:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 本地锁定(停用/deactivate 置 true;与上游状态独立)。
|
|
|
|
|
|
credentialStatus:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 凭据状态:active=可登录;pending=同步创建待激活(不可登录,待管理员激活并出初始凭据)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- active
|
|
|
|
|
|
- pending
|
|
|
|
|
|
locale:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 界面语言偏好;未设置为 null。
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 创建时间。
|
|
|
|
|
|
|
|
|
|
|
|
AdminUserList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 用户条目(前缀模式按 account 升序且仅激活资格用户;管理列表模式按 createdAt 与 ID 稳定倒序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AdminUser'
|
|
|
|
|
|
|
|
|
|
|
|
AdminUserStatusFilter:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: |
|
|
|
|
|
|
管理列表治理状态过滤(单值归类):pending=待激活;disabled=上游停用;
|
|
|
|
|
|
locked=本地锁定;active=其余可正常登录。同时命中多状态时按
|
|
|
|
|
|
pending > disabled > locked > active 优先级归类后匹配。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- active
|
|
|
|
|
|
- pending
|
|
|
|
|
|
- disabled
|
|
|
|
|
|
- locked
|
|
|
|
|
|
|
|
|
|
|
|
AdminUserUpdateRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 用户治理属性部分更新(仅提交的字段被修改;sourceStatus 不在可更新集)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
role:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 公司角色。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- staff
|
|
|
|
|
|
- admin
|
|
|
|
|
|
localLocked:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 本地锁定;置 true 撤销该用户全部会话。
|
|
|
|
|
|
displayName:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 展示姓名。
|
|
|
|
|
|
|
|
|
|
|
|
AdminPasswordResetRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 管理员重置密码请求;newPassword 缺省由服务端生成随机密码。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
newPassword:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 8
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 指定新密码(至少 8 位);缺省服务端生成。
|
|
|
|
|
|
|
|
|
|
|
|
AdminPasswordResetResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 重置结果;newPassword 仅此一次返回(请求指定或服务端生成)。
|
|
|
|
|
|
required: [newPassword]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
newPassword:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 重置后的密码(一次性展示,转交用户后不再可见)。
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncState:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 同步引擎状态:idle=空闲/从未运行;其余为最近批次结局。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- idle
|
|
|
|
|
|
- running
|
|
|
|
|
|
- success
|
|
|
|
|
|
- partial
|
|
|
|
|
|
- failed
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncRunState:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 批次状态(partial=部分行失败,其余行照常应用)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- running
|
|
|
|
|
|
- success
|
|
|
|
|
|
- partial
|
|
|
|
|
|
- failed
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncCounts:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 批次计数。
|
|
|
|
|
|
required: [added, updated, disabled, failed]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
added:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 新增用户数(建为待激活)。
|
|
|
|
|
|
updated:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 幂等更新数(改名等)。
|
|
|
|
|
|
disabled:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 上游停用数(撤会话)。
|
|
|
|
|
|
failed:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 失败行数(明细见 /admin/user-sync/errors)。
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncStatus:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 用户同步引擎状态(A29;mock 源先行,G4 后仅替换 provider)。
|
|
|
|
|
|
required: [state]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
lastRunAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 最近批次开始时间;从未运行为 null。
|
|
|
|
|
|
lastSuccessAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 最近完全成功批次开始时间;从未成功为 null。
|
|
|
|
|
|
state:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncState'
|
|
|
|
|
|
sourceVersion:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 已提交的源水位(版本游标);从未同步为 null。
|
|
|
|
|
|
counts:
|
|
|
|
|
|
description: 最近批次计数;从未运行为 null。
|
|
|
|
|
|
anyOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/UserSyncCounts'
|
|
|
|
|
|
- type: 'null'
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncRun:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 同步批次条目。
|
|
|
|
|
|
required: [id, trigger, state, counts, startedAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 批次 ID。
|
|
|
|
|
|
trigger:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 触发方式(定时/手动补拉)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- cron
|
|
|
|
|
|
- manual
|
|
|
|
|
|
state:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncRunState'
|
|
|
|
|
|
cursor:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 本批次已提交的源水位(同步游标,非分页游标);未提交为 null。
|
|
|
|
|
|
counts:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncCounts'
|
|
|
|
|
|
startedAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 批次开始时间。
|
|
|
|
|
|
finishedAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 批次结束时间;运行中为 null。
|
|
|
|
|
|
error:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 批次级失败摘要;无为 null。
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncRunList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 批次列表(startedAt 与 ID 稳定倒序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/UserSyncRun'
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncRunCreated:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 手动触发受理结果。
|
|
|
|
|
|
required: [runId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
runId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 批次 ID(已有批次运行中时为该进行中批次)。
|
|
|
|
|
|
|
|
|
|
|
|
UserSyncError:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 同步失败行明细(坏行记录,其余行照常应用的证据链)。
|
|
|
|
|
|
required: [runId, externalUserId, code, detail, createdAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
runId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 归属批次 ID。
|
|
|
|
|
|
externalUserId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 上游用户标识。
|
|
|
|
|
|
code:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 失败分类码(provider 级约定,如 upstream_timeout/invalid_record)。
|
|
|
|
|
|
detail:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 失败详情(诊断用)。
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 记录时间。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
UserSyncErrorList:
|
2026-09-18 08:23:59 +08:00
|
|
|
|
type: object
|
2026-09-20 15:56:38 +08:00
|
|
|
|
description: 失败明细列表(createdAt 倒序;无游标即取即用)。
|
2026-09-18 08:23:59 +08:00
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
2026-09-20 15:56:38 +08:00
|
|
|
|
$ref: '#/components/schemas/UserSyncError'
|
|
|
|
|
|
|
|
|
|
|
|
UsageAlbum:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 单相册用量聚合(实时 SUM;P5 换物化/OSS 用量,登记偏差)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- albumId
|
|
|
|
|
|
- title
|
|
|
|
|
|
- photoCount
|
|
|
|
|
|
- originalBytes
|
|
|
|
|
|
- variantBytes
|
|
|
|
|
|
- totalBytes
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 相册 ID。
|
|
|
|
|
|
title:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 相册标题(defaultLocale 解析)。
|
|
|
|
|
|
photoCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 照片总数(全部状态)。
|
|
|
|
|
|
originalBytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 原图存储字节数。
|
|
|
|
|
|
variantBytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 变体(缩略/浏览/水印等)存储字节数。
|
|
|
|
|
|
totalBytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 合计字节数(originalBytes + variantBytes)。
|
|
|
|
|
|
|
|
|
|
|
|
UsageTotals:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 全库用量合计。
|
|
|
|
|
|
required: [photoCount, totalBytes]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 照片总数。
|
|
|
|
|
|
totalBytes:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 存储总字节数。
|
|
|
|
|
|
|
|
|
|
|
|
UsageThresholds:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 用量阈值;null 表示该维度未设置(告警停用)。
|
|
|
|
|
|
required: [storageBytes, perAlbumBytes]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
storageBytes:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 全库存储阈值。
|
|
|
|
|
|
perAlbumBytes:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 单相册存储阈值。
|
|
|
|
|
|
|
|
|
|
|
|
UsageThresholdsUpdate:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 阈值更新请求;字段缺省=保持不变,显式 null=清除该阈值。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
storageBytes:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 全库存储阈值;null 清除。
|
|
|
|
|
|
perAlbumBytes:
|
|
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 单相册存储阈值;null 清除。
|
|
|
|
|
|
|
|
|
|
|
|
UsageAlert:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
阈值告警(A23 后台侧;接收人通知渠道 P5)。超阈写入一次直到回落
|
|
|
|
|
|
(同 kind+albumId 活跃告警唯一——重复告警去重);resolvedAt 非空为
|
|
|
|
|
|
已解除。
|
|
|
|
|
|
required: [id, kind, message, createdAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 告警 ID。
|
|
|
|
|
|
kind:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 告警维度。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- storage
|
|
|
|
|
|
- perAlbum
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 相册 ID;kind=perAlbum 必有,storage 为 null。
|
|
|
|
|
|
message:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 告警描述。
|
|
|
|
|
|
createdAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 产生时间。
|
|
|
|
|
|
resolvedAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 解除时间(阈值上调/用量回落时标记);活跃告警为 null。
|
|
|
|
|
|
|
|
|
|
|
|
UsageSummary:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 用量汇总(A23 后台侧)。
|
|
|
|
|
|
required: [albums, totals, thresholds, alerts]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albums:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 相册用量(按 totalBytes 降序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageAlbum'
|
|
|
|
|
|
totals:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageTotals'
|
|
|
|
|
|
thresholds:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageThresholds'
|
|
|
|
|
|
alerts:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 告警列表(createdAt 倒序,含已解除)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/UsageAlert'
|
2026-09-18 08:23:59 +08:00
|
|
|
|
|
2026-09-17 17:31:11 +08:00
|
|
|
|
# ── 公开(观众端) ──
|
|
|
|
|
|
|
|
|
|
|
|
SignedUrl:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 私有对象的短期签名 URL;不得写入持久分享链接,过期后经原入口刷新。
|
|
|
|
|
|
required: [url, expiresAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
url:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 签名访问 URL。
|
|
|
|
|
|
expiresAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: URL 失效时间。
|
|
|
|
|
|
|
|
|
|
|
|
PublicAlbumTranslation:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 按请求 locale 回退解析后的单语言相册内容(locale 为实际返回语言)。
|
|
|
|
|
|
required: [locale, title, description, venue, address]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
locale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
title:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 相册标题。
|
|
|
|
|
|
description:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 相册描述;无内容为 null。
|
|
|
|
|
|
venue:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 场地名称;无内容为 null。
|
|
|
|
|
|
address:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
description: 场地地址;无内容为 null。
|
|
|
|
|
|
|
|
|
|
|
|
PublicCategory:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 公开分类(名称已按请求 locale 回退解析)。
|
|
|
|
|
|
required: [id, name, sortOrder]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
id:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 分类 ID。
|
|
|
|
|
|
name:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 分类名称。
|
|
|
|
|
|
sortOrder:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 排序序号(升序)。
|
|
|
|
|
|
|
|
|
|
|
|
PublicAlbum:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 观众端相册信息(不泄露工作人员信息与内部存储键)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- publicToken
|
|
|
|
|
|
- resolvedLocale
|
|
|
|
|
|
- defaultLocale
|
|
|
|
|
|
- timezone
|
|
|
|
|
|
- startAt
|
|
|
|
|
|
- endAt
|
2026-09-17 18:06:54 +08:00
|
|
|
|
- translation
|
2026-09-17 17:31:11 +08:00
|
|
|
|
- categories
|
|
|
|
|
|
- banner
|
|
|
|
|
|
- viewCount
|
2026-09-20 18:32:34 +08:00
|
|
|
|
- downloadEnabled
|
|
|
|
|
|
- originalDownloadEnabled
|
2026-09-17 17:31:11 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
publicToken:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
2026-09-17 18:06:54 +08:00
|
|
|
|
pattern: '^[0-9a-z]{20,32}$'
|
2026-09-17 17:31:11 +08:00
|
|
|
|
description: 相册公开令牌。
|
|
|
|
|
|
resolvedLocale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
defaultLocale:
|
|
|
|
|
|
$ref: '#/components/schemas/Locale'
|
|
|
|
|
|
timezone:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 活动 IANA 时区(展示用,不随请求语言变化)。
|
|
|
|
|
|
startAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 活动开始时间(UTC,客户端按时区格式化)。
|
|
|
|
|
|
endAt:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 活动结束时间;未定为 null。
|
2026-09-17 18:06:54 +08:00
|
|
|
|
translation:
|
2026-09-17 17:31:11 +08:00
|
|
|
|
$ref: '#/components/schemas/PublicAlbumTranslation'
|
|
|
|
|
|
categories:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 分类列表(按 sortOrder 升序)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicCategory'
|
|
|
|
|
|
banner:
|
|
|
|
|
|
description: 封面图签名 URL;未设置为 null。
|
|
|
|
|
|
anyOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/SignedUrl'
|
|
|
|
|
|
- type: 'null'
|
|
|
|
|
|
viewCount:
|
2026-09-18 17:05:56 +08:00
|
|
|
|
type: [integer, 'null']
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
2026-09-17 17:31:11 +08:00
|
|
|
|
readOnly: true
|
2026-09-18 17:05:56 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
累计浏览数。cn 部署返回 null(P1a 占位,Task 9 起由统计副本回填);
|
|
|
|
|
|
ov 部署返回 album_stats 权威累计值(无行默认 0;计数由 /visits
|
|
|
|
|
|
端点维护,技术实施方案 §7.1)。
|
2026-09-20 18:32:34 +08:00
|
|
|
|
downloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
|
|
|
|
|
浏览图下载开关(P4a Task 4 / A18):false 时观众端不出现下载入口,
|
|
|
|
|
|
download 端点 browse/original 均 403 DOWNLOAD_DISABLED。
|
|
|
|
|
|
originalDownloadEnabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
|
|
|
|
|
原图下载开关(更高级:需与 downloadEnabled 同时开启才允许
|
|
|
|
|
|
variant=original;单独开启不生效——两级级联语义)。
|
2026-09-17 17:31:11 +08:00
|
|
|
|
|
|
|
|
|
|
PublicPhoto:
|
|
|
|
|
|
type: object
|
2026-09-17 18:06:54 +08:00
|
|
|
|
description: 公开照片条目(仅 published 照片,处理完成即有宽高;URL 为短期签名,需在过期前刷新)。
|
|
|
|
|
|
required: [photoId, width, height, thumb, browse, likeCount, publishedAt]
|
2026-09-17 17:31:11 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 照片 ID。
|
|
|
|
|
|
width:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 浏览图宽度(像素);用于列表占位,减少加载跳动。
|
|
|
|
|
|
height:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 浏览图高度(像素)。
|
|
|
|
|
|
thumb:
|
|
|
|
|
|
$ref: '#/components/schemas/SignedUrl'
|
|
|
|
|
|
browse:
|
|
|
|
|
|
$ref: '#/components/schemas/SignedUrl'
|
|
|
|
|
|
likeCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 累计点赞数。
|
|
|
|
|
|
publishedAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 发布时间(列表排序依据)。
|
|
|
|
|
|
|
|
|
|
|
|
PublicPhotoDetail:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/PublicPhoto'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [categoryId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
categoryId:
|
|
|
|
|
|
type: [string, 'null']
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: 所属分类 ID;未分类为 null。
|
|
|
|
|
|
|
|
|
|
|
|
PublicPhotoList:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/CursorPageMeta'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [items]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/PublicPhoto'
|
2026-09-18 13:34:35 +08:00
|
|
|
|
|
|
|
|
|
|
# ── 互动(观众端,ov 域) ──
|
|
|
|
|
|
|
2026-09-20 15:56:38 +08:00
|
|
|
|
DownloadVariant:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: |
|
|
|
|
|
|
下载版本(P4a A18):browse=当前生效浏览图(水印版);
|
|
|
|
|
|
original=原图(需 originalDownloadEnabled 更高级开关)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- browse
|
|
|
|
|
|
- original
|
|
|
|
|
|
|
|
|
|
|
|
PublicPhotoDownload:
|
|
|
|
|
|
allOf:
|
|
|
|
|
|
- $ref: '#/components/schemas/SignedUrl'
|
|
|
|
|
|
- type: object
|
|
|
|
|
|
required: [variant]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
variant:
|
|
|
|
|
|
$ref: '#/components/schemas/DownloadVariant'
|
|
|
|
|
|
|
2026-09-18 13:34:35 +08:00
|
|
|
|
LikeBatchRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
点赞批次上报请求。sessionId 为客户端生成的会话随机标识(会话期间复用);
|
|
|
|
|
|
batchId 为批次幂等键,同一批的失败重试必须复用,跨批次不得复用。
|
|
|
|
|
|
required: [sessionId, batchId, delta]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
sessionId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
description: 会话标识(客户端随机生成,会话期间复用)。
|
|
|
|
|
|
batchId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 64
|
|
|
|
|
|
description: 批次幂等键;同批重试复用,重复提交不加计。
|
|
|
|
|
|
delta:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 20
|
|
|
|
|
|
description: 本批新增点赞数(客户端短窗合并后的累计点击数)。
|
|
|
|
|
|
|
|
|
|
|
|
LikeBatchResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
点赞批次处理结果。total 恒为服务端权威累计值;batchAccepted 区分
|
|
|
|
|
|
本批是否被计入(幂等重复=true;窗口外过期批次=false 且不加计)。
|
|
|
|
|
|
required: [total, countVersion, batchAccepted]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
total:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 照片权威累计点赞数(客户端据此校准乐观计数)。
|
|
|
|
|
|
countVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 计数版本(单调递增,实时消息与校准的乱序判别依据)。
|
|
|
|
|
|
batchAccepted:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
|
|
|
|
|
本批是否被计入:true=新批次或幂等重放已确认批次;
|
|
|
|
|
|
false=窗口外过期批次(拒绝重放,返回权威 total)。
|
|
|
|
|
|
|
|
|
|
|
|
VisitReportRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
浏览上报请求。visitorId 跨标签页共享(同一访客);requestId 为本次
|
|
|
|
|
|
访次的上报幂等键(建议 UUID),counted 确认前持久复用。
|
|
|
|
|
|
required: [visitorId, requestId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
visitorId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 8
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 访客标识(客户端持久化并在标签页间共享)。
|
|
|
|
|
|
requestId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 8
|
|
|
|
|
|
maxLength: 128
|
|
|
|
|
|
description: 上报幂等键;重复提交不重复计数。
|
|
|
|
|
|
|
|
|
|
|
|
VisitReportResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 浏览上报结果。viewCount 恒为相册权威累计浏览数。
|
|
|
|
|
|
required: [viewCount, counted]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
viewCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 相册权威累计浏览数。
|
|
|
|
|
|
counted:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
readOnly: true
|
|
|
|
|
|
description: |
|
2026-09-18 18:14:01 +08:00
|
|
|
|
本次是否计入:true=新访次,或幂等重放已确认计入的 requestId
|
|
|
|
|
|
(回显原结局);false=去重窗口内重复或过期 requestId 重放
|
|
|
|
|
|
(均不重复计数)。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
|
|
|
|
|
|
# ── 内部同步 ──
|
|
|
|
|
|
|
|
|
|
|
|
SyncEntityType:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 同步实体类型(slot-state 为预留给后续阶段)。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- album
|
|
|
|
|
|
- category
|
|
|
|
|
|
- photo
|
|
|
|
|
|
- asset
|
|
|
|
|
|
- slot-state
|
|
|
|
|
|
|
|
|
|
|
|
SyncPriority:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: |
|
|
|
|
|
|
推送优先级:high 为相册下线、照片隐藏/删除等需即时生效的事件
|
|
|
|
|
|
(发送器即发,不等批间隔);normal 走常规批量推送。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- normal
|
|
|
|
|
|
- high
|
|
|
|
|
|
|
|
|
|
|
|
SyncEvent:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
cn→ov 内容同步事件(线格式)。与 cn outbox 事件(src/events.ts)
|
|
|
|
|
|
一一对应:eventId 幂等、entityVersion 单调、tombstone 墓碑优先。
|
|
|
|
|
|
payload 为实体类型相关载荷(album.updated 携带 translations/开关/
|
|
|
|
|
|
banner 对象键,photo.* 携带对象键与宽高等展示字段)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- eventId
|
|
|
|
|
|
- schemaVersion
|
|
|
|
|
|
- entityType
|
|
|
|
|
|
- entityId
|
|
|
|
|
|
- albumId
|
|
|
|
|
|
- entityVersion
|
|
|
|
|
|
- priority
|
|
|
|
|
|
- payload
|
|
|
|
|
|
properties:
|
|
|
|
|
|
eventId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 事件 ID(全局唯一,接收方幂等键)。
|
|
|
|
|
|
schemaVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 载荷 schema 版本;当前为 1。
|
|
|
|
|
|
entityType:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncEntityType'
|
|
|
|
|
|
entityId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 实体 ID(albumId/categoryId/photoId/assetId 等)。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 归属相册 ID(album 实体时与 entityId 相同)。
|
|
|
|
|
|
entityVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 实体版本(单调递增;接收方仅应用更高版本)。
|
|
|
|
|
|
tombstone:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
default: false
|
|
|
|
|
|
description: 墓碑标记:true 表示实体删除,副本删除且不被旧事件复活。
|
|
|
|
|
|
priority:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncPriority'
|
|
|
|
|
|
payload:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
additionalProperties: true
|
|
|
|
|
|
description: 实体类型相关载荷;结构由发送方按 schemaVersion 约定。
|
|
|
|
|
|
|
|
|
|
|
|
ContentBatchRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 内容事件批量推送请求体。
|
|
|
|
|
|
required: [batch]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
batch:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
maxItems: 100
|
|
|
|
|
|
description: 事件批次(单批上限对齐 SYNC_BATCH_SIZE,默认 100)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncEvent'
|
|
|
|
|
|
|
|
|
|
|
|
ContentBatchResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 批量推送受理结果。
|
|
|
|
|
|
required: [acceptedEventIds, applied]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
acceptedEventIds:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 本批受理的事件 ID(含此前已应用的同 eventId 幂等重复)。
|
|
|
|
|
|
items:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
applied:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
description: 本批实际应用(新版本生效)的条数。
|
|
|
|
|
|
|
|
|
|
|
|
SyncStatKind:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 统计快照种类。
|
|
|
|
|
|
enum:
|
|
|
|
|
|
- likes
|
|
|
|
|
|
- views
|
|
|
|
|
|
|
|
|
|
|
|
StatSnapshot:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
ov→cn 统计快照:权威累计值的版本化替换单元(cn 侧仅更高 statVersion
|
|
|
|
|
|
替换副本列,绝不相加)。
|
|
|
|
|
|
required: [albumId, kind, total, statVersion, source, confirmedAt]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
photoId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 照片 ID;kind=likes 时必填,kind=views 无此字段。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 归属相册 ID。
|
|
|
|
|
|
kind:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncStatKind'
|
|
|
|
|
|
total:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 权威累计值(点赞数或浏览数)。
|
|
|
|
|
|
statVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
description: 统计版本(单调递增;接收方幂等与替换依据)。
|
|
|
|
|
|
source:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 快照来源标识(如 ov)。
|
|
|
|
|
|
confirmedAt:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
format: date-time
|
|
|
|
|
|
description: 快照确认时间。
|
|
|
|
|
|
|
|
|
|
|
|
StatSnapshotRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 统计快照回传请求体。
|
|
|
|
|
|
required: [snapshots]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
snapshots:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
minItems: 1
|
|
|
|
|
|
description: 增量快照批次。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/StatSnapshot'
|
|
|
|
|
|
|
|
|
|
|
|
StatSnapshotResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 快照回传受理结果。
|
|
|
|
|
|
required: [accepted]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
accepted:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
description: 接受(应用或幂等确认)的快照条数;旧版本被忽略的不计。
|
|
|
|
|
|
|
|
|
|
|
|
ReconcileRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 对账拉取请求:某实体类型在 sinceVersion 之后的事件清单。
|
|
|
|
|
|
required: [entityType, sinceVersion, limit]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
entityType:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncEntityType'
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 可选:限定单相册;缺省为该实体类型全部。
|
|
|
|
|
|
sinceVersion:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 起始版本(exclusive;0 表示从头拉取,配合 bootstrap)。
|
|
|
|
|
|
limit:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 1
|
|
|
|
|
|
maximum: 1000
|
|
|
|
|
|
default: 100
|
|
|
|
|
|
description: 本批拉取上限(分批重放,对齐 SYNC_BATCH_SIZE)。
|
|
|
|
|
|
|
|
|
|
|
|
ReconcileResponse:
|
|
|
|
|
|
type: object
|
2026-09-18 16:18:31 +08:00
|
|
|
|
description: |
|
|
|
|
|
|
对账结果:按 entityVersion 升序的**当前状态事件**(可直接重放的完整
|
|
|
|
|
|
SyncEvent,非仅版本清单——P2 Task 4 设计决策:重放走既有
|
|
|
|
|
|
content-batches 管道,无需第二条拉取通道;sinceVersion 之后无实体时为
|
|
|
|
|
|
空数组)。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
required: [events]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
events:
|
|
|
|
|
|
type: array
|
2026-09-18 16:18:31 +08:00
|
|
|
|
description: 当前状态事件(升序);请求方按序经 content-batches 重放。
|
2026-09-18 13:34:35 +08:00
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/SyncEvent'
|
|
|
|
|
|
|
|
|
|
|
|
BootstrapRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 全量快照引导请求。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 指定相册;缺省为全部相册。
|
|
|
|
|
|
|
|
|
|
|
|
BootstrapResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 全量快照规模与水位;事件本体经 reconcile 通道分批拉取。
|
|
|
|
|
|
required: [eventCount, watermark]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
eventCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 快照事件总数(供拉取分批与完成校验)。
|
|
|
|
|
|
watermark:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
format: int64
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 快照水位:后续增量对账的 sinceVersion 起点。
|
2026-09-18 16:18:31 +08:00
|
|
|
|
|
|
|
|
|
|
DigestRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 对账摘要请求(P2 Task 4)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 指定相册;缺省为全部相册。
|
|
|
|
|
|
|
|
|
|
|
|
AlbumDigest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: |
|
|
|
|
|
|
单相册权威计数摘要。ov 侧比对口径:albums_ov.categories 元素数应等于
|
|
|
|
|
|
categoryCount;photos_ov 行数落在 [publishedPhotoCount, photoCount]
|
|
|
|
|
|
区间内即视为一致(hidden/deleted 照片若从未以 published 态同步过,ov
|
|
|
|
|
|
合法地无行——缺席即撤下语义);相册行缺失即不一致。assetCount 供观测
|
|
|
|
|
|
(ov 无 asset 副本行,不参与比对)。
|
|
|
|
|
|
required:
|
|
|
|
|
|
- albumId
|
|
|
|
|
|
- categoryCount
|
|
|
|
|
|
- publishedPhotoCount
|
|
|
|
|
|
- photoCount
|
|
|
|
|
|
- assetCount
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 相册 ID。
|
|
|
|
|
|
categoryCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 当前分类数(cn 权威行数)。
|
|
|
|
|
|
publishedPhotoCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 可见(published)照片数——ov 必须持有的副本行数下界。
|
|
|
|
|
|
photoCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: published+hidden+deleted 照片总数——ov 副本行数上界。
|
|
|
|
|
|
assetCount:
|
|
|
|
|
|
type: integer
|
|
|
|
|
|
minimum: 0
|
|
|
|
|
|
description: 生效(effective)资产数(观测用;ov 无 asset 副本行)。
|
|
|
|
|
|
|
|
|
|
|
|
DigestResponse:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 每相册计数摘要(albumId 升序)。
|
|
|
|
|
|
required: [albums]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albums:
|
|
|
|
|
|
type: array
|
|
|
|
|
|
description: 相册摘要清单;空库为空数组。
|
|
|
|
|
|
items:
|
|
|
|
|
|
$ref: '#/components/schemas/AlbumDigest'
|
2026-09-18 16:19:02 +08:00
|
|
|
|
|
|
|
|
|
|
EmergencyDisableRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 紧急停用请求(albumToken 与 albumId 恰好提供其一)。
|
|
|
|
|
|
required: [reason]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumToken:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 公开令牌定位相册(与 albumId 二选一)。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 相册 ID 定位(与 albumToken 二选一)。
|
|
|
|
|
|
reason:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
minLength: 1
|
|
|
|
|
|
maxLength: 500
|
|
|
|
|
|
description: 停用原因(审计留痕)。
|
|
|
|
|
|
|
|
|
|
|
|
EmergencyEnableRequest:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 解除停用请求(albumToken 与 albumId 恰好提供其一)。
|
|
|
|
|
|
properties:
|
|
|
|
|
|
albumToken:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 公开令牌定位相册(与 albumId 二选一)。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 相册 ID 定位(与 albumToken 二选一)。
|
|
|
|
|
|
|
|
|
|
|
|
EmergencyStatus:
|
|
|
|
|
|
type: object
|
|
|
|
|
|
description: 紧急停用通道操作结果。
|
|
|
|
|
|
required: [disabled, albumId]
|
|
|
|
|
|
properties:
|
|
|
|
|
|
disabled:
|
|
|
|
|
|
type: boolean
|
|
|
|
|
|
description: 操作后的停用状态(disable 恒 true / enable 恒 false)。
|
|
|
|
|
|
albumId:
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: 相册 ID。
|