From 8e674a902ed9d9f87fd55b79e98b4e4cdfa468a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Wed, 23 Sep 2026 10:13:08 +0800 Subject: [PATCH] feat(albums): soft-delete albums (admin+owner, hidden & irreversible, both app entries) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 契约 deleteAlbum(DELETE /albums/{albumId} → 204 幂等)+ status enum 'deleted': - 服务端:softDelete(canView 404→canManage 403 防枚举;乐观锁 claim + outbox album.updated priority=high + audit album.delete);列表/详情/更新/ 成员/资产/分类/水印/照片/展示位绑定全部 deleted→404;公开端 cn (status!=='active')与 ov(isAlbumVisibleOv)天然屏蔽;ov 副本经 album.updated 载荷 status 直投自动下线 - Admin:列表表格操作「删除」+ 详情页头「删除相册」(确认含不可恢复说明) - App:操作面板「删除相册」(红字、二次确认、成功退回列表并刷新) - 验证:API 56/56、App 397/397(analyze 0)、admin typecheck/lint/test/build 绿 Co-Authored-By: Claude Code --- apps/admin/src/api/albums.ts | 5 + apps/admin/src/locales/langs/en.json | 8 +- apps/admin/src/locales/langs/zh.json | 8 +- apps/admin/src/views/albums/detail/index.vue | 28 +- apps/admin/src/views/albums/manage/index.vue | 26 +- apps/mobile/lib/core/api_client.dart | 155 +++++----- apps/mobile/lib/l10n/app_en.arb | 129 +++++++- apps/mobile/lib/l10n/app_localizations.dart | 24 ++ .../mobile/lib/l10n/app_localizations_en.dart | 13 + .../mobile/lib/l10n/app_localizations_zh.dart | 12 + apps/mobile/lib/l10n/app_zh.arb | 129 +++++++- apps/mobile/lib/pages/album_detail_page.dart | 281 +++++++++++------- packages/contracts/openapi.yaml | 38 ++- packages/contracts/src/generated/openapi.d.ts | 58 +++- .../migration.sql | 6 + packages/db-ov/prisma/schema.prisma | 4 + services/api/src/albums/albums.controller.ts | 11 + services/api/src/albums/albums.service.ts | 110 ++++++- services/api/src/albums/assets.service.ts | 5 +- services/api/src/albums/categories.service.ts | 6 +- services/api/src/albums/members.service.ts | 5 +- services/api/src/albums/watermark.service.ts | 5 +- services/api/src/embed/embed.service.ts | 5 +- services/api/src/photos/photos.service.ts | 10 +- .../api/src/public-ov/public-ov.service.ts | 8 +- services/api/src/public/public.service.ts | 10 +- .../api/src/sync-inbox/sync-inbox.service.ts | 9 +- services/api/test/embed.e2e-spec.ts | 23 ++ services/api/test/public-ov.e2e-spec.ts | 52 ++++ services/api/test/public.e2e-spec.ts | 29 ++ services/api/test/ui01-contracts.e2e-spec.ts | 41 +++ 31 files changed, 995 insertions(+), 258 deletions(-) create mode 100644 packages/db-ov/prisma/migrations/20260923095000_albums_ov_cover_asset_key/migration.sql diff --git a/apps/admin/src/api/albums.ts b/apps/admin/src/api/albums.ts index 127e06d..e4b83f8 100644 --- a/apps/admin/src/api/albums.ts +++ b/apps/admin/src/api/albums.ts @@ -30,6 +30,11 @@ export function fetchUpdateAlbum(albumId: string, data: Api.Album.UpdatePayload) return request.patch({ url: `/v1/albums/${albumId}`, data }) } +/** 软删除相册(status=deleted:列表/公开端即刻不可见;数据保留,无恢复端点;幂等 204) */ +export function fetchDeleteAlbum(albumId: string) { + return request.del({ url: `/v1/albums/${albumId}` }) +} + /** 初始化资产上传(banner/cover/logo;返回 staging 直传凭证) */ export function fetchInitAlbumAsset(albumId: string, data: Api.Album.AssetInitPayload) { return request.post({ diff --git a/apps/admin/src/locales/langs/en.json b/apps/admin/src/locales/langs/en.json index e96a242..a384c07 100644 --- a/apps/admin/src/locales/langs/en.json +++ b/apps/admin/src/locales/langs/en.json @@ -316,7 +316,10 @@ "viewTable": "Table view", "loadedCount": "{n} albums loaded", "cursorNote": "Sorted by creation time · cursor-based loading", - "emptyFiltered": "No albums match these filters" + "emptyFiltered": "No albums match these filters", + "actionDelete": "Delete", + "deleteConfirm": "Delete album \"{title}\"? It becomes invisible immediately and cannot be restored (data retained; ops-only recovery).", + "deleted": "Album deleted" }, "form": { "createTitle": "New Album", @@ -385,7 +388,8 @@ "fieldOwnerId": "Owner", "subtitle": "Album workspace · Manage the moments that matter", "share": "Share album", - "tabAssets": "Branding assets" + "tabAssets": "Branding assets", + "delete": "Delete album" }, "banner": { "kind": "Asset Kind", diff --git a/apps/admin/src/locales/langs/zh.json b/apps/admin/src/locales/langs/zh.json index a9a6779..743cc2f 100644 --- a/apps/admin/src/locales/langs/zh.json +++ b/apps/admin/src/locales/langs/zh.json @@ -316,7 +316,10 @@ "viewTable": "表格视图", "loadedCount": "已加载 {n} 个相册", "cursorNote": "按创建时间排序 · 游标加载", - "emptyFiltered": "没有符合筛选条件的相册" + "emptyFiltered": "没有符合筛选条件的相册", + "actionDelete": "删除", + "deleteConfirm": "确定删除相册「{title}」?删除后立即不可见且不可恢复(数据保留,仅运维可恢复)。", + "deleted": "相册已删除" }, "form": { "createTitle": "新建相册", @@ -385,7 +388,8 @@ "fieldOwnerId": "负责人", "subtitle": "相册工作区 · 管理活动中的精彩瞬间", "share": "分享相册", - "tabAssets": "品牌资产" + "tabAssets": "品牌资产", + "delete": "删除相册" }, "banner": { "kind": "资产类型", diff --git a/apps/admin/src/views/albums/detail/index.vue b/apps/admin/src/views/albums/detail/index.vue index 7581c76..abc3660 100644 --- a/apps/admin/src/views/albums/detail/index.vue +++ b/apps/admin/src/views/albums/detail/index.vue @@ -39,6 +39,9 @@ > {{ $t('albumsManage.detail.edit') }} + + {{ $t('albumsManage.detail.delete') }} + @@ -104,6 +107,7 @@