uniLogin.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <div class="root">
  3. <div class="logo">
  4. <img alt="哪吒乐跑" src="/logo.svg" height="40">
  5. <span class="title">哪吒乐跑 | 快捷登录</span>
  6. </div>
  7. <a-form size="large" :model="form" :rules="[]" class="form" @submit="handleSubmit">
  8. <div class="uniLoginButton">
  9. <div class="button">
  10. <a-tooltip content="QQ登录" mini>
  11. <a-avatar :size="64" :style="{ backgroundColor: 'rgb(255, 52, 52)' }"
  12. @click="GetLoginUrl('qq')"><icon-qq /></a-avatar>
  13. </a-tooltip>
  14. </div>
  15. <div class="button">
  16. <a-tooltip content="微信登录" mini>
  17. <a-avatar :size="64" :style="{ backgroundColor: 'rgb(255, 52, 52)' }"
  18. @click="GetLoginUrl('wx')"><icon-wechat /></a-avatar>
  19. </a-tooltip>
  20. </div>
  21. </div>
  22. <div class="tip">未注册的账号登录后将自动注册<br>不同登录方式的账号资产和权限互不共享</div>
  23. <a-button type="text" class="forgetpass" @click="emit('changeMode', 'login')">账号密码登录</a-button>
  24. </a-form>
  25. </div>
  26. <div class="loading" v-if="loading">
  27. <div class="loadingTip">
  28. <icon-loading :size="32" />
  29. <div class="text">努力加载中</div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup>
  34. import { getLoginUrl } from '@/api/login'
  35. import { timeFix } from '@/utils/util'
  36. import { useRoute, useRouter } from 'vue-router'
  37. import { ref, onMounted } from 'vue'
  38. import { Notification } from '@arco-design/web-vue'
  39. import { useUserStore } from '@/store/modules/user'
  40. import { isElectron } from '@/utils/electron'
  41. const userStore = useUserStore()
  42. const loading = ref(false)
  43. const route = useRoute()
  44. const router = useRouter()
  45. const emit = defineEmits(['changeMode', 'changeLoading'])
  46. const from = route.query.from
  47. const GetLoginUrl = async (type) => {
  48. try {
  49. changeLoading(true)
  50. const res = await getLoginUrl({ type })
  51. if (!res || res.code != 0)
  52. return requestFailed('获取登录链接失败!' + res?.msg ?? '')
  53. if (isElectron())
  54. window.electron.openNewWindow(res.data)
  55. else
  56. window.location.href = res.data
  57. } catch (error) {
  58. console.log(error)
  59. requestFailed('获取登录链接失败!')
  60. } finally {
  61. changeLoading(false)
  62. }
  63. }
  64. const UniLogin = async (type, code) => {
  65. try {
  66. changeLoading(true)
  67. userStore.uniLogin(type, code)
  68. .then((res) => { loginSuccess(res) })
  69. .catch((err) => {
  70. requestFailed(err.message)
  71. })
  72. .finally(() => {
  73. changeLoading(false)
  74. })
  75. } catch (error) {
  76. requestFailed('登录失败!请稍后再试')
  77. }
  78. }
  79. const changeLoading = (value) => {
  80. loading.value = value
  81. }
  82. const loginSuccess = (res) => {
  83. Notification.success({
  84. title: `${timeFix()},${res.username}`,
  85. content: '欢迎回来!',
  86. duration: 2000
  87. })
  88. if (isElectron())
  89. window.electron.openOldWindow(from || '/')
  90. else
  91. router.push(from || '/')
  92. }
  93. const requestFailed = (msg) => {
  94. Notification.error({
  95. title: '错误',
  96. content: msg || '请求出现错误,请稍后再试',
  97. })
  98. }
  99. onMounted(() => {
  100. if (route.query.type && route.query.code) {
  101. UniLogin(route.query.type, route.query.code)
  102. }
  103. })
  104. </script>
  105. <style lang="less" scoped>
  106. .loading {
  107. position: fixed;
  108. top: 0;
  109. left: 0;
  110. height: 100%;
  111. width: 100%;
  112. background-color: rgba(0, 0, 0, 0.2);
  113. z-index: 9999;
  114. border-radius: 10px;
  115. .loadingTip {
  116. position: absolute;
  117. top: 50%;
  118. left: 50%;
  119. transform: translate(-50%, -50%);
  120. color: rgb(255, 52, 52);
  121. .text {
  122. font-family: 'Alimama ShuHeiTi';
  123. font-size: 1.2em;
  124. }
  125. }
  126. }
  127. .root {
  128. display: flex;
  129. gap: 40px;
  130. flex-direction: column;
  131. align-items: center;
  132. justify-content: center;
  133. }
  134. .form {
  135. width: 100%;
  136. }
  137. .logo {
  138. display: flex;
  139. .title {
  140. color: rgb(255, 52, 52);
  141. font-size: 1.8em;
  142. font-weight: bold;
  143. margin-left: 15px;
  144. font-family: Alimama ShuHeiTi, -apple-system, BlinkMacSystemFont;
  145. }
  146. }
  147. .tip {
  148. color: #777;
  149. font-size: 0.9em;
  150. text-align: left;
  151. margin-bottom: 20px;
  152. margin-left: -8px;
  153. }
  154. .uniLoginButton {
  155. display: flex;
  156. gap: 40px;
  157. justify-content: center;
  158. height: 100px;
  159. .button {
  160. cursor: pointer;
  161. }
  162. }
  163. .forgetpass {
  164. width: 100px;
  165. margin-top: -10px;
  166. margin-left: -15px;
  167. }
  168. </style>