diff --git a/src/api/index.ts b/src/api/index.ts index b5a49a6..6aae075 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,6 +34,69 @@ export const startHighlight = (reportId: number) => export const getLeads = (status = 'pending') => apiGet('/report/leads', { status }) +export type FollowUpTaskView = { + taskId: string + storeCustomerId: number + sourceLeadId: number + reportId?: number | null + displayName?: string | null + phone?: string | null + phoneMasked?: string | null + petName?: string | null + serviceType?: string | null + status: 'pending' | 'in_progress' | 'completed' | 'canceled' + outcome?: 'rebooked' | 'not_interested' | 'invalid_contact' | 'unsubscribed' | null + dueDate: string + attemptCount: number + lastAttemptOutcome?: 'no_answer' | 'follow_later' | null + assignedUserId?: number | null + assignedUserName?: string | null + assignedToCurrentUser: boolean + lastContactedAt?: string | null + closedAt?: string | null + rebookedAppointmentId?: number | null + overdue: boolean + createTime: string + updateTime: string +} + +export type FollowUpTaskPage = { + total: number + page: number + pageSize: number + hasMore: boolean + list: FollowUpTaskView[] +} + +export const getFollowUpTasks = (params: Record = {}) => + apiGet('/admin/follow-up-tasks', params) + +export const startFollowUpTask = (taskId: string) => + apiPost(`/admin/follow-up-tasks/${encodeURIComponent(taskId)}/start`) + +export const rescheduleFollowUpTask = ( + taskId: string, + dueDate: string, + reason: 'no_answer' | 'follow_later', +) => apiPost( + `/admin/follow-up-tasks/${encodeURIComponent(taskId)}/reschedule`, + { dueDate, reason }, +) + +export const closeFollowUpTask = ( + taskId: string, + outcome: 'not_interested' | 'invalid_contact', +) => apiPost( + `/admin/follow-up-tasks/${encodeURIComponent(taskId)}/close`, + { outcome }, +) + +export const createAppointment = (data: Record) => + apiPost('/appointment/create', data) + +export const getAppointmentAvailableSlots = (storeId: number, date: string, serviceType: string) => + apiGet('/appointment/available-slots', { storeId, date, serviceType }) + export const getServiceCustomers = (params: Record = {}) => apiGet('/admin/service-customers', params) @@ -73,6 +136,14 @@ export type CustomerTimelineItem = { remindDate?: string | null remindStatus?: string | null } + followUpTask?: { + taskId: string + status: 'pending' | 'in_progress' | 'completed' | 'canceled' + outcome?: 'rebooked' | 'not_interested' | 'invalid_contact' | 'unsubscribed' | null + dueDate?: string | null + attemptCount?: number + rebookedAppointmentId?: number | null + } } export type CustomerTimelineResponse = { diff --git a/src/views/CustomersView.vue b/src/views/CustomersView.vue index 355bd68..8ff21ac 100644 --- a/src/views/CustomersView.vue +++ b/src/views/CustomersView.vue @@ -95,11 +95,15 @@ {{ formatLeadStatus(item.lead.remindStatus) }} + + {{ followUpStatusLabel(item.followUpTask.status) }} + -
+
查看预约 查看报告 进入回访池 + 查看回访任务
@@ -276,6 +280,14 @@ function reportSendLabel(value?: string | null) { return '报告' } +function followUpStatusLabel(value?: string | null) { + if (value === 'pending') return '回访待领取' + if (value === 'in_progress') return '回访处理中' + if (value === 'completed') return '回访已完成' + if (value === 'canceled') return '回访已取消' + return '回访任务' +} + function roleLabel(value?: string | null) { if (value === 'boss') return '老板' if (value === 'staff') return '员工' diff --git a/src/views/LeadsView.vue b/src/views/LeadsView.vue index 3396d53..b4f21dc 100644 --- a/src/views/LeadsView.vue +++ b/src/views/LeadsView.vue @@ -1,88 +1,497 @@ + + diff --git a/src/views/WorkbenchView.vue b/src/views/WorkbenchView.vue index ecb2e4a..2a91ad4 100644 --- a/src/views/WorkbenchView.vue +++ b/src/views/WorkbenchView.vue @@ -102,7 +102,7 @@ 服务结果

今天的报告走到哪一步

- 发送已接入真实确认;再次预约仍待归因 + 发送与再次预约均来自真实业务回执
@@ -134,7 +134,7 @@ type WorkbenchMetrics = { } type ActionItem = { - resourceType: 'appointment' | 'report' | 'lead' + resourceType: 'appointment' | 'report' | 'follow_up_task' resourceId: number petName?: string | null serviceType?: string | null @@ -244,7 +244,7 @@ const groupDefinitions: Record