index.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { shallowRef, reactive } from 'vue'
  2. import { v4 } from 'uuid'
  3. import { timerTask } from '@/utils/timer'
  4. import { wsLogin, httpLogin, logout, queryLoginId } from '@/services/api/account'
  5. import { useGlobalStore, useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore, useNoticeStore } from '@/stores'
  6. import service from '@/services'
  7. import quoteSocket from '@/services/websocket/quote'
  8. import tradeSocket from '@/services/websocket/trade'
  9. import tradeV2Socket from '@/services/websocket/tradeV2'
  10. import { encryptBody } from '@/services/websocket/package/crypto'
  11. import { checkToken, checkTokenLoop, stopCheckToken } from '@/business/common'
  12. import eventBus from '@/services/bus'
  13. import cryptojs from 'crypto-js'
  14. /**
  15. * 登录业务模块
  16. * @param persist 登录状态是否持久化---------不太合理的方式,待优化
  17. * @returns
  18. */
  19. export function useLogin(persist = false) {
  20. const globalStore = useGlobalStore()
  21. const enumStore = useEnumStore()
  22. const errorInfoStore = useErrorInfoStore()
  23. const loginStore = useLoginStore()
  24. const userStore = useUserStore()
  25. const accountStore = useAccountStore()
  26. const futuresStore = useFuturesStore()
  27. const noticeStore = useNoticeStore()
  28. const { logining, token } = loginStore.$toRefs()
  29. const remember = shallowRef(true) // 记住账号
  30. const formData = reactive<Model.LoginReq>({
  31. userName: localStorage.getItem('app_loginId') ?? '',
  32. password: '',
  33. clientType: 0,
  34. })
  35. const loadBaseData = async () => {
  36. await service.onReady() // 等待服务初始化
  37. await Promise.all([
  38. errorInfoStore.getErrorInfoList(),
  39. enumStore.getAllEnumList(),
  40. ])
  41. }
  42. const loadUserData = async () => {
  43. await checkToken() // 令牌校验
  44. await Promise.all([
  45. userStore.getUserData(),
  46. accountStore.getAccountList(),
  47. ])
  48. futuresStore.getGoodsList()
  49. noticeStore.getNoticeList()
  50. checkTokenLoop()
  51. if (globalStore.getSystemInfo('tradeChannel') === 'http') {
  52. tradeV2Socket.connect()
  53. }
  54. }
  55. // 用户登录
  56. const userLogin = async (autoLogin = false) => {
  57. try {
  58. logining.value = true
  59. await loadBaseData()
  60. const payload = await new Promise<Model.LoginReq>((resolve, reject) => {
  61. if (autoLogin) {
  62. const params = loginStore.getAutoLoginData()
  63. if (params) {
  64. resolve(params)
  65. } else {
  66. reject('自动登录失败')
  67. }
  68. } else {
  69. if (globalStore.getSystemInfo('tradeChannel') === 'ws') {
  70. // websocket 登录参数
  71. queryLoginId({
  72. data: {
  73. username: formData.userName
  74. }
  75. }).then((res) => {
  76. resolve({
  77. userName: res.data,
  78. password: cryptojs.SHA256(res.data + formData.password).toString(),
  79. clientType: loginStore.getClientType()
  80. })
  81. }).catch((err) => {
  82. reject(err)
  83. })
  84. } else {
  85. // http 登录参数
  86. resolve({
  87. userName: formData.userName,
  88. password: encryptBody(formData.password),
  89. clientType: loginStore.getClientType()
  90. })
  91. }
  92. }
  93. })
  94. if (globalStore.getSystemInfo('tradeChannel') === 'ws') {
  95. // websocket 登录
  96. const res = await wsLogin({
  97. LoginID: payload.userName,
  98. LoginPWD: payload.password,
  99. GUID: v4(),
  100. LoginType: 0,
  101. ClientType: payload.clientType,
  102. Version: '2.0.0.0',
  103. DeviceID: ''
  104. })
  105. // 更新登录信息
  106. loginStore.setLoginInfo({
  107. expiresAt: 0,
  108. loginId: res.LoginID,
  109. token: res.Token,
  110. userId: res.UserID,
  111. }, persist)
  112. } else {
  113. // http 登录
  114. const res = await httpLogin({ data: payload })
  115. // 更新登录信息
  116. loginStore.setLoginInfo(res.data, persist)
  117. }
  118. loginStore.setAutoLoginData(payload) // 更新自动登录信息
  119. localStorage.setItem('app_loginId', formData.userName) // 记住登录ID
  120. await loadUserData()
  121. eventBus.$emit('LoginNotify') // 登录成功通知
  122. } finally {
  123. logining.value = false
  124. }
  125. }
  126. // 用户登出
  127. const userLogout = (callback?: () => void) => {
  128. stopCheckToken()
  129. tradeSocket.close()
  130. tradeV2Socket.close()
  131. quoteSocket.close()
  132. timerTask.clearAll()
  133. accountStore.$reset() // 待处理,重置后可能会出现多个重复的 store 实例
  134. loginStore.clearAutoLoginData()
  135. loginStore.clearLoginInfo()
  136. callback && callback()
  137. }
  138. // 初始化业务数据
  139. const initBaseData = async (autoLogin = false) => {
  140. try {
  141. logining.value = true
  142. await loadBaseData()
  143. if (token.value) {
  144. await loadUserData()
  145. } else if (autoLogin && loginStore.getAutoLoginData()) {
  146. await userLogin(true)
  147. }
  148. } finally {
  149. logining.value = false
  150. }
  151. }
  152. return {
  153. logining,
  154. remember,
  155. formData,
  156. initBaseData,
  157. userLogin,
  158. userLogout,
  159. }
  160. }