166 lines
4.8 KiB
JavaScript
166 lines
4.8 KiB
JavaScript
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 }
|
||
}) |