忽略本地报错信息文件
This commit is contained in:
@@ -38,6 +38,8 @@ import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { getCurrentUserId } from '@/utils/store.uts'
|
||||
import {
|
||||
getServiceOrderStatusText,
|
||||
isArrivalPendingStatus,
|
||||
normalizeOrderStatusCode,
|
||||
type ServiceOrderStatus,
|
||||
type ServiceOrderTimelineItemType,
|
||||
type ServiceOrderType
|
||||
@@ -496,11 +498,36 @@ export async function fetchConsumerHomeServiceCases(): Promise<Array<HomeService
|
||||
}
|
||||
|
||||
export async function fetchConsumerHomeServiceCaseDetail(caseId: string): Promise<HomeServiceCaseType | null> {
|
||||
const detail = await getServiceOrderDetail(caseId)
|
||||
if (detail != null) {
|
||||
return mapOrderToCase(detail)
|
||||
console.log('[CONSUMER_SERVICE_TRACE][fetchConsumerHomeServiceCaseDetail][START]', {
|
||||
caseId: caseId
|
||||
})
|
||||
try {
|
||||
const detail = await getServiceOrderDetail(caseId)
|
||||
console.log('[CONSUMER_SERVICE_TRACE][fetchConsumerHomeServiceCaseDetail][RAW]', {
|
||||
result: detail
|
||||
})
|
||||
if (detail != null) {
|
||||
const parsed = mapOrderToCase(detail)
|
||||
console.log('[CONSUMER_SERVICE_TRACE][fetchConsumerHomeServiceCaseDetail][PARSED]', {
|
||||
id: parsed.id,
|
||||
status: parsed.status,
|
||||
statusText: parsed.statusText,
|
||||
checkinTime: parsed.checkinTime,
|
||||
arriveTime: '',
|
||||
evidenceCount: parsed.evidenceCount,
|
||||
timelineCount: parsed.timeline.length
|
||||
})
|
||||
return parsed
|
||||
}
|
||||
return null
|
||||
} catch (e) {
|
||||
console.error('[CONSUMER_SERVICE_TRACE][fetchConsumerHomeServiceCaseDetail][ERROR]', {
|
||||
caseId: caseId,
|
||||
errorMessage: e != null ? String(e) : '',
|
||||
errorStack: ''
|
||||
})
|
||||
throw e
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export async function createHomeServiceApplication(draft: HomeServiceApplicationDraftType): Promise<HomeServiceCaseType | null> {
|
||||
@@ -569,6 +596,7 @@ function getCaseStep(status: ServiceOrderStatus): number {
|
||||
if (status == 'assigned') return 3
|
||||
if (status == 'accepted') return 4
|
||||
if (status == 'departed') return 5
|
||||
if (status == 'ARRIVAL_PENDING') return 6
|
||||
if (status == 'arrived' || status == 'in_service') return 6
|
||||
if (status == 'pending_acceptance') return 7
|
||||
if (status == 'accepted_by_user' || status == 'reviewed' || status == 'settled') return 8
|
||||
@@ -577,7 +605,7 @@ function getCaseStep(status: ServiceOrderStatus): number {
|
||||
}
|
||||
|
||||
function getCaseTone(status: ServiceOrderStatus): string {
|
||||
if (status == 'created' || status == 'assigned' || status == 'pending_acceptance') return 'warning'
|
||||
if (status == 'created' || status == 'assigned' || status == 'pending_acceptance' || status == 'ARRIVAL_PENDING') return 'warning'
|
||||
if (status == 'accepted' || status == 'departed' || status == 'arrived' || status == 'in_service') return 'primary'
|
||||
if (status == 'accepted_by_user' || status == 'reviewed' || status == 'settled') return 'success'
|
||||
if (status == 'exception' || status == 'cancelled' || status == 'rejected') return 'danger'
|
||||
@@ -593,6 +621,7 @@ function getTimelineDescription(log: ServiceOrderTimelineItemType): string {
|
||||
if (log.toStatus == 'accepted') return '服务人员已接单,正在准备上门。'
|
||||
if (log.toStatus == 'departed') return '服务人员已出发,正在前往服务地点。'
|
||||
if (log.toStatus == 'arrived') return '服务人员已到达服务地点。'
|
||||
if (log.toStatus == 'ARRIVAL_PENDING') return '服务人员已提交到达签到,等待消费者确认。'
|
||||
if (log.toStatus == 'in_service') return '服务已开始执行,请留意后续进度。'
|
||||
if (log.toStatus == 'completed') return '服务执行已完成,正在整理结果。'
|
||||
if (log.toStatus == 'pending_acceptance') return '服务记录已提交,等待家属验收。'
|
||||
@@ -604,6 +633,26 @@ function getTimelineDescription(log: ServiceOrderTimelineItemType): string {
|
||||
return '服务过程状态已更新。'
|
||||
}
|
||||
|
||||
function buildArrivalPendingTimelineFallback(order: ServiceOrderType): HomeServiceTimelineItemType | null {
|
||||
if (!order.waitingConsumerConfirm && !isArrivalPendingStatus(order.status)) {
|
||||
return null
|
||||
}
|
||||
for (let i = 0; i < order.logs.length; i++) {
|
||||
if (isArrivalPendingStatus(order.logs[i].toStatus)) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
const timeValue = order.executionRecord != null && order.executionRecord.checkinTime != ''
|
||||
? order.executionRecord.checkinTime
|
||||
: order.arrivedAt
|
||||
return {
|
||||
id: order.id + '-arrival-pending-fallback',
|
||||
title: '等待消费者确认到达',
|
||||
time: timeValue,
|
||||
description: '服务人员已提交到达签到,请确认其是否已到达服务地点'
|
||||
} as HomeServiceTimelineItemType
|
||||
}
|
||||
|
||||
function formatServiceAppointmentText(value: string): string {
|
||||
if (value == '') {
|
||||
return ''
|
||||
@@ -655,6 +704,11 @@ function mapOrderToCase(order: ServiceOrderType): HomeServiceCaseType {
|
||||
const displayStatus = getHomecareOrderDisplayStatus(order)
|
||||
let statusText = displayStatus
|
||||
let statusTone = getCaseTone(order.status)
|
||||
const timeline = mapLogsToTimeline(order.logs)
|
||||
const arrivalPendingFallback = buildArrivalPendingTimelineFallback(order)
|
||||
if (arrivalPendingFallback != null) {
|
||||
timeline.unshift(arrivalPendingFallback)
|
||||
}
|
||||
if (displayStatus == '已超时未支付') {
|
||||
statusTone = 'danger'
|
||||
}
|
||||
@@ -667,6 +721,7 @@ function mapOrderToCase(order: ServiceOrderType): HomeServiceCaseType {
|
||||
status: order.status,
|
||||
statusText: statusText,
|
||||
statusTone: statusTone,
|
||||
waitingConsumerConfirm: order.waitingConsumerConfirm,
|
||||
serviceName: order.serviceName,
|
||||
serviceTime: formatServiceAppointmentText(order.appointmentTime),
|
||||
applicantName: order.contactName,
|
||||
@@ -689,7 +744,7 @@ function mapOrderToCase(order: ServiceOrderType): HomeServiceCaseType {
|
||||
executionSummary: order.executionRecord != null ? (order.executionRecord.summary != '' ? order.executionRecord.summary : order.executionRecord.remark) : '',
|
||||
evidenceCount: order.evidenceFiles.length,
|
||||
serviceAddressSnapshot: null,
|
||||
timeline: mapLogsToTimeline(order.logs)
|
||||
timeline: timeline
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import type { HomeServiceCatalogType, HomeServicePackageType } from '@/types/hom
|
||||
import type { DeliveryServiceRecordType } from '@/types/delivery.uts'
|
||||
import {
|
||||
getServiceOrderStatusText,
|
||||
isArrivalPendingStatus,
|
||||
normalizeOrderStatusCode,
|
||||
normalizeServiceOrderStatus,
|
||||
type ServiceOrderAddressSnapshotType,
|
||||
type ServiceEvidenceFileType,
|
||||
@@ -217,6 +219,7 @@ function shouldBypassEcCareTaskCreate(error: any): boolean {
|
||||
|| hasMissingColumnError(error, 'service_catalog_id')
|
||||
|| hasMissingColumnError(error, 'elder_name')
|
||||
|| hasMissingColumnError(error, 'contact_name')
|
||||
|| hasMissingColumnError(error, 'contact_phone')
|
||||
}
|
||||
|
||||
function readServiceItems(source: any): Array<DeliveryServiceItemType> {
|
||||
@@ -256,33 +259,79 @@ function buildDefaultServiceItems(order: DeliveryOrderType): Array<DeliveryServi
|
||||
names.push('用药情况核对')
|
||||
names.push('随访结论反馈')
|
||||
} else {
|
||||
names.push('上门签到确认')
|
||||
names.push('服务项目执行')
|
||||
names.push('服务过程记录')
|
||||
names.push('完成情况确认')
|
||||
}
|
||||
const result = [] as Array<DeliveryServiceItemType>
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
result.push({
|
||||
id: order.id + '-item-' + String(i + 1),
|
||||
name: names[i],
|
||||
required: true,
|
||||
completed: false,
|
||||
incompleteReason: '',
|
||||
remark: '',
|
||||
updatedAt: ''
|
||||
} as DeliveryServiceItemType)
|
||||
payload.address_snapshot_json = params.address as any
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async function getCurrentStaffId(): Promise<string> {
|
||||
const userId = getCurrentUserId()
|
||||
if (userId == '') {
|
||||
return ''
|
||||
function buildEcCareTaskPayloadWithoutAddress(params: CreateServiceOrderParams, userId: string, requestId: string, taskId: string, taskNo: string, createdAt: string, appointmentTime: string | null): any {
|
||||
return {
|
||||
id: taskId,
|
||||
task_no: taskNo,
|
||||
request_id: requestId,
|
||||
user_id: userId,
|
||||
service_catalog_id: params.service.id,
|
||||
service_name: params.service.name,
|
||||
service_category: params.service.category,
|
||||
service_snapshot_json: buildServiceSnapshot(params),
|
||||
elder_name: params.recipientName,
|
||||
elder_phone: params.recipientPhone,
|
||||
elder_age: params.recipientAge,
|
||||
elder_gender: params.recipientGender,
|
||||
contact_name: params.contactName,
|
||||
contact_phone: params.contactPhone,
|
||||
scheduled_at: appointmentTime,
|
||||
remark: params.remark,
|
||||
status: 'ORDER_CREATED',
|
||||
created_at: createdAt,
|
||||
updated_at: createdAt
|
||||
} as any
|
||||
}
|
||||
|
||||
function parseTimeline(item: any): ServiceOrderTimelineItemType {
|
||||
return {
|
||||
id: readString(item, 'id'),
|
||||
orderId: readString(item, 'order_id'),
|
||||
fromStatus: readString(item, 'from_status'),
|
||||
toStatus: normalizeServiceOrderStatus(readString(item, 'to_status')),
|
||||
operatorId: readString(item, 'operator_id'),
|
||||
operatorRole: readString(item, 'operator_role'),
|
||||
remark: readString(item, 'remark'),
|
||||
createdAt: readString(item, 'created_at')
|
||||
}
|
||||
}
|
||||
|
||||
function parseReview(item: any): ServiceReviewType {
|
||||
return {
|
||||
id: readString(item, 'id'),
|
||||
orderId: readString(item, 'order_id'),
|
||||
userId: readString(item, 'user_id'),
|
||||
rating: readNumber(item, 'rating') == 0 ? 5 : readNumber(item, 'rating'),
|
||||
tags: safeParseArray(safeJsonField(item, 'tags_json')),
|
||||
content: readString(item, 'content'),
|
||||
createdAt: readString(item, 'created_at')
|
||||
}
|
||||
}
|
||||
|
||||
function parseExecutionRecord(item: any): ServiceExecutionRecordType {
|
||||
return {
|
||||
id: readString(item, 'id'),
|
||||
orderId: readString(item, 'order_id'),
|
||||
assignmentId: readString(item, 'assignment_id'),
|
||||
checkinTime: readString(item, 'checkin_time'),
|
||||
checkinLatitude: readNumber(item, 'checkin_latitude'),
|
||||
checkinLongitude: readNumber(item, 'checkin_longitude'),
|
||||
checkinAddress: readString(item, 'checkin_address'),
|
||||
serviceStartedAt: readString(item, 'service_started_at'),
|
||||
serviceFinishedAt: readString(item, 'service_finished_at'),
|
||||
actualDurationMinutes: readNumber(item, 'actual_duration_minutes'),
|
||||
serviceItemsJson: safeJsonField(item, 'service_items_json'),
|
||||
summary: readString(item, 'summary'),
|
||||
remark: readString(item, 'remark'),
|
||||
trackPointsJson: safeJsonField(item, 'track_points_json'),
|
||||
createdAt: readString(item, 'created_at'),
|
||||
updatedAt: readString(item, 'updated_at')
|
||||
}
|
||||
const profile = await getDeliveryProfileByUserId(userId)
|
||||
return profile != null ? profile.id : ''
|
||||
}
|
||||
|
||||
function getCurrentWorkerUserId(): string {
|
||||
@@ -479,6 +528,7 @@ function mapCareTaskToLegacyShape(item: any): any {
|
||||
appointment_time: readFirstString(item, ['scheduled_at', 'appointment_time']),
|
||||
remark: readString(item, 'remark'),
|
||||
status: derivedStatus,
|
||||
waiting_consumer_confirm: waitingConsumerConfirm,
|
||||
current_assignment_id: readFirstString(item, ['assignment_id', 'current_assignment_id']),
|
||||
current_staff_id: readFirstString(item, ['assigned_to', 'current_staff_id']),
|
||||
accepted_at: readString(item, 'accepted_at'),
|
||||
@@ -626,7 +676,7 @@ async function getCareTaskDetail(taskId: string): Promise<ServiceOrderType | nul
|
||||
parsed.dispatchStatus = parsed.currentStaffId != '' ? HOMECARE_DISPATCH_STATUS_ASSIGNED : HOMECARE_DISPATCH_STATUS_PENDING
|
||||
parsed.dispatchErrorCode = ''
|
||||
parsed.dispatchErrorMessage = ''
|
||||
return parsed
|
||||
return applyArrivalPendingState(parsed)
|
||||
}
|
||||
|
||||
async function tryCreateCareTask(params: CreateServiceOrderParams): Promise<ServiceOrderType | null> {
|
||||
@@ -748,7 +798,7 @@ async function getLegacyServiceOrderDetail(orderId: string): Promise<ServiceOrde
|
||||
}
|
||||
}
|
||||
}
|
||||
return parsed
|
||||
return applyArrivalPendingState(parsed)
|
||||
}
|
||||
|
||||
export function buildAddressSnapshot(address: UserAddress, latitude: number, longitude: number): ServiceOrderAddressSnapshotType {
|
||||
@@ -768,6 +818,197 @@ export function buildAddressSnapshot(address: UserAddress, latitude: number, lon
|
||||
}
|
||||
}
|
||||
|
||||
export function getHomecareOrderDisplayStatus(order: ServiceOrderType): string {
|
||||
if (order.paymentStatus == 1 && order.status == 'created' && isHomecarePaymentExpired(order)) {
|
||||
return '已超时未支付'
|
||||
}
|
||||
if (order.paymentStatus == 1 && order.status == 'created') {
|
||||
return '待付款'
|
||||
}
|
||||
if (order.paymentStatus == 2 && order.dispatchStatus == HOMECARE_DISPATCH_STATUS_PENDING) {
|
||||
return '待派单'
|
||||
}
|
||||
if (order.paymentStatus == 2 && order.dispatchStatus == HOMECARE_DISPATCH_STATUS_DISPATCHING) {
|
||||
return '正在派单'
|
||||
}
|
||||
if (order.paymentStatus == 2 && order.dispatchStatus == HOMECARE_DISPATCH_STATUS_FAILED) {
|
||||
return '派单未成功'
|
||||
}
|
||||
if (order.paymentStatus == 2 && order.dispatchStatus == HOMECARE_DISPATCH_STATUS_ASSIGNED) {
|
||||
return '已派单'
|
||||
}
|
||||
return getServiceOrderStatusText(order.status)
|
||||
}
|
||||
|
||||
function isHomecarePaymentExpired(order: ServiceOrderType): boolean {
|
||||
if (order.paymentStatus != 1 || order.status != 'created') {
|
||||
return false
|
||||
}
|
||||
const payExpireAt = order.payExpireAt != null ? order.payExpireAt : ''
|
||||
if (payExpireAt == '') {
|
||||
return false
|
||||
}
|
||||
const expireMs = Date.parse(payExpireAt)
|
||||
if (isNaN(expireMs)) {
|
||||
return false
|
||||
}
|
||||
return expireMs <= Date.now()
|
||||
}
|
||||
|
||||
export async function dispatchPaidHomecareOrder(orderId: string): Promise<HomecareDispatchResult> {
|
||||
if (orderId == null || orderId.trim() == '') {
|
||||
return {
|
||||
success: false,
|
||||
code: 'ORDER_ID_REQUIRED',
|
||||
message: '订单信息异常,请返回后重试',
|
||||
display_type: 'modal',
|
||||
retryable: false
|
||||
}
|
||||
}
|
||||
|
||||
// LEGACY/TODO: rpc_homecare_auto_dispatch 当前只操作 hss_service_orders(旧交易链)。
|
||||
// 对于 ec_care_tasks 新链(UUID 格式订单 ID),不要调用旧 RPC,避免错误回写旧表。
|
||||
if (shouldUseCareTaskPath(orderId)) {
|
||||
return {
|
||||
success: true,
|
||||
code: 'SYNC_IN_PROGRESS',
|
||||
message: '付款成功,服务安排信息正在同步中,请稍后在我的服务中查看。',
|
||||
display_type: 'toast',
|
||||
retryable: false,
|
||||
dispatch_status: HOMECARE_DISPATCH_STATUS_PENDING,
|
||||
order_id: orderId
|
||||
}
|
||||
}
|
||||
|
||||
const { data, error } = await supa.rpc('rpc_homecare_auto_dispatch', {
|
||||
p_order_id: orderId
|
||||
} as any)
|
||||
|
||||
if (error != null) {
|
||||
console.error('[homecare-dispatch] rpc failed:', error)
|
||||
return {
|
||||
success: false,
|
||||
code: 'RPC_EXECUTION_FAILED',
|
||||
message: '派单服务暂时异常,请稍后重试',
|
||||
display_type: 'modal',
|
||||
retryable: true,
|
||||
dispatch_status: 'failed',
|
||||
order_id: orderId
|
||||
}
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return {
|
||||
success: false,
|
||||
code: 'RPC_EMPTY_RESULT',
|
||||
message: '未获取到派单结果,请稍后重试',
|
||||
display_type: 'modal',
|
||||
retryable: true,
|
||||
dispatch_status: 'failed',
|
||||
order_id: orderId
|
||||
}
|
||||
}
|
||||
|
||||
const result = plainObject(data)
|
||||
const successValue = result['success']
|
||||
const isSuccess = successValue === true || successValue === 'true' || (typeof successValue === 'boolean' && successValue)
|
||||
const code = readString(result, 'code')
|
||||
const message = readString(result, 'message')
|
||||
const displayType = readString(result, 'display_type')
|
||||
const retryable = result['retryable'] === true || result['retryable'] === 'true'
|
||||
const dispatchStatus = readString(result, 'dispatch_status')
|
||||
|
||||
if (isSuccess || code == 'DISPATCH_ASSIGNED' || code == 'ALREADY_ASSIGNED' || code == 'ALREADY_ASSIGNED_RECOVERED') {
|
||||
return {
|
||||
success: true,
|
||||
code: code != '' ? code : 'DISPATCH_ASSIGNED',
|
||||
message: message != '' ? message : '系统已为您匹配服务人员',
|
||||
display_type: displayType != '' ? displayType : 'none',
|
||||
retryable: false,
|
||||
dispatch_status: dispatchStatus != '' ? dispatchStatus : 'assigned',
|
||||
order_id: readString(result, 'order_id'),
|
||||
assignment_id: readString(result, 'assignment_id'),
|
||||
staff_id: readString(result, 'staff_id'),
|
||||
station_id: readString(result, 'station_id'),
|
||||
dispatch_distance_km: readNumber(result, 'dispatch_distance_km')
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
code: code != '' ? code : 'DISPATCH_FAILED',
|
||||
message: message != '' ? message : '派单失败,请稍后重试',
|
||||
display_type: displayType != '' ? displayType : 'modal',
|
||||
retryable: retryable,
|
||||
dispatch_status: dispatchStatus != '' ? dispatchStatus : 'failed',
|
||||
order_id: readString(result, 'order_id')
|
||||
}
|
||||
}
|
||||
|
||||
export function showHomecareDispatchFailureModal(orderId: string, result: HomecareDispatchResult, retryCallback: (id: string) => void): void {
|
||||
const code = result.code
|
||||
let title = '操作失败'
|
||||
let allowRetry = false
|
||||
|
||||
if (code == 'ORDER_ID_REQUIRED') {
|
||||
title = '操作失败'
|
||||
allowRetry = false
|
||||
} else if (code == 'UNAUTHENTICATED') {
|
||||
title = '请重新登录'
|
||||
allowRetry = false
|
||||
} else if (code == 'USER_PROFILE_NOT_FOUND') {
|
||||
title = '账户异常'
|
||||
allowRetry = false
|
||||
} else if (code == 'ORDER_NOT_FOUND') {
|
||||
title = '订单异常'
|
||||
allowRetry = false
|
||||
} else if (code == 'ORDER_ACCESS_DENIED') {
|
||||
title = '无权操作'
|
||||
allowRetry = false
|
||||
} else if (code == 'ORDER_NOT_PAID') {
|
||||
title = '暂不能派单'
|
||||
allowRetry = false
|
||||
} else if (code == 'ORDER_STATUS_NOT_DISPATCHABLE') {
|
||||
title = '暂不能派单'
|
||||
allowRetry = false
|
||||
} else if (code == 'NO_ONLINE_STAFF' || code == 'NO_STAFF_IN_SERVICE_STATION' || code == 'NO_QUALIFIED_STAFF' || code == 'NO_NEARBY_STAFF' || code == 'ALL_ELIGIBLE_STAFF_BUSY') {
|
||||
title = '暂未匹配成功'
|
||||
allowRetry = true
|
||||
} else if (code == 'DISPATCH_CONFLICT_RETRY') {
|
||||
title = '请重新尝试'
|
||||
allowRetry = true
|
||||
} else if (code == 'RPC_EXECUTION_FAILED' || code == 'RPC_EMPTY_RESULT') {
|
||||
title = '派单服务异常'
|
||||
allowRetry = true
|
||||
} else {
|
||||
title = '操作失败'
|
||||
allowRetry = result.retryable
|
||||
}
|
||||
|
||||
if (!allowRetry) {
|
||||
uni.showModal({
|
||||
title: title,
|
||||
content: result.message,
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: title,
|
||||
content: result.message,
|
||||
showCancel: true,
|
||||
cancelText: '稍后再试',
|
||||
confirmText: '重新派单',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
retryCallback(orderId)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function createServiceOrder(params: CreateServiceOrderParams): Promise<ServiceOrderType | null> {
|
||||
// 当前下单链路分为两层:
|
||||
// 1) 交易支付层:hss_service_orders(旧表,仍承担套餐价格快照与支付状态)。
|
||||
@@ -797,6 +1038,7 @@ export async function createServiceOrder(params: CreateServiceOrderParams): Prom
|
||||
user_id: userId,
|
||||
service_id: params.service.id,
|
||||
service_name: params.service.name,
|
||||
service_category: params.service.category != '' ? params.service.category : '居家服务',
|
||||
service_snapshot_json: serviceSnapshot,
|
||||
service_package_id: params.packageInfo.id,
|
||||
pricing_snapshot_json: pricingSnapshot,
|
||||
@@ -805,13 +1047,22 @@ export async function createServiceOrder(params: CreateServiceOrderParams): Prom
|
||||
total_amount: payableAmount,
|
||||
service_address_id: normalizeUuidOrNull(params.address.addressId),
|
||||
address_snapshot_json: params.address as any,
|
||||
service_lat: params.address.latitude != null ? params.address.latitude : null,
|
||||
service_lng: params.address.longitude != null ? params.address.longitude : null,
|
||||
recipient_name: params.recipientName,
|
||||
recipient_phone: params.recipientPhone,
|
||||
recipient_age: params.recipientAge,
|
||||
recipient_gender: params.recipientGender,
|
||||
elder_name: params.recipientName,
|
||||
elder_phone: params.recipientPhone,
|
||||
contact_name: params.contactName,
|
||||
contact_phone: params.contactPhone,
|
||||
appointment_time: appointmentTime,
|
||||
scheduled_at: appointmentTime,
|
||||
price: payableAmount,
|
||||
staff_income: payableAmount,
|
||||
duration_minutes: 90,
|
||||
request_id: '',
|
||||
remark: params.remark,
|
||||
status: 'created',
|
||||
payment_status: 1,
|
||||
|
||||
Reference in New Issue
Block a user