xsh_1997 пре 6 дана
родитељ
комит
152222590b
3 измењених фајлова са 49 додато и 12 уклоњено
  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
     syncUserOnLaunch().catch(() => {})
8
     syncUserOnLaunch().catch(() => {})
9
   },
9
   },
10
   onShow() {
10
   onShow() {
11
-    console.log('App Show')
11
+    installTabBarApiGuard()
12
   },
12
   },
13
   onHide() {
13
   onHide() {
14
     console.log('App Hide')
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
  * Tab 子页共用:根节点语言 class、导航标题、底部 tab 文案与 i18n 同步
4
  * Tab 子页共用:根节点语言 class、导航标题、底部 tab 文案与 i18n 同步
@@ -19,6 +19,7 @@ export default {
19
     }
19
     }
20
   },
20
   },
21
   onShow() {
21
   onShow() {
22
+    installTabBarApiGuard()
22
     const applyTabPageUi = () => {
23
     const applyTabPageUi = () => {
23
       if (!isTabBarPage()) {
24
       if (!isTabBarPage()) {
24
         return
25
         return

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

@@ -21,6 +21,9 @@ const TABBAR_API_NAMES = [
21
   'setTabBarMidButton'
21
   'setTabBarMidButton'
22
 ]
22
 ]
23
 
23
 
24
+/** 首次安装时缓存的原始 API(避免重复 bind 已包装函数) */
25
+const TABBAR_RAW_APIS = {}
26
+
24
 let tabBarEntryTask = null
27
 let tabBarEntryTask = null
25
 
28
 
26
 function readUniTabPagePaths() {
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
 export function isTabBarPage() {
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
   return String(msg || '').includes('TabBar') && String(msg || '').includes('fail')
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
 function wrapTabBarApi(target, name) {
188
 function wrapTabBarApi(target, name) {
169
   if (!target || typeof target[name] !== 'function') {
189
   if (!target || typeof target[name] !== 'function') {
170
     return
190
     return
171
   }
191
   }
172
-  const current = target[name]
173
-  if (current._tabBarGuardPatched) {
192
+  const raw = rememberRawTabBarApi(target, name)
193
+  if (!raw) {
174
     return
194
     return
175
   }
195
   }
176
-  const raw = current.bind(target)
177
   function patchedTabBarApi(options) {
196
   function patchedTabBarApi(options) {
178
     const opts = options || {}
197
     const opts = options || {}
179
     if (!isTabBarPage()) {
198
     if (!isTabBarPage()) {
@@ -189,6 +208,22 @@ function wrapTabBarApi(target, name) {
189
           throw err
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
       return ret
227
       return ret
193
     } catch (err) {
228
     } catch (err) {
194
       if (isTabBarFailMsg(err && err.errMsg)) {
229
       if (isTabBarFailMsg(err && err.errMsg)) {
@@ -198,6 +233,7 @@ function wrapTabBarApi(target, name) {
198
     }
233
     }
199
   }
234
   }
200
   patchedTabBarApi._tabBarGuardPatched = true
235
   patchedTabBarApi._tabBarGuardPatched = true
236
+  patchedTabBarApi._tabBarGuardRaw = raw
201
   target[name] = patchedTabBarApi
237
   target[name] = patchedTabBarApi
202
 }
238
 }
203
 
239