import { wecomAuth } from "@/api/indexAI"; import router from '@/router'; import md5 from 'js-md5'; // 企业微信登录相关类型定义(无变化,无需可选链) export interface GuidInfo { guid: string; time: number; // 时间戳(毫秒) } export interface LastCode { code: string; } // 登录中状态锁(避免并发登录请求) let isLogging = false; /** * 校验是否已登录(AIToken 存在 + guidInfo 未过期) * @returns {boolean} 是否已登录 */ export const checkLoginStatus = (): boolean => { const AIToken = window.localStorage.getItem('AIToken'); const guidInfoStr = window.localStorage.getItem('guidInfo'); if (!AIToken) return false; if (!guidInfoStr) return false; return true; // try { // const guidInfo: GuidInfo = JSON.parse(guidInfoStr); // const currentTime = new Date().getTime(); // const expireTime = 1000 * 60 * 60 * 12; // 12 小时过期 // return guidInfo && guidInfo.guid && (currentTime - guidInfo.time) < expireTime; // } catch (error) { // return false; // } }; /** * 初始化 guidInfo */ export const initGuidInfo = (): void => { let guidInfo = JSON.parse(window.localStorage.getItem("guidInfo")); const currentTime = new Date().getTime(); const guid = getGuid(); const guidTime = new Date().getTime(); const newGuidInfo: GuidInfo = { guid, time: guidTime }; // 有缓存但过期-存储 if (guidInfo && (currentTime - guidInfo.time) >= (1000 * 60 * 60 * 12)) { window.localStorage.setItem("guidInfo", JSON.stringify(newGuidInfo)); window.localStorage.removeItem('lastCode'); } else if (!guidInfo) { // 无缓存-存储 window.localStorage.setItem('guidInfo', JSON.stringify(newGuidInfo)); } }; /** * 企业微信登录核心流程(获取 code → 兑换 AIToken) * @param code 企业微信授权返回的 code * @returns {Promise} */ export const doWecomLogin = async (code: string, wxId?: string): Promise => { if (isLogging) return; // 正在登录中,忽略重复调用 isLogging = true; try { const lastCodeStr = window.localStorage.getItem('lastCode'); const lastCode: LastCode | null = lastCodeStr ? JSON.parse(lastCodeStr) : null; // 同一 code 不重复请求 if (lastCode && lastCode.code === code) { isLogging = false; return; } // 存储当前 code,避免重复使用 window.localStorage.setItem('lastCode', JSON.stringify({ code })); const formData = new FormData(); formData.append('code', code); if (wxId) { formData.append("wxId", wxId); } else { formData.append("wxId", process.env.VUE_APP_APPID); } // 调用接口兑换 AIToken const res = await wecomAuth(formData); if (res && res.StatusCode === 200 && res.Data && res.Data.token) { const userInfoV1 = JSON.stringify(res.Data); window.localStorage.setItem('userInfoV1', userInfoV1); window.localStorage.setItem('AIToken', res.Data.token); window.localStorage.setItem('isRefreshProvider', res.Data.isRefreshProvider); window.localStorage.setItem('weChat', res.Data.weChat); // 处理身份,身份可能为多个,只能按身份权限大小来固定为某个身份; // if (res.Data.userType) { // // 使用位运算 // const ROLE_CONFIG = [ // { bit: 1 << 0, code: 'ssb', desc: '经销商' }, // 1 // { bit: 1 << 1, code: 'hbs', desc: '立邦用户' }, // 2 // { bit: 1 << 2, code: 'stoneLikePaint', desc: '服务商' }, // 4 // { bit: 1 << 3, code: 'goldShop', desc: '金牌店' }, // 8 // { bit: 1 << 4, code: 'dg', desc: '导购' }, // 16 // { bit: 1 << 5, code: 'xlskf', desc: '新零售客服' } // 32 // ]; // const userType = Number(res.Data.userType); // console.log("userType=", userType); // const matchRole = ROLE_CONFIG.find(item => (userType & item.bit) === item.bit); // console.log("matchRole=", matchRole) // const agent = matchRole && matchRole.code || 'xlskf'; // window.localStorage.setItem('agentFrom', agent); // window.localStorage.setItem('agentFromAI', agent); // }else{ window.localStorage.setItem('agentFrom', 'xlskf'); window.localStorage.setItem('agentFromAI', 'xlskf'); // } isLogging = false; } else { isLogging = false; } } catch (error) { isLogging = false; console.error('企业微信登录失败:', error); // 登录失败可提示用户或重试 // alert('登录失败,请刷新页面重试'); } }; export const getGuid = () => { return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) { let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } 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`; } /** * 生成指定规则的MD5签名 * @param nonce 随机串 (如:8a2d9f7c3b5e10s6g9h2j4k8l0z7x5c3v) * @param timestamp 时间戳 (如:1736000000000) * @param wxId wx标识 (如:zhangsan123) * @returns 32位大写MD5加密字符串 */ export const getMD5 = (nonce: string, timestamp: string, wxId: string): string => { // 严格按规则拼接参数字符串:nonce=xxx×tamp=xxx&wxId=xxx&key=xxx const signStr = `nonce=${nonce}×tamp=${timestamp}&wxId=${wxId}&key=${process.env.VUE_APP_SECRETKEY}`; const md5Result = md5(signStr); return md5Result; }; // 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();