import { shallowRef, reactive } from 'vue' import { v4 } from 'uuid' import { timerTask } from '@/utils/timer' import { wsLogin, httpLogin, logout, queryLoginId } from '@/services/api/account' import { useGlobalStore, useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore, useNoticeStore } from '@/stores' import service from '@/services' import quoteSocket from '@/services/websocket/quote' import tradeSocket from '@/services/websocket/trade' import tradeV2Socket from '@/services/websocket/tradeV2' import { encryptBody } from '@/services/websocket/package/crypto' import { checkToken, checkTokenLoop, stopCheckToken } from '@/business/common' import eventBus from '@/services/bus' import cryptojs from 'crypto-js' /** * 登录业务模块 * @param persist 登录状态是否持久化---------不太合理的方式,待优化 * @returns */ export function useLogin(persist = false) { const globalStore = useGlobalStore() const enumStore = useEnumStore() const errorInfoStore = useErrorInfoStore() const loginStore = useLoginStore() const userStore = useUserStore() const accountStore = useAccountStore() const futuresStore = useFuturesStore() const noticeStore = useNoticeStore() const { logining, token } = loginStore.$toRefs() const remember = shallowRef(true) // 记住账号 const formData = reactive({ userName: localStorage.getItem('app_loginId') ?? '', password: '', clientType: 0, }) const loadBaseData = async () => { await service.onReady() // 等待服务初始化 await Promise.all([ errorInfoStore.getErrorInfoList(), enumStore.getAllEnumList(), ]) } const loadUserData = async () => { await checkToken() // 令牌校验 await Promise.all([ userStore.getUserData(), accountStore.getAccountList(), ]) futuresStore.getGoodsList() noticeStore.getNoticeList() checkTokenLoop() if (globalStore.getSystemInfo('tradeChannel') === 'http') { tradeV2Socket.connect() } } // 用户登录 const userLogin = async (autoLogin = false) => { try { logining.value = true await loadBaseData() const payload = await new Promise((resolve, reject) => { if (autoLogin) { const params = loginStore.getAutoLoginData() if (params) { resolve(params) } else { reject('自动登录失败') } } else { if (globalStore.getSystemInfo('tradeChannel') === 'ws') { // websocket 登录参数 queryLoginId({ data: { username: formData.userName } }).then((res) => { resolve({ userName: res.data, password: cryptojs.SHA256(res.data + formData.password).toString(), clientType: loginStore.getClientType() }) }).catch((err) => { reject(err) }) } else { // http 登录参数 resolve({ userName: formData.userName, password: encryptBody(formData.password), clientType: loginStore.getClientType() }) } } }) if (globalStore.getSystemInfo('tradeChannel') === 'ws') { // websocket 登录 const res = await wsLogin({ LoginID: payload.userName, LoginPWD: payload.password, GUID: v4(), LoginType: 0, ClientType: payload.clientType, Version: '2.0.0.0', DeviceID: '' }) // 更新登录信息 loginStore.setLoginInfo({ expiresAt: 0, loginId: res.LoginID, token: res.Token, userId: res.UserID, }, persist) } else { // http 登录 const res = await httpLogin({ data: payload }) // 更新登录信息 loginStore.setLoginInfo(res.data, persist) } loginStore.setAutoLoginData(payload) // 更新自动登录信息 localStorage.setItem('app_loginId', formData.userName) // 记住登录ID await loadUserData() eventBus.$emit('LoginNotify') // 登录成功通知 } finally { logining.value = false } } // 用户登出 const userLogout = (callback?: () => void) => { stopCheckToken() tradeSocket.close() tradeV2Socket.close() quoteSocket.close() timerTask.clearAll() accountStore.$reset() // 待处理,重置后可能会出现多个重复的 store 实例 loginStore.clearAutoLoginData() loginStore.clearLoginInfo() callback && callback() } // 初始化业务数据 const initBaseData = async (autoLogin = false) => { try { logining.value = true await loadBaseData() if (token.value) { await loadUserData() } else if (autoLogin && loginStore.getAutoLoginData()) { await userLogin(true) } } finally { logining.value = false } } return { logining, remember, formData, initBaseData, userLogin, userLogout, } }