继续完善居家服务模块
This commit is contained in:
500
services/serviceOrderService.uts
Normal file
500
services/serviceOrderService.uts
Normal file
@@ -0,0 +1,500 @@
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { getCurrentUserId } from '@/utils/store.uts'
|
||||
import { getDeliveryProfileByUserId } from '@/api/delivery.uts'
|
||||
import { getServiceOrderStatusText, normalizeServiceOrderStatus, type ServiceOrderStatus } from '@/types/service-order.uts'
|
||||
import type {
|
||||
DeliveryCheckinPayloadType,
|
||||
DeliveryDashboardType,
|
||||
DeliveryLocationType,
|
||||
DeliveryOrderType,
|
||||
DeliveryServiceRecordType
|
||||
} from '@/types/delivery.uts'
|
||||
|
||||
function nowIso(): string {
|
||||
return new Date().toISOString()
|
||||
}
|
||||
|
||||
function buildId(prefix: string): string {
|
||||
return prefix + '-' + String(Date.now()) + '-' + String(Math.floor(Math.random() * 100000)).padStart(5, '0')
|
||||
}
|
||||
|
||||
async function getCurrentStaffId(): Promise<string> {
|
||||
const userId = getCurrentUserId()
|
||||
if (userId == '') {
|
||||
return ''
|
||||
}
|
||||
const profile = await getDeliveryProfileByUserId(userId)
|
||||
return profile != null ? profile.id : ''
|
||||
}
|
||||
|
||||
async function insertStatusLog(orderId: string, fromStatus: string, toStatus: ServiceOrderStatus, remark: string): Promise<void> {
|
||||
const userId = getCurrentUserId()
|
||||
await supa.from('hss_service_order_status_logs').insert({
|
||||
id: buildId('slog'),
|
||||
order_id: orderId,
|
||||
from_status: fromStatus,
|
||||
to_status: toStatus,
|
||||
operator_id: userId == '' ? null : userId,
|
||||
operator_role: 'delivery',
|
||||
remark,
|
||||
created_at: nowIso()
|
||||
}).execute()
|
||||
}
|
||||
|
||||
function emptyOrder(): DeliveryOrderType {
|
||||
return {
|
||||
id: '',
|
||||
orderNo: '',
|
||||
serviceType: '',
|
||||
serviceName: '',
|
||||
serviceCategory: '',
|
||||
serviceItems: [] as Array<any>,
|
||||
elderId: '',
|
||||
elderName: '',
|
||||
elderNameMasked: '',
|
||||
elderGender: '',
|
||||
elderAge: 0,
|
||||
elderPhone: '',
|
||||
elderPhoneMasked: '',
|
||||
fullElderName: '',
|
||||
fullPhone: '',
|
||||
contactRelation: '家属',
|
||||
addressSummary: '',
|
||||
address: '',
|
||||
addressDetail: '',
|
||||
fullAddress: '',
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
appointmentTime: '',
|
||||
appointmentStartTime: '',
|
||||
appointmentEndTime: '',
|
||||
duration: 90,
|
||||
estimatedDuration: 90,
|
||||
price: 0,
|
||||
staffIncome: 0,
|
||||
distance: '',
|
||||
actualStartTime: '',
|
||||
actualEndTime: '',
|
||||
status: 'pending_assignment' as any,
|
||||
statusText: '',
|
||||
statusTone: 'warning',
|
||||
riskTags: [] as Array<string>,
|
||||
healthTags: [] as Array<string>,
|
||||
careLevel: '',
|
||||
needFamilyPresent: false,
|
||||
needMaterials: false,
|
||||
remark: '',
|
||||
merchantId: '',
|
||||
merchantName: '',
|
||||
deliveryStaffId: '',
|
||||
deliveryStaffName: '',
|
||||
acceptTime: '',
|
||||
departTime: '',
|
||||
arriveTime: '',
|
||||
checkinTime: '',
|
||||
finishTime: '',
|
||||
cancelReason: '',
|
||||
exceptionType: '',
|
||||
exceptionDesc: '',
|
||||
evidenceList: [] as Array<any>,
|
||||
signatureUrl: '',
|
||||
signatureName: '',
|
||||
satisfactionStatus: '',
|
||||
settlementStatus: '',
|
||||
archiveStatus: '',
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
contactName: '',
|
||||
contactPhone: '',
|
||||
notices: [] as Array<string>,
|
||||
timeline: [] as Array<any>,
|
||||
statusLog: [] as Array<any>,
|
||||
serviceSummary: '',
|
||||
progressNote: '',
|
||||
distanceKm: '',
|
||||
allowCheckinRadiusMeters: 100,
|
||||
lastLocation: null,
|
||||
trackPoints: [] as Array<any>,
|
||||
serviceRecord: null,
|
||||
abnormalReport: null
|
||||
} as DeliveryOrderType
|
||||
}
|
||||
|
||||
function safeJsonField(source: any, key: string): string {
|
||||
const plain = JSON.parse(JSON.stringify(source)) as any
|
||||
const value = plain[key]
|
||||
if (value == null) {
|
||||
return ''
|
||||
}
|
||||
return JSON.stringify(value)
|
||||
}
|
||||
|
||||
function statusToDeliveryStatus(status: ServiceOrderStatus): string {
|
||||
if (status == 'assigned') return 'pending_assignment'
|
||||
if (status == 'accepted') return 'accepted'
|
||||
if (status == 'departed') return 'departed'
|
||||
if (status == 'arrived') return 'arrived'
|
||||
if (status == 'in_service') return 'in_service'
|
||||
if (status == 'pending_acceptance') return 'pending_acceptance'
|
||||
if (status == 'reviewed' || status == 'accepted_by_user' || status == 'settled') return 'completed'
|
||||
if (status == 'rejected') return 'rejected'
|
||||
if (status == 'cancelled') return 'cancelled'
|
||||
if (status == 'exception') return 'abnormal'
|
||||
return 'pending_assignment'
|
||||
}
|
||||
|
||||
function statusTone(status: ServiceOrderStatus): string {
|
||||
if (status == 'pending_acceptance' || status == 'assigned') 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 == 'rejected' || status == 'cancelled' || status == 'exception') return 'danger'
|
||||
return 'warning'
|
||||
}
|
||||
|
||||
async function parseDeliveryOrder(orderId: string, item: any): Promise<DeliveryOrderType> {
|
||||
const order = emptyOrder()
|
||||
const obj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
|
||||
const addressRaw = safeJsonField(item, 'address_snapshot_json')
|
||||
const serviceRaw = safeJsonField(item, 'service_snapshot_json')
|
||||
const addressObj = JSON.parse(addressRaw == '' ? '{}' : addressRaw) as UTSJSONObject
|
||||
const serviceObj = JSON.parse(serviceRaw == '' ? '{}' : serviceRaw) as UTSJSONObject
|
||||
const normalizedStatus = normalizeServiceOrderStatus(obj.getString('status') ?? '')
|
||||
order.id = obj.getString('id') ?? ''
|
||||
order.orderNo = obj.getString('order_no') ?? ''
|
||||
order.serviceType = serviceObj.getString('category') ?? '居家服务'
|
||||
order.serviceName = obj.getString('service_name') ?? ''
|
||||
order.serviceCategory = serviceObj.getString('category') ?? ''
|
||||
order.elderName = obj.getString('recipient_name') ?? ''
|
||||
order.elderNameMasked = order.elderName
|
||||
order.fullElderName = order.elderName
|
||||
order.elderPhone = obj.getString('recipient_phone') ?? ''
|
||||
order.elderPhoneMasked = order.elderPhone
|
||||
order.fullPhone = order.elderPhone
|
||||
order.contactName = obj.getString('contact_name') ?? ''
|
||||
order.contactPhone = obj.getString('contact_phone') ?? ''
|
||||
order.contactRelation = '家属'
|
||||
order.address = addressObj.getString('fullAddress') ?? ''
|
||||
order.addressDetail = addressObj.getString('detailAddress') ?? ''
|
||||
order.fullAddress = order.address
|
||||
order.latitude = addressObj.getNumber('latitude') ?? 0
|
||||
order.longitude = addressObj.getNumber('longitude') ?? 0
|
||||
order.appointmentTime = obj.getString('appointment_time') ?? ''
|
||||
order.appointmentStartTime = order.appointmentTime
|
||||
order.appointmentEndTime = order.appointmentTime
|
||||
order.duration = 90
|
||||
order.estimatedDuration = 90
|
||||
order.price = serviceObj.getNumber('price') ?? 0
|
||||
order.staffIncome = order.price
|
||||
order.status = statusToDeliveryStatus(normalizedStatus) as any
|
||||
order.statusText = getServiceOrderStatusText(normalizedStatus)
|
||||
order.statusTone = statusTone(normalizedStatus)
|
||||
order.remark = obj.getString('remark') ?? ''
|
||||
order.deliveryStaffId = obj.getString('current_staff_id') ?? ''
|
||||
order.acceptTime = obj.getString('accepted_at') ?? ''
|
||||
order.departTime = obj.getString('departed_at') ?? ''
|
||||
order.arriveTime = obj.getString('arrived_at') ?? ''
|
||||
order.actualStartTime = obj.getString('service_started_at') ?? ''
|
||||
order.startServiceTime = order.actualStartTime
|
||||
order.finishTime = obj.getString('completed_at') ?? ''
|
||||
order.createdAt = obj.getString('created_at') ?? ''
|
||||
order.updatedAt = obj.getString('updated_at') ?? ''
|
||||
order.allowCheckinRadiusMeters = 100
|
||||
const logsResponse = await supa.from('hss_service_order_status_logs').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (logsResponse.data != null) {
|
||||
const rawLogs = logsResponse.data as any[]
|
||||
for (let i = 0; i < rawLogs.length; i++) {
|
||||
const logObj = JSON.parse(JSON.stringify(rawLogs[i])) as UTSJSONObject
|
||||
order.timeline.push({
|
||||
id: logObj.getString('id') ?? '',
|
||||
title: getServiceOrderStatusText(normalizeServiceOrderStatus(logObj.getString('to_status') ?? 'created')),
|
||||
time: logObj.getString('created_at') ?? '',
|
||||
description: logObj.getString('remark') ?? ''
|
||||
})
|
||||
}
|
||||
}
|
||||
const recordResponse = await supa.from('hss_service_execution_records').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (recordResponse.data != null) {
|
||||
const raw = recordResponse.data as any[]
|
||||
if (raw.length > 0) {
|
||||
const recordObj = JSON.parse(JSON.stringify(raw[0])) as UTSJSONObject
|
||||
order.checkinTime = recordObj.getString('checkin_time') ?? ''
|
||||
order.serviceRecord = {
|
||||
id: recordObj.getString('id') ?? '',
|
||||
orderId: orderId,
|
||||
startTime: recordObj.getString('service_started_at') ?? '',
|
||||
endTime: recordObj.getString('service_finished_at') ?? '',
|
||||
actualDurationMinutes: recordObj.getNumber('actual_duration_minutes') ?? 0,
|
||||
serviceItems: [] as Array<any>,
|
||||
serviceContent: [] as Array<string>,
|
||||
processNote: recordObj.getString('summary') ?? '',
|
||||
elderStatus: '',
|
||||
healthMetrics: { bloodPressure: '', heartRate: '', bloodSugar: '', bloodOxygen: '' },
|
||||
materialsUsed: '',
|
||||
abnormalNote: '',
|
||||
photos: [] as Array<string>,
|
||||
staffRemark: recordObj.getString('remark') ?? '',
|
||||
familyConfirmation: { method: 'none', code: '', signatureName: '', signatureUrl: '', confirmedAt: '' },
|
||||
createdAt: recordObj.getString('created_at') ?? '',
|
||||
updatedAt: recordObj.getString('updated_at') ?? ''
|
||||
} as any
|
||||
}
|
||||
}
|
||||
const evidenceResponse = await supa.from('hss_service_evidence_files').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (evidenceResponse.data != null) {
|
||||
const rawEvidence = evidenceResponse.data as any[]
|
||||
for (let i = 0; i < rawEvidence.length; i++) {
|
||||
const evidenceObj = JSON.parse(JSON.stringify(rawEvidence[i])) as UTSJSONObject
|
||||
order.evidenceList.push({
|
||||
id: evidenceObj.getString('id') ?? '',
|
||||
orderId: orderId,
|
||||
phase: evidenceObj.getString('phase') ?? '',
|
||||
fileType: evidenceObj.getString('file_type') ?? 'image',
|
||||
name: evidenceObj.getString('storage_path') ?? '',
|
||||
url: evidenceObj.getString('file_url') ?? '',
|
||||
localPath: '',
|
||||
status: 'success',
|
||||
progress: 100,
|
||||
retryable: false,
|
||||
createdAt: evidenceObj.getString('created_at') ?? ''
|
||||
})
|
||||
}
|
||||
}
|
||||
return order
|
||||
}
|
||||
|
||||
export async function getDashboard(): Promise<DeliveryDashboardType> {
|
||||
const orders = await getOrdersByTab('all')
|
||||
let pending = 0
|
||||
let today = 0
|
||||
let serving = 0
|
||||
let completed = 0
|
||||
let nextOrder: DeliveryOrderType | null = null
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const item = orders[i]
|
||||
if (item.status == 'pending_assignment') pending++
|
||||
if (item.status == 'pending_assignment' || item.status == 'accepted' || item.status == 'departed' || item.status == 'arrived' || item.status == 'in_service') today++
|
||||
if (item.status == 'in_service') serving++
|
||||
if (item.status == 'completed' || item.status == 'pending_acceptance') completed++
|
||||
if (nextOrder == null && item.status != 'completed' && item.status != 'cancelled' && item.status != 'abnormal') {
|
||||
nextOrder = item
|
||||
}
|
||||
}
|
||||
return {
|
||||
pendingAssignmentCount: pending,
|
||||
pendingAcceptCount: pending,
|
||||
todayOrderCount: today,
|
||||
pendingDepartCount: 0,
|
||||
servingCount: serving,
|
||||
completedCount: completed,
|
||||
exceptionCount: 0,
|
||||
expectedIncome: 0,
|
||||
onlineStatus: 'online',
|
||||
nextOrder,
|
||||
recentOrders: orders.slice(0, 5)
|
||||
} as DeliveryDashboardType
|
||||
}
|
||||
|
||||
export async function getOrdersByTab(tab: string): Promise<Array<DeliveryOrderType>> {
|
||||
const staffId = await getCurrentStaffId()
|
||||
if (staffId == '') {
|
||||
return [] as Array<DeliveryOrderType>
|
||||
}
|
||||
const response = await supa.from('hss_service_orders').select('*').eq('current_staff_id', staffId).order('created_at', { ascending: false }).execute()
|
||||
if (response.error != null || response.data == null) {
|
||||
return [] as Array<DeliveryOrderType>
|
||||
}
|
||||
const rawOrders = response.data as any[]
|
||||
const result = [] as Array<DeliveryOrderType>
|
||||
for (let i = 0; i < rawOrders.length; i++) {
|
||||
const orderObj = JSON.parse(JSON.stringify(rawOrders[i])) as UTSJSONObject
|
||||
const normalized = normalizeServiceOrderStatus(orderObj.getString('status') ?? '')
|
||||
let matched = true
|
||||
if (tab == 'pending') {
|
||||
matched = normalized == 'assigned'
|
||||
} else if (tab == 'today') {
|
||||
matched = normalized == 'assigned' || normalized == 'accepted' || normalized == 'departed' || normalized == 'arrived' || normalized == 'in_service' || normalized == 'pending_acceptance'
|
||||
} else if (tab == 'history') {
|
||||
matched = normalized == 'pending_acceptance' || normalized == 'accepted_by_user' || normalized == 'reviewed' || normalized == 'settled' || normalized == 'exception' || normalized == 'cancelled'
|
||||
}
|
||||
if (tab == 'all' || matched) {
|
||||
result.push(await parseDeliveryOrder(orderObj.getString('id') ?? '', rawOrders[i]))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export async function getOrderDetail(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
const response = await supa.from('hss_service_orders').select('*').eq('id', orderId).single().execute()
|
||||
if (response.error != null || response.data == null) {
|
||||
return null
|
||||
}
|
||||
return await parseDeliveryOrder(orderId, response.data)
|
||||
}
|
||||
|
||||
async function updateOrderStatus(orderId: string, nextStatus: ServiceOrderStatus, updateData: UTSJSONObject, remark: string): Promise<DeliveryOrderType | null> {
|
||||
const current = await getOrderDetail(orderId)
|
||||
if (current == null) {
|
||||
return null
|
||||
}
|
||||
const map = JSON.parse('{}') as UTSJSONObject
|
||||
map.set('status', nextStatus)
|
||||
map.set('updated_at', nowIso())
|
||||
const iterator = updateData.keys()
|
||||
while (iterator.hasNext()) {
|
||||
const key = iterator.next()
|
||||
map.set(key, updateData.get(key))
|
||||
}
|
||||
const response = await supa.from('hss_service_orders').update(map).eq('id', orderId).execute()
|
||||
if (response.error != null) {
|
||||
console.error('updateOrderStatus failed', response.error)
|
||||
return null
|
||||
}
|
||||
await insertStatusLog(orderId, normalizeServiceOrderStatus(current.status as string), nextStatus, remark)
|
||||
return await getOrderDetail(orderId)
|
||||
}
|
||||
|
||||
export async function acceptOrder(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
const assignmentResponse = await supa.from('hss_service_assignments').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (assignmentResponse.data != null) {
|
||||
const raw = assignmentResponse.data as any[]
|
||||
if (raw.length > 0) {
|
||||
const assignmentId = JSON.parse(JSON.stringify(raw[0]))['id'] as string
|
||||
await supa.from('hss_service_assignments').update({ status: 'accepted', accepted_at: nowIso(), updated_at: nowIso() }).eq('id', assignmentId).execute()
|
||||
}
|
||||
}
|
||||
const updateData = JSON.parse('{}') as UTSJSONObject
|
||||
updateData.set('accepted_at', nowIso())
|
||||
return await updateOrderStatus(orderId, 'accepted', updateData, '服务人员接单')
|
||||
}
|
||||
|
||||
export async function departOrder(orderId: string, location: DeliveryLocationType | null): Promise<DeliveryOrderType | null> {
|
||||
const updateData = JSON.parse('{}') as UTSJSONObject
|
||||
updateData.set('departed_at', nowIso())
|
||||
return await updateOrderStatus(orderId, 'departed', updateData, location == null ? '服务人员出发' : '服务人员出发:' + location.address)
|
||||
}
|
||||
|
||||
export async function arriveOrder(orderId: string, location: DeliveryLocationType | null): Promise<DeliveryOrderType | null> {
|
||||
const updateData = JSON.parse('{}') as UTSJSONObject
|
||||
updateData.set('arrived_at', nowIso())
|
||||
return await updateOrderStatus(orderId, 'arrived', updateData, location == null ? '服务人员到达' : '服务人员到达:' + location.address)
|
||||
}
|
||||
|
||||
export async function checkinOrder(orderId: string, payload: DeliveryCheckinPayloadType): Promise<DeliveryOrderType | null> {
|
||||
const current = await getOrderDetail(orderId)
|
||||
if (current == null) {
|
||||
return null
|
||||
}
|
||||
let assignmentId = ''
|
||||
const assignmentResponse = await supa.from('hss_service_assignments').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (assignmentResponse.data != null) {
|
||||
const rawAssignments = assignmentResponse.data as any[]
|
||||
if (rawAssignments.length > 0) {
|
||||
assignmentId = JSON.parse(JSON.stringify(rawAssignments[0]))['id'] as string
|
||||
}
|
||||
}
|
||||
let recordId = buildId('ser')
|
||||
const recordResponse = await supa.from('hss_service_execution_records').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (recordResponse.data != null) {
|
||||
const records = recordResponse.data as any[]
|
||||
if (records.length > 0) {
|
||||
recordId = JSON.parse(JSON.stringify(records[0]))['id'] as string
|
||||
await supa.from('hss_service_execution_records').update({
|
||||
checkin_time: nowIso(),
|
||||
checkin_latitude: payload.location.latitude,
|
||||
checkin_longitude: payload.location.longitude,
|
||||
checkin_address: payload.location.address,
|
||||
remark: payload.note,
|
||||
updated_at: nowIso()
|
||||
}).eq('id', recordId).execute()
|
||||
} else {
|
||||
await supa.from('hss_service_execution_records').insert({
|
||||
id: recordId,
|
||||
order_id: orderId,
|
||||
assignment_id: assignmentId,
|
||||
checkin_time: nowIso(),
|
||||
checkin_latitude: payload.location.latitude,
|
||||
checkin_longitude: payload.location.longitude,
|
||||
checkin_address: payload.location.address,
|
||||
remark: payload.note,
|
||||
created_at: nowIso(),
|
||||
updated_at: nowIso()
|
||||
}).execute()
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < payload.photos.length; i++) {
|
||||
await supa.from('hss_service_evidence_files').insert({
|
||||
id: buildId('sef'),
|
||||
order_id: orderId,
|
||||
execution_record_id: recordId,
|
||||
phase: 'checkin',
|
||||
file_type: 'image',
|
||||
storage_path: payload.photos[i],
|
||||
file_url: payload.photos[i],
|
||||
latitude: payload.location.latitude,
|
||||
longitude: payload.location.longitude,
|
||||
captured_at: nowIso(),
|
||||
created_at: nowIso()
|
||||
}).execute()
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
export async function startService(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
let recordId = ''
|
||||
const recordResponse = await supa.from('hss_service_execution_records').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (recordResponse.data != null) {
|
||||
const records = recordResponse.data as any[]
|
||||
if (records.length > 0) {
|
||||
recordId = JSON.parse(JSON.stringify(records[0]))['id'] as string
|
||||
await supa.from('hss_service_execution_records').update({ service_started_at: nowIso(), updated_at: nowIso() }).eq('id', recordId).execute()
|
||||
}
|
||||
}
|
||||
const updateData = JSON.parse('{}') as UTSJSONObject
|
||||
updateData.set('service_started_at', nowIso())
|
||||
return await updateOrderStatus(orderId, 'in_service', updateData, '开始服务')
|
||||
}
|
||||
|
||||
export async function saveServiceRecord(orderId: string, record: DeliveryServiceRecordType): Promise<DeliveryOrderType | null> {
|
||||
let assignmentId = ''
|
||||
const assignmentResponse = await supa.from('hss_service_assignments').select('*').eq('order_id', orderId).order('created_at', { ascending: false }).execute()
|
||||
if (assignmentResponse.data != null) {
|
||||
const assignments = assignmentResponse.data as any[]
|
||||
if (assignments.length > 0) {
|
||||
assignmentId = JSON.parse(JSON.stringify(assignments[0]))['id'] as string
|
||||
}
|
||||
}
|
||||
await supa.from('hss_service_execution_records').upsert({
|
||||
id: record.id,
|
||||
order_id: orderId,
|
||||
assignment_id: assignmentId,
|
||||
service_started_at: record.startTime,
|
||||
service_finished_at: record.endTime,
|
||||
actual_duration_minutes: record.actualDurationMinutes,
|
||||
service_items_json: record.serviceItems as any,
|
||||
summary: record.processNote,
|
||||
remark: record.staffRemark,
|
||||
updated_at: nowIso(),
|
||||
created_at: record.createdAt
|
||||
}).execute()
|
||||
for (let i = 0; i < record.photos.length; i++) {
|
||||
await supa.from('hss_service_evidence_files').insert({
|
||||
id: buildId('sef'),
|
||||
order_id: orderId,
|
||||
execution_record_id: record.id,
|
||||
phase: 'service',
|
||||
file_type: 'image',
|
||||
storage_path: record.photos[i],
|
||||
file_url: record.photos[i],
|
||||
captured_at: nowIso(),
|
||||
created_at: nowIso()
|
||||
}).execute()
|
||||
}
|
||||
return await getOrderDetail(orderId)
|
||||
}
|
||||
|
||||
export async function finishOrder(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
const updateData = JSON.parse('{}') as UTSJSONObject
|
||||
updateData.set('completed_at', nowIso())
|
||||
updateData.set('pending_acceptance_at', nowIso())
|
||||
return await updateOrderStatus(orderId, 'pending_acceptance', updateData, '服务完成,等待用户验收')
|
||||
}
|
||||
Reference in New Issue
Block a user