383 lines
7.8 KiB
Vue
383 lines
7.8 KiB
Vue
<template>
|
||
<view class="card-container">
|
||
<!-- 顶部标题栏 -->
|
||
|
||
|
||
<!-- 就诊卡列表 -->
|
||
<view class="card-list">
|
||
<view
|
||
v-for="card in cardList"
|
||
:key="card.id"
|
||
class="card-item"
|
||
@click="viewCardDetail(card)"
|
||
>
|
||
<!-- 卡片头部 -->
|
||
<view class="card-header">
|
||
<view class="card-id">
|
||
<text class="label">诊单编号:</text>
|
||
<text class="value">{{ card.id }}</text>
|
||
</view>
|
||
<view :class="['status-badge', getStatusClass(card.status)]">
|
||
{{ card.status_desc || getStatusText(card.status) }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 患者信息 -->
|
||
<view class="card-info">
|
||
<view class="info-row">
|
||
<text class="info-label">患者姓名:</text>
|
||
<text class="info-value">{{ card.patient_name || '-' }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">性别年龄:</text>
|
||
<text class="info-value">{{ card.gender_desc || '-' }} / {{ card.age }}岁</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">诊断类型:</text>
|
||
<text class="info-value">{{ getDiagnosisTypeName(card.diagnosis_type) }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="info-label">证型:</text>
|
||
<text class="info-value">{{ getSyndromeTypeName(card.syndrome_type) }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 时间信息 -->
|
||
<view class="card-footer">
|
||
<view class="time-info">
|
||
<text class="time-label">诊断日期:</text>
|
||
<text class="time-value">{{ card.diagnosis_date_text || formatDate(card.diagnosis_date) }}</text>
|
||
</view>
|
||
<view class="time-info">
|
||
<text class="time-label">创建时间:</text>
|
||
<text class="time-value">{{ card.create_time || '-' }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view v-if="!loading && cardList.length === 0" class="empty-state">
|
||
<uni-icons type="wallet" size="60" color="#999"></uni-icons>
|
||
<text class="empty-text">暂无就诊卡</text>
|
||
<view class="add-card-btn" @click="createCard">新建就诊卡</view>
|
||
</view>
|
||
|
||
<!-- 加载状态 -->
|
||
<view v-if="loading" class="loading-state">
|
||
<text class="loading-text">加载中...</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||
import { onLaunch, onShow, onHide, onError ,onShareAppMessage} from '@dcloudio/uni-app'
|
||
const { proxy } = getCurrentInstance()
|
||
|
||
// 数据
|
||
const cardList = ref([])
|
||
const loading = ref(false)
|
||
|
||
// 页面加载时获取数据
|
||
onMounted(() => {
|
||
loadCardList()
|
||
})
|
||
onShow(() => {
|
||
loadCardList()
|
||
})
|
||
// 加载就诊卡列表
|
||
const loadCardList = async () => {
|
||
loading.value = true
|
||
try {
|
||
// 检查token是否存在
|
||
const token = uni.getStorageSync('token')
|
||
if (!token) {
|
||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||
// setTimeout(() => {
|
||
// uni.redirectTo({ url: '/pages/login/login' })
|
||
// }, 1500)
|
||
return
|
||
}
|
||
|
||
// 获取当前用户的patient_id
|
||
const userData = uni.getStorageSync('userData')
|
||
const patientId = userData?.diagnosis?.patient_id
|
||
|
||
if (!patientId) {
|
||
//uni.showToast({ title: '患者信息不存在', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
// 调用后端接口获取就诊卡列表
|
||
const res = await proxy.apiUrl({
|
||
url: '/api/tcm/getCardList',
|
||
method: 'GET',
|
||
data: {
|
||
patient_id: patientId
|
||
}
|
||
})
|
||
|
||
if (res.code === 1) {
|
||
cardList.value = res.data || []
|
||
} else {
|
||
uni.showToast({ title: res.msg || '获取失败', icon: 'none' })
|
||
}
|
||
} catch (err) {
|
||
console.error('加载就诊卡列表失败:', err)
|
||
//uni.showToast({ title: '加载失败', icon: 'none' })
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 查看卡片详情
|
||
const viewCardDetail = (card) => {
|
||
uni.navigateTo({
|
||
url: `/pages/Card/edit_card?id=${card.id}`
|
||
})
|
||
}
|
||
|
||
// 新建就诊卡(patient_id 创建后自动生成,仅需登录)
|
||
const createCard = () => {
|
||
const token = uni.getStorageSync('token')
|
||
if (!token) {
|
||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||
return
|
||
}
|
||
uni.navigateTo({
|
||
url: '/pages/Card/edit_card?add=1'
|
||
})
|
||
}
|
||
|
||
// 获取状态文本
|
||
const getStatusText = (status) => {
|
||
return status === 1 ? '启用' : '禁用'
|
||
}
|
||
|
||
// 获取状态样式类
|
||
const getStatusClass = (status) => {
|
||
return status === 1 ? 'status-confirmed' : 'status-pending'
|
||
}
|
||
|
||
// 诊断类型字典
|
||
const diagnosisTypeMap = {
|
||
'first_visit': '初诊',
|
||
'follow_up': '复诊',
|
||
'consultation': '会诊'
|
||
}
|
||
|
||
// 证型字典
|
||
const syndromeTypeMap = {
|
||
'qi_deficiency': '气虚',
|
||
'blood_deficiency': '血虚',
|
||
'yin_deficiency': '阴虚',
|
||
'yang_deficiency': '阳虚',
|
||
'qi_stagnation': '气滞',
|
||
'blood_stasis': '血瘀',
|
||
'phlegm_dampness': '痰湿',
|
||
'damp_heat': '湿热',
|
||
'cold_dampness': '寒湿',
|
||
'wind_cold': '风寒',
|
||
'wind_heat': '风热'
|
||
}
|
||
|
||
// 获取诊断类型名称
|
||
const getDiagnosisTypeName = (type) => {
|
||
return diagnosisTypeMap[type] || type || '-'
|
||
}
|
||
|
||
// 获取证型名称
|
||
const getSyndromeTypeName = (type) => {
|
||
return syndromeTypeMap[type] || type || '-'
|
||
}
|
||
|
||
// 格式化日期(时间戳转日期)
|
||
const formatDate = (timestamp) => {
|
||
if (!timestamp) return '-'
|
||
const date = new Date(timestamp * 1000)
|
||
const year = date.getFullYear()
|
||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||
const day = String(date.getDate()).padStart(2, '0')
|
||
return `${year}-${month}-${day}`
|
||
}
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.card-container {
|
||
min-height: 100vh;
|
||
background: linear-gradient(180deg, #f0f7ff 0%, #ffffff 100%);
|
||
padding-bottom: 40rpx;
|
||
}
|
||
|
||
.header {
|
||
background: #ffffff;
|
||
padding: 40rpx 30rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
|
||
.header-title {
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
color: #1890ff;
|
||
}
|
||
}
|
||
|
||
.card-list {
|
||
padding: 30rpx;
|
||
}
|
||
|
||
.card-item {
|
||
background: #ffffff;
|
||
border-radius: 20rpx;
|
||
padding: 30rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||
transition: all 0.3s;
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
padding-bottom: 20rpx;
|
||
border-bottom: 2rpx solid #f0f0f0;
|
||
}
|
||
|
||
.card-id {
|
||
.label {
|
||
font-size: 28rpx;
|
||
color: #666666;
|
||
}
|
||
|
||
.value {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
}
|
||
|
||
.status-badge {
|
||
padding: 8rpx 20rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
|
||
&.status-confirmed {
|
||
background: #f6ffed;
|
||
color: #204e2b;
|
||
border: 2rpx solid #204e2b;
|
||
}
|
||
|
||
&.status-pending {
|
||
background: #fff7e6;
|
||
color: #fa8c16;
|
||
border: 2rpx solid #ffd591;
|
||
}
|
||
}
|
||
|
||
.card-info {
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.info-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
|
||
.info-label {
|
||
font-size: 28rpx;
|
||
color: #666666;
|
||
min-width: 160rpx;
|
||
}
|
||
|
||
.info-value {
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.card-footer {
|
||
padding-top: 20rpx;
|
||
border-top: 2rpx solid #f0f0f0;
|
||
}
|
||
|
||
.time-info {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12rpx;
|
||
|
||
.time-label {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
min-width: 140rpx;
|
||
}
|
||
|
||
.time-value {
|
||
font-size: 26rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.view-count {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 8rpx;
|
||
|
||
.count-icon {
|
||
font-size: 28rpx;
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
.count-text {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
.empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 120rpx 0;
|
||
|
||
.empty-icon {
|
||
font-size: 120rpx;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.empty-text {
|
||
font-size: 32rpx;
|
||
color: #999999;
|
||
margin-bottom: 40rpx;
|
||
}
|
||
}
|
||
|
||
.add-card-btn {
|
||
padding: 24rpx 64rpx;
|
||
background: #1890ff;
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
border-radius: 48rpx;
|
||
}
|
||
|
||
.loading-state {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 80rpx 0;
|
||
|
||
.loading-text {
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
</style>
|