From c62a61cfdba5cf60f59e7e79432150e479155da4 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期一, 31 八月 2026 09:01:12 +0800
Subject: [PATCH] feat: 关闭标签页/浏览器后强制重新登录——认证信息(token/username/realName/modules)改存 sessionStorage,目录记忆/备注草稿等偏好仍存 localStorage

---
 traffic-audit-web/src/views/ReportExport.vue |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/traffic-audit-web/src/views/ReportExport.vue b/traffic-audit-web/src/views/ReportExport.vue
index bcfd56b..2530d22 100644
--- a/traffic-audit-web/src/views/ReportExport.vue
+++ b/traffic-audit-web/src/views/ReportExport.vue
@@ -1,6 +1,6 @@
 <template>
-  <el-container>
-    <el-header>浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁� - 鎶ヨ〃鐢熸垚</el-header>
+  <el-container direction="vertical">
+    <app-header title="浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁� - 鎶ヨ〃鐢熸垚"></app-header>
     <el-container>
       <el-aside width="200px">
         <el-menu router :default-active="activeMenu">
@@ -12,7 +12,6 @@
           <el-menu-item index="/report">鎶ヨ〃鐢熸垚</el-menu-item>
           <el-menu-item index="/rules">瑙勫垯绠$悊</el-menu-item>
           <el-menu-item index="/users">鐢ㄦ埛绠$悊</el-menu-item>
-          <el-menu-item index="/login" @click="logout">閫�鍑虹櫥褰�</el-menu-item>
         </el-menu>
       </el-aside>
       <el-main>
@@ -146,9 +145,11 @@
 </template>
 
 <script>
+import AppHeader from '@/components/AppHeader.vue'
 import api from '@/api'
 
 export default {
+  components: { AppHeader },
   name: 'ReportExport',
   data() {
     return {
@@ -210,10 +211,10 @@
     }
   },
   computed: {
-    username() { return localStorage.getItem('username') || '' },
-    realName() { return localStorage.getItem('realName') || '' },
+    username() { return sessionStorage.getItem('username') || '' },
+    realName() { return sessionStorage.getItem('realName') || '' },
     myModules() {
-      const s = localStorage.getItem('modules')
+      const s = sessionStorage.getItem('modules')
       if (!s) return []
       return s.split(',').filter(Boolean)
     },
@@ -263,7 +264,7 @@
       return m ? m.title : key
     },
     logout() {
-      localStorage.removeItem('token'); localStorage.removeItem('username'); localStorage.removeItem('realName'); localStorage.removeItem('modules')
+      sessionStorage.removeItem('token'); sessionStorage.removeItem('username'); sessionStorage.removeItem('realName'); sessionStorage.removeItem('modules')
       this.$router.push('/login')
     },
     // ==================== 鏌ヨ鏉′欢涓庣姸鎬佸埛鏂� ====================
@@ -303,7 +304,7 @@
       const m = this.curModule
       if (!m || !this.period) return
       const params = Object.assign(this.buildParams(), { types: m.items.map(i => i.key).join(',') })
-      api.get('/report/ready', { params })
+      api.get('/report/ready', { params, timeout: 60000 })
         .then(res => {
           const list = (res && res.data && res.data.items) || []
           list.forEach(r => {
@@ -348,7 +349,7 @@
       if (!items.length) { this.$message.warning('璇烽�夋嫨瑕侀瑙堢殑鎶ヨ〃'); return }
       this.loading = 'preview-' + m.key
       const params = Object.assign(this.buildParams(), { types: items.map(i => i.key).join(',') })
-      api.get('/report/preview', { params })
+      api.get('/report/preview', { params, timeout: 60000 })
         .then(res => {
           const list = (res && res.data && res.data.items) || []
           this.previewItems = list.map(it => {
@@ -386,18 +387,18 @@
       const params = this.buildParams()
       const doExport = () => {
         if (items.length === 1) {
-          api.get('/report/export/' + items[0].key, { params, responseType: 'blob' })
+          api.get('/report/export/' + items[0].key, { params, responseType: 'blob', timeout: 120000 })
             .then(res => { this.downloadBlob(res, items[0].fileName); this.$message.success('鎶ヨ〃瀵煎嚭鎴愬姛'); this.loading = '' })
             .catch(err => this.failWith(err))
           return
         }
         const zipParams = Object.assign({}, params, { types: items.map(i => i.key).join(',') })
-        api.get('/report/export/selected', { params: zipParams, responseType: 'blob' })
+        api.get('/report/export/selected', { params: zipParams, responseType: 'blob', timeout: 120000 })
           .then(res => { this.downloadBlob(res, '鐢熸垚_鎵�閫夋姤琛╛' + this.period + '.zip'); this.$message.success('宸插鍑� ' + items.length + ' 寮犳姤琛紙zip锛�'); this.loading = '' })
           .catch(err => this.failWith(err))
       }
       const readyParams = Object.assign({}, params, { types: items.map(i => i.key).join(',') })
-      api.get('/report/ready', { params: readyParams })
+      api.get('/report/ready', { params: readyParams, timeout: 60000 })
         .then(rd => {
           const list = (rd && rd.data && rd.data.items) || []
           const missing = list.filter(i => !i.ready)
@@ -419,6 +420,7 @@
         .catch(() => doExport())
     },
     failWith(err) {
+      if (err && err._toast) { this.loading = ''; return }
       let msg = ''
       const d = err && err.response && err.response.data
       if (d && typeof d === 'object' && d.message) msg = d.message

--
Gitblit v1.9.1