This commit is contained in:
lik
2026-06-08 12:01:40 +08:00
parent 010cf160a0
commit 894a9881d7
51 changed files with 2667 additions and 740 deletions

View File

@@ -1,66 +1,90 @@
// pages/home/index.js
const API = require('../../utils/api.js')
Page({
/**
* 页面的初始数据
*/
data: {
todayCount: 0,
pendingCount: 0,
completedCount: 0,
menuList: [
{ icon: '/images/icon_order.png', name: '订单管理', url: '/pages/order/index' },
{ icon: '/images/icon_patient.png', name: '患者管理', url: '/pages/patient/index' },
{ icon: '/images/icon_escort.png', name: '陪诊员管理', url: '/pages/escort/index' },
{ icon: '/images/icon_schedule.png', name: '排班管理', url: '/pages/schedule/index' },
{ icon: '/images/icon_stats.png', name: '数据统计', url: '/pages/stats/index' },
{ icon: '/images/icon_setting.png', name: '系统设置', url: '/pages/setting/index' }
],
todayOrders: [],
statusMap: {
pending: '待确认',
confirmed: '已确认',
in_progress: '进行中',
completed: '已完成',
cancelled: '已取消'
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
return {
title: '暖橙陪诊后台', // 转发标题
path: '/pages/home/index',
}
},
onShareTimeline: function () {
return {
title: '暖橙陪诊后台',
}
},
onLoad(options) {
this.getTodayOrders();
this.getStats();
},
onShow() {
this.getTodayOrders();
this.getStats();
},
async getStats() {
const today = new Date().toISOString().substring(0, 10);
const [todayRes, pendingRes, completedRes] = await Promise.all([
API.escort.getMyRecords({ appointmentDate: today }),
API.escort.getMyRecords({ status: ['pending', 'confirmed'] }),
API.escort.getMyRecords({ status: ['completed'] })
]);
this.setData({
todayCount: todayRes.code === 0 ? (todayRes.data.records || []).length : 0,
pendingCount: pendingRes.code === 0 ? (pendingRes.data.records || []).length : 0,
completedCount: completedRes.code === 0 ? (completedRes.data.records || []).length : 0,
});
},
async getTodayOrders() {
const res = await API.escort.getMyRecords({
appointmentDate: new Date().toISOString().substring(0, 10),
});
if (res.code == 0) {
const records = (res.data.records || []).map(item => {
if (item.schedule && item.schedule.date) {
const d = new Date(item.schedule.date);
item.schedule.date = d.toISOString().substring(0, 10) + ' ' + d.toTimeString().substring(0, 5);
}
return item;
});
this.setData({ todayOrders: records });
}
},
navigateTo(e) {
const url = e.currentTarget.dataset.url
wx.navigateTo({ url })
},
viewAllOrders() {
wx.navigateTo({
url: '/pages/order/index'
})
}
})
})

View File

@@ -1,2 +1,69 @@
<!--pages/home/index.wxml-->
<text>pages/home/index.wxml</text>
<view class="container">
<!-- 顶部统计卡片 -->
<view class="stats-section">
<view class="stats-card">
<text class="stats-num">{{todayCount}}</text>
<text class="stats-label">今日订单</text>
</view>
<view class="stats-card">
<text class="stats-num">{{pendingCount}}</text>
<text class="stats-label">待处理</text>
</view>
<view class="stats-card">
<text class="stats-num">{{completedCount}}</text>
<text class="stats-label">已完成</text>
</view>
</view>
<!-- 功能菜单 -->
<view class="menu-section">
<view class="section-title">功能菜单</view>
<view class="menu-grid">
<view class="menu-item" wx:for="{{menuList}}" wx:key="index" bindtap="navigateTo" data-url="{{item.url}}">
<view class="menu-icon">
<text class="icon-text">{{item.name[0]}}</text>
</view>
<text class="menu-name">{{item.name}}</text>
</view>
</view>
</view>
<!-- 今日订单 -->
<view class="order-section">
<view class="section-header">
<text class="section-title">今日订单</text>
<text class="view-all" bindtap="viewAllOrders">查看全部 ></text>
</view>
<view class="order-list">
<view class="order-item" wx:for="{{todayOrders}}" wx:key="_id">
<view class="order-header">
<text class="order-id">{{item._id}}</text>
<text class="order-status status-{{item.status}}">{{statusMap[item.status] || item.status}}</text>
</view>
<view class="order-info">
<view class="info-row">
<text class="info-label">患者</text>
<text class="info-value">{{item.patient.name}}</text>
</view>
<view class="info-row">
<text class="info-label">医院</text>
<text class="info-value">{{item.hospital.name}} · {{item.hospital.department}}</text>
</view>
<view class="info-row">
<text class="info-label">时间</text>
<text class="info-value">{{item.schedule.date}}</text>
</view>
<view class="info-row">
<text class="info-label">服务</text>
<text class="info-value">{{item.escort.serviceName}}</text>
</view>
<view class="info-row">
<text class="info-label">费用</text>
<text class="info-value fee-value">¥{{item.payment.totalFee}}</text>
</view>
</view>
</view>
</view>
</view>
</view>

View File

@@ -1 +1,208 @@
/* pages/home/index.wxss */
/* pages/home/index.wxss */
.container {
padding: 20rpx;
background-color: #f5f6fa;
min-height: 100vh;
}
/* 统计卡片 */
.stats-section {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
}
.stats-card {
flex: 1;
background: #fff;
border-radius: 16rpx;
padding: 30rpx 0;
margin: 0 10rpx;
text-align: center;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
}
.stats-card:first-child {
margin-left: 0;
}
.stats-card:last-child {
margin-right: 0;
}
.stats-num {
display: block;
font-size: 48rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8rpx;
}
.stats-label {
display: block;
font-size: 26rpx;
color: #7f8c8d;
}
/* 功能菜单 */
.menu-section {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #2c3e50;
margin-bottom: 24rpx;
}
.menu-grid {
display: flex;
flex-wrap: wrap;
}
.menu-item {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx 0;
}
.menu-icon {
width: 88rpx;
height: 88rpx;
background: #e8f4fd;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12rpx;
}
.icon-text {
font-size: 36rpx;
color: #3498db;
font-weight: 600;
}
.menu-name {
font-size: 26rpx;
color: #555;
}
/* 今日订单 */
.order-section {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.section-header .section-title {
margin-bottom: 0;
}
.view-all {
font-size: 26rpx;
color: #3498db;
}
.order-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.order-item {
background: #f8f9fa;
border-radius: 12rpx;
padding: 24rpx;
}
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.order-id {
font-size: 26rpx;
color: #7f8c8d;
}
.order-status {
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 8rpx;
}
.status-pending {
background: #fff3e0;
color: #f39c12;
}
.status-in_progress {
background: #e8f5e9;
color: #27ae60;
}
.status-confirmed {
background: #e3f2fd;
color: #2980b9;
}
.status-pending {
background: #fff3e0;
color: #f39c12;
}
.status-completed {
background: #f3e5f5;
color: #8e44ad;
}
.status-cancelled {
background: #fafafa;
color: #95a5a6;
}
.order-info {
display: flex;
flex-direction: column;
gap: 10rpx;
}
.info-row {
display: flex;
align-items: center;
}
.info-label {
font-size: 26rpx;
color: #95a5a6;
width: 80rpx;
flex-shrink: 0;
}
.info-value {
font-size: 28rpx;
color: #2c3e50;
}
.fee-value {
color: #e74c3c;
font-weight: 600;
}