|
|
<template>
|
|
|
<view class="container">
|
|
|
<view class="user-bar card">
|
|
|
<view class="user-info">
|
|
|
<view class="user-avatar">👤</view>
|
|
|
<view>
|
|
|
<view class="user-name">{{ patientName }},您好</view>
|
|
|
<view class="user-desc">欢迎使用医技预约系统</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="logout-btn" @tap="handleLogout">退出</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="tab-bar">
|
|
|
<view class="tab-item" :class="{ active: currentTab === 0 }" @tap="switchTab(0)">待预约</view>
|
|
|
<view class="tab-item" :class="{ active: currentTab === 1 }" @tap="switchTab(1)">已预约</view>
|
|
|
</view>
|
|
|
|
|
|
<view v-if="list.length === 0" class="empty-state">
|
|
|
<view class="empty-icon">📋</view>
|
|
|
<view>{{ currentTab === 0 ? '暂无待预约的检查项目' : '暂无已预约的检查项目' }}</view>
|
|
|
</view>
|
|
|
|
|
|
<view v-for="item in list" :key="item.id" class="card list-card" @tap="goDetail(item)">
|
|
|
<view class="card-header">
|
|
|
<view class="item-name">{{ item.examination_item_name }}</view>
|
|
|
<view class="status-tag" :class="getStatusClass(item.status)">{{ getStatusText(item.status) }}</view>
|
|
|
</view>
|
|
|
<view class="card-info">
|
|
|
<view class="info-row"><text class="info-label">执行科室</text><text class="info-value">{{ item.examination_department_name || '-' }}</text></view>
|
|
|
<view class="info-row"><text class="info-label">申请科室</text><text class="info-value">{{ item.apply_department_name || '-' }}</text></view>
|
|
|
<view class="info-row"><text class="info-label">申请时间</text><text class="info-value">{{ formatTime(item.apply_time) }}</text></view>
|
|
|
</view>
|
|
|
<view v-if="item.appointment_info" class="appointment-info">
|
|
|
<view class="info-row"><text class="info-label">预约时间</text><text class="info-value highlight">{{ formatTime(item.appointment_info.appointment_time) }}</text></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { getApplicationList } from '../../services/application'
|
|
|
import { useUserStore } from '../../store/user'
|
|
|
import { formatTime, getStatusText, getStatusClass } from '../../utils/format'
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
|
return { currentTab: 0, list: [], loading: false }
|
|
|
},
|
|
|
computed: {
|
|
|
patientName() { return useUserStore().patientName }
|
|
|
},
|
|
|
onShow() { this.loadData() },
|
|
|
onPullDownRefresh() { this.loadData().finally(() => uni.stopPullDownRefresh()) },
|
|
|
methods: {
|
|
|
formatTime, getStatusText, getStatusClass,
|
|
|
switchTab(idx) { this.currentTab = idx; this.loadData() },
|
|
|
async loadData() {
|
|
|
if (this.loading) return
|
|
|
this.loading = true
|
|
|
try {
|
|
|
const res = await getApplicationList({ status: this.currentTab === 0 ? 0 : 1 })
|
|
|
this.list = res.data.list || []
|
|
|
} catch (e) { this.list = [] }
|
|
|
this.loading = false
|
|
|
},
|
|
|
goDetail(item) {
|
|
|
uni.navigateTo({ url: `/pages/application/detail?id=${item.id}` })
|
|
|
},
|
|
|
handleLogout() {
|
|
|
uni.showModal({ title: '提示', content: '确定要退出登录吗?', success: (res) => {
|
|
|
if (res.confirm) { useUserStore().logout() }
|
|
|
}})
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
.user-bar { display: flex; justify-content: space-between; align-items: center; padding: 30rpx; }
|
|
|
.user-info { display: flex; align-items: center; }
|
|
|
.user-avatar { width: 80rpx; height: 80rpx; border-radius: 50%; background: #E8F4FD; display: flex; align-items: center; justify-content: center; font-size: 40rpx; margin-right: 20rpx; }
|
|
|
.user-name { font-size: 32rpx; font-weight: 600; color: #333; }
|
|
|
.user-desc { font-size: 24rpx; color: #999; margin-top: 4rpx; }
|
|
|
.logout-btn { font-size: 26rpx; color: #999; padding: 12rpx 24rpx; border: 2rpx solid #E8E8E8; border-radius: 8rpx; }
|
|
|
.tab-bar { display: flex; background: #FFF; border-radius: 16rpx; padding: 8rpx; margin-bottom: 20rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
|
|
|
.tab-item { flex: 1; text-align: center; padding: 20rpx 0; font-size: 30rpx; color: #666; border-radius: 12rpx; transition: all 0.2s; }
|
|
|
.tab-item.active { background: #2B7FD2; color: #FFF; font-weight: 600; }
|
|
|
.list-card { padding: 30rpx; }
|
|
|
.card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20rpx; }
|
|
|
.item-name { font-size: 32rpx; font-weight: 600; color: #333; }
|
|
|
.card-info { border-top: 2rpx solid #F5F5F5; padding-top: 16rpx; }
|
|
|
.info-row { display: flex; justify-content: space-between; padding: 8rpx 0; font-size: 26rpx; }
|
|
|
.info-label { color: #999; }
|
|
|
.info-value { color: #333; }
|
|
|
.info-value.highlight { color: #2B7FD2; font-weight: 500; }
|
|
|
.appointment-info { border-top: 2rpx solid #F5F5F5; margin-top: 16rpx; padding-top: 16rpx; }
|
|
|
</style>
|