|
|
@@ -77,6 +77,7 @@ import TabBar from '@/components/tab-bar.vue'
|
|
|
import { handleQrScanResult } from '@/utils/qr'
|
|
|
import request from '@/api/request'
|
|
|
import { avatarCache } from '@/utils/avatarCache'
|
|
|
+import { queryBoundFamiliesActivities } from '@/api/userActivity'
|
|
|
|
|
|
const user = ref<{ avatar?: string; nickname?: string }>({})
|
|
|
|
|
|
@@ -102,23 +103,11 @@ const todayReminders = ref({
|
|
|
abnormalCount: 0
|
|
|
})
|
|
|
|
|
|
-const familyActivities = ref([
|
|
|
- {
|
|
|
- desc: '家人张三完成了今日用药',
|
|
|
- time: '10分钟前',
|
|
|
- familyAvatar: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
|
|
- },
|
|
|
- {
|
|
|
- desc: '家人李四血糖数据已更新',
|
|
|
- time: '1小时前',
|
|
|
- familyAvatar: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
|
|
- },
|
|
|
- {
|
|
|
- desc: '家人王五预约了下周复诊',
|
|
|
- time: '2小时前',
|
|
|
- familyAvatar: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
|
|
- }
|
|
|
-])
|
|
|
+const familyActivities = ref<Array<{
|
|
|
+ desc: string
|
|
|
+ time: string
|
|
|
+ familyAvatar: string
|
|
|
+}>>([])
|
|
|
|
|
|
const loadUser = () => {
|
|
|
try {
|
|
|
@@ -208,17 +197,163 @@ const fetchFamilyActivities = async () => {
|
|
|
try {
|
|
|
const token = uni.getStorageSync('token')
|
|
|
if (!token) return
|
|
|
- const response = await request({
|
|
|
- url: 'https://wx.baiyun.work/family/activities',
|
|
|
- method: 'GET',
|
|
|
+
|
|
|
+ // 调用真实接口获取家人动态
|
|
|
+ const response = await queryBoundFamiliesActivities({
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
})
|
|
|
+
|
|
|
const resp = response.data as any
|
|
|
if (resp && resp.code === 200 && resp.data) {
|
|
|
- familyActivities.value = resp.data
|
|
|
+ // 转换数据格式,异步获取头像
|
|
|
+ const activitiesPromises = resp.data.records.map(async (activity: any) => ({
|
|
|
+ desc: formatActivityDescription(activity),
|
|
|
+ time: formatTime(activity.createTime),
|
|
|
+ familyAvatar: await getFamilyAvatar(activity.userId)
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 等待所有头像获取完成
|
|
|
+ const activities = await Promise.all(activitiesPromises)
|
|
|
+ familyActivities.value = activities
|
|
|
+ } else {
|
|
|
+ familyActivities.value = []
|
|
|
}
|
|
|
} catch (err) {
|
|
|
console.error('Fetch family activities error:', err)
|
|
|
+ // 如果接口调用失败,显示空数据
|
|
|
+ familyActivities.value = []
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 格式化时间显示
|
|
|
+const formatTime = (createTime: string) => {
|
|
|
+ try {
|
|
|
+ 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
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 获取家人头像
|
|
|
+const getFamilyAvatar = async (userId: string): Promise<string> => {
|
|
|
+ try {
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
+ if (!token) return defaultAvatarUrl
|
|
|
+
|
|
|
+ // 检查是否有缓存的头像
|
|
|
+ if (avatarCache.has(userId)) {
|
|
|
+ return avatarCache.get(userId)!
|
|
|
+ }
|
|
|
+
|
|
|
+ // 尝试下载用户头像
|
|
|
+ const downloadRes = await uni.downloadFile({
|
|
|
+ url: `https://wx.baiyun.work/user/avatar/${userId}`,
|
|
|
+ header: {
|
|
|
+ Authorization: `Bearer ${token}`
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if (downloadRes.statusCode === 200 && downloadRes.tempFilePath) {
|
|
|
+ // 缓存头像路径
|
|
|
+ avatarCache.set(userId, downloadRes.tempFilePath)
|
|
|
+ return downloadRes.tempFilePath
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('Download family avatar error:', e)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果获取失败,使用默认头像
|
|
|
+ return defaultAvatarUrl
|
|
|
+}
|
|
|
+
|
|
|
+// 格式化活动描述
|
|
|
+const formatActivityDescription = (activity: any) => {
|
|
|
+ // 如果已经有友好的描述,直接返回
|
|
|
+ if (activity.friendlyDescription) {
|
|
|
+ return activity.friendlyDescription
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据 activityDescription 内容进一步细化描述
|
|
|
+ const description = activity.activityDescription || ''
|
|
|
+ let baseDescription = ''
|
|
|
+
|
|
|
+ // 根据活动类型生成基础描述
|
|
|
+ switch (activity.activityType) {
|
|
|
+ case 'BLOOD_GLUCOSE_UPLOAD':
|
|
|
+ baseDescription = '上传了血糖数据'
|
|
|
+ break
|
|
|
+ case 'BLOOD_GLUCOSE_UPDATE':
|
|
|
+ baseDescription = '更新了血糖数据'
|
|
|
+ break
|
|
|
+ case 'BLOOD_PRESSURE_UPLOAD':
|
|
|
+ baseDescription = '上传了血压数据'
|
|
|
+ break
|
|
|
+ case 'HEART_RATE_UPLOAD':
|
|
|
+ baseDescription = '上传了心率数据'
|
|
|
+ break
|
|
|
+ case 'PHYSICAL_DATA_UPLOAD':
|
|
|
+ baseDescription = '上传了体格数据'
|
|
|
+ break
|
|
|
+ case 'HEALTH_RECORD_CREATE':
|
|
|
+ // 根据描述内容判断是创建还是更新
|
|
|
+ if (description.includes('save') || description.includes('update')) {
|
|
|
+ baseDescription = '更新了健康档案'
|
|
|
+ } else {
|
|
|
+ baseDescription = '创建了健康档案'
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case 'HEALTH_RECORD_UPDATE':
|
|
|
+ baseDescription = '更新了健康档案'
|
|
|
+ break
|
|
|
+ case 'MEDICATION_CREATE':
|
|
|
+ baseDescription = '添加了用药记录'
|
|
|
+ break
|
|
|
+ case 'MEDICATION_UPDATE':
|
|
|
+ baseDescription = '更新了用药记录'
|
|
|
+ break
|
|
|
+ case 'FOLLOW_UP_CREATE':
|
|
|
+ baseDescription = '提交了复诊申请'
|
|
|
+ break
|
|
|
+ case 'FOLLOW_UP_UPDATE':
|
|
|
+ baseDescription = '更新了复诊信息'
|
|
|
+ break
|
|
|
+ case 'FOLLOW_UP_CONFIRM':
|
|
|
+ baseDescription = '医生已确认复诊'
|
|
|
+ break
|
|
|
+ case 'FOLLOW_UP_CANCEL':
|
|
|
+ baseDescription = '医生已取消复诊'
|
|
|
+ break
|
|
|
+ case 'FOLLOW_UP_COMPLETE':
|
|
|
+ baseDescription = '医生已完成复诊'
|
|
|
+ break
|
|
|
+ case 'USER_BINDING_CREATE':
|
|
|
+ baseDescription = '绑定了新家人'
|
|
|
+ break
|
|
|
+ case 'USER_BINDING_DELETE':
|
|
|
+ baseDescription = '解除了家人绑定'
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ // 如果没有匹配的类型,尝试使用 activityDescription 或返回默认值
|
|
|
+ baseDescription = description && !description.includes('Controller')
|
|
|
+ ? description
|
|
|
+ : '执行了操作'
|
|
|
}
|
|
|
+
|
|
|
+ return baseDescription
|
|
|
}
|
|
|
|
|
|
// 如果在微信小程序端且未登录,自动跳转到登录页
|