xsh_1997 6 dni temu
rodzic
commit
152222590b
3 zmienionych plików z 49 dodań i 12 usunięć
  1. 1 1
      ruoyi-ui-app/App.vue
  2. 2 1
      ruoyi-ui-app/mixins/tabPage.js
  3. 46 10
      ruoyi-ui-app/utils/tabBar.js

+ 1 - 1
ruoyi-ui-app/App.vue

@@ -8,7 +8,7 @@ export default {
8 8
     syncUserOnLaunch().catch(() => {})
9 9
   },
10 10
   onShow() {
11
-    console.log('App Show')
11
+    installTabBarApiGuard()
12 12
   },
13 13
   onHide() {
14 14
     console.log('App Hide')

+ 2 - 1
ruoyi-ui-app/mixins/tabPage.js

@@ -1,4 +1,4 @@
1
-import { ensureTabBarEntry, isTabBarPage, syncTabBarText } from '@/utils/tabBar'
1
+import { ensureTabBarEntry, installTabBarApiGuard, isTabBarPage, syncTabBarText } from '@/utils/tabBar'
2 2
 
3 3
 /**
4 4
  * Tab 子页共用:根节点语言 class、导航标题、底部 tab 文案与 i18n 同步
@@ -19,6 +19,7 @@ export default {
19 19
     }
20 20
   },
21 21
   onShow() {
22
+    installTabBarApiGuard()
22 23
     const applyTabPageUi = () => {
23 24
       if (!isTabBarPage()) {
24 25
         return

+ 46 - 10
ruoyi-ui-app/utils/tabBar.js

@@ -21,6 +21,9 @@ const TABBAR_API_NAMES = [
21 21
   'setTabBarMidButton'
22 22
 ]
23 23
 
24
+/** 首次安装时缓存的原始 API(避免重复 bind 已包装函数) */
25
+const TABBAR_RAW_APIS = {}
26
+
24 27
 let tabBarEntryTask = null
25 28
 
26 29
 function readUniTabPagePaths() {
@@ -105,15 +108,16 @@ export function isTabBarRoute(route) {
105 108
 }
106 109
 
107 110
 /**
108
- * 当前栈顶是否为原生 TabBar 页(须 meta.isTabBar,不能只看 route)
109
- * H5 history 直开 /bqH5/pages/home/index 时 route 会匹配 Tab,但 meta.isTabBar 为 false
111
+ * 当前栈顶是否为原生 TabBar 页
112
+ * 须同时满足:meta.isTabBar === true 且 route 在 tabBar.list 内
113
+ * (仅 meta 或仅 route 在 H5 生产环境都可能误判,导致 setTabBarStyle:fail)
110 114
  */
111 115
 export function isTabBarPage() {
112
-  const meta = getCurrentPageMeta()
113
-  if (meta && typeof meta.isTabBar === 'boolean') {
114
-    return meta.isTabBar
116
+  if (!isTabBarRoute()) {
117
+    return false
115 118
   }
116
-  return false
119
+  const meta = getCurrentPageMeta()
120
+  return !!(meta && meta.isTabBar === true)
117 121
 }
118 122
 
119 123
 /**
@@ -162,18 +166,33 @@ function isTabBarFailMsg(msg) {
162 166
   return String(msg || '').includes('TabBar') && String(msg || '').includes('fail')
163 167
 }
164 168
 
169
+function rememberRawTabBarApi(target, name) {
170
+  if (TABBAR_RAW_APIS[name]) {
171
+    return TABBAR_RAW_APIS[name]
172
+  }
173
+  const fn = target[name]
174
+  if (typeof fn !== 'function') {
175
+    return null
176
+  }
177
+  if (fn._tabBarGuardRaw) {
178
+    TABBAR_RAW_APIS[name] = fn._tabBarGuardRaw
179
+    return TABBAR_RAW_APIS[name]
180
+  }
181
+  TABBAR_RAW_APIS[name] = fn.bind(target)
182
+  return TABBAR_RAW_APIS[name]
183
+}
184
+
165 185
 /**
166
- * H5 生产包中 addInterceptor 偶发拦不住框架内部调用,直接包装 uni/wx API 更稳
186
+ * H5 生产包中框架 / uview 可能在我们安装守卫后又写回 uni API,故每次启动 / 切页都重装
167 187
  */
168 188
 function wrapTabBarApi(target, name) {
169 189
   if (!target || typeof target[name] !== 'function') {
170 190
     return
171 191
   }
172
-  const current = target[name]
173
-  if (current._tabBarGuardPatched) {
192
+  const raw = rememberRawTabBarApi(target, name)
193
+  if (!raw) {
174 194
     return
175 195
   }
176
-  const raw = current.bind(target)
177 196
   function patchedTabBarApi(options) {
178 197
     const opts = options || {}
179 198
     if (!isTabBarPage()) {
@@ -189,6 +208,22 @@ function wrapTabBarApi(target, name) {
189 208
           throw err
190 209
         })
191 210
       }
211
+      if (ret && typeof ret.then === 'function') {
212
+        return ret.then(
213
+          (res) => {
214
+            if (res && isTabBarFailMsg(res.errMsg)) {
215
+              return noopTabBarResult(name)
216
+            }
217
+            return res
218
+          },
219
+          (err) => {
220
+            if (isTabBarFailMsg(err && err.errMsg)) {
221
+              return noopTabBarResult(name)
222
+            }
223
+            throw err
224
+          }
225
+        )
226
+      }
192 227
       return ret
193 228
     } catch (err) {
194 229
       if (isTabBarFailMsg(err && err.errMsg)) {
@@ -198,6 +233,7 @@ function wrapTabBarApi(target, name) {
198 233
     }
199 234
   }
200 235
   patchedTabBarApi._tabBarGuardPatched = true
236
+  patchedTabBarApi._tabBarGuardRaw = raw
201 237
   target[name] = patchedTabBarApi
202 238
 }
203 239