فهرست منبع

feat(doctor): 新增我的病人页面及功能

- 新增医生端"我的病人"页面,支持查看病人列表
- 修改医生首页"病人管理"入口为"我的病人"
- 调整页面跳转路径,优化路由配置
- 简化医生信息展示,仅保留必要字段
- 移除冗余的医生详细信息接口调用
- 优化医生头像下载逻辑和错误处理
- 更新相关页面的导航链接和文字描述
- 调整页面样式,提升用户体验一致性
mcbaiyun 1 ماه پیش
والد
کامیت
2a7b4245e1
5فایلهای تغییر یافته به همراه142 افزوده شده و 136 حذف شده
  1. 7 1
      src/pages.json
  2. 5 5
      src/pages/doctor/index/index.vue
  3. 110 0
      src/pages/doctor/index/my-patients.vue
  4. 1 1
      src/pages/patient/index/index.vue
  5. 19 129
      src/pages/patient/index/my-doctor.vue

+ 7 - 1
src/pages.json

@@ -79,7 +79,7 @@
 			}
 		},
 		{
-			"path": "pages/patient/profile/infos/my-doctor",
+			"path": "pages/patient/index/my-doctor",
 			"style": {
 				"navigationBarTitleText": "我的医生"
 			}
@@ -137,6 +137,12 @@
 			"style": {
 				"navigationBarTitleText": "体测记录"
 			}
+		},
+		{
+			"path": "pages/doctor/index/my-patients",
+			"style": {
+				"navigationBarTitleText": "我的病人"
+			}
 		}
 	],
 	"globalStyle": {

+ 5 - 5
src/pages/doctor/index/index.vue

@@ -21,11 +21,11 @@
 
       <view class="function-container">
         <view class="function-row">
-          <view class="function-item blue" @click="onItemClick('病人管理')">
+          <view class="function-item blue" @click="onItemClick('我的病人')">
             <view class="item-content">
               <view class="title-row">
                 <view class="item-line"></view>
-                <text class="item-title">病人管理</text>
+                <text class="item-title">我的病人</text>
               </view>
               <text class="item-desc">管理慢性病患者</text>
             </view>
@@ -56,7 +56,7 @@
               <text class="reminder-label">待处理复诊</text>
             </view>
           </view>
-          <view class="reminder-item" @click="onItemClick('病人管理')"> 
+          <view class="reminder-item" @click="onItemClick('我的病人')"> 
             <view class="reminder-icon">
               <image src="/static/icons/remixicon/alert-line.svg" class="icon" />
             </view>
@@ -257,8 +257,8 @@ function handleScan(res: any) {
 }
 
 function onItemClick(type: string) {
-  if (type === '病人管理') {
-    uni.navigateTo({ url: '/pages/doctor/manage/index' })
+  if (type === '我的病人') {
+    uni.navigateTo({ url: '/pages/doctor/index/my-patients' })
   } else if (type === '复诊管理') {
     uni.navigateTo({ url: '/pages/doctor/manage/followup' })
   } else {

+ 110 - 0
src/pages/doctor/index/my-patients.vue

@@ -0,0 +1,110 @@
+<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" />
+        </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>
+      </view>
+    </view>
+  </view>
+  <TabBar />
+</template>
+
+<script setup lang="ts">
+import { onShow } from '@dcloudio/uni-app'
+import CustomNav from '@/components/custom-nav.vue'
+import TabBar from '@/components/tab-bar.vue'
+
+// 如果在微信小程序端且未登录,自动跳转到登录页
+onShow(() => {
+  const token = uni.getStorageSync('token')
+  if (!token) {
+    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>
+
+<style scoped>
+.content {
+  padding-top: calc(var(--status-bar-height) + 44px);
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  box-sizing: border-box;
+}
+
+.menu-card {
+  padding: 50rpx 0rpx;
+}
+
+.menu-list {
+  background-color: #fff;
+  border-radius: 12rpx;
+  overflow: hidden;
+}
+
+.menu-item {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  padding: 30rpx 40rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.menu-item:last-child {
+  border-bottom: none;
+}
+
+.menu-text {
+  font-size: 32rpx;
+  color: #000000;
+  flex: 1;
+  letter-spacing: 1rpx;
+}
+
+.menu-arrow {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 44rpx;
+  height: 44rpx;
+}
+
+.menu-icon {
+  width: 40rpx;
+  height: 40rpx;
+  margin-right: 30rpx;
+  display: inline-block;
+}
+</style>

+ 1 - 1
src/pages/patient/index/index.vue

@@ -215,7 +215,7 @@ function onItemClick(type: string) {
   } else if (type === '提醒管理') {
     uni.navigateTo({ url: '/pages/patient/health/reminder' })
   } else if (type === '我的医生') {
-    uni.navigateTo({ url: '/pages/patient/profile/infos/my-doctor' })
+    uni.navigateTo({ url: '/pages/patient/index/my-doctor' })
   } else {
     uni.showToast({ title: '功能正在开发中', icon: 'none' })
   }

+ 19 - 129
src/pages/patient/profile/infos/my-doctor.vue → src/pages/patient/index/my-doctor.vue

@@ -10,27 +10,9 @@
         </view>
         <view class="doctor-info">
           <text class="doctor-name">{{ doctorInfo.name }}</text>
-          <text class="doctor-title" v-if="doctorInfo.title">{{ doctorInfo.title }}</text>
-          <text class="doctor-hospital" v-if="doctorInfo.hospital">{{ doctorInfo.hospital }}</text>
-        </view>
-      </view>
-      
-      <view class="doctor-details">
-        <view class="detail-item">
-          <text class="label">科室:</text>
-          <text class="value">{{ doctorInfo.department || '未填写' }}</text>
-        </view>
-        <view class="detail-item">
-          <text class="label">联系电话:</text>
-          <text class="value">{{ doctorInfo.phone || '未填写' }}</text>
-        </view>
-        <view class="detail-item">
-          <text class="label">擅长领域:</text>
-          <text class="value">{{ doctorInfo.specialty || '未填写' }}</text>
-        </view>
-        <view class="detail-item">
-          <text class="label">简介:</text>
-          <text class="value intro">{{ doctorInfo.introduction || '暂无介绍' }}</text>
+          <!-- 根据当前API返回数据,只显示姓名和电话 -->
+          <text class="doctor-phone" v-if="doctorInfo.phone">联系电话: {{ doctorInfo.phone }}</text>
+          <text class="doctor-phone" v-else>联系电话: 未提供</text>
         </view>
       </view>
       
@@ -54,18 +36,12 @@ import { onLoad } from '@dcloudio/uni-app'
 import CustomNav from '@/components/custom-nav.vue'
 import { listUserBindingsByPatient, type UserBindingResponse, type UserBindingPageResponse } from '@/api/userBinding'
 import { downloadAvatar } from '@/api/user'
-import { getUserInfo } from '@/api/user'
 
-// 为避免与导入的类型冲突,重命名本地接口
+// 简化医生信息接口,只包含API实际返回的字段
 interface LocalDoctorInfo {
   id: string
   name: string
-  title?: string
-  hospital?: string
-  department?: string
   phone?: string
-  specialty?: string
-  introduction?: string
   avatar?: string
 }
 
@@ -143,76 +119,26 @@ const fetchDoctorInfo = async () => {
       pageData.value.pages = pageResult.pages
       
       // 如果有绑定的医生,获取第一个医生的详细信息
-      // 这里需要另一个接口获取医生详细信息,暂时使用模拟数据
       if (pageResult.records && pageResult.records.length > 0) {
         const boundDoctor = pageResult.records[0]
         
-        // 通过用户接口获取医生详细信息
+        // 直接使用绑定接口返回的信息,不再调用额外的用户详情接口
+        doctorInfo.value = {
+          id: boundDoctor.id,
+          name: boundDoctor.boundUserNickname || '未知医生',
+          phone: boundDoctor.boundUserPhone || '未提供', // 当电话为null时显示"未提供"
+        }
+        
+        // 尝试下载头像(绑定接口返回的数据中可能没有 avatar)
         try {
-          // 将 ID 作为字符串传入以保证 Snowflake ID 的精度(前端全程文本存储)
-          const userInfoResponse = await getUserInfo(String(boundDoctor.boundUserId))
-          const userInfo = userInfoResponse.data?.data
-          
-          if (userInfo) {
-            doctorInfo.value = {
-              id: boundDoctor.id,
-              name: userInfo.nickname || boundDoctor.boundUserNickname || '未知医生',
-              title: userInfo.title || '医生',
-              hospital: userInfo.hospital || '未知医院',
-              department: userInfo.department || '未知科室',
-              phone: boundDoctor.boundUserPhone || userInfo.phone || '未提供',
-              specialty: userInfo.specialty || '未知',
-              introduction: userInfo.introduction || '暂无介绍',
-              avatar: userInfo.avatar
-            }
-            // 尝试从后端下载用户头像(如果后端未返回 avatar 或想替换为下载后的临时路径)
-            try {
-              if (boundDoctor.boundUserId) {
-                const dlRes: any = await downloadAvatar(String(boundDoctor.boundUserId))
-                if (dlRes && dlRes.statusCode === 200 && dlRes.tempFilePath) {
-                  downloadedAvatar.value = dlRes.tempFilePath
-                }
-              }
-            } catch (err) {
-              console.warn('下载医生头像失败:', err)
+          if (boundDoctor.boundUserId) {
+            const dlRes: any = await downloadAvatar(String(boundDoctor.boundUserId))
+            if (dlRes && dlRes.statusCode === 200 && dlRes.tempFilePath) {
+              downloadedAvatar.value = dlRes.tempFilePath
             }
-          } else {
-            // 如果获取详细信息失败,使用绑定接口返回的基础信息
-            doctorInfo.value = {
-              id: boundDoctor.id,
-              name: boundDoctor.boundUserNickname || '未知医生',
-              title: '医生',
-              hospital: '未知医院',
-              department: '未知科室',
-              phone: boundDoctor.boundUserPhone || '未提供',
-              specialty: '未知',
-              introduction: '暂无介绍'
-            }
-            // 尝试下载头像(绑定接口返回的数据中可能没有 avatar)
-            try {
-              if (boundDoctor.boundUserId) {
-                const dlRes: any = await downloadAvatar(String(boundDoctor.boundUserId))
-                if (dlRes && dlRes.statusCode === 200 && dlRes.tempFilePath) {
-                  downloadedAvatar.value = dlRes.tempFilePath
-                }
-              }
-            } catch (err) {
-              console.warn('下载医生头像失败:', err)
-            }
-          }
-        } catch (error) {
-          console.error('获取医生详细信息失败:', error)
-          // 使用绑定接口返回的基础信息
-          doctorInfo.value = {
-            id: boundDoctor.id,
-            name: boundDoctor.boundUserNickname || '未知医生',
-            title: '医生',
-            hospital: '未知医院',
-            department: '未知科室',
-            phone: boundDoctor.boundUserPhone || '未提供',
-            specialty: '未知',
-            introduction: '暂无介绍'
           }
+        } catch (err) {
+          console.warn('下载医生头像失败:', err)
         }
       } else {
         doctorInfo.value = null
@@ -313,47 +239,11 @@ onLoad(() => {
   margin-bottom: 10rpx;
 }
 
-.doctor-title {
-  font-size: 28rpx;
-  color: #666;
-  margin-bottom: 10rpx;
-}
-
-.doctor-hospital {
-  font-size: 28rpx;
-  color: #666;
-}
-
-.doctor-details {
-  padding: 30rpx 40rpx;
-}
-
-.detail-item {
-  display: flex;
-  margin-bottom: 20rpx;
-}
-
-.detail-item:last-child {
-  margin-bottom: 0;
-}
-
-.label {
-  width: 160rpx;
+.doctor-phone {
   font-size: 28rpx;
   color: #666;
 }
 
-.value {
-  flex: 1;
-  font-size: 28rpx;
-  color: #333;
-  line-height: 1.5;
-}
-
-.value.intro {
-  white-space: pre-wrap;
-}
-
 .action-buttons {
   display: flex;
   padding: 30rpx 40rpx;