import { ref } from "vue"; import { defineStore } from "pinia"; import api from '@/utils/api'; import { toast } from '@/utils/widget'; import { initGlobalTIM, globalTimChatManager } from "@/utils/tim-chat.js"; import cache from '@/utils/cache'; import { get, remove } from "@/utils/cache"; const env = __VITE_ENV__; // 缓存键名 const CACHE_KEYS = { ACCOUNT: 'account', OPENID: 'openid', DOCTOR_INFO: 'doctorInfo' }; export default defineStore("accountStore", () => { const appid = env.MP_WX_APP_ID; const corpId = env.MP_CORP_ID; // 从缓存中恢复数据 const mp_appid = env.MP_WX_MP_APP_ID; const account = ref(cache.get(CACHE_KEYS.ACCOUNT, null)); const loginPromise = ref(null); // IM 相关 const openid = ref(cache.get(CACHE_KEYS.OPENID, "")); const isIMInitialized = ref(false); // 医生信息 - 不做缓冲处理,每次都重新获取 const doctorInfo = ref(null); function getLoginPromise(phoneCode = '') { if (loginPromise.value) return loginPromise.value; loginPromise.value = loginByCode(phoneCode); return loginPromise.value; } async function login(phoneCode) { const res = getLoginPromise(phoneCode); loginPromise.value = null; return res } async function loginByCode(phoneCode = '') { try { console.log('appid', appid); console.log('mp_appid', mp_appid); // 获取小程序 code(静默,无需授权页) const { code } = await uni.login({ appid, provider: "weixin", scope: "snsapi_base", }); // 公众号(服务号)OAuth code 不能在小程序内通过 uni.login 获取。 // 正确方式:在“微信内置浏览器/H5”走公众号 OAuth 重定向后,把 code 回传到小程序(例如通过 query 参数/缓存),这里读取并透传给后端做映射。 const mpCode = get("mp-oauth-code", ""); if (code) { // 将小程序 code + 公众号 code 一起传给后端,进行用户映射(后端用各自 appid/secret 换 openid/unionid) const res = await api('wxAppLogin', { appId: appid, phoneCode, code, // 小程序code mpCode, // 公众号 code(如果有) corpId, }); if (mpCode) remove("mp-oauth-code"); if (res.success && res.data) { if (!res.data.mobile) { const target = '/pages/login/login'; uni.redirectTo({ url: target }); return; } account.value = res.data; openid.value = res.data.openid; // 持久化账户信息 cache.set(CACHE_KEYS.ACCOUNT, res.data); cache.set(CACHE_KEYS.OPENID, res.data.openid); // 登录成功后初始化腾讯IM await getDoctorInfo(openid.value); await initIMAfterLogin(); return res.data } } toast('登录失败,请重新登录'); } catch (e) { console.error('登录失败:', e); toast('登录失败,请重新登录'); } return Promise.reject() } async function getDoctorInfo(data = {}) { try { const res = await api('getCorpMemberData', { ...data, weChatOpenId: account.value.openid, }); doctorInfo.value = res?.data || null; // 检查账号是否被禁用 if (doctorInfo.value?.accountState === "disable") { uni.showModal({ title: '账号被禁用', content: '您的账号已被禁用,请联系管理员', showCancel: false, confirmText: '确定', success: () => { uni.redirectTo({ url: "/pages/login/login" }); } }); return; } } catch (e) { console.error('获取医生信息失败:', e); } } async function initIMAfterLogin() { if (isIMInitialized.value) return true; if (!doctorInfo.value) return; try { const userID = doctorInfo.value.userid; if (!userID) await getDoctorInfo(); await initGlobalTIM(userID); isIMInitialized.value = true; return true; } catch (error) { console.error('IM初始化失败:', error); return false; } } // 退出登录 async function logout() { try { // 退出腾讯IM if (globalTimChatManager && globalTimChatManager.tim) { console.log('开始退出腾讯IM'); await globalTimChatManager.destroy(); console.log('腾讯IM退出成功'); } } catch (error) { console.error('退出腾讯IM失败:', error); } // 清空账户信息 account.value = null; openid.value = ""; isIMInitialized.value = false; doctorInfo.value = null; // 清空缓存 cache.remove(CACHE_KEYS.ACCOUNT); cache.remove(CACHE_KEYS.OPENID); } return { account, openid, isIMInitialized, doctorInfo, login, getDoctorInfo, initIMAfterLogin, logout } })