From fd801caa73d0dcf875e1685df561f555f5274516 Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 6 Aug 2026 12:44:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=88=BF=E8=A1=A8=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=8F=90=E7=A4=BA=E5=92=8C=E6=97=A5=E6=9C=9F=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/i18n/locales/en-US.ts | 2 +- client/src/i18n/locales/th-TH.ts | 2 +- client/src/i18n/locales/zh-CN.ts | 2 +- client/src/tests/roomingListView.spec.ts | 1 + .../M010-rooming-list-excel-generation-v1.md | 8 ++++---- .../service/impl/RoomingListExcelRenderer.java | 2 +- ...ationRoomingListGenerationControllerTest.java | 12 ++++++------ ...tionRoomingListGenerationServiceImplTest.java | 16 ++++++++-------- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/src/i18n/locales/en-US.ts b/client/src/i18n/locales/en-US.ts index cdb2eef..1729bb0 100644 --- a/client/src/i18n/locales/en-US.ts +++ b/client/src/i18n/locales/en-US.ts @@ -414,7 +414,7 @@ export default { departure: 'Departure', datePlaceholder: 'yyyy-MM-dd', roomType: 'Room type', - roomTypePlaceholder: 'e.g. DLX / TWN', + roomTypePlaceholder: 'e.g. RM2/RM3', titleColumn: 'Title', rateCode: 'Rate Code', adults: 'Adults', diff --git a/client/src/i18n/locales/th-TH.ts b/client/src/i18n/locales/th-TH.ts index efd5f7b..ea6595f 100644 --- a/client/src/i18n/locales/th-TH.ts +++ b/client/src/i18n/locales/th-TH.ts @@ -414,7 +414,7 @@ export default { departure: 'Departure', datePlaceholder: 'yyyy-MM-dd', roomType: 'Room Type', - roomTypePlaceholder: 'เช่น DLX / TWN', + roomTypePlaceholder: 'เช่น RM2/RM3', titleColumn: 'Title', rateCode: 'Rate Code', adults: 'Adults', diff --git a/client/src/i18n/locales/zh-CN.ts b/client/src/i18n/locales/zh-CN.ts index 011d63a..ebd1972 100644 --- a/client/src/i18n/locales/zh-CN.ts +++ b/client/src/i18n/locales/zh-CN.ts @@ -413,7 +413,7 @@ export default { departure: '离店日期', datePlaceholder: 'yyyy-MM-dd', roomType: '房型', - roomTypePlaceholder: '例如 DLX / TWN', + roomTypePlaceholder: '例如 RM2/RM3', titleColumn: '称谓(Title)', rateCode: '价格代码(Rate Code)', adults: '成人数(Adults)', diff --git a/client/src/tests/roomingListView.spec.ts b/client/src/tests/roomingListView.spec.ts index 7271fa9..fb0b124 100644 --- a/client/src/tests/roomingListView.spec.ts +++ b/client/src/tests/roomingListView.spec.ts @@ -157,6 +157,7 @@ describe('ReservationRoomingListGenerationView', () => { expect(wrapper.find('[data-testid="rooming-list-arrival"]').exists()).toBe(true) expect(wrapper.find('[data-testid="rooming-list-departure"]').exists()).toBe(true) + expect(wrapper.find('[data-testid="rooming-list-room-type"]').attributes('placeholder')).toBe('例如 RM2/RM3') expect(wrapper.find('[data-testid="rooming-list-title"]').exists()).toBe(false) expect(wrapper.find('[data-testid="rooming-list-rate-code"]').exists()).toBe(false) expect(wrapper.find('[data-testid="rooming-list-adults"]').exists()).toBe(false) diff --git a/docs/project/requirements/M010-rooming-list-excel-generation-v1.md b/docs/project/requirements/M010-rooming-list-excel-generation-v1.md index a1ae322..63dcd7d 100644 --- a/docs/project/requirements/M010-rooming-list-excel-generation-v1.md +++ b/docs/project/requirements/M010-rooming-list-excel-generation-v1.md @@ -131,15 +131,15 @@ CP2 起后端应识别来源 Excel 的 `旅游日期` 表头,并从有名单 - 右侧结束日期可以省略年份;省略年份时继承起始日期年份。 - 右侧结束日期可以省略月份;省略月份时继承起始日期月份。 - 支持常见区间分隔符,例如 `-`、`-`、`–`、`—`、`至`、`到`。 -- `Arrival` 使用起始日期,格式化为 `yyyy/MM/dd`。 -- `Departure` 使用结束日期,格式化为 `yyyy/MM/dd`。 +- `Arrival` 使用起始日期,生成目标 Excel 时格式化为 `dd/MM/yyyy`。 +- `Departure` 使用结束日期,生成目标 Excel 时格式化为 `dd/MM/yyyy`。 - 旅游日期属于酒店本地业务日期,不按 UTC 时间点换算。 - 同一来源文件中参与生成的名单行必须解析出同一个旅游日期区间;如果出现多个不同区间,CP2 先返回受控错误,不自动混合生成。 - 如果缺少 `旅游日期` 表头、旅游日期为空、格式无法解析或结束日期不晚于起始日期,返回 `ROOMING_LIST_SOURCE_FILE_INVALID` 或统一受控业务错误,不应生成半成品 Excel。 中文说明: -- 当前样表第 2 行表头中包含 `旅游日期`,第 3 行起数据为 `2026年5月9日-5月14日`,可派生 `Arrival=2026/05/09`、`Departure=2026/05/14`。 +- 当前样表第 2 行表头中包含 `旅游日期`,第 3 行起数据为 `2026年5月9日-5月14日`,可派生目标 Excel 展示值 `Arrival=09/05/2026`、`Departure=14/05/2026`。 - CP2 暂不支持同一个文件中多批次、多旅游日期混合分房;如后续出现该真实场景,需要先设计按批次拆文件或按旅游日期分组生成多个 Sheet / 多个文件。 ### 4.2 第二种来源样式:英文姓 + 英文名 @@ -409,7 +409,7 @@ RESERVATION_ROOMING_LIST_GENERATE 后端测试建议覆盖: - 能识别 `护照全名` 表头。 -- 能识别 `旅游日期` 表头,并把 `2026年5月9日-5月14日` 解析为 `Arrival=2026/05/09`、`Departure=2026/05/14`。 +- 能识别 `旅游日期` 表头,并把 `2026年5月9日-5月14日` 解析为目标 Excel 展示值 `Arrival=09/05/2026`、`Departure=14/05/2026`。 - 能识别第二种来源样式 `英文姓` / `英文名` 表头。 - 第二种来源样式下 `英文姓=FENG`、`英文名=MINNA` 能生成 `Name=FENG`、`First Name=MINNA`。 - 第二种来源样式下领队也进入房表,实际人数以后端读取到的有效名单行数为准。 diff --git a/server/src/main/java/cn/nianxx/thhotel/workflows/reservation/service/impl/RoomingListExcelRenderer.java b/server/src/main/java/cn/nianxx/thhotel/workflows/reservation/service/impl/RoomingListExcelRenderer.java index 21477ee..22a7f05 100644 --- a/server/src/main/java/cn/nianxx/thhotel/workflows/reservation/service/impl/RoomingListExcelRenderer.java +++ b/server/src/main/java/cn/nianxx/thhotel/workflows/reservation/service/impl/RoomingListExcelRenderer.java @@ -22,7 +22,7 @@ import org.springframework.stereotype.Component; public class RoomingListExcelRenderer { private static final DateTimeFormatter TARGET_DATE_FORMATTER = - DateTimeFormatter.ofPattern("yyyy/MM/dd"); + DateTimeFormatter.ofPattern("dd/MM/yyyy"); private static final String[] HEADERS = { "Line", "Name", diff --git a/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/control/ReservationRoomingListGenerationControllerTest.java b/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/control/ReservationRoomingListGenerationControllerTest.java index c2056b8..9c2b4ad 100644 --- a/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/control/ReservationRoomingListGenerationControllerTest.java +++ b/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/control/ReservationRoomingListGenerationControllerTest.java @@ -104,9 +104,9 @@ class ReservationRoomingListGenerationControllerTest { .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 3)) .isEmpty()) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 4)) - .isEqualTo("2026/05/09")) + .isEqualTo("09/05/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 5)) - .isEqualTo("2026/05/14")) + .isEqualTo("14/05/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 9)) .isEqualTo("2")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 10)) @@ -141,9 +141,9 @@ class ReservationRoomingListGenerationControllerTest { .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 2)) .isEqualTo("ONE")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 4)) - .isEqualTo("2026/05/10")) + .isEqualTo("10/05/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 5)) - .isEqualTo("2026/05/16")) + .isEqualTo("16/05/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 9)) .isEqualTo("2")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 13)) @@ -180,9 +180,9 @@ class ReservationRoomingListGenerationControllerTest { .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 2)) .isEqualTo("HAIYUN")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 4)) - .isEqualTo("2026/08/03")) + .isEqualTo("03/08/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 5)) - .isEqualTo("2026/08/08")) + .isEqualTo("08/08/2026")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 9)) .isEqualTo("3")) .andExpect(result -> assertThat(workbookCell(result.getResponse().getContentAsByteArray(), 1, 13)) diff --git a/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/service/impl/ReservationRoomingListGenerationServiceImplTest.java b/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/service/impl/ReservationRoomingListGenerationServiceImplTest.java index c810173..11f2f47 100644 --- a/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/service/impl/ReservationRoomingListGenerationServiceImplTest.java +++ b/server/src/test/java/cn/nianxx/thhotel/workflows/reservation/service/impl/ReservationRoomingListGenerationServiceImplTest.java @@ -61,8 +61,8 @@ class ReservationRoomingListGenerationServiceImplTest { assertThat(cellText(firstRoom.getCell(1))).isEqualTo("LI"); assertThat(cellText(firstRoom.getCell(2))).isEqualTo("CHUNHONG"); assertThat(cellText(firstRoom.getCell(3))).isEmpty(); - assertThat(cellText(firstRoom.getCell(4))).isEqualTo("2026/05/09"); - assertThat(cellText(firstRoom.getCell(5))).isEqualTo("2026/05/14"); + assertThat(cellText(firstRoom.getCell(4))).isEqualTo("09/05/2026"); + assertThat(cellText(firstRoom.getCell(5))).isEqualTo("14/05/2026"); assertThat(cellText(firstRoom.getCell(6))).isEqualTo("UG1"); assertThat(cellText(firstRoom.getCell(7))).isEmpty(); assertThat(cellText(firstRoom.getCell(8))).isEqualTo("1"); @@ -146,8 +146,8 @@ class ReservationRoomingListGenerationServiceImplTest { try (XSSFWorkbook workbook = new XSSFWorkbook(new ByteArrayInputStream(generatedFile.content()))) { Row firstRoom = workbook.getSheetAt(0).getRow(1); - assertThat(cellText(firstRoom.getCell(4))).isEqualTo("2026/05/09"); - assertThat(cellText(firstRoom.getCell(5))).isEqualTo("2026/05/14"); + assertThat(cellText(firstRoom.getCell(4))).isEqualTo("09/05/2026"); + assertThat(cellText(firstRoom.getCell(5))).isEqualTo("14/05/2026"); } } @@ -164,8 +164,8 @@ class ReservationRoomingListGenerationServiceImplTest { Row firstRoom = workbook.getSheetAt(0).getRow(1); assertThat(cellText(firstRoom.getCell(1))).isEqualTo("ALPHA"); assertThat(cellText(firstRoom.getCell(2))).isEqualTo("ONE"); - assertThat(cellText(firstRoom.getCell(4))).isEqualTo("2026/05/10"); - assertThat(cellText(firstRoom.getCell(5))).isEqualTo("2026/05/16"); + assertThat(cellText(firstRoom.getCell(4))).isEqualTo("10/05/2026"); + assertThat(cellText(firstRoom.getCell(5))).isEqualTo("16/05/2026"); assertThat(cellText(firstRoom.getCell(9))).isEqualTo("2"); assertThat(cellText(firstRoom.getCell(13))).isEqualTo("BRAVO TWO"); @@ -192,8 +192,8 @@ class ReservationRoomingListGenerationServiceImplTest { assertThat(cellText(leaderRoom.getCell(0))).isEqualTo("1"); assertThat(cellText(leaderRoom.getCell(1))).isEqualTo("CAI"); assertThat(cellText(leaderRoom.getCell(2))).isEqualTo("HAIYUN"); - assertThat(cellText(leaderRoom.getCell(4))).isEqualTo("2026/08/03"); - assertThat(cellText(leaderRoom.getCell(5))).isEqualTo("2026/08/08"); + assertThat(cellText(leaderRoom.getCell(4))).isEqualTo("03/08/2026"); + assertThat(cellText(leaderRoom.getCell(5))).isEqualTo("08/08/2026"); assertThat(cellText(leaderRoom.getCell(9))).isEqualTo("3"); assertThat(cellText(leaderRoom.getCell(13))).isEqualTo("HUANG YUHENG, MA XIUHAN");