diff --git a/apps/admin/e2e/albums-governance.spec.ts b/apps/admin/e2e/albums-governance.spec.ts index 977a9fc..d7729bb 100644 --- a/apps/admin/e2e/albums-governance.spec.ts +++ b/apps/admin/e2e/albums-governance.spec.ts @@ -18,14 +18,17 @@ test.beforeAll(() => { async function createAlbumViaUi(page: Page): Promise { const suffix = Date.now().toString(36) + Math.random().toString(36).slice(2, 6) await page.getByTestId('album-create-btn').click() - await expect(page.getByTestId('album-form-dialog')).toBeVisible() + // UI06:创建改整页表单路由 + await expect(page.getByTestId('album-form-page')).toBeVisible() await page.getByTestId('album-form-title-zh-CN').fill(`E2E治理相册 ${suffix}`) await page.getByRole('tab', { name: '英文' }).click() await page.getByTestId('album-form-title-en').fill(`E2E Gov Album ${suffix}`) await page.getByTestId('album-form-start-at').locator('input').fill('2026-10-01 10:00:00') await page.keyboard.press('Enter') await page.getByTestId('album-form-submit').click() - await expect(page.getByTestId('album-form-dialog')).toBeHidden() + // 保存成功后跳相册详情;返回列表做断言 + await expect(page.getByTestId('album-form-page')).toBeHidden() + await page.goBack() // UI06:列表默认封面卡片网格;表格断言前先切换 await page.getByTestId('album-view-table').click() await expect( @@ -42,7 +45,7 @@ function albumRow(page: Page, suffix: string) { /** 进入详情页,返回 albumId */ async function openAlbumDetail(page: Page, suffix: string): Promise { await albumRow(page, suffix).getByTestId('album-detail-btn').click() - await expect(page.getByTestId('album-detail-card')).toBeVisible() + await expect(page.getByTestId('album-summary-cover')).toBeVisible() const albumId = /\/albums\/detail\/([^/?#]+)/.exec(page.url())?.[1] ?? '' expect(albumId).not.toBe('') return albumId diff --git a/apps/admin/e2e/albums.spec.ts b/apps/admin/e2e/albums.spec.ts index f896b46..a54cdaa 100644 --- a/apps/admin/e2e/albums.spec.ts +++ b/apps/admin/e2e/albums.spec.ts @@ -16,7 +16,8 @@ test.beforeAll(() => { async function createAlbumViaUi(page: Page): Promise { const suffix = Date.now().toString(36) + Math.random().toString(36).slice(2, 6) await page.getByTestId('album-create-btn').click() - await expect(page.getByTestId('album-form-dialog')).toBeVisible() + // UI06:创建改整页表单路由 + await expect(page.getByTestId('album-form-page')).toBeVisible() await page.getByTestId('album-form-title-zh-CN').fill(`E2E相册 ${suffix}`) // 非激活页签的内容被隐藏(v-show):先切到英文页签再填写 await page.getByRole('tab', { name: '英文' }).click() @@ -25,7 +26,9 @@ async function createAlbumViaUi(page: Page): Promise { await page.getByTestId('album-form-start-at').locator('input').fill('2026-10-01 10:00:00') await page.keyboard.press('Enter') await page.getByTestId('album-form-submit').click() - await expect(page.getByTestId('album-form-dialog')).toBeHidden() + // 保存成功后跳相册详情;返回列表做断言 + await expect(page.getByTestId('album-form-page')).toBeHidden() + await page.goBack() // UI06:列表默认封面卡片网格;表格断言前先切换 await page.getByTestId('album-view-table').click() await expect(page.getByTestId('album-list-table').getByText(`E2E相册 ${suffix}`)).toBeVisible() @@ -43,12 +46,16 @@ test('创建相册(zh+en)→ 列表可见 → 关闭上传开关 → 标签 const row = albumRow(page, suffix) await row.getByTestId('album-edit-btn').click() - await expect(page.getByTestId('album-form-dialog')).toBeVisible() + // UI06:编辑改整页表单(资料/访问页签) + await expect(page.getByTestId('album-form-page')).toBeVisible() + await page.getByRole('tab', { name: '访问' }).click() await page.getByTestId('album-form-switch-upload').click() await page.getByTestId('album-form-submit').click() - await expect(page.getByTestId('album-form-dialog')).toBeHidden() + await expect(page.getByTestId('album-form-page')).toBeHidden() + await page.goBack() + await page.getByTestId('album-view-table').click() - await expect(row.getByTestId('album-switch-upload')).toContainText('关') + await expect(albumRow(page, suffix).getByTestId('album-switch-upload')).toContainText('关') }) test('详情:邀请成员 → 建分类 → 传 banner → 照片管理(隐藏)', async ({ page }) => { @@ -57,7 +64,7 @@ test('详情:邀请成员 → 建分类 → 传 banner → 照片管理(隐 // ── 进入详情 ── await albumRow(page, suffix).getByTestId('album-detail-btn').click() - await expect(page.getByTestId('album-detail-card')).toBeVisible() + await expect(page.getByTestId('album-summary-cover')).toBeVisible() const albumId = /\/albums\/detail\/([^/?#]+)/.exec(page.url())?.[1] ?? '' expect(albumId).not.toBe('') @@ -84,6 +91,8 @@ test('详情:邀请成员 → 建分类 → 传 banner → 照片管理(隐 await expect(page.getByTestId('category-list-table').getByText(`E2E分类 ${suffix}`)).toBeVisible() // ── banner:真实小 jpeg 走 file chooser → init/PUT/complete → 预览 ── + // UI06:banner 收进「品牌资产」页签 + await page.getByTestId('album-assets-tab').click() const fileChooserPromise = page.waitForEvent('filechooser') await page.getByTestId('album-banner-pick').click() const fileChooser = await fileChooserPromise diff --git a/apps/admin/src/locales/langs/en.json b/apps/admin/src/locales/langs/en.json index 085d420..d6dca5d 100644 --- a/apps/admin/src/locales/langs/en.json +++ b/apps/admin/src/locales/langs/en.json @@ -240,7 +240,9 @@ "albums": { "title": "Albums", "manage": "Album Management", - "detail": "Album Detail" + "detail": "Album Detail", + "formCreate": "Create album", + "formEdit": "Edit album" }, "group": { "workspace": "Workspace", @@ -345,7 +347,18 @@ "titleRequired": "Title is required", "titleRequiredWithFields": "Title is required when other fields of this locale are filled", "endAtNotAfterStartAt": "End time must be later than start time" - } + }, + "pageSubtitle": "Fill both languages by tab; default locale is required and all languages are preserved on save.", + "basicCard": "Basics", + "switchesCard": "Download switches", + "createSwitchesHint": "Upload & public switches are adjusted after creation via Edit · Access (create contract includes download switches only).", + "tabDetails": "Details", + "tabAccess": "Access", + "accessCard": "Access & download", + "switchUploadDesc": "Staff can upload photos in the app when on", + "switchPublicDesc": "Viewers can browse published photos via link when on", + "switchDownloadDesc": "Allow viewers to download watermarked variants", + "switchOriginalDesc": "Allow original download (use with care)" }, "detail": { "back": "Back to List", @@ -371,7 +384,8 @@ "statsNotSynced": "Not synced yet", "fieldOwnerId": "Owner", "subtitle": "Album workspace · Manage the moments that matter", - "share": "Share album" + "share": "Share album", + "tabAssets": "Branding assets" }, "banner": { "kind": "Asset Kind", diff --git a/apps/admin/src/locales/langs/zh.json b/apps/admin/src/locales/langs/zh.json index d765f0e..6a602c0 100644 --- a/apps/admin/src/locales/langs/zh.json +++ b/apps/admin/src/locales/langs/zh.json @@ -240,7 +240,9 @@ "albums": { "title": "相册管理", "manage": "相册管理", - "detail": "相册详情" + "detail": "相册详情", + "formCreate": "新建相册", + "formEdit": "编辑相册" }, "group": { "workspace": "工作空间", @@ -345,7 +347,18 @@ "titleRequired": "标题必填", "titleRequiredWithFields": "该语言已填写其他字段,标题也必填", "endAtNotAfterStartAt": "结束时间必须晚于开始时间" - } + }, + "pageSubtitle": "双语内容按语言分页填写;默认语言必填,保存时保留全部语言。", + "basicCard": "基础资料", + "switchesCard": "下载开关", + "createSwitchesHint": "上传与公开访问开关在创建后经「编辑 · 访问」调整(创建契约仅含下载开关)。", + "tabDetails": "资料", + "tabAccess": "访问", + "accessCard": "访问与下载", + "switchUploadDesc": "开启后工作人员可在 App 上传照片", + "switchPublicDesc": "开启后观众可通过链接浏览已公开照片", + "switchDownloadDesc": "允许观众下载带水印变体", + "switchOriginalDesc": "允许下载原图(谨慎开启)" }, "detail": { "back": "返回列表", @@ -371,7 +384,8 @@ "statsNotSynced": "尚无回传", "fieldOwnerId": "负责人", "subtitle": "相册工作区 · 管理活动中的精彩瞬间", - "share": "分享相册" + "share": "分享相册", + "tabAssets": "品牌资产" }, "banner": { "kind": "资产类型", diff --git a/apps/admin/src/router/modules/albums.ts b/apps/admin/src/router/modules/albums.ts index 29211b2..1ce297e 100644 --- a/apps/admin/src/router/modules/albums.ts +++ b/apps/admin/src/router/modules/albums.ts @@ -36,6 +36,30 @@ export const albumsRoutes: AppRouteRecord = { keepAlive: false, activePath: '/albums/manage' } + }, + { + path: 'form/create', + name: 'AlbumsFormCreate', + component: '/albums/form', + meta: { + title: 'menus.albums.formCreate', + icon: 'ri:edit-2-line', + isHide: true, + keepAlive: false, + activePath: '/albums/manage' + } + }, + { + path: 'form/:albumId', + name: 'AlbumsFormEdit', + component: '/albums/form', + meta: { + title: 'menus.albums.formEdit', + icon: 'ri:edit-2-line', + isHide: true, + keepAlive: false, + activePath: '/albums/manage' + } } ] } diff --git a/apps/admin/src/views/albums/detail/index.vue b/apps/admin/src/views/albums/detail/index.vue index e008b48..7581c76 100644 --- a/apps/admin/src/views/albums/detail/index.vue +++ b/apps/admin/src/views/albums/detail/index.vue @@ -35,7 +35,7 @@ type="primary" plain data-test="album-detail-edit" - @click="editVisible = true" + @click="router.push({ name: 'AlbumsFormEdit', params: { albumId: albumId } })" > {{ $t('albumsManage.detail.edit') }} @@ -44,11 +44,6 @@ - - -
- -
@@ -88,10 +83,15 @@ + + + + - (null) const loading = ref(false) const error = ref(null) - const editVisible = ref(false) const transferVisible = ref(false) const activeTab = ref('photos') @@ -143,10 +141,6 @@ } } - function onAlbumSaved(saved: Api.Album.Detail) { - album.value = saved - } - /** 交接成功:回包 ownerId 已变更,原位替换相册详情 */ function onTransferred(transferred: Api.Album.Detail) { album.value = transferred diff --git a/apps/admin/src/views/albums/form/index.vue b/apps/admin/src/views/albums/form/index.vue new file mode 100644 index 0000000..853b1d5 --- /dev/null +++ b/apps/admin/src/views/albums/form/index.vue @@ -0,0 +1,466 @@ + + + + + + diff --git a/apps/admin/src/views/albums/manage/AlbumFormDialog.vue b/apps/admin/src/views/albums/manage/AlbumFormDialog.vue deleted file mode 100644 index 6fdafbd..0000000 --- a/apps/admin/src/views/albums/manage/AlbumFormDialog.vue +++ /dev/null @@ -1,294 +0,0 @@ - - - - diff --git a/apps/admin/src/views/albums/manage/index.vue b/apps/admin/src/views/albums/manage/index.vue index 4ed5766..19bc675 100644 --- a/apps/admin/src/views/albums/manage/index.vue +++ b/apps/admin/src/views/albums/manage/index.vue @@ -170,8 +170,6 @@ {{ $t('albumsManage.list.noMore') }} - - @@ -180,7 +178,6 @@ import { useRouter } from 'vue-router' import { useI18n } from 'vue-i18n' import { Search, Menu, Grid } from '@element-plus/icons-vue' - import AlbumFormDialog from './AlbumFormDialog.vue' import AlbumCoverCard from '@/components/business/albums/AlbumCoverCard.vue' import { fetchAlbumList } from '@/api/albums' import { useCursorList } from '@/views/albums/composables/useCursorList' @@ -243,22 +240,13 @@ ] } - // ── 创建 / 编辑 ── - const formVisible = ref(false) - const editing = ref(null) - + // ── 创建 / 编辑(UI06:整页表单路由) ── function openCreate() { - editing.value = null - formVisible.value = true + router.push({ name: 'AlbumsFormCreate' }) } function openEdit(album: Api.Album.Summary) { - editing.value = album - formVisible.value = true - } - - function onSaved() { - loadFirst() + router.push({ name: 'AlbumsFormEdit', params: { albumId: album.id } }) } // ── 跳转 ── diff --git a/docs/designs/ui06-implementation/after-b3b/01-login.png b/docs/designs/ui06-implementation/after-b3b/01-login.png new file mode 100644 index 0000000..6537357 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/01-login.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/02-albums.png b/docs/designs/ui06-implementation/after-b3b/02-albums.png new file mode 100644 index 0000000..3e9b692 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/02-albums.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/03-photos.png b/docs/designs/ui06-implementation/after-b3b/03-photos.png new file mode 100644 index 0000000..b70754b Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/03-photos.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/04-members.png b/docs/designs/ui06-implementation/after-b3b/04-members.png new file mode 100644 index 0000000..448ef9b Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/04-members.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/05-categories.png b/docs/designs/ui06-implementation/after-b3b/05-categories.png new file mode 100644 index 0000000..68769c0 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/05-categories.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/06-watermark.png b/docs/designs/ui06-implementation/after-b3b/06-watermark.png new file mode 100644 index 0000000..f490d7d Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/06-watermark.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/07-share.png b/docs/designs/ui06-implementation/after-b3b/07-share.png new file mode 100644 index 0000000..b3dfdaa Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/07-share.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/08-create.png b/docs/designs/ui06-implementation/after-b3b/08-create.png new file mode 100644 index 0000000..9c03b3e Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/08-create.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/09-edit.png b/docs/designs/ui06-implementation/after-b3b/09-edit.png new file mode 100644 index 0000000..6e0d442 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/09-edit.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/10-users.png b/docs/designs/ui06-implementation/after-b3b/10-users.png new file mode 100644 index 0000000..0c06602 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/10-users.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/11-user-sync.png b/docs/designs/ui06-implementation/after-b3b/11-user-sync.png new file mode 100644 index 0000000..e873096 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/11-user-sync.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/12-usage.png b/docs/designs/ui06-implementation/after-b3b/12-usage.png new file mode 100644 index 0000000..9912a1a Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/12-usage.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/13-embed-slots.png b/docs/designs/ui06-implementation/after-b3b/13-embed-slots.png new file mode 100644 index 0000000..e47a71e Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/13-embed-slots.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/14-embed-editor.png b/docs/designs/ui06-implementation/after-b3b/14-embed-editor.png new file mode 100644 index 0000000..7046d4b Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/14-embed-editor.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/15-branding.png b/docs/designs/ui06-implementation/after-b3b/15-branding.png new file mode 100644 index 0000000..cc24848 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/15-branding.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/16-photo-viewer.png b/docs/designs/ui06-implementation/after-b3b/16-photo-viewer.png new file mode 100644 index 0000000..37d6eba Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/16-photo-viewer.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/17-403.png b/docs/designs/ui06-implementation/after-b3b/17-403.png new file mode 100644 index 0000000..900295a Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/17-403.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/18-404.png b/docs/designs/ui06-implementation/after-b3b/18-404.png new file mode 100644 index 0000000..ab73f15 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/18-404.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/19-500.png b/docs/designs/ui06-implementation/after-b3b/19-500.png new file mode 100644 index 0000000..8631abb Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/19-500.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/20-sync-detail.png b/docs/designs/ui06-implementation/after-b3b/20-sync-detail.png new file mode 100644 index 0000000..2574f17 Binary files /dev/null and b/docs/designs/ui06-implementation/after-b3b/20-sync-detail.png differ diff --git a/docs/designs/ui06-implementation/after-b3b/capture.json b/docs/designs/ui06-implementation/after-b3b/capture.json new file mode 100644 index 0000000..99927c3 --- /dev/null +++ b/docs/designs/ui06-implementation/after-b3b/capture.json @@ -0,0 +1,10 @@ +{ + "date": "2026-09-22T22:54:34.211Z", + "base": "http://219.157.255.213:32005", + "viewport": "1440x1000", + "errors": [], + "notes": [ + "15-branding: before 状态 banner 位于详情卡内,未独立页签", + "16-photo-viewer: before 状态无大图预览,以照片表格代替" + ] +} \ No newline at end of file