适配 M002 V3 前端任务流与同卡复核

This commit is contained in:
andy
2026-07-12 00:33:15 +08:00
parent fd027f124c
commit 155db63028
17 changed files with 1593 additions and 85 deletions

View File

@@ -10,7 +10,7 @@ import ReservationOrderListView from '@/views/reservation/ReservationOrderListVi
import ReservationSourceMessageConversationView from '@/views/reservation/ReservationSourceMessageConversationView.vue'
import ReservationTaskListView from '@/views/reservation/ReservationTaskListView.vue'
import { useAuthStore } from '@/stores/authStore'
import type { SourceMessageConversationResult } from '@/types/reservation'
import type { ReservationTaskListResult, SourceMessageConversationResult } from '@/types/reservation'
vi.mock('@/services/reservationService', async (importOriginal) => {
const actual = await importOriginal<typeof import('@/services/reservationService')>()
@@ -62,7 +62,7 @@ function createTaskListResult(
page_size: 20,
total: 1,
},
) {
): ReservationTaskListResult {
return {
items: [
{
@@ -93,25 +93,29 @@ function createTaskListResult(
}
}
function createSourceMessageOnlyTaskListResult(taskSubtype: 'S000' | 'S999' = 'S000') {
function createSourceMessageOnlyTaskListResult(taskSubtype: 'S10' | 'S99' | 'S000' | 'S999' = 'S10') {
return {
items: [
{
task_id: taskSubtype === 'S000' ? '19990' : '19999',
order_id: taskSubtype === 'S000' ? '29990' : '29999',
task_id: taskSubtype === 'S10' || taskSubtype === 'S000' ? '19990' : '19999',
order_id: taskSubtype === 'S10' || taskSubtype === 'S000' ? '29990' : '29999',
hotel_id: 'HOTEL-TEST',
display_order_key: null,
temporary_order_no: null,
task_type: 'SOURCE_MESSAGE_ONLY',
task_type: 'MESSAGE_NOTIFICATION',
task_subtype: taskSubtype,
result_type: 'source_message_review_notification',
ai_task_type: 'Message Notification',
route_code: taskSubtype,
system_process_category: 'SOURCE_MESSAGE_NOTIFICATION',
task_status: 'COMPLETED',
card_name: 'SOURCE_MESSAGE_ONLY',
card_name: 'Message Notification',
queue_sequence: null,
queue_participation: false,
can_process: false,
readonly_reason_code: 'QUEUE_EXCLUDED',
source_message_id: taskSubtype === 'S000' ? '39990' : '39999',
source_subject: taskSubtype === 'S000' ? 'FYI only' : 'Unclear email',
source_message_id: taskSubtype === 'S10' || taskSubtype === 'S000' ? '39990' : '39999',
source_subject: taskSubtype === 'S10' || taskSubtype === 'S000' ? 'FYI only' : 'Unclear email',
source_sender_summary: 'guest@example.test',
source_received_at: '2026-07-08T03:00:00Z',
external_conversation_id: 'thread-source-only',
@@ -475,39 +479,42 @@ describe('reservation P0 views', () => {
expect(wrapper.text()).not.toContain('NEW_BOOKING / NEW_BOOKING')
})
it('filters source-message-only tasks with S000 and S999 subtypes', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S000'))
it('filters source-message-only tasks with S10 and S99 subtypes', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S10'))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(wrapper.find('select[name="task_type"]').text()).toContain('来源消息只读')
expect(wrapper.find('select[name="task_type"]').text()).toContain('历史 Message Notification')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('纯信息类邮件S10')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('无法形成业务素材包S99')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('纯信息类邮件')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('无法形成业务素材包')
await wrapper.find('select[name="task_type"]').setValue('SOURCE_MESSAGE_ONLY')
await vi.dynamicImportSettled()
await wrapper.find('select[name="task_subtype"]').setValue('S999')
await wrapper.find('select[name="task_subtype"]').setValue('S99')
await vi.dynamicImportSettled()
expect(service.fetchReservationTaskList).toHaveBeenLastCalledWith(
expect.objectContaining({
task_type: 'SOURCE_MESSAGE_ONLY',
task_subtype: 'S999',
task_subtype: 'S99',
page_num: 1,
}),
)
})
it('renders source-message-only task rows without a visible order action', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S000'))
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S10'))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(wrapper.text()).toContain('来源消息只读')
expect(wrapper.text()).toContain('纯信息类邮件')
expect(wrapper.text()).toContain('纯信息类邮件S10')
expect(wrapper.text()).toContain('来源消息通知')
expect(wrapper.text()).toContain('FYI only')
expect(wrapper.text()).toContain('查看任务')
expect(wrapper.text()).toContain('查看邮件会话')
@@ -515,6 +522,31 @@ describe('reservation P0 views', () => {
expect(wrapper.text()).not.toContain('29990')
})
it('does not treat a business task as source-message-only only because subtype is S10', async () => {
const result = createTaskListResult('GRP-S10-BUSINESS', 'Business booking request')
result.items[0] = {
...result.items[0]!,
task_type: 'NEW_BOOKING',
task_subtype: 'S10',
result_type: 'normal_task',
ai_task_type: 'NEW_BOOKING',
route_code: 'S10',
system_process_category: 'BUSINESS_TASK',
card_name: 'New Booking',
}
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(result)
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
const rowText = wrapper.find('tbody').text()
expect(rowText).toContain('GRP-S10-BUSINESS')
expect(rowText).toContain('20001')
expect(rowText).toContain('查看订单')
expect(rowText).not.toContain('来源消息只读')
expect(rowText).not.toContain('不关联可见订单')
})
it('filters and paginates task list with supported backend fields', async () => {
vi.mocked(service.fetchReservationTaskList)
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))