浏览代码

fix: 修改长时间不操作一直刷新问题以及bug

shiyanyu 1 天之前
父节点
当前提交
cc0c65e695

+ 1 - 1
src/components/costAudit/FilePreview.vue

@@ -72,7 +72,7 @@
 <style lang="scss" scoped>
   .preview-frame {
     width: 100%;
-    height: 80vh;
+    height: 73vh;
     border: none;
   }
   #myIframe img {

+ 66 - 17
src/utils/request.js

@@ -19,6 +19,30 @@ import { isArray } from '@/utils/validate'
 
 let loadingInstance
 
+// ===== 防止登录失效时并发请求导致的重复弹窗/重复跳转/刷新死循环 =====
+let __authRedirecting = false
+let __authRedirectingAt = 0
+const AUTH_REDIRECT_COOLDOWN_MS = 3000
+
+const beginAuthRedirectOnce = () => {
+  const now = Date.now()
+  if (
+    __authRedirecting &&
+    now - __authRedirectingAt < AUTH_REDIRECT_COOLDOWN_MS
+  )
+    return false
+  __authRedirecting = true
+  __authRedirectingAt = now
+  return true
+}
+
+const endAuthRedirectLater = () => {
+  // 给路由跳转/整页跳转留一点时间,避免立即被后续请求打断
+  setTimeout(() => {
+    __authRedirecting = false
+  }, AUTH_REDIRECT_COOLDOWN_MS)
+}
+
 // ensure custom style for scrollable error message box exists
 const ensureScrollableBoxStyle = () => {
   if (typeof document === 'undefined') return
@@ -63,7 +87,10 @@ const ensureScrollableBoxStyle = () => {
  */
 const handleCode = (code, msg) => {
   switch (code) {
-    case invalidCode:
+    case invalidCode: {
+      // token/会话失效:只允许触发一次清理与跳转,避免并发请求造成循环跳转/刷新
+      const canRedirect = beginAuthRedirectOnce()
+
       ensureScrollableBoxStyle()
       MessageBox.alert(
         `<div class="scrollable-error-content">${
@@ -78,37 +105,52 @@ const handleCode = (code, msg) => {
           center: false,
         }
       )
-      store.dispatch('user/resetAccessToken')
-      if (loginInterception) {
-        try {
-          const fullPath = router.currentRoute.fullPath
-          if (recordRoute && fullPath) {
-            router.push(`/login?redirect=${fullPath}`)
-          } else {
-            router.push('/login')
+
+      if (canRedirect) {
+        store.dispatch('user/resetAccessToken')
+        if (loginInterception) {
+          try {
+            const fullPath = router.currentRoute.fullPath
+            if (recordRoute && fullPath) {
+              router.replace(`/login?redirect=${fullPath}`)
+            } else {
+              router.replace('/login')
+            }
+          } catch (e) {
+            // 兜底:直接跳转登录页
+            window.location.href = '/login'
+          } finally {
+            endAuthRedirectLater()
           }
-        } catch (e) {
-          // 兜底:直接跳转登录页
-          window.location.href = '/login'
+        } else {
+          endAuthRedirectLater()
         }
       }
       break
-    case noPermissionCode:
+    }
+    case noPermissionCode: {
+      const canRedirect = beginAuthRedirectOnce()
+      if (!canRedirect) break
+
       store
         .dispatch('user/logout')
         .then(() => {
           if (recordRoute) {
             const fullPath = router.currentRoute.fullPath
-            router.push(`/login?redirect=${fullPath}`)
+            router.replace(`/login?redirect=${fullPath}`)
           } else {
-            router.push('/login')
+            router.replace('/login')
           }
         })
         .catch(() => {
           // logout时可能因为token过期报401错误,此时用href跳转到login页面
           window.location.href = '/login'
         })
+        .finally(() => {
+          endAuthRedirectLater()
+        })
       break
+    }
     default:
       if (Number(code) === 500) {
         // 500 保持原来的轻提示样式
@@ -236,8 +278,15 @@ instance.interceptors.response.use(
     const { response, message } = error
     if (error.response && error.response.data) {
       const { status, data } = response
-      //data.msg
-      handleCode(status, data.message || message)
+
+      // 避免并发401/会话失效时重复弹窗、重复跳转
+      // 注意:后端可能直接返回 HTTP 401/403,而不是业务 code
+      if (status === 401 || status === invalidCode) {
+        handleCode(invalidCode, data.message || message)
+      } else {
+        handleCode(status, data.message || message)
+      }
+
       return Promise.reject(error)
     } else {
       let { message } = error

+ 2 - 1
src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/auditNoticeTab.vue

@@ -818,7 +818,8 @@
           }
           if (this.strIncludes(item.pinyin, 'DiGaoNeiRong') && item.dataValue) {
             // 移除所有HTML标签
-            item.dataValue = item.dataValue.replace(/<[^>]+>/g, '')
+            // item.dataValue = item.dataValue.replace(/<[^>]+>/g, '')
+            item.dataValue = item.dataValue
           }
           if (this.strIncludes(documenName, '成本监审通知书')) {
             if (primaryUnit) {