Przeglądaj źródła

feat(health): 增强提醒页面的订阅状态检测与生命周期管理

- 引入 onShow/onHide 生命周期钩子以监听页面显隐
- 新增对小程序/APP前后台切换时的订阅状态检查逻辑
- 在页面显示时主动同步全局通知设置状态
- 添加 H5 平台的 visibilitychange 事件监听支持
- 注册 uni-app 全局前后台切换事件(onAppShow/onAppHide)
- 移除初始加载时冗余的订阅状态检查调用
- 增加详细的调试日志便于问题追踪
- 完善组件卸载阶段的事件解绑逻辑避免内存泄漏
mcbaiyun 1 miesiąc temu
rodzic
commit
993d535f8f
1 zmienionych plików z 102 dodań i 2 usunięć
  1. 102 2
      src/pages/health/reminder.vue

+ 102 - 2
src/pages/health/reminder.vue

@@ -43,7 +43,8 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref, onMounted, computed } from 'vue'
+import { ref, onMounted, onUnmounted, computed } from 'vue'
+import { onShow, onHide } 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 TabBar from '@/components/tab-bar.vue'
@@ -88,13 +89,14 @@ const entrySourceText = computed(() => {
 onMounted(() => {
 onMounted(() => {
   try {
   try {
     const val = (uni as any).getStorageSync('notificationsEnabled')
     const val = (uni as any).getStorageSync('notificationsEnabled')
+    console.log('已获取全局消息开关状态:', val)
     if (typeof val === 'boolean') notificationsEnabled.value = val
     if (typeof val === 'boolean') notificationsEnabled.value = val
   } catch (e) {
   } catch (e) {
     // 忽略错误
     // 忽略错误
   }
   }
   
   
   // 检查用户订阅状态
   // 检查用户订阅状态
-  checkSubscriptionStatus()
+  // checkSubscriptionStatus()
   
   
   // 尝试判断来源:优先检查页面栈的上一个页面;若无(直接打开),则检查 launch options 的 query
   // 尝试判断来源:优先检查页面栈的上一个页面;若无(直接打开),则检查 launch options 的 query
   try {
   try {
@@ -168,6 +170,104 @@ onMounted(() => {
   }
   }
 })
 })
 
 
+// 监听页面显示/隐藏(用于检测用户将小程序/APP切到后台或再次回到前台)
+onShow(() => {
+  console.log('[reminder] 页面/应用返回前台(onShow)', { entrySource: entrySource.value })
+  // 在页面返回前台时,检查订阅设置;如果用户关闭了通知订阅主开关或对本模板拒绝,则主动关闭本地消息开关
+  try {
+    if (typeof (uni as any).getSetting === 'function') {
+      ;(uni as any).getSetting({
+        withSubscriptions: true,
+        success(res: any) {
+          try {
+            const subs = res.subscriptionsSetting || {}
+            const mainSwitch = subs.mainSwitch
+            const itemSettings = subs.itemSettings || {}
+            const templateStatus = itemSettings[TEMPLATE_ID]
+            console.log('[reminder][onShow] 订阅设置检查结果:', { mainSwitch, templateStatus })
+            // 若主开关关闭或模板被拒绝/屏蔽,则主动关闭本地通知开关
+            if (mainSwitch === false || templateStatus === 'reject' || templateStatus === 'ban') {
+              console.log('[reminder][onShow] 发现订阅被关闭或本模板被拒绝,主动关闭通知开关')
+              notificationsEnabled.value = false
+              //showPermissionGuide.value = (mainSwitch === false)
+              try {
+                ;(uni as any).setStorageSync('notificationsEnabled', false)
+              } catch (e) {}
+            } else {
+              // 订阅为开启或未明确拒绝,不修改本地开关(按要求)
+              console.log('[reminder][onShow] 订阅设置未发现关闭,不更改本地开关状态')
+            }
+          } catch (e) {
+            console.error('[reminder][onShow] 处理 getSetting 返回值时出错:', e)
+          }
+        },
+        fail(err: any) {
+          console.error('[reminder][onShow] 获取订阅设置失败:', err)
+        }
+      })
+    } else {
+      console.log('[reminder][onShow] 当前环境不支持 getSetting,跳过订阅检查')
+    }
+  } catch (e) {
+    console.error('[reminder][onShow] 检查订阅设置时异常:', e)
+  }
+})
+
+onHide(() => {
+  console.log('[reminder] 页面/应用进入后台(onHide)', { entrySource: entrySource.value })
+})
+
+// H5 平台兼容:document.visibilityState
+const handleVisibilityChange = () => {
+  try {
+    const state = (document as any).visibilityState
+    if (state === 'hidden') {
+      console.log('[reminder][visibilitychange] H5 页面变为 hidden(退到后台/切换窗口)')
+    } else if (state === 'visible') {
+      console.log('[reminder][visibilitychange] H5 页面变为 visible(回到前台)')
+    }
+  } catch (e) {
+    // 忽略在非 H5 环境下的错误
+  }
+}
+
+onMounted(() => {
+  // 注册 H5 可见性变更监听
+  try {
+    if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
+      document.addEventListener('visibilitychange', handleVisibilityChange)
+    }
+  } catch (e) {
+    // 忽略
+  }
+
+  // 额外注册 uni 全局的 App 前后台事件(部分平台需要)
+  try {
+    if ((uni as any) && typeof (uni as any).onAppShow === 'function') {
+      ;(uni as any).onAppShow((res: any) => {
+        console.log('[reminder][uni.onAppShow] App 回到前台', res)
+      })
+    }
+    if ((uni as any) && typeof (uni as any).onAppHide === 'function') {
+      ;(uni as any).onAppHide(() => {
+        console.log('[reminder][uni.onAppHide] App 进入后台')
+      })
+    }
+  } catch (e) {
+    // 忽略注册错误
+  }
+})
+
+onUnmounted(() => {
+  try {
+    if (typeof document !== 'undefined' && typeof document.removeEventListener === 'function') {
+      document.removeEventListener('visibilitychange', handleVisibilityChange)
+    }
+  } catch (e) {
+    // 忽略
+  }
+})
+
 /**
 /**
  * 检查用户订阅状态
  * 检查用户订阅状态
  */
  */