665 lines
15 KiB
JavaScript
665 lines
15 KiB
JavaScript
// pages/order/index.js
|
|
|
|
// 状态映射配置
|
|
const STATUS_MAP = {
|
|
pending: { label: '待确认', text: '待确认', color: '#f59f00' },
|
|
confirmed: { label: '已确认', text: '已确认', color: '#4c6ef5' },
|
|
in_progress: { label: '进行中', text: '进行中', color: '#20c997' },
|
|
completed: { label: '已完成', text: '已完成', color: '#51cf66' },
|
|
cancelled: { label: '已取消', text: '已取消', color: '#ff6b6b' }
|
|
};
|
|
|
|
// 状态筛选选项
|
|
const STATUS_FILTERS = [
|
|
{ label: '全部', value: '', count: 0 },
|
|
{ label: '待确认', value: 'pending', count: 0 },
|
|
{ label: '已确认', value: 'confirmed', count: 0 },
|
|
{ label: '进行中', value: 'in_progress', count: 0 },
|
|
{ label: '已完成', value: 'completed', count: 0 },
|
|
{ label: '已取消', value: 'cancelled', count: 0 }
|
|
];
|
|
|
|
// Mock 数据 - 基于 escort_record.js 的数据结构
|
|
const MOCK_ORDERS = [
|
|
{
|
|
_id: 'ORD20240530001',
|
|
orderNo: '20240530001',
|
|
userId: 'user001',
|
|
patient: {
|
|
name: '张三',
|
|
mobile: '138****1234',
|
|
sex: 'male',
|
|
age: 65,
|
|
idnumber: '310***********1234'
|
|
},
|
|
escort: {
|
|
serviceId: 1,
|
|
serviceName: '全程陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '复旦大学附属中山医院',
|
|
address: '上海市徐汇区枫林路180号',
|
|
department: '心内科',
|
|
doctor: '李医生',
|
|
medicalRecordNo: 'MR202405001'
|
|
},
|
|
schedule: {
|
|
date: '2024-06-01T09:00:00.000Z',
|
|
dateText: '06月01日',
|
|
startTime: '09:00',
|
|
endTime: '12:00',
|
|
duration: 180
|
|
},
|
|
attendant: {
|
|
id: 'att001',
|
|
name: '王陪诊',
|
|
sex: 'female'
|
|
},
|
|
payment: {
|
|
totalFee: 298,
|
|
paidFee: 298,
|
|
status: 'paid'
|
|
},
|
|
notes: {
|
|
patientNote: '患者行动不便,需要轮椅',
|
|
escortNote: '',
|
|
medicalSummary: ''
|
|
},
|
|
status: 'pending',
|
|
statusText: '待确认',
|
|
meta: {
|
|
createtime: '2024-05-30T10:00:00.000Z',
|
|
updatetime: '2024-05-30T10:00:00.000Z'
|
|
}
|
|
},
|
|
{
|
|
_id: 'ORD20240529002',
|
|
orderNo: '20240529002',
|
|
userId: 'user002',
|
|
patient: {
|
|
name: '李四',
|
|
mobile: '139****5678',
|
|
sex: 'female',
|
|
age: 42,
|
|
idnumber: '310***********5678'
|
|
},
|
|
escort: {
|
|
serviceId: 2,
|
|
serviceName: '挂号陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '上海交通大学医学院附属瑞金医院',
|
|
address: '上海市黄浦区瑞金二路197号',
|
|
department: '内分泌科',
|
|
doctor: '张医生',
|
|
medicalRecordNo: 'MR202405002'
|
|
},
|
|
schedule: {
|
|
date: '2024-05-31T14:00:00.000Z',
|
|
dateText: '05月31日',
|
|
startTime: '14:00',
|
|
endTime: '16:00',
|
|
duration: 120
|
|
},
|
|
attendant: {
|
|
id: 'att002',
|
|
name: '赵陪诊',
|
|
sex: 'male'
|
|
},
|
|
payment: {
|
|
totalFee: 198,
|
|
paidFee: 198,
|
|
status: 'paid'
|
|
},
|
|
notes: {
|
|
patientNote: '需要帮忙取药',
|
|
escortNote: '',
|
|
medicalSummary: ''
|
|
},
|
|
status: 'confirmed',
|
|
statusText: '已确认',
|
|
meta: {
|
|
createtime: '2024-05-29T08:30:00.000Z',
|
|
updatetime: '2024-05-29T15:00:00.000Z'
|
|
}
|
|
},
|
|
{
|
|
_id: 'ORD20240528003',
|
|
orderNo: '20240528003',
|
|
userId: 'user003',
|
|
patient: {
|
|
name: '王五',
|
|
mobile: '137****9012',
|
|
sex: 'male',
|
|
age: 78,
|
|
idnumber: '310***********9012'
|
|
},
|
|
escort: {
|
|
serviceId: 1,
|
|
serviceName: '全程陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '上海市第六人民医院',
|
|
address: '上海市徐汇区宜山路600号',
|
|
department: '骨科',
|
|
doctor: '刘医生',
|
|
medicalRecordNo: 'MR202405003'
|
|
},
|
|
schedule: {
|
|
date: '2024-05-30T08:30:00.000Z',
|
|
dateText: '05月30日',
|
|
startTime: '08:30',
|
|
endTime: '11:30',
|
|
duration: 180
|
|
},
|
|
attendant: {
|
|
id: 'att003',
|
|
name: '陈陪诊',
|
|
sex: 'female'
|
|
},
|
|
payment: {
|
|
totalFee: 398,
|
|
paidFee: 200,
|
|
status: 'partial'
|
|
},
|
|
notes: {
|
|
patientNote: '听力不好,请大声说话',
|
|
escortNote: '已接到患者,正在前往医院',
|
|
medicalSummary: ''
|
|
},
|
|
status: 'in_progress',
|
|
statusText: '进行中',
|
|
meta: {
|
|
createtime: '2024-05-28T16:00:00.000Z',
|
|
updatetime: '2024-05-30T08:35:00.000Z'
|
|
}
|
|
},
|
|
{
|
|
_id: 'ORD20240525004',
|
|
orderNo: '20240525004',
|
|
userId: 'user004',
|
|
patient: {
|
|
name: '赵六',
|
|
mobile: '136****3456',
|
|
sex: 'female',
|
|
age: 55,
|
|
idnumber: '310***********3456'
|
|
},
|
|
escort: {
|
|
serviceId: 3,
|
|
serviceName: '检查陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '华东医院',
|
|
address: '上海市静安区延安西路221号',
|
|
department: '体检中心',
|
|
doctor: '',
|
|
medicalRecordNo: 'MR202405004'
|
|
},
|
|
schedule: {
|
|
date: '2024-05-28T07:30:00.000Z',
|
|
dateText: '05月28日',
|
|
startTime: '07:30',
|
|
endTime: '11:00',
|
|
duration: 210
|
|
},
|
|
attendant: {
|
|
id: 'att004',
|
|
name: '孙陪诊',
|
|
sex: 'male'
|
|
},
|
|
payment: {
|
|
totalFee: 258,
|
|
paidFee: 258,
|
|
status: 'paid'
|
|
},
|
|
notes: {
|
|
patientNote: '需要空腹检查',
|
|
escortNote: '服务完成,患者已安全送回家',
|
|
medicalSummary: '完成全身检查,各项指标正常'
|
|
},
|
|
status: 'completed',
|
|
statusText: '已完成',
|
|
meta: {
|
|
createtime: '2024-05-25T09:00:00.000Z',
|
|
updatetime: '2024-05-28T11:30:00.000Z'
|
|
}
|
|
},
|
|
{
|
|
_id: 'ORD20240524005',
|
|
orderNo: '20240524005',
|
|
userId: 'user005',
|
|
patient: {
|
|
name: '钱七',
|
|
mobile: '135****7890',
|
|
sex: 'male',
|
|
age: 33,
|
|
idnumber: '310***********7890'
|
|
},
|
|
escort: {
|
|
serviceId: 2,
|
|
serviceName: '挂号陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '上海市第一人民医院',
|
|
address: '上海市虹口区武进路85号',
|
|
department: '眼科',
|
|
doctor: '周医生',
|
|
medicalRecordNo: 'MR202405005'
|
|
},
|
|
schedule: {
|
|
date: '2024-05-27T10:00:00.000Z',
|
|
dateText: '05月27日',
|
|
startTime: '10:00',
|
|
endTime: '11:00',
|
|
duration: 60
|
|
},
|
|
attendant: {
|
|
id: '',
|
|
name: '',
|
|
sex: 'none'
|
|
},
|
|
payment: {
|
|
totalFee: 128,
|
|
paidFee: 0,
|
|
status: 'unpaid'
|
|
},
|
|
notes: {
|
|
patientNote: '临时有事,需要取消',
|
|
escortNote: '',
|
|
medicalSummary: ''
|
|
},
|
|
status: 'cancelled',
|
|
statusText: '已取消',
|
|
meta: {
|
|
createtime: '2024-05-24T14:00:00.000Z',
|
|
updatetime: '2024-05-26T09:00:00.000Z'
|
|
}
|
|
},
|
|
{
|
|
_id: 'ORD20240523006',
|
|
orderNo: '20240523006',
|
|
userId: 'user006',
|
|
patient: {
|
|
name: '孙八',
|
|
mobile: '134****2468',
|
|
sex: 'female',
|
|
age: 60,
|
|
idnumber: '310***********2468'
|
|
},
|
|
escort: {
|
|
serviceId: 1,
|
|
serviceName: '全程陪诊服务'
|
|
},
|
|
hospital: {
|
|
province: '上海',
|
|
name: '上海中医药大学附属龙华医院',
|
|
address: '上海市徐汇区宛平南路725号',
|
|
department: '中医内科',
|
|
doctor: '吴医生',
|
|
medicalRecordNo: 'MR202405006'
|
|
},
|
|
schedule: {
|
|
date: '2024-06-02T08:00:00.000Z',
|
|
dateText: '06月02日',
|
|
startTime: '08:00',
|
|
endTime: '11:00',
|
|
duration: 180
|
|
},
|
|
attendant: {
|
|
id: 'att005',
|
|
name: '周陪诊',
|
|
sex: 'female'
|
|
},
|
|
payment: {
|
|
totalFee: 328,
|
|
paidFee: 328,
|
|
status: 'paid'
|
|
},
|
|
notes: {
|
|
patientNote: ' prefer 女陪诊员',
|
|
escortNote: '',
|
|
medicalSummary: ''
|
|
},
|
|
status: 'pending',
|
|
statusText: '待确认',
|
|
meta: {
|
|
createtime: '2024-05-23T11:00:00.000Z',
|
|
updatetime: '2024-05-23T11:00:00.000Z'
|
|
}
|
|
}
|
|
];
|
|
|
|
Page({
|
|
|
|
/**
|
|
* 页面的初始数据
|
|
*/
|
|
data: {
|
|
// 统计
|
|
stats: {
|
|
total: 0,
|
|
pending: 0,
|
|
confirmed: 0,
|
|
inProgress: 0,
|
|
completed: 0,
|
|
cancelled: 0
|
|
},
|
|
// 状态筛选
|
|
statusFilters: STATUS_FILTERS,
|
|
currentStatus: '',
|
|
// 订单列表
|
|
orderList: [],
|
|
// 分页
|
|
page: 1,
|
|
pageSize: 10,
|
|
hasMore: true,
|
|
// 加载状态
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
isRefreshing: false
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
onLoad(options) {
|
|
this.loadOrderList();
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面显示
|
|
*/
|
|
onShow() {
|
|
// 页面显示时刷新数据
|
|
if (this.data.orderList.length > 0) {
|
|
this.refreshData();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 计算统计数据
|
|
*/
|
|
calculateStats(orders) {
|
|
const stats = {
|
|
total: orders.length,
|
|
pending: 0,
|
|
confirmed: 0,
|
|
inProgress: 0,
|
|
completed: 0,
|
|
cancelled: 0
|
|
};
|
|
|
|
orders.forEach(order => {
|
|
switch (order.status) {
|
|
case 'pending':
|
|
stats.pending++;
|
|
break;
|
|
case 'confirmed':
|
|
stats.confirmed++;
|
|
break;
|
|
case 'in_progress':
|
|
stats.inProgress++;
|
|
break;
|
|
case 'completed':
|
|
stats.completed++;
|
|
break;
|
|
case 'cancelled':
|
|
stats.cancelled++;
|
|
break;
|
|
}
|
|
});
|
|
|
|
return stats;
|
|
},
|
|
|
|
/**
|
|
* 更新筛选标签计数
|
|
*/
|
|
updateFilterCounts(stats) {
|
|
const statusFilters = this.data.statusFilters.map(filter => {
|
|
let count = 0;
|
|
switch (filter.value) {
|
|
case '':
|
|
count = stats.total;
|
|
break;
|
|
case 'pending':
|
|
count = stats.pending;
|
|
break;
|
|
case 'confirmed':
|
|
count = stats.confirmed;
|
|
break;
|
|
case 'in_progress':
|
|
count = stats.inProgress;
|
|
break;
|
|
case 'completed':
|
|
count = stats.completed;
|
|
break;
|
|
case 'cancelled':
|
|
count = stats.cancelled;
|
|
break;
|
|
}
|
|
return { ...filter, count };
|
|
});
|
|
|
|
this.setData({ statusFilters });
|
|
},
|
|
|
|
/**
|
|
* 格式化日期
|
|
*/
|
|
formatDate(dateStr) {
|
|
if (!dateStr) return '';
|
|
const date = new Date(dateStr);
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
return `${month}月${day}日`;
|
|
},
|
|
|
|
/**
|
|
* 处理订单数据
|
|
*/
|
|
processOrders(orders) {
|
|
return orders.map(order => ({
|
|
...order,
|
|
statusText: STATUS_MAP[order.status]?.text || order.status,
|
|
'schedule.dateText': this.formatDate(order.schedule.date)
|
|
}));
|
|
},
|
|
|
|
/**
|
|
* 加载订单列表
|
|
*/
|
|
loadOrderList(isRefresh = false) {
|
|
if (this.data.isLoading || this.data.isLoadingMore) return;
|
|
|
|
const { currentStatus, page, pageSize } = this.data;
|
|
|
|
this.setData({ isLoading: !isRefresh, isLoadingMore: isRefresh && page > 1 });
|
|
|
|
// 模拟 API 请求延迟
|
|
setTimeout(() => {
|
|
// 筛选数据
|
|
let filteredOrders = MOCK_ORDERS;
|
|
if (currentStatus) {
|
|
filteredOrders = MOCK_ORDERS.filter(order => order.status === currentStatus);
|
|
}
|
|
|
|
// 分页
|
|
const start = (page - 1) * pageSize;
|
|
const end = start + pageSize;
|
|
const pageData = filteredOrders.slice(start, end);
|
|
|
|
// 处理数据
|
|
const processedOrders = this.processOrders(pageData);
|
|
|
|
// 计算统计
|
|
const stats = this.calculateStats(MOCK_ORDERS);
|
|
this.updateFilterCounts(stats);
|
|
|
|
// 更新列表
|
|
const orderList = isRefresh && page > 1
|
|
? [...this.data.orderList, ...processedOrders]
|
|
: processedOrders;
|
|
|
|
this.setData({
|
|
orderList,
|
|
stats,
|
|
isLoading: false,
|
|
isLoadingMore: false,
|
|
isRefreshing: false,
|
|
hasMore: end < filteredOrders.length
|
|
});
|
|
}, 600);
|
|
},
|
|
|
|
/**
|
|
* 刷新数据
|
|
*/
|
|
refreshData() {
|
|
this.setData({ page: 1, hasMore: true }, () => {
|
|
this.loadOrderList();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 状态筛选切换
|
|
*/
|
|
onStatusChange(e) {
|
|
const status = e.currentTarget.dataset.status;
|
|
if (status === this.data.currentStatus) return;
|
|
|
|
this.setData({
|
|
currentStatus: status,
|
|
page: 1,
|
|
hasMore: true,
|
|
orderList: []
|
|
}, () => {
|
|
this.loadOrderList();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 订单详情
|
|
*/
|
|
onOrderDetail(e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
wx.navigateTo({
|
|
url: `/pages/order/detail?id=${id}`
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 订单操作
|
|
*/
|
|
onOrderAction(e) {
|
|
const { id, action } = e.currentTarget.dataset;
|
|
const order = this.data.orderList.find(item => item._id === id);
|
|
if (!order) return;
|
|
|
|
// 阻止冒泡,防止触发卡片点击
|
|
e.stopPropagation();
|
|
|
|
const actionMap = {
|
|
confirm: { title: '确认订单', content: '确认接受此订单?', nextStatus: 'confirmed' },
|
|
cancel: { title: '取消订单', content: '确定要取消此订单?', nextStatus: 'cancelled' },
|
|
start: { title: '开始服务', content: '确认开始陪诊服务?', nextStatus: 'in_progress' },
|
|
complete: { title: '完成服务', content: '确认陪诊服务已完成?', nextStatus: 'completed' },
|
|
detail: { title: '', content: '', nextStatus: '' }
|
|
};
|
|
|
|
const actionConfig = actionMap[action];
|
|
if (!actionConfig) return;
|
|
|
|
if (action === 'detail') {
|
|
wx.navigateTo({
|
|
url: `/pages/order/detail?id=${id}`
|
|
});
|
|
return;
|
|
}
|
|
|
|
wx.showModal({
|
|
title: actionConfig.title,
|
|
content: actionConfig.content,
|
|
confirmColor: '#4c6ef5',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
// 更新订单状态
|
|
this.updateOrderStatus(id, actionConfig.nextStatus);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 更新订单状态
|
|
*/
|
|
updateOrderStatus(id, newStatus) {
|
|
wx.showLoading({ title: '处理中...' });
|
|
|
|
// 模拟 API 请求
|
|
setTimeout(() => {
|
|
const orderList = this.data.orderList.map(order => {
|
|
if (order._id === id) {
|
|
return {
|
|
...order,
|
|
status: newStatus,
|
|
statusText: STATUS_MAP[newStatus]?.text || newStatus,
|
|
'meta.updatetime': new Date().toISOString()
|
|
};
|
|
}
|
|
return order;
|
|
});
|
|
|
|
// 重新计算统计
|
|
const allOrders = MOCK_ORDERS.map(order => {
|
|
if (order._id === id) {
|
|
return { ...order, status: newStatus };
|
|
}
|
|
return order;
|
|
});
|
|
const stats = this.calculateStats(allOrders);
|
|
this.updateFilterCounts(stats);
|
|
|
|
this.setData({ orderList, stats });
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '操作成功', icon: 'success' });
|
|
}, 500);
|
|
},
|
|
|
|
/**
|
|
* 页面相关事件处理函数--监听用户下拉动作
|
|
*/
|
|
onPullDownRefresh() {
|
|
this.setData({ isRefreshing: true, page: 1, hasMore: true }, () => {
|
|
this.loadOrderList();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 页面上拉触底事件的处理函数
|
|
*/
|
|
onReachBottom() {
|
|
if (!this.data.hasMore || this.data.isLoadingMore) return;
|
|
|
|
this.setData({ page: this.data.page + 1 }, () => {
|
|
this.loadOrderList(true);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 用户点击右上角分享
|
|
*/
|
|
onShareAppMessage() {
|
|
return {
|
|
title: '订单管理',
|
|
path: '/pages/order/index'
|
|
};
|
|
}
|
|
});
|