uniapp-app/pages_app/patientDetail/patientDetail.vue
2025-10-14 17:46:23 +08:00

287 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<!-- 顶部导航栏 -->
<uni-nav-bar
left-icon="left"
title="患者详情"
@clickLeft="goBack"
fixed
color="#8B2316"
height="180rpx"
:border="false"
backgroundColor="#eeeeee"
>
<template #right>
<view class="nav-right" @click.stop="editPatient">
<uni-icons type="compose" size="22" color="#8B2316"></uni-icons>
</view>
</template>
</uni-nav-bar>
<!-- 头部信息卡片 -->
<view class="card header-card">
<image class="avatar" :src="docUrl+patientInfo.photo" mode="aspectFill"></image>
<view class="base-info">
<view class="name-row">
<text class="name">{{ patientInfo.realName || '未知' }}</text>
<up-image :src="genderIcon" width="36rpx" height="36rpx"></up-image>
</view>
<view class="line"><text class="label">昵称</text><text class="value">{{nickname }}</text></view>
<view class="line">
<text class="label">年龄</text><text class="value">{{ patientDetail.age || '未知' }}</text>
<text class="sep"></text>
<text class="label">民族</text><text class="value">{{ patientInfo.nationName || '未知' }}</text>
</view>
<view class="line multi">
<text class="label">地区</text>
<text class="value">{{ fullAddress }}</text>
</view>
</view>
</view>
<!-- 功能分组条目 -->
<view class="cell" @click="openGroup" style="margin-top: 20rpx;">
<text class="cell-label">分组</text>
<view class="cell-right">
<text class="hint">{{ group.name }}</text>
<uni-icons type="right" color="#999" size="18"></uni-icons>
</view>
</view>
<view class="cell" @click="openGroup">
<text class="cell-label">描述</text>
<view class="cell-right">
<text class="hint">补充患者关键信息方便随访患者</text>
<uni-icons type="right" color="#999" size="18"></uni-icons>
</view>
</view>
<view class="cell">
<text class="cell-label">电话号码</text>
<view class="cell-right">
<text class="phone">{{ patientInfo.mobile || '未设置' }}</text>
</view>
</view>
<!-- 患者病史 -->
<view class="history-section" v-if="patientDetail.medicalHistoryContent">
<view class="section-title">患者病史</view>
<view class="card history-card">
<text class="history-text" :class="{ fold: !showAllHistory }">{{ patientDetail.medicalHistoryContent }}</text>
<text class="toggle" @click="toggleHistory" v-if="patientDetail.medicalHistoryContent">{{ showAllHistory ? '收起' : '展开全部' }}</text>
</view>
</view>
<!-- 检查报告 -->
<view class="history-section" v-if="patientDetail.patientCase && patientDetail.patientCase.length>0">
<view class="section-title">检查报告</view>
<view class="card report-card">
<view class="report-item" v-for="item in patientDetail.patientCase" :key="item.diseaseUuid" @click="openCase(item.uuid)">
<view class="report-item-title">{{ $u.timeFormat(item.createDate, 'yyyy-mm-dd') }}</view>
<view class="report-item-content">{{ item.diseaseName }}</view>
</view>
</view>
</view>
<!-- 底部操作 -->
<view class="actions">
<view class="action" @click="sendMessage">
<up-image :src="msgImg" width="44rpx" height="44rpx" ></up-image>
<text class="action-text">发消息</text>
</view>
<view class="action" @click="goMakePlan">
<up-image :src="planImg" width="44rpx" height="44rpx" ></up-image>
<text class="action-text">制定随访计划</text>
</view>
<view class="action" @click="recordIllness">
<up-image :src="recordImg" width="44rpx" height="44rpx" ></up-image>
<text class="action-text">记录病情</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onShow,onLoad } from '@dcloudio/uni-app'
import api from '@/api/api.js'
import docUrl from '@/utils/docUrl.js'
import navTo from '@/utils/navTo.js'
import msgImg from "@/static/icon_message_big.png"
import planImg from "@/static/image_backgrond_red_big1.png"
import recordImg from "@/static/image_backgrond_red_big.png"
import manImg from "@/static/new_man_big.png"
import womanImg from "@/static/new_woman_big.png"
const showAllHistory = ref(false);
const patientDetail = ref({});
const patient_uuid = ref('');
const note = ref('');
// 计算属性:患者基本信息
const patientInfo = computed(() => {
return patientDetail.value.patient || {};
});
// 计算属性:性别图标
const genderIcon = computed(() => {
return patientInfo.value.sex === 2 ? womanImg : manImg;
});
// 计算属性:完整地址
const fullAddress = computed(() => {
const { provName, cityName, countyName } = patientInfo.value;
const addressParts = [provName, cityName, countyName].filter(Boolean);
return addressParts.length > 0 ? addressParts.join('') : '未设置';
});
// 计算属性:患者病史文本
onLoad((options) => {
patient_uuid.value = options.uuid;
});
const goBack = ()=> uni.navigateBack()
const openCase = (uuid)=>{
navTo({
url:'/pages_app/checkRecord/checkRecord?uuid='+uuid
})
}
const editPatient = ()=> {
navTo({
url:'/pages_app/patientSetting/patientSetting?uuid=' + patient_uuid.value
})
}
const openGroup = ()=>{
navTo({
url:'/pages_app/patientRemark/patientRemark?uuid=' + patientInfo.value.uuid
})
}
const editDesc = ()=> uni.showToast({ title:'编辑描述', icon:'none' })
const sendMessage = async()=>{
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
let conversationId=userId+'|1|'+patientInfo.value.uuid.toLowerCase();
await uni.$UIKitStore.uiStore.selectConversation(conversationId)
navTo({
url:'/pages_chat/chat/index'
})
};
const nickname = ref('');
const group = ref({});
const getPatientCard = ()=>{
api.patientCard({
patient_uuid: patient_uuid.value,
}).then(res=>{
console.log(res)
if(res.code == 200){
group.value = res.group;
}
})
}
const getToAddNickname = ()=>{
let userInfo=uni.getStorageSync('userInfo');
api.toAddNickname({
patientUuid: patient_uuid.value,
expertUuid: userInfo.uuid,
}).then(res=>{
if(res.code == 200){
nickname.value = res.data.nickname;
note.value = res.data.note;
}
})
}
const getPatientDetail = ()=>{
api.patientDetail({
patientUuid: patient_uuid.value,
}).then(res=>{
if(res.code == 200){
patientDetail.value = res.data;
console.log('患者详情数据:', res.data);
} else {
uni.showToast({
title: res.msg || '获取患者详情失败',
icon: 'none'
});
}
}).catch(err => {
console.error('获取患者详情失败:', err);
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
});
});
};
onShow(()=>{
getPatientDetail();
getToAddNickname();
getPatientCard();
});
const goMakePlan = ()=> {
navTo({
url:'/pages_app/visitPlan/visitPlan'
})
}
const recordIllness = ()=> {
navTo({
url:'/pages_app/caseList/caseList?uuid='+patient_uuid.value
})
}
const toggleHistory = ()=> showAllHistory.value = !showAllHistory.value
</script>
<style lang="scss" scoped>
.report-card{
display: flex;
gap: 55rpx;
flex-wrap: wrap;
}
.report-item{
display: flex;
flex-direction: column;
gap: 10rpx;
background: #f5f5f5;
padding: 20rpx;
align-items: center;
border-radius: 12rpx;
.report-item-title{
font-size: 28rpx;
color:#666;
}
.report-item-content{
font-size: 28rpx;
color:#333;
}
}
.content { background:#f5f5f5; min-height:100vh; }
.nav-right { padding-right: 20rpx; }
.card { background:#ffffff; padding: 20rpx; padding-top: 0;}
.header-card { display:flex; padding-top: 20rpx;}
.avatar { width: 140rpx; height: 140rpx; border-radius: 12rpx; margin-right: 20rpx; }
.base-info { flex:1; }
.name-row { display:flex; align-items:center; margin-bottom: 10rpx; }
.name { font-size: 40rpx; color:#222; margin-right: 10rpx;}
.line { font-size: 28rpx; color:#666; margin-top: 6rpx; display:flex; align-items:center; }
.label { color:#999;white-space: nowrap; }
.value { color:#333; }
.sep { color:#ddd; margin: 0 10rpx; }
.multi{
display: inline;
}
.cell { display:flex; align-items:center; justify-content:space-between; background:#ffffff; padding: 28rpx 30rpx; border-top:1rpx solid #efefef; }
.cell:first-of-type { margin-top: 10rpx; border-top:none; }
.cell-label { font-size: 28rpx; color:#333; }
.cell-right { display:flex; align-items:center; }
.hint { font-size: 28rpx; color:#999; margin-right: 12rpx; }
.phone { font-size: 32rpx; color:#b10000; }
.section-title { padding: 16rpx 30rpx; color:#8B2316; font-size: 30rpx; margin-top: 20rpx; background: #fff;}
.history-card { position: relative; }
.history-text { font-size: 28rpx; color:#666; line-height: 1.7; display:block; }
.history-text.fold { display:-webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.toggle { position:absolute; right: 20rpx; bottom: 25rpx; color:#b10000; font-size: 28rpx;background: #fff; z-index: 10;}
.actions { background:#ffffff; margin-top: 20rpx;}
.action { display:flex; align-items:center;justify-content: center; padding: 28rpx 30rpx; border-top:1rpx solid #f0f0f0; }
.action-text { font-size:28rpx; color:#333; margin-left: 12rpx; }
</style>