login.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <!--
  2. * @FileDescription: 登录
  3. * @Author: 黄琪勇
  4. * @Date:2024-03-19 17:13:28
  5. -->
  6. <template>
  7. <div class="login">
  8. <div class="loginCon">
  9. <div class="decoration">
  10. <img class="star" src="@/img/loginErr/star.png" />
  11. <img class="bStar" src="@/img/loginErr/bStar.png" />
  12. <img class="music" src="@/img/loginErr/music.png" />
  13. </div>
  14. <div class="loginBox">
  15. <img v-show="qrcodeStatus === 2" class="scanned" src="@/img/loginErr/scanned.png" />
  16. <div v-show="qrcodeStatus !== 2" v-loading="!uuid" class="qrcodeBox">
  17. <div class="qrCodeCon" :class="{ refresh: qrcodeStatus === 3 }">
  18. <qrcode-vue class="qrCode" v-if="uuid" :value="qrcode" :size="164" />
  19. <img @click="handleRefresh" src="@/img/loginErr/refresh.png" />
  20. </div>
  21. </div>
  22. <div class="dsc">
  23. <img src="@/img/loginErr/jiantou1.png" />
  24. <div>{{ qrcodeStatus === 2 ? "扫码完成,请在手机上操作" : "使用客户端扫描二维码登录乐教通" }}</div>
  25. <img src="@/img/loginErr/jiantou2.png" />
  26. </div>
  27. <div class="refreshBtn" @click="handleRefresh">{{ qrcodeStatus === 2 ? "重新扫码" : "刷新二维码" }}</div>
  28. </div>
  29. </div>
  30. </div>
  31. </template>
  32. <script setup lang="ts">
  33. import { createQrcodeApi, queryQrcodeStatusApi } from "@/api/user.api"
  34. import { httpAjax } from "@/plugin/httpAjax"
  35. import QrcodeVue from "qrcode.vue"
  36. import { ref, computed } from "vue"
  37. import userStore from "@/store/modules/user"
  38. import { useRouter } from "vue-router"
  39. const userStoreHook = userStore()
  40. const router = useRouter()
  41. const uuid = ref<string>("")
  42. const qrcode = computed(() => {
  43. return JSON.stringify({ action: "login", uuid: uuid.value })
  44. })
  45. const qrcodeStatus = ref<1 | 2 | 3>(1) // 1 未扫码 2 扫码完成 3 二维码过期
  46. let _time: number
  47. handleCreateQrcode()
  48. function handleCreateQrcode() {
  49. httpAjax(createQrcodeApi).then(res => {
  50. if (res.code === 200) {
  51. uuid.value = res.data.uuid
  52. handleQrcodeStatus()
  53. }
  54. })
  55. }
  56. function handleQrcodeStatus() {
  57. httpAjax(queryQrcodeStatusApi, uuid.value as string).then(res => {
  58. if (res.code === 200) {
  59. const { status } = res.data
  60. if (status === "FINISH") {
  61. // 登录成功
  62. userStoreHook.login(res.data).then(() => {
  63. router.push({ path: "/" })
  64. })
  65. return
  66. }
  67. if (status === "SCANNED") {
  68. // 扫码完成
  69. qrcodeStatus.value = 2
  70. } else if (status === "VERIFIED") {
  71. // 已验证
  72. qrcodeStatus.value = 2
  73. } else if (status === "EXPIRED") {
  74. // 二维码过期
  75. qrcodeStatus.value = 3
  76. return
  77. } else if (status === "NOT_SCAN") {
  78. // 未扫码
  79. qrcodeStatus.value = 1
  80. }
  81. _time = setTimeout(() => {
  82. clearTimeout(_time)
  83. handleQrcodeStatus()
  84. }, 3000)
  85. } else if (res.code === 5440) {
  86. // 二维码过期
  87. qrcodeStatus.value = 3
  88. }
  89. })
  90. }
  91. function handleRefresh() {
  92. _time && clearTimeout(_time)
  93. handleCreateQrcode()
  94. }
  95. </script>
  96. <style lang="scss" scoped>
  97. .login {
  98. width: 100%;
  99. min-height: 100%;
  100. background: url("@/img/loginErr/bg.png") no-repeat;
  101. background-size: cover;
  102. display: flex;
  103. justify-content: center;
  104. align-items: center;
  105. min-width: 1280px;
  106. .loginCon {
  107. display: flex;
  108. justify-content: space-between;
  109. width: 80%;
  110. }
  111. .loginBox {
  112. width: 440px;
  113. height: 498px;
  114. background: url("@/img/loginErr/loginBox.png") no-repeat;
  115. background-size: cover;
  116. z-index: 2;
  117. display: flex;
  118. flex-direction: column;
  119. align-items: center;
  120. .scanned {
  121. margin-top: 132px;
  122. }
  123. .qrcodeBox {
  124. margin-top: 154px;
  125. width: 188px;
  126. height: 188px;
  127. display: flex;
  128. justify-content: center;
  129. align-items: center;
  130. background: url("@/img/loginErr/border.png") no-repeat;
  131. background-size: cover;
  132. .qrCodeCon {
  133. position: relative;
  134. &.refresh {
  135. background-color: rgba(255, 255, 255, 0.8);
  136. > .qrCode {
  137. opacity: 0.3;
  138. }
  139. > img {
  140. cursor: pointer;
  141. position: absolute;
  142. left: 50%;
  143. top: 50%;
  144. transform: translate(-50%, -50%);
  145. display: block;
  146. }
  147. }
  148. > img {
  149. display: none;
  150. }
  151. }
  152. }
  153. .dsc {
  154. margin-top: 28px;
  155. display: flex;
  156. justify-content: center;
  157. align-items: center;
  158. > div {
  159. width: 240px;
  160. text-align: center;
  161. font-size: 16px;
  162. color: #777;
  163. margin: 0 14px;
  164. }
  165. }
  166. .refreshBtn {
  167. margin-top: 14px;
  168. line-height: 22px;
  169. font-size: 16px;
  170. color: #f67146;
  171. display: inline;
  172. font-weight: bold;
  173. cursor: pointer;
  174. &:hover {
  175. opacity: $opacity-hover;
  176. }
  177. }
  178. }
  179. .decoration {
  180. position: relative;
  181. width: 522px;
  182. height: 626px;
  183. background: url("@/img/loginErr/xiaoren.png") no-repeat;
  184. background-size: cover;
  185. z-index: 1;
  186. .star {
  187. position: absolute;
  188. right: 0;
  189. top: 0;
  190. width: 26px;
  191. height: 38px;
  192. }
  193. .bStar {
  194. position: absolute;
  195. left: -20px;
  196. top: 178px;
  197. width: 60px;
  198. height: 58px;
  199. }
  200. .music {
  201. position: absolute;
  202. right: -26px;
  203. top: 24px;
  204. width: 28px;
  205. height: 56px;
  206. }
  207. }
  208. }
  209. </style>