Просмотр исходного кода

feat(qr): 实现二维码手动刷新功能

- 新增 fetchUserInfo 方法从后端获取最新用户信息
- 添加刷新按钮点击事件,触发 refreshAndGenerate 方法
- 实现用户信息缺失时自动跳转补全资料页面
- 优化页面加载逻辑,首次进入检查登录态
- 移除不必要的动画和过渡效果
- 修复卡片入场动画 translate 属性兼容性问题
mcbaiyun 1 месяц назад
Родитель
Сommit
578200e26e
1 измененных файлов с 68 добавлено и 8 удалено
  1. 68 8
      src/pages/public/profile/qr/index.vue

+ 68 - 8
src/pages/public/profile/qr/index.vue

@@ -18,7 +18,7 @@
             v-if="qrData"
             v-if="qrData"
           ></canvas>
           ></canvas>
         </view>
         </view>
-        <view class="refresh-btn" @click="generateQRCode">
+        <view class="refresh-btn" @click="refreshAndGenerate">
           <text class="refresh-text">刷新二维码</text>
           <text class="refresh-text">刷新二维码</text>
         </view>
         </view>
       </view>
       </view>
@@ -35,6 +35,7 @@ import drawQrcode from 'weapp-qrcode'
 
 
 const user = ref<{ nickname?: string; role?: string | number; openid?: string; wx_openid?: string }>({})
 const user = ref<{ nickname?: string; role?: string | number; openid?: string; wx_openid?: string }>({})
 const qrData = ref('')
 const qrData = ref('')
+const isFetching = ref(false)
 
 
 const getPageTitle = (role: string | number | undefined) => {
 const getPageTitle = (role: string | number | undefined) => {
   const roleMap: { [key: number]: string } = {
   const roleMap: { [key: number]: string } = {
@@ -76,6 +77,64 @@ const loadUser = () => {
   }
   }
 }
 }
 
 
+// 从后端刷新用户信息(仅在用户手动触发刷新时调用)
+const fetchUserInfo = async () => {
+  try {
+    const token = uni.getStorageSync('token')
+    if (!token) return
+    if (isFetching.value) return
+    isFetching.value = true
+    uni.showLoading({ title: '加载中...' })
+    const response: any = await uni.request({
+      url: 'https://wx.baiyun.work/user_info',
+      method: 'POST',
+      header: {
+        'Content-Type': 'application/json',
+        'Authorization': `Bearer ${token}`
+      },
+      data: {}
+    })
+    uni.hideLoading()
+    console.log('User info response:', response)
+    const resp = response.data as any
+    if (response.statusCode === 401) {
+      // Token 无效,清除并跳转登录
+      uni.removeStorageSync('token')
+      uni.removeStorageSync('role')
+      user.value = {}
+      uni.reLaunch({ url: '/pages/public/login/index' })
+      isFetching.value = false
+      return
+    }
+    if (resp && resp.code === 200 && resp.data) {
+      user.value = resp.data
+      uni.setStorageSync('user_info', resp.data)
+      // 如果缺少必要信息,引导用户补全
+      if (!resp.data.nickname || !resp.data.avatar) {
+        uni.navigateTo({ url: '/pages/patient/profile/infos/base-info' })
+      }
+    }
+  } catch (err) {
+    uni.hideLoading()
+    console.error('Fetch user info error:', err)
+  } finally {
+    isFetching.value = false
+  }
+}
+
+// 手动刷新:先从后端拉取最新用户信息,再重新生成二维码
+const refreshAndGenerate = async () => {
+  await fetchUserInfo()
+  // fetchUserInfo 可能会在 token 无效时跳转登录,下面仅在本地有用户信息时重绘二维码
+  if (user.value && (user.value.wx_openid || user.value.openid)) {
+    generateQRCode()
+  } else {
+    // 如果后端未返回 openid 等,仍尝试使用本地缓存绘制
+    loadUser()
+    generateQRCode()
+  }
+}
+
 const generateQRCode = () => {
 const generateQRCode = () => {
   console.log('Generating QR code, user data:', user.value)
   console.log('Generating QR code, user data:', user.value)
   if (!user.value.wx_openid || !user.value.role) {
   if (!user.value.wx_openid || !user.value.role) {
@@ -104,6 +163,12 @@ const generateQRCode = () => {
 }
 }
 
 
 onShow(() => {
 onShow(() => {
+  // 首次进入时不主动向后端请求数据(首页已获取),但需要检查登录态
+  const token = uni.getStorageSync('token')
+  if (!token) {
+    uni.reLaunch({ url: '/pages/public/login/index' })
+    return
+  }
   loadUser()
   loadUser()
   generateQRCode()
   generateQRCode()
 })
 })
@@ -144,7 +209,6 @@ onShow(() => {
   position: relative;
   position: relative;
   overflow: hidden;
   overflow: hidden;
   border: 1rpx solid rgba(255, 255, 255, 0.2);
   border: 1rpx solid rgba(255, 255, 255, 0.2);
-  animation: cardEntrance 0.6s ease-out;
 }
 }
 
 
 /* 渐变边框效果 */
 /* 渐变边框效果 */
@@ -237,7 +301,6 @@ onShow(() => {
     0 8rpx 20rpx rgba(0, 0, 0, 0.1);
     0 8rpx 20rpx rgba(0, 0, 0, 0.1);
   position: relative;
   position: relative;
   overflow: hidden;
   overflow: hidden;
-  transition: all 0.3s ease;
 }
 }
 
 
 /* 二维码装饰角 */
 /* 二维码装饰角 */
@@ -265,7 +328,6 @@ onShow(() => {
 }
 }
 
 
 .qr-container:active {
 .qr-container:active {
-  transform: scale(0.98);
   box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
   box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
 }
 }
 
 
@@ -279,11 +341,11 @@ onShow(() => {
 @keyframes cardEntrance {
 @keyframes cardEntrance {
   0% {
   0% {
     opacity: 0;
     opacity: 0;
-    transform: translateY(30rpx) scale(0.95);
+    transform: translate3d(0, 30rpx, 0) scale(0.95);
   }
   }
   100% {
   100% {
     opacity: 1;
     opacity: 1;
-    transform: translateY(0) scale(1);
+    transform: translate3d(0, 0, 0) scale(1);
   }
   }
 }
 }
 
 
@@ -331,11 +393,9 @@ onShow(() => {
   font-size: 28rpx;
   font-size: 28rpx;
   font-weight: 500;
   font-weight: 500;
   box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
   box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
-  transition: all 0.3s ease;
 }
 }
 
 
 .refresh-btn:active {
 .refresh-btn:active {
-  transform: scale(0.95);
   box-shadow: 0 2rpx 6rpx rgba(102, 126, 234, 0.4);
   box-shadow: 0 2rpx 6rpx rgba(102, 126, 234, 0.4);
 }
 }
 </style>
 </style>