解决登录显示、首页显示bug
This commit is contained in:
759
mock/delivery.mock.uts
Normal file
759
mock/delivery.mock.uts
Normal file
@@ -0,0 +1,759 @@
|
||||
import type { UserProfile } from '@/types/mall-types.uts'
|
||||
import {
|
||||
DeliveryCheckinPayloadType,
|
||||
DeliveryDashboardType,
|
||||
DeliveryExceptionPayloadType,
|
||||
DeliveryEvidenceRecordType,
|
||||
DeliveryFinishPayloadType,
|
||||
DeliveryInfoType,
|
||||
DeliveryLocationType,
|
||||
DeliveryLoginPayloadType,
|
||||
DeliveryLoginResultType,
|
||||
DeliveryMessageType,
|
||||
DeliveryOrderQueryType,
|
||||
DeliveryOrderStatus,
|
||||
DeliveryOrderType,
|
||||
DeliveryProgressPayloadType,
|
||||
DeliveryRecordType,
|
||||
DeliveryServiceItemType,
|
||||
DeliveryTimelineItemType
|
||||
} from '@/types/delivery.uts'
|
||||
|
||||
type MockAccountType = {
|
||||
account: string
|
||||
password: string
|
||||
userInfo: UserProfile
|
||||
}
|
||||
|
||||
export const DELIVERY_ROLE_ALIASES: Array<string> = ['Deliverer']
|
||||
|
||||
const MOCK_ACCOUNTS: Array<MockAccountType> = [
|
||||
{
|
||||
account: 'service01',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'delivery-user-01',
|
||||
username: '陈护理',
|
||||
email: 'service01@demo.local',
|
||||
avatar_url: '/static/logo.png',
|
||||
role: 'Deliverer'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'care01',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'delivery-user-02',
|
||||
username: '黄巡护',
|
||||
email: 'care01@demo.local',
|
||||
avatar_url: '/static/logo.png',
|
||||
role: 'Deliverer'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'delivery-no-profile',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'delivery-user-03',
|
||||
username: '未建档账号',
|
||||
email: 'delivery-no-profile@demo.local',
|
||||
role: 'Deliverer'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'delivery-disabled',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'delivery-user-04',
|
||||
username: '停用账号',
|
||||
email: 'delivery-disabled@demo.local',
|
||||
role: 'Deliverer'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'admin01',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'admin-user-01',
|
||||
username: '后台账号',
|
||||
email: 'admin01@demo.local',
|
||||
role: 'admin'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'consumer01',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'consumer-user-01',
|
||||
username: '普通用户',
|
||||
email: 'consumer01@demo.local',
|
||||
role: 'consumer'
|
||||
} as UserProfile
|
||||
},
|
||||
{
|
||||
account: 'merchant01',
|
||||
password: '123456',
|
||||
userInfo: {
|
||||
id: 'merchant-user-01',
|
||||
username: '机构账号',
|
||||
email: 'merchant01@demo.local',
|
||||
role: 'merchant'
|
||||
} as UserProfile
|
||||
}
|
||||
]
|
||||
|
||||
function createCertificate(id: string, name: string, expireAt: string): any {
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
status: expireAt > '2026-05-15' ? 'valid' : 'expired',
|
||||
expireAt,
|
||||
issuer: '梅州市民政培训中心',
|
||||
imageUrl: ''
|
||||
}
|
||||
}
|
||||
|
||||
let DELIVERY_STAFF_STORE: Array<DeliveryInfoType> = [
|
||||
{
|
||||
id: 'staff-01',
|
||||
userId: 'delivery-user-01',
|
||||
staffNo: 'DEL-202605-001',
|
||||
name: '陈护理',
|
||||
phone: '13600001111',
|
||||
role: 'Deliverer',
|
||||
status: 'active',
|
||||
organizationId: 'org-01',
|
||||
organizationName: '梅江区居家康护中心',
|
||||
certificates: [createCertificate('cert-01', '护理员证', '2027-08-31'), createCertificate('cert-02', '健康证', '2027-05-20')],
|
||||
certificateStatus: 'valid',
|
||||
certificateExpireAt: '2027-08-31',
|
||||
onlineStatus: 'online',
|
||||
serviceArea: '梅江区',
|
||||
skills: ['基础护理', '慢病随访', '上门巡视'],
|
||||
avatarUrl: '/static/logo.png',
|
||||
todayAccepted: 1,
|
||||
todayServing: 1,
|
||||
todayCompleted: 2,
|
||||
usesMock: true
|
||||
},
|
||||
{
|
||||
id: 'staff-02',
|
||||
userId: 'delivery-user-02',
|
||||
staffNo: 'DEL-202605-002',
|
||||
name: '黄巡护',
|
||||
phone: '13600002222',
|
||||
role: 'Deliverer',
|
||||
status: 'active',
|
||||
organizationId: 'org-01',
|
||||
organizationName: '梅江区居家康护中心',
|
||||
certificates: [createCertificate('cert-03', '巡护员培训证', '2027-11-30')],
|
||||
certificateStatus: 'valid',
|
||||
certificateExpireAt: '2027-11-30',
|
||||
onlineStatus: 'resting',
|
||||
serviceArea: '梅县区',
|
||||
skills: ['巡护', '风险上报'],
|
||||
avatarUrl: '/static/logo.png',
|
||||
todayAccepted: 0,
|
||||
todayServing: 0,
|
||||
todayCompleted: 1,
|
||||
usesMock: true
|
||||
},
|
||||
{
|
||||
id: 'staff-03',
|
||||
userId: 'delivery-user-04',
|
||||
staffNo: 'DEL-202605-003',
|
||||
name: '停用账号',
|
||||
phone: '13600003333',
|
||||
role: 'Deliverer',
|
||||
status: 'disabled',
|
||||
organizationId: 'org-02',
|
||||
organizationName: '梅县区银龄服务站',
|
||||
certificates: [createCertificate('cert-04', '护理员证', '2027-01-31')],
|
||||
certificateStatus: 'valid',
|
||||
certificateExpireAt: '2027-01-31',
|
||||
onlineStatus: 'resting',
|
||||
serviceArea: '梅县区',
|
||||
skills: ['基础护理'],
|
||||
avatarUrl: '/static/logo.png',
|
||||
todayAccepted: 0,
|
||||
todayServing: 0,
|
||||
todayCompleted: 0,
|
||||
usesMock: true
|
||||
}
|
||||
]
|
||||
|
||||
function nowText(): string {
|
||||
return new Date().toISOString().replace('T', ' ').substring(0, 19)
|
||||
}
|
||||
|
||||
function makeTimeline(idPrefix: string, items: Array<string>): Array<DeliveryTimelineItemType> {
|
||||
const timeline: Array<DeliveryTimelineItemType> = []
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
timeline.push({
|
||||
id: idPrefix + '-' + String(i + 1),
|
||||
title: items[i],
|
||||
time: nowText(),
|
||||
description: items[i] + ' 已记录'
|
||||
})
|
||||
}
|
||||
return timeline
|
||||
}
|
||||
|
||||
function makeItems(prefix: string): Array<DeliveryServiceItemType> {
|
||||
return [
|
||||
{
|
||||
id: prefix + '-1',
|
||||
name: '生命体征监测',
|
||||
required: true,
|
||||
completed: false,
|
||||
incompleteReason: '',
|
||||
remark: '',
|
||||
updatedAt: ''
|
||||
},
|
||||
{
|
||||
id: prefix + '-2',
|
||||
name: '基础照护',
|
||||
required: true,
|
||||
completed: false,
|
||||
incompleteReason: '',
|
||||
remark: '',
|
||||
updatedAt: ''
|
||||
},
|
||||
{
|
||||
id: prefix + '-3',
|
||||
name: '健康宣教',
|
||||
required: false,
|
||||
completed: false,
|
||||
incompleteReason: '',
|
||||
remark: '',
|
||||
updatedAt: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function statusMeta(status: DeliveryOrderStatus): any {
|
||||
if (status == 'pending_accept') return { text: '待接单', tone: 'warning' }
|
||||
if (status == 'accepted') return { text: '待出发', tone: 'primary' }
|
||||
if (status == 'on_the_way') return { text: '出发中', tone: 'primary' }
|
||||
if (status == 'arrived') return { text: '已到达', tone: 'primary' }
|
||||
if (status == 'checked_in') return { text: '已签到', tone: 'success' }
|
||||
if (status == 'serving') return { text: '服务中', tone: 'primary' }
|
||||
if (status == 'pending_submit') return { text: '待提交', tone: 'warning' }
|
||||
if (status == 'pending_acceptance') return { text: '待验收', tone: 'success' }
|
||||
if (status == 'completed') return { text: '已完成', tone: 'success' }
|
||||
if (status == 'exception_pending') return { text: '异常待处理', tone: 'warning' }
|
||||
if (status == 'settled') return { text: '已结算', tone: 'success' }
|
||||
if (status == 'archived') return { text: '已归档', tone: 'neutral' }
|
||||
return { text: '已取消', tone: 'neutral' }
|
||||
}
|
||||
|
||||
function buildOrder(id: string, status: DeliveryOrderStatus, elderName: string, address: string, serviceName: string, distanceKm: string): DeliveryOrderType {
|
||||
const meta = statusMeta(status)
|
||||
return {
|
||||
id,
|
||||
orderNo: 'HS-' + id.toUpperCase(),
|
||||
serviceType: '居家上门服务',
|
||||
serviceName,
|
||||
serviceItems: makeItems(id),
|
||||
elderId: 'elder-' + id,
|
||||
elderNameMasked: elderName.substring(0, 1) + '**',
|
||||
elderPhoneMasked: '138****' + id.substring(id.length - 2),
|
||||
fullElderName: elderName,
|
||||
fullPhone: '1380013' + id.substring(id.length - 4),
|
||||
addressSummary: address,
|
||||
fullAddress: address + ' 详细门牌',
|
||||
latitude: 24.289,
|
||||
longitude: 116.123,
|
||||
appointmentStartTime: '2026-05-15 09:00',
|
||||
appointmentEndTime: '2026-05-15 11:00',
|
||||
estimatedDuration: 120,
|
||||
actualStartTime: '',
|
||||
actualEndTime: '',
|
||||
status,
|
||||
statusText: meta.text,
|
||||
statusTone: meta.tone,
|
||||
riskTags: ['跌倒风险', '高血压'],
|
||||
careLevel: '护理二级',
|
||||
merchantId: 'merchant-org-01',
|
||||
merchantName: '梅江区居家康护中心',
|
||||
deliveryStaffId: 'staff-01',
|
||||
deliveryStaffName: '陈护理',
|
||||
acceptTime: '',
|
||||
departTime: '',
|
||||
arriveTime: '',
|
||||
checkinTime: '',
|
||||
finishTime: '',
|
||||
cancelReason: '',
|
||||
exceptionType: '',
|
||||
exceptionDesc: '',
|
||||
evidenceList: [],
|
||||
signatureUrl: '',
|
||||
signatureName: '',
|
||||
satisfactionStatus: 'pending',
|
||||
settlementStatus: 'pending',
|
||||
archiveStatus: 'pending',
|
||||
createdAt: nowText(),
|
||||
updatedAt: nowText(),
|
||||
contactName: '家属联系人',
|
||||
contactPhone: '13900139000',
|
||||
notices: ['接单前仅显示脱敏信息', '签到需在 50 米范围内完成'],
|
||||
timeline: makeTimeline(id, ['工单创建', '调度派单']),
|
||||
serviceSummary: '',
|
||||
progressNote: '',
|
||||
distanceKm,
|
||||
allowCheckinRadiusMeters: 50,
|
||||
lastLocation: null,
|
||||
trackPoints: []
|
||||
}
|
||||
}
|
||||
|
||||
let ORDER_STORE: Array<DeliveryOrderType> = [
|
||||
buildOrder('1001', 'pending_accept', '李奶奶', '梅江区学海路 18 号', '基础护理上门', '2.1km'),
|
||||
buildOrder('1002', 'accepted', '张爷爷', '梅县区华侨城康宁路 66 号', '慢病随访', '3.8km'),
|
||||
buildOrder('1003', 'on_the_way', '陈阿婆', '梅江区团结路 9 号', '康复训练指导', '1.5km'),
|
||||
buildOrder('1004', 'checked_in', '林伯伯', '梅江区江南路 27 号', '基础护理上门', '0.6km'),
|
||||
buildOrder('1005', 'serving', '温阿姨', '梅县区扶大高新区 12 号', '慢病随访', '4.2km'),
|
||||
buildOrder('1006', 'pending_acceptance', '丘奶奶', '梅江区芹洋路 8 号', '基础护理上门', '6.0km')
|
||||
]
|
||||
|
||||
ORDER_STORE[4].actualStartTime = '2026-05-15 08:40'
|
||||
ORDER_STORE[4].serviceItems[0].completed = true
|
||||
ORDER_STORE[4].serviceItems[0].updatedAt = '2026-05-15 08:50'
|
||||
ORDER_STORE[4].serviceItems[0].remark = '血压 132/82,血糖 6.8'
|
||||
ORDER_STORE[4].timeline.unshift({ id: '1005-serve', title: '开始服务', time: '2026-05-15 08:40', description: '服务人员已开始执行服务项目' })
|
||||
ORDER_STORE[5].actualStartTime = '2026-05-14 15:00'
|
||||
ORDER_STORE[5].actualEndTime = '2026-05-14 16:25'
|
||||
ORDER_STORE[5].finishTime = '2026-05-14 16:25'
|
||||
ORDER_STORE[5].serviceSummary = '已完成基础护理和家属宣教,待家属验收。'
|
||||
|
||||
let MESSAGE_STORE: Array<DeliveryMessageType> = [
|
||||
{ id: 'msg-01', title: '新工单提醒', content: '工单 HS-1001 已派发,请在 10 分钟内处理。', type: 'new_order', createdAt: nowText(), read: false, orderId: '1001' },
|
||||
{ id: 'msg-02', title: '超时提醒', content: '工单 HS-1003 已接近预约时间,请尽快到达。', type: 'timeout', createdAt: nowText(), read: false, orderId: '1003' },
|
||||
{ id: 'msg-03', title: '验收结果', content: '工单 HS-1006 已进入待验收,请关注后续反馈。', type: 'acceptance', createdAt: nowText(), read: true, orderId: '1006' }
|
||||
]
|
||||
|
||||
function delay(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
}, 80)
|
||||
})
|
||||
}
|
||||
|
||||
function cloneUserProfile(profile: UserProfile): UserProfile {
|
||||
return JSON.parse(JSON.stringify(profile)) as UserProfile
|
||||
}
|
||||
|
||||
function cloneDeliveryInfo(info: DeliveryInfoType): DeliveryInfoType {
|
||||
return JSON.parse(JSON.stringify(info)) as DeliveryInfoType
|
||||
}
|
||||
|
||||
function cloneOrder(order: DeliveryOrderType): DeliveryOrderType {
|
||||
return JSON.parse(JSON.stringify(order)) as DeliveryOrderType
|
||||
}
|
||||
|
||||
function cloneRecord(record: DeliveryRecordType): DeliveryRecordType {
|
||||
return JSON.parse(JSON.stringify(record)) as DeliveryRecordType
|
||||
}
|
||||
|
||||
function getDeliveryInfoByUserId(userId: string): DeliveryInfoType | null {
|
||||
for (let i = 0; i < DELIVERY_STAFF_STORE.length; i++) {
|
||||
if (DELIVERY_STAFF_STORE[i].userId == userId) {
|
||||
return DELIVERY_STAFF_STORE[i]
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getOrderById(orderId: string): DeliveryOrderType | null {
|
||||
for (let i = 0; i < ORDER_STORE.length; i++) {
|
||||
if (ORDER_STORE[i].id == orderId) {
|
||||
return ORDER_STORE[i]
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function refreshStatus(order: DeliveryOrderType): void {
|
||||
const meta = statusMeta(order.status)
|
||||
order.statusText = meta.text
|
||||
order.statusTone = meta.tone
|
||||
order.updatedAt = nowText()
|
||||
}
|
||||
|
||||
function appendTimeline(order: DeliveryOrderType, title: string, description: string): void {
|
||||
order.timeline.unshift({
|
||||
id: order.id + '-tl-' + String(order.timeline.length + 1),
|
||||
title,
|
||||
time: nowText(),
|
||||
description
|
||||
})
|
||||
}
|
||||
|
||||
function buildRecords(): Array<DeliveryRecordType> {
|
||||
const list: Array<DeliveryRecordType> = []
|
||||
for (let i = 0; i < ORDER_STORE.length; i++) {
|
||||
const order = ORDER_STORE[i]
|
||||
if (order.status == 'pending_acceptance' || order.status == 'completed' || order.status == 'exception_pending') {
|
||||
list.push({
|
||||
id: 'record-' + order.id,
|
||||
orderId: order.id,
|
||||
orderNo: order.orderNo,
|
||||
serviceName: order.serviceName,
|
||||
elderNameMasked: order.elderNameMasked,
|
||||
status: order.status,
|
||||
statusText: order.statusText,
|
||||
appointmentStartTime: order.appointmentStartTime,
|
||||
actualStartTime: order.actualStartTime,
|
||||
actualEndTime: order.actualEndTime,
|
||||
settlementStatus: order.settlementStatus,
|
||||
acceptanceStatus: order.satisfactionStatus,
|
||||
exceptionDesc: order.exceptionDesc,
|
||||
ratingText: order.satisfactionStatus == 'done' ? '已评价' : '待评价'
|
||||
})
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
export async function mockLoginDelivery(payload: DeliveryLoginPayloadType): Promise<DeliveryLoginResultType> {
|
||||
await delay()
|
||||
for (let i = 0; i < MOCK_ACCOUNTS.length; i++) {
|
||||
const account = MOCK_ACCOUNTS[i]
|
||||
if (account.account == payload.account && account.password == payload.password) {
|
||||
const deliveryInfo = account.userInfo.id != null ? getDeliveryInfoByUserId(account.userInfo.id as string) : null
|
||||
return {
|
||||
token: 'mock-delivery-token-' + payload.account + '-' + String(Date.now()),
|
||||
userInfo: cloneUserProfile(account.userInfo),
|
||||
deliveryInfo: deliveryInfo == null ? null : cloneDeliveryInfo(deliveryInfo),
|
||||
usesMock: true
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error('演示环境仅开放以下账号:service01、care01、delivery-no-profile、delivery-disabled、consumer01、merchant01、admin01,密码均为 123456')
|
||||
}
|
||||
|
||||
export async function mockGetDeliveryProfileByUserId(userId: string): Promise<DeliveryInfoType | null> {
|
||||
await delay()
|
||||
const info = getDeliveryInfoByUserId(userId)
|
||||
return info == null ? null : cloneDeliveryInfo(info)
|
||||
}
|
||||
|
||||
export async function mockGetDashboard(staffId: string): Promise<DeliveryDashboardType> {
|
||||
await delay()
|
||||
let pendingAcceptCount = 0
|
||||
let pendingDepartCount = 0
|
||||
let servingCount = 0
|
||||
let completedCount = 0
|
||||
let exceptionCount = 0
|
||||
const recentOrders: Array<DeliveryOrderType> = []
|
||||
for (let i = 0; i < ORDER_STORE.length; i++) {
|
||||
const order = ORDER_STORE[i]
|
||||
if (order.deliveryStaffId != staffId) {
|
||||
continue
|
||||
}
|
||||
if (order.status == 'pending_accept') pendingAcceptCount++
|
||||
if (order.status == 'accepted') pendingDepartCount++
|
||||
if (order.status == 'on_the_way' || order.status == 'arrived' || order.status == 'checked_in' || order.status == 'serving') servingCount++
|
||||
if (order.status == 'completed' || order.status == 'pending_acceptance') completedCount++
|
||||
if (order.status == 'exception_pending') exceptionCount++
|
||||
if (recentOrders.length < 3) {
|
||||
recentOrders.push(cloneOrder(order))
|
||||
}
|
||||
}
|
||||
const info = DELIVERY_STAFF_STORE.find((item) => item.id == staffId)
|
||||
return {
|
||||
pendingAcceptCount,
|
||||
pendingDepartCount,
|
||||
servingCount,
|
||||
completedCount,
|
||||
exceptionCount,
|
||||
onlineStatus: info != null ? info.onlineStatus : 'resting',
|
||||
recentOrders
|
||||
}
|
||||
}
|
||||
|
||||
function matchTab(order: DeliveryOrderType, tab: string): boolean {
|
||||
if (tab == '' || tab == 'all') return true
|
||||
if (tab == 'pending_accept') return order.status == 'pending_accept'
|
||||
if (tab == 'accepted') return order.status == 'accepted'
|
||||
if (tab == 'serving') return order.status == 'on_the_way' || order.status == 'arrived' || order.status == 'checked_in' || order.status == 'serving'
|
||||
if (tab == 'pending_submit') return order.status == 'pending_submit'
|
||||
if (tab == 'completed') return order.status == 'pending_acceptance' || order.status == 'completed'
|
||||
if (tab == 'exception') return order.status == 'exception_pending'
|
||||
return true
|
||||
}
|
||||
|
||||
export async function mockGetOrders(staffId: string, query: DeliveryOrderQueryType): Promise<Array<DeliveryOrderType>> {
|
||||
await delay()
|
||||
const list: Array<DeliveryOrderType> = []
|
||||
for (let i = 0; i < ORDER_STORE.length; i++) {
|
||||
const order = ORDER_STORE[i]
|
||||
if (order.deliveryStaffId != staffId) {
|
||||
continue
|
||||
}
|
||||
if (!matchTab(order, query.tab)) {
|
||||
continue
|
||||
}
|
||||
if (query.keyword != '') {
|
||||
const keyword = query.keyword
|
||||
if (order.orderNo.indexOf(keyword) < 0 && order.serviceName.indexOf(keyword) < 0 && order.addressSummary.indexOf(keyword) < 0) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
list.push(cloneOrder(order))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
export async function mockGetOrderDetail(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
return order == null ? null : cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockAcceptOrder(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'accepted'
|
||||
order.acceptTime = nowText()
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '已接单', '服务人员已确认接单,待出发')
|
||||
MESSAGE_STORE.unshift({ id: 'msg-' + String(Date.now()), title: '接单成功', content: order.orderNo + ' 已进入待出发状态。', type: 'order_update', createdAt: nowText(), read: false, orderId })
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockRejectOrder(orderId: string, reason: string): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'cancelled'
|
||||
order.cancelReason = reason
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '已拒单', reason)
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockStartDepart(orderId: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'on_the_way'
|
||||
order.departTime = location.time
|
||||
order.lastLocation = location
|
||||
order.trackPoints.push(location)
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '已出发', '当前位置已上报,正在前往服务地址')
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockArriveOrder(orderId: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'arrived'
|
||||
order.arriveTime = location.time
|
||||
order.lastLocation = location
|
||||
order.trackPoints.push(location)
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '已到达', '服务人员已到达服务地点')
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockCheckinOrder(orderId: string, payload: DeliveryCheckinPayloadType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'checked_in'
|
||||
order.checkinTime = payload.location.time
|
||||
order.lastLocation = payload.location
|
||||
order.trackPoints.push(payload.location)
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '签到完成', payload.note != '' ? payload.note : '已完成定位签到和现场拍照')
|
||||
for (let i = 0; i < payload.photos.length; i++) {
|
||||
const evidence: DeliveryEvidenceRecordType = {
|
||||
id: 'checkin-' + orderId + '-' + String(order.evidenceList.length + 1),
|
||||
orderId,
|
||||
phase: 'before',
|
||||
fileType: 'image',
|
||||
name: '签到照片' + String(i + 1),
|
||||
url: payload.photos[i],
|
||||
localPath: payload.photos[i],
|
||||
status: 'success',
|
||||
progress: 100,
|
||||
retryable: false,
|
||||
createdAt: nowText()
|
||||
}
|
||||
order.evidenceList.push(evidence)
|
||||
}
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockStartService(orderId: string): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'serving'
|
||||
if (order.actualStartTime == '') {
|
||||
order.actualStartTime = nowText()
|
||||
}
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '开始服务', '服务计时已开始')
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockSaveProgress(orderId: string, payload: DeliveryProgressPayloadType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.progressNote = payload.progressNote
|
||||
order.serviceSummary = payload.serviceSummary
|
||||
order.serviceItems = JSON.parse(JSON.stringify(payload.items)) as Array<DeliveryServiceItemType>
|
||||
appendTimeline(order, '服务记录暂存', payload.progressNote != '' ? payload.progressNote : '已保存当前服务进度')
|
||||
if (order.status == 'serving') {
|
||||
order.status = 'pending_submit'
|
||||
refreshStatus(order)
|
||||
}
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
let duringUploadFailedOnce = false
|
||||
|
||||
export async function mockUploadEvidence(orderId: string, phase: string, files: Array<string>): Promise<Array<DeliveryEvidenceRecordType>> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
const result: Array<DeliveryEvidenceRecordType> = []
|
||||
if (order == null) return result
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let status = 'success'
|
||||
let progress = 100
|
||||
let retryable = false
|
||||
if (phase == 'during' && duringUploadFailedOnce == false) {
|
||||
status = 'failed'
|
||||
progress = 0
|
||||
retryable = true
|
||||
duringUploadFailedOnce = true
|
||||
}
|
||||
const evidence: DeliveryEvidenceRecordType = {
|
||||
id: 'evidence-' + orderId + '-' + String(order.evidenceList.length + 1),
|
||||
orderId,
|
||||
phase,
|
||||
fileType: 'image',
|
||||
name: phase + '-image-' + String(i + 1),
|
||||
url: status == 'success' ? files[i] : '',
|
||||
localPath: files[i],
|
||||
status,
|
||||
progress,
|
||||
retryable,
|
||||
createdAt: nowText()
|
||||
}
|
||||
order.evidenceList.push(evidence)
|
||||
result.push(JSON.parse(JSON.stringify(evidence)) as DeliveryEvidenceRecordType)
|
||||
}
|
||||
appendTimeline(order, '证据材料更新', '已上传 ' + phase + ' 阶段材料')
|
||||
return result
|
||||
}
|
||||
|
||||
export async function mockRetryEvidence(orderId: string, evidenceId: string): Promise<DeliveryEvidenceRecordType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
for (let i = 0; i < order.evidenceList.length; i++) {
|
||||
const evidence = order.evidenceList[i]
|
||||
if (evidence.id == evidenceId) {
|
||||
evidence.status = 'success'
|
||||
evidence.progress = 100
|
||||
evidence.retryable = false
|
||||
evidence.url = evidence.localPath
|
||||
appendTimeline(order, '证据重试成功', evidence.name + ' 已重新上传')
|
||||
return JSON.parse(JSON.stringify(evidence)) as DeliveryEvidenceRecordType
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export async function mockSubmitException(orderId: string, payload: DeliveryExceptionPayloadType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
order.status = 'exception_pending'
|
||||
order.exceptionType = payload.exceptionType
|
||||
order.exceptionDesc = payload.description
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '异常上报', payload.description)
|
||||
MESSAGE_STORE.unshift({ id: 'msg-' + String(Date.now()), title: '异常已上报', content: order.orderNo + ' 已提交异常,请等待调度处理。', type: 'exception', createdAt: nowText(), read: false, orderId })
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
function hasRequiredEvidence(order: DeliveryOrderType): boolean {
|
||||
let count = 0
|
||||
for (let i = 0; i < order.evidenceList.length; i++) {
|
||||
if (order.evidenceList[i].status == 'success') {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count >= 2
|
||||
}
|
||||
|
||||
function hasServiceRecord(order: DeliveryOrderType): boolean {
|
||||
if (order.progressNote != '' || order.serviceSummary != '') {
|
||||
return true
|
||||
}
|
||||
for (let i = 0; i < order.serviceItems.length; i++) {
|
||||
if (order.serviceItems[i].completed == true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export async function mockFinishService(orderId: string, payload: DeliveryFinishPayloadType): Promise<DeliveryOrderType | null> {
|
||||
await delay()
|
||||
const order = getOrderById(orderId)
|
||||
if (order == null) return null
|
||||
if (!hasServiceRecord(order)) {
|
||||
throw new Error('请至少填写一项服务记录后再提交完成')
|
||||
}
|
||||
if (!hasRequiredEvidence(order)) {
|
||||
throw new Error('请至少上传两份有效证据材料后再提交完成')
|
||||
}
|
||||
order.status = 'pending_acceptance'
|
||||
order.actualEndTime = nowText()
|
||||
order.finishTime = order.actualEndTime
|
||||
order.signatureName = payload.signatureName
|
||||
order.signatureUrl = payload.signatureName != '' ? 'mock-signature://' + payload.signatureName : ''
|
||||
order.serviceSummary = payload.serviceSummary
|
||||
refreshStatus(order)
|
||||
appendTimeline(order, '完成提交', '服务记录、证据和签名已提交,等待验收')
|
||||
return cloneOrder(order)
|
||||
}
|
||||
|
||||
export async function mockGetRecords(staffId: string): Promise<Array<DeliveryRecordType>> {
|
||||
await delay()
|
||||
const records = buildRecords()
|
||||
const list: Array<DeliveryRecordType> = []
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
const order = getOrderById(records[i].orderId)
|
||||
if (order != null && order.deliveryStaffId == staffId) {
|
||||
list.push(cloneRecord(records[i]))
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
export async function mockGetMessages(): Promise<Array<DeliveryMessageType>> {
|
||||
await delay()
|
||||
return JSON.parse(JSON.stringify(MESSAGE_STORE)) as Array<DeliveryMessageType>
|
||||
}
|
||||
|
||||
export async function mockUpdateOnlineStatus(staffId: string, status: string): Promise<DeliveryInfoType | null> {
|
||||
await delay()
|
||||
for (let i = 0; i < DELIVERY_STAFF_STORE.length; i++) {
|
||||
if (DELIVERY_STAFF_STORE[i].id == staffId) {
|
||||
DELIVERY_STAFF_STORE[i].onlineStatus = status as any
|
||||
return cloneDeliveryInfo(DELIVERY_STAFF_STORE[i])
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user