|
|
@@ -15,7 +15,8 @@
|
|
|
</view>
|
|
|
<view class="message-button" @click="onMessageClick">
|
|
|
<image src="/static/icons/remixicon/message-3-line.svg" class="message-icon" />
|
|
|
- <view class="badge" v-if="unreadMessageCount > 0">{{ unreadMessageCount > 99 ? '99+' : unreadMessageCount }}</view>
|
|
|
+ <view class="badge" v-if="unreadMessageCount > 0">{{ unreadMessageCount > 99 ? '99+' : unreadMessageCount }}
|
|
|
+ </view>
|
|
|
</view>
|
|
|
<view class="qr-button" @click="onQrClick">
|
|
|
<image src="/static/icons/remixicon/qr-code-line.svg" class="qr-icon" />
|
|
|
@@ -34,13 +35,33 @@
|
|
|
<text class="item-desc">管理慢性病患者</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view class="function-item orange" @click="onItemClick('复诊管理')">
|
|
|
+ <view class="function-item orange" @click="onItemClick('药品信息管理')">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">药品管理</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">管理药品信息</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="function-row">
|
|
|
+ <view class="function-item purple" @click="onItemClick('危急值管理')">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">危急值管理</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">设置与管理危急值阈值</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="function-item green" @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>
|
|
|
+ <text class="item-desc">管理健康资讯与文章</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -182,30 +203,30 @@ const fetchUserInfo = async () => {
|
|
|
const userIdRaw = resp.data.id || resp.data.userId
|
|
|
const userId = userIdRaw ? String(userIdRaw) : ''
|
|
|
if (userId) {
|
|
|
- try {
|
|
|
- // 使用 avatarCache.getOrFetch 做并发去重,loader 只在真正需要下载时被调用一次
|
|
|
- const path = await avatarCache.getOrFetch(userId, async (id) => {
|
|
|
- try {
|
|
|
- const downloadRes = await uni.downloadFile({
|
|
|
- url: `https://wx.baiyun.work/user/avatar/${id}`,
|
|
|
- header: {
|
|
|
- Authorization: `Bearer ${token}`
|
|
|
- }
|
|
|
- })
|
|
|
- if (downloadRes.statusCode === 200 && downloadRes.tempFilePath) {
|
|
|
- return downloadRes.tempFilePath
|
|
|
+ try {
|
|
|
+ // 使用 avatarCache.getOrFetch 做并发去重,loader 只在真正需要下载时被调用一次
|
|
|
+ const path = await avatarCache.getOrFetch(userId, async (id) => {
|
|
|
+ try {
|
|
|
+ const downloadRes = await uni.downloadFile({
|
|
|
+ url: `https://wx.baiyun.work/user/avatar/${id}`,
|
|
|
+ header: {
|
|
|
+ Authorization: `Bearer ${token}`
|
|
|
}
|
|
|
- } catch (e) {
|
|
|
- console.error('Download avatar error:', e)
|
|
|
+ })
|
|
|
+ if (downloadRes.statusCode === 200 && downloadRes.tempFilePath) {
|
|
|
+ return downloadRes.tempFilePath
|
|
|
}
|
|
|
- return undefined
|
|
|
- })
|
|
|
-
|
|
|
- if (path) resp.data.avatar = path
|
|
|
- } catch (e) {
|
|
|
- console.error('avatar fetch error:', e)
|
|
|
- }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('Download avatar error:', e)
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ })
|
|
|
+
|
|
|
+ if (path) resp.data.avatar = path
|
|
|
+ } catch (e) {
|
|
|
+ console.error('avatar fetch error:', e)
|
|
|
}
|
|
|
+ }
|
|
|
}
|
|
|
user.value = resp.data
|
|
|
uni.setStorageSync('user_info', resp.data)
|
|
|
@@ -243,21 +264,21 @@ const fetchPatientActivities = async () => {
|
|
|
console.log('No token found, skipping fetchPatientActivities')
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
console.log('Fetching patient activities...')
|
|
|
-
|
|
|
+
|
|
|
// 调用真实接口获取患者动态
|
|
|
const response = await queryBoundPatientsActivities({
|
|
|
pageNum: 1,
|
|
|
pageSize: 10
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
console.log('Patient activities response:', response)
|
|
|
-
|
|
|
+
|
|
|
const resp = response.data as any
|
|
|
if (resp && resp.code === 200 && resp.data) {
|
|
|
console.log('Patient activities data:', resp.data)
|
|
|
-
|
|
|
+
|
|
|
// 转换数据格式,异步获取头像
|
|
|
const activitiesPromises = resp.data.records.map(async (activity: any) => ({
|
|
|
desc: formatActivityDescription(activity),
|
|
|
@@ -265,7 +286,7 @@ const fetchPatientActivities = async () => {
|
|
|
// 强制把 userId 转为字符串,避免数值精度或类型不匹配引起的问题
|
|
|
patientAvatar: await getPatientAvatar(String(activity.userId))
|
|
|
}))
|
|
|
-
|
|
|
+
|
|
|
// 等待所有头像获取完成
|
|
|
const activities = await Promise.all(activitiesPromises)
|
|
|
console.log('Converted activities:', activities)
|
|
|
@@ -374,16 +395,16 @@ const formatTime = (createTime: string) => {
|
|
|
const now = new Date()
|
|
|
const create = new Date(createTime)
|
|
|
const diff = now.getTime() - create.getTime()
|
|
|
-
|
|
|
+
|
|
|
const minutes = Math.floor(diff / (1000 * 60))
|
|
|
const hours = Math.floor(diff / (1000 * 60 * 60))
|
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
|
|
-
|
|
|
+
|
|
|
if (minutes < 1) return '刚刚'
|
|
|
if (minutes < 60) return `${minutes}分钟前`
|
|
|
if (hours < 24) return `${hours}小时前`
|
|
|
if (days < 7) return `${days}天前`
|
|
|
-
|
|
|
+
|
|
|
return create.toLocaleDateString('zh-CN')
|
|
|
} catch (e) {
|
|
|
return createTime
|
|
|
@@ -391,7 +412,7 @@ const formatTime = (createTime: string) => {
|
|
|
}
|
|
|
|
|
|
function onMessageClick() {
|
|
|
- uni.navigateTo({
|
|
|
+ uni.navigateTo({
|
|
|
url: '/pages/public/message-detail',
|
|
|
events: {
|
|
|
// 监听消息详情页的消息已读事件
|
|
|
@@ -407,7 +428,7 @@ const getPatientAvatar = async (userId: string | number): Promise<string> => {
|
|
|
try {
|
|
|
const token = uni.getStorageSync('token')
|
|
|
if (!token) return defaultAvatarUrl
|
|
|
-
|
|
|
+
|
|
|
// 使用 getOrFetch 去重并缓存下载结果
|
|
|
const idStr = String(userId)
|
|
|
try {
|
|
|
@@ -435,7 +456,7 @@ const getPatientAvatar = async (userId: string | number): Promise<string> => {
|
|
|
} catch (e) {
|
|
|
console.error('Download patient avatar error:', e)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 如果获取失败,使用默认头像
|
|
|
return defaultAvatarUrl
|
|
|
}
|
|
|
@@ -466,10 +487,21 @@ function handleScan(res: any) {
|
|
|
}
|
|
|
|
|
|
function onItemClick(type: string) {
|
|
|
- if (type === '我的病人') {
|
|
|
- uni.navigateTo({ url: '/pages/doctor/index/my-patients' })
|
|
|
- } else {
|
|
|
- uni.showToast({ title: '功能正在开发中', icon: 'none' })
|
|
|
+ switch (type) {
|
|
|
+ case '我的病人':
|
|
|
+ uni.navigateTo({ url: '/pages/doctor/index/my-patients' })
|
|
|
+ break
|
|
|
+ case '药品管理':
|
|
|
+ uni.navigateTo({ url: '/pages/doctor/manage/medicine' })
|
|
|
+ break
|
|
|
+ case '健康资讯管理':
|
|
|
+ uni.navigateTo({ url: '/pages/doctor/manage/news' })
|
|
|
+ break
|
|
|
+ case '危急值管理':
|
|
|
+ uni.navigateTo({ url: '/pages/doctor/manage/critical-values' })
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ uni.showToast({ title: '功能正在开发中', icon: 'none' })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -483,11 +515,11 @@ const formatActivityDescription = (activity: any) => {
|
|
|
if (activity.friendlyDescription) {
|
|
|
return activity.friendlyDescription
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 根据 activityDescription 内容进一步细化描述
|
|
|
const description = activity.activityDescription || ''
|
|
|
let baseDescription = ''
|
|
|
-
|
|
|
+
|
|
|
// 根据活动类型生成基础描述
|
|
|
switch (activity.activityType) {
|
|
|
case 'BLOOD_GLUCOSE_UPLOAD':
|
|
|
@@ -530,11 +562,11 @@ const formatActivityDescription = (activity: any) => {
|
|
|
break
|
|
|
default:
|
|
|
// 如果没有匹配的类型,尝试使用 activityDescription 或返回默认值
|
|
|
- baseDescription = description && !description.includes('Controller')
|
|
|
- ? description
|
|
|
+ baseDescription = description && !description.includes('Controller')
|
|
|
+ ? description
|
|
|
: '执行了操作'
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return baseDescription
|
|
|
}
|
|
|
|
|
|
@@ -717,6 +749,14 @@ const formatActivityDescription = (activity: any) => {
|
|
|
background-color: #ffa502;
|
|
|
}
|
|
|
|
|
|
+.green .item-line {
|
|
|
+ background-color: #2ecc71;
|
|
|
+}
|
|
|
+
|
|
|
+.purple .item-line {
|
|
|
+ background-color: #9b59b6;
|
|
|
+}
|
|
|
+
|
|
|
.item-title {
|
|
|
font-size: 36rpx;
|
|
|
font-weight: bold;
|
|
|
@@ -760,7 +800,7 @@ const formatActivityDescription = (activity: any) => {
|
|
|
padding: 24rpx 28rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- background: linear-gradient(90deg, rgba(255,255,255,0.9), rgba(255,255,255,0.75));
|
|
|
+ background: linear-gradient(90deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.75));
|
|
|
border-bottom: 1rpx solid #f3f4f6;
|
|
|
}
|
|
|
|