<template>
|
<view class="cases-container">
|
<!-- 时间轴视图 -->
|
<scroll-view
|
scroll-y
|
class="timeline-view"
|
refresher-enabled
|
:refresher-triggered="refreshing"
|
@refresherrefresh="onRefresh"
|
@scrolltolower="onLoadMore"
|
>
|
<view class="timeline">
|
<view
|
class="timeline-item"
|
v-for="(item, index) in caseList"
|
:key="index"
|
@tap="viewDetail(item)"
|
>
|
<!-- 时间点 -->
|
<view class="time-point">
|
<text class="date">{{ item.date.split(' ')[0] }}</text>
|
<text class="time">{{ item.date.split(' ')[1] }}</text>
|
</view>
|
|
<!-- 病例卡片 -->
|
<view class="case-card">
|
<!-- 医院信息 -->
|
<view class="hospital-info">
|
<image :src="item.hospitalLogo" mode="aspectFit" class="logo" />
|
<view class="info">
|
<text class="name">{{ item.hospitalName }}</text>
|
<text class="department">{{ item.departmentName }}</text>
|
</view>
|
</view>
|
|
<!-- 诊断信息 -->
|
<view class="diagnosis-info">
|
<view class="section">
|
<text class="label">主诉</text>
|
<text class="value">{{ item.complaint }}</text>
|
</view>
|
<view class="section">
|
<text class="label">诊断</text>
|
<text class="value">{{ item.diagnosis }}</text>
|
</view>
|
<view class="section">
|
<text class="label">处理</text>
|
<text class="value">{{ item.treatment }}</text>
|
</view>
|
</view>
|
|
<!-- 医生信息 -->
|
<view class="doctor-info">
|
<view class="doctor">
|
<image :src="item.doctorAvatar" mode="aspectFill" class="avatar" />
|
<view class="info">
|
<text class="name">{{ item.doctorName }}</text>
|
<text class="title">{{ item.doctorTitle }}</text>
|
</view>
|
</view>
|
<view class="actions">
|
<view class="action-btn" @tap.stop="viewReport(item)">
|
<text class="iconfont icon-report"></text>
|
<text>查看报告</text>
|
</view>
|
<view class="action-btn" @tap.stop="bookAgain(item)">
|
<text class="iconfont icon-appointment"></text>
|
<text>复诊预约</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 加载更多 -->
|
<view class="load-more" v-if="hasMore">
|
<text>加载中...</text>
|
</view>
|
|
<!-- 没有更多数据 -->
|
<view class="no-more" v-if="!hasMore && caseList.length > 0">
|
<text>没有更多病例了</text>
|
</view>
|
</view>
|
|
<!-- 空状态 -->
|
<view class="empty-state" v-if="caseList.length === 0">
|
<image src="/static/empty/no-cases.png" mode="aspectFit" />
|
<text>暂无病例记录</text>
|
</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref } from 'vue'
|
|
// 分页相关
|
const pageSize = 10
|
const currentPage = ref(1)
|
const hasMore = ref(true)
|
const refreshing = ref(false)
|
|
// 病例列表数据
|
const caseList = ref([
|
{
|
id: 1,
|
date: '2024-03-25 09:30',
|
hospitalName: '青岛镜湖医院',
|
hospitalLogo: '/static/hospital/kiang-wu.jpg',
|
departmentName: '心内科',
|
complaint: '胸闷、气短2天',
|
diagnosis: '冠心病、高血压2级',
|
treatment: '1. 硝酸甘油片含服\n2. 阿司匹林肠溶片口服\n3. 建议定期复查',
|
doctorName: '张医生',
|
doctorTitle: '主任医师',
|
doctorAvatar: '/static/doctor/doctor1.jpg',
|
hasReport: true
|
},
|
{
|
id: 2,
|
date: '2024-03-20 15:00',
|
hospitalName: '青岛科大医院',
|
hospitalLogo: '/static/hospital/must.jpg',
|
departmentName: '消化内科',
|
complaint: '上腹部不适1周',
|
diagnosis: '慢性胃炎',
|
treatment: '1. 奥美拉唑胶囊\n2. 多潘立酮片\n3. 注意饮食调理',
|
doctorName: '李医生',
|
doctorTitle: '副主任医师',
|
doctorAvatar: '/static/doctor/doctor2.jpg',
|
hasReport: true
|
},
|
// ... 更多病例数据
|
])
|
|
// 下拉刷新
|
const onRefresh = () => {
|
refreshing.value = true
|
// 重置页码
|
currentPage.value = 1
|
// 重新加载数据
|
loadCases()
|
setTimeout(() => {
|
refreshing.value = false
|
}, 1000)
|
}
|
|
// 加载更多
|
const onLoadMore = () => {
|
if (!hasMore.value) return
|
currentPage.value++
|
loadCases()
|
}
|
|
// 加载病例数据
|
const loadCases = () => {
|
// 这里应该调用API获取数据
|
// 模拟加载
|
setTimeout(() => {
|
if (currentPage.value >= 3) {
|
hasMore.value = false
|
}
|
}, 1000)
|
}
|
|
// 查看详情
|
const viewDetail = (item) => {
|
uni.navigateTo({
|
url: `/pages/my/case-detail?id=${item.id}`
|
})
|
}
|
|
// 查看报告
|
const viewReport = (item) => {
|
if (item.hasReport) {
|
uni.navigateTo({
|
url: `/pages/records/report?id=${item.id}`
|
})
|
}
|
}
|
|
// 复诊预约
|
const bookAgain = (item) => {
|
uni.navigateTo({
|
url: `/pages/appointment/doctor?departmentId=${item.departmentId}&hospitalId=${item.hospitalId}`
|
})
|
}
|
</script>
|
|
<style lang="scss">
|
.cases-container {
|
min-height: 100vh;
|
background: $bg-color;
|
|
.timeline-view {
|
height: 100vh;
|
|
.timeline {
|
padding: 30rpx;
|
|
.timeline-item {
|
display: flex;
|
margin-bottom: 40rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.time-point {
|
width: 120rpx;
|
text-align: center;
|
padding-top: 20rpx;
|
|
.date {
|
font-size: 26rpx;
|
color: $text-secondary;
|
margin-bottom: 8rpx;
|
display: block;
|
}
|
|
.time {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
|
&::before {
|
content: '';
|
display: block;
|
width: 16rpx;
|
height: 16rpx;
|
background: $primary-color;
|
border-radius: 50%;
|
margin: 0 auto 8rpx;
|
}
|
|
&::after {
|
content: '';
|
display: block;
|
width: 2rpx;
|
height: calc(100% + 40rpx);
|
background: #eee;
|
margin: 8rpx auto 0;
|
}
|
}
|
|
&:last-child {
|
.time-point::after {
|
display: none;
|
}
|
}
|
|
.case-card {
|
flex: 1;
|
background: #fff;
|
border-radius: $radius-lg;
|
padding: 30rpx;
|
margin-left: 30rpx;
|
box-shadow: $shadow-sm;
|
|
.hospital-info {
|
display: flex;
|
align-items: center;
|
padding-bottom: 20rpx;
|
border-bottom: 1rpx solid #eee;
|
|
.logo {
|
width: 60rpx;
|
height: 60rpx;
|
border-radius: $radius-sm;
|
margin-right: 16rpx;
|
}
|
|
.info {
|
.name {
|
font-size: 30rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 4rpx;
|
display: block;
|
}
|
|
.department {
|
font-size: 26rpx;
|
color: $text-regular;
|
}
|
}
|
}
|
|
.diagnosis-info {
|
padding: 20rpx 0;
|
border-bottom: 1rpx solid #eee;
|
|
.section {
|
margin-bottom: 16rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.label {
|
font-size: 26rpx;
|
color: $text-secondary;
|
margin-bottom: 8rpx;
|
display: block;
|
}
|
|
.value {
|
font-size: 28rpx;
|
color: $text-primary;
|
line-height: 1.6;
|
}
|
}
|
}
|
|
.doctor-info {
|
padding-top: 20rpx;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.doctor {
|
display: flex;
|
align-items: center;
|
|
.avatar {
|
width: 60rpx;
|
height: 60rpx;
|
border-radius: 50%;
|
margin-right: 16rpx;
|
}
|
|
.info {
|
.name {
|
font-size: 28rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 4rpx;
|
display: block;
|
}
|
|
.title {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
}
|
}
|
|
.actions {
|
display: flex;
|
gap: 20rpx;
|
|
.action-btn {
|
display: flex;
|
align-items: center;
|
padding: 12rpx 20rpx;
|
background: $primary-light;
|
border-radius: $radius-xl;
|
|
.iconfont {
|
font-size: 28rpx;
|
color: $primary-color;
|
margin-right: 8rpx;
|
}
|
|
text {
|
font-size: 24rpx;
|
color: $primary-color;
|
}
|
|
&:active {
|
opacity: 0.8;
|
}
|
}
|
}
|
}
|
|
&:active {
|
transform: scale(0.99);
|
}
|
}
|
}
|
}
|
|
.load-more,
|
.no-more {
|
text-align: center;
|
padding: 30rpx 0;
|
|
text {
|
font-size: 26rpx;
|
color: $text-secondary;
|
}
|
}
|
|
.empty-state {
|
padding: 120rpx 0;
|
text-align: center;
|
|
image {
|
width: 240rpx;
|
height: 240rpx;
|
margin-bottom: 30rpx;
|
}
|
|
text {
|
font-size: 28rpx;
|
color: $text-secondary;
|
}
|
}
|
}
|
}
|
</style>
|