armg 2 viikkoa sitten
vanhempi
commit
c80212ba4b
3 muutettua tiedostoa jossa 70 lisäystä ja 22 poistoa
  1. 8 2
      src/router/index.ts
  2. 30 11
      src/utils/requestAI.js
  3. 32 9
      src/utils/wecomLogin.ts

+ 8 - 2
src/router/index.ts

@@ -99,8 +99,14 @@ router.beforeEach((to, from, next) => {
       return;
     }
     const code = to.query.code as string;
-    if (code) {
-      doWecomLogin(code)
+    let finalCode;
+    if (Array.isArray(code)) {
+      finalCode = code.length > 0 ? code[code.length - 1] : null;
+    } else {
+      finalCode = code || null;
+    }
+    if (finalCode) {
+      doWecomLogin(finalCode)
         .then(() => {
           next();
           console.log(`登录成功,即将进入 ${to.path}`);

+ 30 - 11
src/utils/requestAI.js

@@ -5,6 +5,7 @@
 import axios from 'axios'
 import { Toast } from 'vant';
 import errorCode from '@/utils/errorCode'
+import { getQyCode, authLock } from '@/utils/wecomLogin.ts';
 
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 const service = axios.create({
@@ -35,7 +36,7 @@ service.interceptors.request.use(config => {
 })
 
 // 响应拦截器
-service.interceptors.response.use(res => {
+service.interceptors.response.use(async(res) => {
     const code = res.data.StatusCode || 200;
     const msg = errorCode[code] || res.data.msg || errorCode['default']
     if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
@@ -47,20 +48,38 @@ service.interceptors.response.use(res => {
         Toast(msg);
         return Promise.reject(new Error(msg))
     } else if (code === 420) {
-        window.localStorage.clear();
-        let url, appid, agentid;
-        // url = encodeURIComponent(process.env.VUE_APP_AUTHURL);
-        url = encodeURIComponent(window.location.href);
-        appid = process.env.VUE_APP_APPID;
-        agentid = process.env.VUE_APP_AGENTID;
-        // console.log("--url=",url)
-        window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${url}&response_type=code&scope=snsapi_base&state=&agentid=${agentid}&&t=${new Date().getTime()}#wechat_redirect`;
-    } 
+        // 双重判断:内存锁 + 本地缓存锁
+        const isLock = authLock.isAuthorizing || window.localStorage.getItem('isWechatAuthorizing') === 'true';
+        
+        if (isLock) {
+            return Promise.reject(new Error('正在授权,请勿重复操作'));
+        }
+        // 1. 立即加锁(关键:先锁再执行跳转)
+        authLock.lock();
+
+        try {
+            // 2. 取消所有未完成的请求(中断并发接口)
+            const cancelTokenSource = axios.CancelToken.source();
+            service.defaults.cancelToken = cancelTokenSource.token;
+            cancelTokenSource.cancel('授权失效,中断请求');
+
+            // 3. 微任务延迟跳转:给其他接口足够时间感知锁状态
+            await Promise.resolve(); // 或 setTimeout(() => {}, 0)
+
+            // 4. 拼接授权链接并跳转(记录当前页面用于回跳)
+            getQyCode()
+
+        } catch (err) {
+            // 异常时解锁
+            authLock.unlock();
+            console.error('授权跳转失败:', err);
+        }
+    }
     // else if (code !== 200 && code !== 204) {
     //     Toast(msg);
     //     return Promise.reject('error')
     // }
-     else {
+    else {
         return res.data
     }
 },

+ 32 - 9
src/utils/wecomLogin.ts

@@ -67,7 +67,7 @@ export const initGuidInfo = (): void => {
  * @returns {Promise<void>}
  */
 export const doWecomLogin = async (code: string): Promise<void> => {
-    if (isLogging) return; // 正在登录中,忽略重复调用
+   if (isLogging) return; // 正在登录中,忽略重复调用
     isLogging = true;
     try {
         const lastCodeStr = window.localStorage.getItem('lastCode');
@@ -86,26 +86,24 @@ export const doWecomLogin = async (code: string): Promise<void> => {
         // formData.append("code", 'QWert!@345');
         // 调用接口兑换 AIToken
         const res: WecomAuthResponse = await wecomAuth(formData);
-        if (res.StatusCode === 200 && res.Data && res.Data.token) {
+        if (res && res.StatusCode === 200 && res.Data && res.Data.token) {
             // 登录成功:存储 AIToken
             window.localStorage.setItem('AIToken', res.Data.token);
             isLogging = false;
             // console.log("router.currentRoute.fullPath=",router.currentRoute.fullPath)
             // 重新跳转目标页面(此时登录状态已满足)
             // router.push(router.currentRoute.fullPath);
-        } else if (res.StatusCode === 403) {
+        } else if (res && res.StatusCode === 403) {
             // 无权限 → 跳错误页
             isLogging = false;
             router.push('/error');
-        } else if (res.StatusCode === 420) {
+        } else if (res && res.StatusCode === 420) {
             // 需重新获取 code → 清除缓存并重定向
             isLogging = false;
-            window.localStorage.clear();
             getQyCode(); // 你的获取企业微信二维码/授权链接的函数
         } else {
             isLogging = false;
-            // 兼容写法:判断 res.Message 是否存在(去掉 ?.)
-            throw new Error(res.Message ? res.Message : '登录失败');
+            throw new Error(res && res.Message ? res.Message : '登录失败');
         }
     } catch (error) {
         isLogging = false;
@@ -123,11 +121,36 @@ export const getGuid = () => {
     });
 }
 export const getQyCode = () => {
+    window.localStorage.clear();
     let url, appid, agentid;
     // url = encodeURIComponent(process.env.VUE_APP_AUTHURL);
     url = encodeURIComponent(window.location.href);
+    // console.log("-url=",url)
     appid = process.env.VUE_APP_APPID;
     agentid = process.env.VUE_APP_AGENTID;
-
     window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${url}&response_type=code&scope=snsapi_base&state=&agentid=${agentid}&t=${new Date().getTime()}#wechat_redirect`;
-}
+}
+
+// utils/authLock.js
+export const authLock = {
+  // 内存锁:实时判断
+  isAuthorizing: false,
+  // 初始化:从本地缓存恢复锁状态(防止页面刷新后锁失效)
+  init() {
+    const lock = window.localStorage.getItem('isWechatAuthorizing');
+    this.isAuthorizing = lock === 'true';
+  },
+  // 加锁:同时更新内存和本地缓存
+  lock() {
+    this.isAuthorizing = true;
+    window.localStorage.setItem('isWechatAuthorizing', 'true');
+  },
+  // 解锁:同时更新内存和本地缓存
+  unlock() {
+    this.isAuthorizing = false;
+    window.localStorage.removeItem('isWechatAuthorizing');
+  }
+};
+
+// 初始化锁
+authLock.init();