179 lines
5.6 KiB
TypeScript
179 lines
5.6 KiB
TypeScript
import { apiDelete, apiGet, apiPost, apiPut } from './http'
|
|
|
|
export const login = (phone: string, code: string) =>
|
|
apiPost<{ sessionToken: string; user: Record<string, unknown>; store: Record<string, unknown> | null }>(
|
|
'/user/login',
|
|
{ phone, code },
|
|
)
|
|
|
|
export const sendSms = (phone: string) => apiPost('/sms/send', { phone })
|
|
|
|
export const getUserInfo = () => apiGet<Record<string, unknown>>('/user/info')
|
|
|
|
export const getAppointmentList = (params: Record<string, unknown> = {}) =>
|
|
apiGet('/appointment/list', params)
|
|
|
|
export const getAppointmentDetail = (id: number) => apiGet('/appointment/detail', { id })
|
|
|
|
export const startAppointment = (appointmentId: number) =>
|
|
apiPost('/appointment/start', { appointmentId })
|
|
|
|
export const cancelAppointment = (id: number) =>
|
|
apiPut(`/appointment/status?id=${id}&status=cancel`)
|
|
|
|
export const getReportList = (params: Record<string, unknown> = {}) =>
|
|
apiGet('/report/list', params)
|
|
|
|
/** 员工在真实发送完成后显式确认;复制链接或打开 H5 不会自动确认。 */
|
|
export const confirmReportSent = (reportId: number, channel: 'wechat' | 'qr' | 'other') =>
|
|
apiPost('/report/confirm-sent', { reportId, channel })
|
|
|
|
export const startHighlight = (reportId: number) =>
|
|
apiPost('/report/highlight/start', { reportId })
|
|
|
|
export const getLeads = (status = 'pending') =>
|
|
apiGet('/report/leads', { status })
|
|
|
|
export const getServiceCustomers = (params: Record<string, unknown> = {}) =>
|
|
apiGet('/admin/service-customers', params)
|
|
|
|
export type CustomerTimelineItem = {
|
|
eventId: string
|
|
eventType: string
|
|
occurredAt?: string | null
|
|
title: string
|
|
description: string
|
|
source?: string
|
|
actorRole?: string | null
|
|
actorName?: string | null
|
|
appointment?: {
|
|
id: number
|
|
appointmentTime?: string | null
|
|
endTime?: string | null
|
|
petName?: string | null
|
|
petType?: string | null
|
|
serviceType?: string | null
|
|
durationMinutes?: number
|
|
currentStatus?: string | null
|
|
}
|
|
report?: {
|
|
id: number
|
|
appointmentId?: number | null
|
|
petName?: string | null
|
|
serviceType?: string | null
|
|
sendStatus?: 'unknown' | 'unsent' | 'sent' | null
|
|
sentAt?: string | null
|
|
sendChannel?: 'wechat' | 'qr' | 'other' | null
|
|
}
|
|
lead?: {
|
|
id: number
|
|
reportId?: number | null
|
|
petName?: string | null
|
|
serviceType?: string | null
|
|
remindDate?: string | null
|
|
remindStatus?: string | null
|
|
}
|
|
}
|
|
|
|
export type CustomerTimelineResponse = {
|
|
customer: {
|
|
storeCustomerId: number
|
|
displayName?: string | null
|
|
phoneMasked?: string | null
|
|
originSource?: string | null
|
|
firstContactAt?: string | null
|
|
lastContactAt?: string | null
|
|
}
|
|
total: number
|
|
page: number
|
|
pageSize: number
|
|
hasMore: boolean
|
|
list: CustomerTimelineItem[]
|
|
}
|
|
|
|
export const getServiceCustomerTimeline = (storeCustomerId: number, page = 1, pageSize = 20) =>
|
|
apiGet<CustomerTimelineResponse>('/admin/service-customers/timeline', { storeCustomerId, page, pageSize })
|
|
|
|
export const getWorkbenchReportFunnel = (date?: string) =>
|
|
apiGet('/admin/workbench/report-funnel', date ? { date } : {})
|
|
|
|
export const getWorkbenchActions = () =>
|
|
apiGet('/admin/workbench/actions')
|
|
|
|
export const getAdminStore = () => apiGet<Record<string, unknown>>('/admin/store')
|
|
|
|
export const updateStore = (data: Record<string, unknown>) => apiPut('/store/update', data)
|
|
|
|
export const getScheduleDay = (date: string) =>
|
|
apiGet('/schedule/day', { date })
|
|
|
|
export const createScheduleBlock = (data: { slotStart: string; durationMinutes: number; blockType: string; note?: string }) =>
|
|
apiPost('/schedule/block', data)
|
|
|
|
export const deleteScheduleBlock = (id: number) =>
|
|
apiDelete('/schedule/block', { id })
|
|
|
|
export const getStore = (id: number) => apiGet('/store/get', { id })
|
|
|
|
export const getStaffList = () => apiGet('/user/staff-list')
|
|
|
|
export type StaffInvitation = {
|
|
invitationId: string
|
|
storeName: string
|
|
invitedName: string
|
|
maskedPhone: string
|
|
status: 'pending' | 'accepted' | 'revoked' | 'expired'
|
|
expiresAt: string
|
|
acceptedAt?: string | null
|
|
createdAt: string
|
|
inviteToken?: string
|
|
invitePath?: string
|
|
}
|
|
|
|
export type OnboardingStep = {
|
|
id: 'profile' | 'booking' | 'services' | 'team'
|
|
title: string
|
|
required: boolean
|
|
completed: boolean
|
|
hint: string
|
|
}
|
|
|
|
export type OnboardingStatus = {
|
|
status: 'unknown' | 'in_progress' | 'completed'
|
|
completedAt?: string | null
|
|
readyToComplete: boolean
|
|
missingRequiredSteps: string[]
|
|
completedStepCount: number
|
|
totalStepCount: number
|
|
staffCount: number
|
|
steps: OnboardingStep[]
|
|
alreadyCompleted?: boolean
|
|
}
|
|
|
|
export const getOnboardingStatus = () => apiGet<OnboardingStatus>('/admin/onboarding')
|
|
|
|
export const completeOnboarding = () => apiPost<OnboardingStatus>('/admin/onboarding/complete')
|
|
|
|
export const getStaffInvitations = () => apiGet<StaffInvitation[]>('/admin/staff-invitations')
|
|
|
|
export const createStaffInvitation = (data: { name: string; phone: string; validDays: number }) =>
|
|
apiPost<StaffInvitation>('/admin/staff-invitations', data)
|
|
|
|
export const revokeStaffInvitation = (invitationId: string) =>
|
|
apiDelete<StaffInvitation>('/admin/staff-invitations', { invitationId })
|
|
|
|
export const deleteStaff = (staffId: number) =>
|
|
apiDelete('/user/staff', { staffId })
|
|
|
|
export const getServiceTypeList = (storeId?: number | null) =>
|
|
apiGet('/service-type/list', storeId != null ? { storeId } : {})
|
|
|
|
export const createServiceType = (name: string, durationMinutes: number) =>
|
|
apiPost('/service-type/create', { name, durationMinutes })
|
|
|
|
export const updateServiceType = (id: number, name: string, durationMinutes: number) =>
|
|
apiPut('/service-type/update', { id, name, durationMinutes })
|
|
|
|
export const deleteServiceType = (id: number) =>
|
|
apiDelete('/service-type/delete', { id })
|