From e44b35db2831dd334f76cf74c5f170a0d342d93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Wed, 23 Sep 2026 14:13:58 +0800 Subject: [PATCH] feat(albums): date-only pickers for start/end (create & edit, admin + app) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 管理后台:DatePicker type=datetime → date;提交归一(开始=当天 00:00、 结束=当天 23:59 整天活动语义;契约仍 datetime 仅交互粒度) - App:去掉时间选择步骤(选日期即定;同上归一);表单显示只显 yyyy/M/d - e2e 日期填入改 '2026-10-01'(date 格式);widget 断言日期粒度 - admin 87/87 + build、app 397/397 全绿 Co-Authored-By: Claude Code --- apps/admin/e2e/albums-governance.spec.ts | 2 +- apps/admin/e2e/albums.spec.ts | 2 +- apps/admin/src/views/albums/form/index.vue | 32 ++++++++++++++++--- apps/mobile/lib/pages/album_form_page.dart | 19 +++++------ .../test/pages/album_form_page_test.dart | 4 +-- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/apps/admin/e2e/albums-governance.spec.ts b/apps/admin/e2e/albums-governance.spec.ts index d7729bb..3445d7a 100644 --- a/apps/admin/e2e/albums-governance.spec.ts +++ b/apps/admin/e2e/albums-governance.spec.ts @@ -23,7 +23,7 @@ async function createAlbumViaUi(page: Page): Promise { 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.getByTestId('album-form-start-at').locator('input').fill('2026-10-01') // UI06:日期粒度 await page.keyboard.press('Enter') await page.getByTestId('album-form-submit').click() // 保存成功后跳相册详情;返回列表做断言 diff --git a/apps/admin/e2e/albums.spec.ts b/apps/admin/e2e/albums.spec.ts index a54cdaa..91ae5ba 100644 --- a/apps/admin/e2e/albums.spec.ts +++ b/apps/admin/e2e/albums.spec.ts @@ -23,7 +23,7 @@ async function createAlbumViaUi(page: Page): Promise { await page.getByRole('tab', { name: '英文' }).click() await page.getByTestId('album-form-title-en').fill(`E2E Album ${suffix}`) // ElDatePicker 透传 attr 被 ElTooltip 吞掉:组件里用普通 div 挂 data-test,这里进 div 找 input - await page.getByTestId('album-form-start-at').locator('input').fill('2026-10-01 10:00:00') + await page.getByTestId('album-form-start-at').locator('input').fill('2026-10-01') // UI06:日期粒度 await page.keyboard.press('Enter') await page.getByTestId('album-form-submit').click() // 保存成功后跳相册详情;返回列表做断言 diff --git a/apps/admin/src/views/albums/form/index.vue b/apps/admin/src/views/albums/form/index.vue index 853b1d5..da763d6 100644 --- a/apps/admin/src/views/albums/form/index.vue +++ b/apps/admin/src/views/albums/form/index.vue @@ -58,18 +58,20 @@
+
+ @@ -332,14 +334,34 @@ drafts['zh-CN'], drafts.en ]) as Api.Album.Translation[] - const endAt = form.endAt ? form.endAt.toISOString() : null + // UI06 纯日期选择:开始=当天 00:00、结束=当天 23:59(整天活动语义)。 + const startAtDate = form.startAt! + const startAt = new Date( + startAtDate.getFullYear(), + startAtDate.getMonth(), + startAtDate.getDate(), + 0, + 0, + 0 + ).toISOString() + const endDate = form.endAt + const endAt = endDate + ? new Date( + endDate.getFullYear(), + endDate.getMonth(), + endDate.getDate(), + 23, + 59, + 59 + ).toISOString() + : null let saved: Api.Album.Detail if (albumId.value) { // 编辑:PATCH 全量可编辑字段(开关独立修改;translations 全量替换) saved = await fetchUpdateAlbum(albumId.value, { translations, defaultLocale: form.defaultLocale, - startAt: form.startAt!.toISOString(), + startAt, endAt, timezone: form.timezone.trim() || 'Asia/Shanghai', uploadEnabled: form.uploadEnabled, @@ -352,7 +374,7 @@ saved = await fetchCreateAlbum({ translations, defaultLocale: form.defaultLocale, - startAt: form.startAt!.toISOString(), + startAt, endAt, timezone: form.timezone.trim() || 'Asia/Shanghai', downloadEnabled: form.downloadEnabled, diff --git a/apps/mobile/lib/pages/album_form_page.dart b/apps/mobile/lib/pages/album_form_page.dart index a0fecdf..8d10bd7 100644 --- a/apps/mobile/lib/pages/album_form_page.dart +++ b/apps/mobile/lib/pages/album_form_page.dart @@ -355,17 +355,14 @@ class _AlbumFormPageState extends ConsumerState lastDate: DateTime(2100), ); if (pickedDate == null || !mounted) return; - final pickedTime = await showTimePicker( - context: context, - initialTime: TimeOfDay(hour: wall.hour, minute: wall.minute), - ); - if (pickedTime == null || !mounted) return; + // UI06(用户需求 2026-09-23):只选日期不带时间——开始=当天 00:00, + // 结束=当天 23:59(活动整天语义;契约仍为 datetime,仅交互粒度变化)。 final naive = DateTime( pickedDate.year, pickedDate.month, pickedDate.day, - pickedTime.hour, - pickedTime.minute, + isStart ? 0 : 23, + isStart ? 0 : 59, ); final utc = albumWallClockToUtc(naive, tzName); setState(() { @@ -764,9 +761,13 @@ class _AlbumFormPageState extends ConsumerState final l10n = AppLocalizations.of(context); final theme = Theme.of(context); final value = isStart ? _startAt : _endAt; - final formatted = value == null + // 只显日期(选择粒度为日期;时间由开始/结束日的 00:00/23:59 语义承载)。 + final wallShown = value == null ? null - : formatAlbumDateTime(value, _timezone.text, l10n.localeName); + : (tryToAlbumZone(value, _timezone.text.trim()) ?? value.toUtc()); + final formatted = wallShown == null + ? null + : '${wallShown.year}/${wallShown.month}/${wallShown.day}'; return Padding( padding: const EdgeInsets.only(bottom: 12), child: InkWell( diff --git a/apps/mobile/test/pages/album_form_page_test.dart b/apps/mobile/test/pages/album_form_page_test.dart index d518a43..0150ea2 100644 --- a/apps/mobile/test/pages/album_form_page_test.dart +++ b/apps/mobile/test/pages/album_form_page_test.dart @@ -258,8 +258,8 @@ void main() { ); expect(titleField.controller!.text, '开幕晚宴'); // 时间回显按相册时区。 - expect(find.text('2026/9/18 14:30'), findsOneWidget); - expect(find.text('2026/9/19 18:00'), findsOneWidget); + expect(find.text('2026/9/18'), findsOneWidget); // UI06:日期粒度显示 + expect(find.text('2026/9/19'), findsOneWidget); // UI06:日期粒度显示 // 无任何变更 → 保存禁用(PATCH minProperties 1)。 expect( tester.widget(find.byType(FilledButton)).onPressed,