|
@@ -1,38 +1,171 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <CustomNav title="我的病人" leftType="home" />
|
|
|
|
|
- <view class="content">
|
|
|
|
|
- <view class="menu-card">
|
|
|
|
|
- <view class="menu-list">
|
|
|
|
|
- <view class="menu-item" @click="onItemClick('我的档案')">
|
|
|
|
|
- <image src="/static/icons/remixicon/profile-line.svg" class="menu-icon" mode="widthFix" />
|
|
|
|
|
- <text class="menu-text">我的档案</text>
|
|
|
|
|
- <uni-icons class="menu-arrow" type="arrowright" size="20" color="#c0c0c0" />
|
|
|
|
|
|
|
+ <CustomNav title="我的病人" leftType="back" />
|
|
|
|
|
+ <view class="page-container">
|
|
|
|
|
+ <view class="patient-card" v-for="patient in patients" :key="patient.id">
|
|
|
|
|
+ <view class="patient-header">
|
|
|
|
|
+ <view class="avatar-section">
|
|
|
|
|
+ <view class="avatar-frame">
|
|
|
|
|
+ <image class="avatar-img" :src="patientAvatar(patient)" mode="aspectFill" />
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="menu-item" @click="onItemClick('健康数据')">
|
|
|
|
|
- <image src="/static/icons/remixicon/heart-pulse-line.svg" class="menu-icon" mode="widthFix" />
|
|
|
|
|
- <text class="menu-text">健康数据</text>
|
|
|
|
|
- <uni-icons class="menu-arrow" type="arrowright" size="20" color="#c0c0c0" />
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="menu-item" @click="onItemClick('用药记录')">
|
|
|
|
|
- <image src="/static/icons/remixicon/capsule-fill.svg" class="menu-icon" mode="widthFix" />
|
|
|
|
|
- <text class="menu-text">用药记录</text>
|
|
|
|
|
- <uni-icons class="menu-arrow" type="arrowright" size="20" color="#c0c0c0" />
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="menu-item" @click="onItemClick('就诊记录')">
|
|
|
|
|
- <image src="/static/icons/remixicon/calendar-check-line.svg" class="menu-icon" mode="widthFix" />
|
|
|
|
|
- <text class="menu-text">就诊记录</text>
|
|
|
|
|
- <uni-icons class="menu-arrow" type="arrowright" size="20" color="#c0c0c0" />
|
|
|
|
|
|
|
+ <view class="patient-info">
|
|
|
|
|
+ <text class="patient-name">{{ patient.boundUserNickname }}</text>
|
|
|
|
|
+ <text class="patient-phone" v-if="patient.boundUserPhone">联系电话: {{ patient.boundUserPhone }}</text>
|
|
|
|
|
+ <text class="patient-phone" v-else>联系电话: 未提供</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="action-buttons">
|
|
|
|
|
+ <button class="action-btn primary" @click="viewHealthData(patient)">健康数据</button>
|
|
|
|
|
+ <button class="action-btn secondary" @click="viewHealthNews(patient)">健康动态</button>
|
|
|
|
|
+ <button class="action-btn secondary" @click="sendReminder(patient)">发送提醒</button>
|
|
|
|
|
+ <button class="action-btn secondary" @click="inviteRevisit(patient)">邀请复诊</button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="empty-state" v-if="patients.length === 0">
|
|
|
|
|
+ <image class="empty-icon" src="/static/icons/remixicon/account-circle-line.svg" />
|
|
|
|
|
+ <text class="empty-text">暂无绑定的病人</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <TabBar />
|
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { onShow } from '@dcloudio/uni-app'
|
|
|
|
|
|
|
+import { ref } from 'vue'
|
|
|
|
|
+import { onLoad, onShow } from '@dcloudio/uni-app'
|
|
|
import CustomNav from '@/components/custom-nav.vue'
|
|
import CustomNav from '@/components/custom-nav.vue'
|
|
|
-import TabBar from '@/components/tab-bar.vue'
|
|
|
|
|
|
|
+import { listUserBindingsByBoundUser, type UserBindingResponse, type UserBindingPageResponse } from '@/api/userBinding'
|
|
|
|
|
+import { downloadAvatar } from '@/api/user'
|
|
|
|
|
+
|
|
|
|
|
+interface PatientInfo extends UserBindingResponse {
|
|
|
|
|
+ avatar?: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const patients = ref<PatientInfo[]>([])
|
|
|
|
|
+const pageData = ref({
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ total: 0,
|
|
|
|
|
+ pages: 0
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const defaultAvatar = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
|
|
|
|
+
|
|
|
|
|
+// 获取病人列表
|
|
|
|
|
+const fetchPatients = async () => {
|
|
|
|
|
+ uni.showLoading({ title: '加载中...' })
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
|
|
+ if (!token) {
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '未登录',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前用户ID(医生ID)
|
|
|
|
|
+ const userInfo = uni.getStorageSync('user_info')
|
|
|
|
|
+ const doctorUserId = userInfo?.id
|
|
|
|
|
+
|
|
|
|
|
+ if (!doctorUserId) {
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '获取用户信息失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询医生绑定的病人列表(使用新的接口)
|
|
|
|
|
+ const response = await listUserBindingsByBoundUser(
|
|
|
|
|
+ doctorUserId,
|
|
|
|
|
+ 'PATIENT',
|
|
|
|
|
+ {
|
|
|
|
|
+ pageNum: pageData.value.pageNum,
|
|
|
|
|
+ pageSize: pageData.value.pageSize
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+
|
|
|
|
|
+ const resp = response.data as any
|
|
|
|
|
+
|
|
|
|
|
+ if (resp && resp.code === 200 && resp.data) {
|
|
|
|
|
+ const pageResult = resp.data as UserBindingPageResponse
|
|
|
|
|
+ patients.value = pageResult.records as PatientInfo[]
|
|
|
|
|
+ pageData.value.total = pageResult.total
|
|
|
|
|
+ pageData.value.pages = pageResult.pages
|
|
|
|
|
+
|
|
|
|
|
+ // 为每个病人尝试下载头像
|
|
|
|
|
+ for (const patient of patients.value) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (patient.patientUserId) {
|
|
|
|
|
+ const dlRes: any = await downloadAvatar(String(patient.patientUserId))
|
|
|
|
|
+ if (dlRes && dlRes.statusCode === 200 && dlRes.tempFilePath) {
|
|
|
|
|
+ patient.avatar = dlRes.tempFilePath
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.warn('下载病人头像失败:', err)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '获取病人信息失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ console.error('获取病人信息失败:', error)
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '获取病人信息失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const patientAvatar = (patient: PatientInfo) => {
|
|
|
|
|
+ if (patient.avatar) {
|
|
|
|
|
+ return patient.avatar
|
|
|
|
|
+ }
|
|
|
|
|
+ return defaultAvatar
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const viewHealthData = (patient: PatientInfo) => {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '健康数据功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const viewHealthNews = (patient: PatientInfo) => {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '健康动态功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const sendReminder = (patient: PatientInfo) => {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '发送提醒功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const inviteRevisit = (patient: PatientInfo) => {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '邀请复诊功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onLoad(() => {
|
|
|
|
|
+ fetchPatients()
|
|
|
|
|
+})
|
|
|
|
|
|
|
|
// 如果在微信小程序端且未登录,自动跳转到登录页
|
|
// 如果在微信小程序端且未登录,自动跳转到登录页
|
|
|
onShow(() => {
|
|
onShow(() => {
|
|
@@ -41,70 +174,110 @@ onShow(() => {
|
|
|
uni.reLaunch({ url: '/pages/public/login/index' })
|
|
uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
-function onItemClick(type: string) {
|
|
|
|
|
- switch (type) {
|
|
|
|
|
- case '我的档案':
|
|
|
|
|
- uni.navigateTo({ url: '/pages/patient/profile/infos/base-info' });
|
|
|
|
|
- break;
|
|
|
|
|
- case '健康数据':
|
|
|
|
|
- uni.navigateTo({ url: '/pages/patient/health/index' });
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- uni.showToast({ title: `${type} 功能正在开发中`, icon: 'none' });
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.content {
|
|
|
|
|
- padding-top: calc(var(--status-bar-height) + 44px);
|
|
|
|
|
|
|
+.page-container {
|
|
|
min-height: 100vh;
|
|
min-height: 100vh;
|
|
|
background-color: #f5f5f5;
|
|
background-color: #f5f5f5;
|
|
|
- box-sizing: border-box;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.menu-card {
|
|
|
|
|
- padding: 50rpx 0rpx;
|
|
|
|
|
|
|
+ padding-top: calc(var(--status-bar-height) + 44px);
|
|
|
|
|
+ padding-bottom: 40rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-list {
|
|
|
|
|
|
|
+.patient-card {
|
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
|
- border-radius: 12rpx;
|
|
|
|
|
|
|
+ margin: 20rpx;
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-item {
|
|
|
|
|
|
|
+.patient-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- justify-content: flex-start;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- padding: 30rpx 40rpx;
|
|
|
|
|
|
|
+ padding: 40rpx;
|
|
|
border-bottom: 1rpx solid #eee;
|
|
border-bottom: 1rpx solid #eee;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-item:last-child {
|
|
|
|
|
- border-bottom: none;
|
|
|
|
|
|
|
+.avatar-section {
|
|
|
|
|
+ margin-right: 30rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-text {
|
|
|
|
|
- font-size: 32rpx;
|
|
|
|
|
- color: #000000;
|
|
|
|
|
|
|
+.avatar-frame {
|
|
|
|
|
+ width: 120rpx;
|
|
|
|
|
+ height: 120rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ border: 1px solid rgba(128, 128, 128, 0.5);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.avatar-img {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ object-fit: cover;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.patient-info {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
- letter-spacing: 1rpx;
|
|
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.patient-name {
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ margin-bottom: 10rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.patient-phone {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #666;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-arrow {
|
|
|
|
|
- display: inline-flex;
|
|
|
|
|
|
|
+.action-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding: 30rpx 40rpx;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-btn {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ border-radius: 10rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ line-height: 70rpx;
|
|
|
|
|
+ min-width: 40%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.primary {
|
|
|
|
|
+ background-color: #3742fa;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.secondary {
|
|
|
|
|
+ background-color: #f0f0f0;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-state {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
- width: 44rpx;
|
|
|
|
|
- height: 44rpx;
|
|
|
|
|
|
|
+ padding: 100rpx 40rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.menu-icon {
|
|
|
|
|
- width: 40rpx;
|
|
|
|
|
- height: 40rpx;
|
|
|
|
|
- margin-right: 30rpx;
|
|
|
|
|
- display: inline-block;
|
|
|
|
|
|
|
+.empty-icon {
|
|
|
|
|
+ width: 120rpx;
|
|
|
|
|
+ height: 120rpx;
|
|
|
|
|
+ margin-bottom: 30rpx;
|
|
|
|
|
+ opacity: 0.5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-text {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+ margin-bottom: 40rpx;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|