AppLogin.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <template>
  2. <div class="login">
  3. <div class="logo">
  4. <img src="../../assets/images/logo.png" alt="">
  5. </div>
  6. <div class="container">
  7. <div class="input-group">
  8. <input type="number" @blur="codeBlur" placeholder="请输入手机号报名或查询进度" class="input" v-model="phoneNumber" pattern="[0-9]">
  9. </div>
  10. <div class="input-group">
  11. <input type="text" @blur="codeBlur" placeholder="请输入验证码" class="input" v-model="code" >
  12. <span class="code-text" v-show="countDownStatus" @click="onSendCode">{{ codeText }}</span>
  13. <span class="code-text" v-show="!countDownStatus">
  14. <van-count-down
  15. ref="countdown"
  16. :auto-start="false"
  17. :time="countDownTime"
  18. @finish="onFinished"
  19. format="ss秒" />
  20. </span>
  21. </div>
  22. <van-button round size="large" @click="onCodeLogin" :disabled="codeDisable">登录</van-button>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. import {sendSms, smsLogin, queryUserByPhone } from '@/api/app'
  28. export default {
  29. name: 'login',
  30. data() {
  31. return {
  32. groupId: this.$route.query.groupId,
  33. codeDisable: true, // 验证码登录按钮状态
  34. countDownStatus: true, // 到计时状态
  35. phoneNumber: null,
  36. isRegister: 0, // 默认没有注册
  37. code: null,
  38. codeText: '获取验证码',
  39. countDownTime: 1000 * 120, // 倒计时时间
  40. isClick: false
  41. }
  42. },
  43. mounted() {
  44. // 登录时删除无用的token
  45. localStorage.removeItem('userInfo')
  46. localStorage.removeItem('Authorization')
  47. },
  48. watch: {
  49. phoneNumber(newValue) {
  50. this.onKeyUp(newValue, this.code)
  51. },
  52. code(newValue) {
  53. this.onKeyUp(this.phoneNumber, newValue)
  54. }
  55. },
  56. methods: {
  57. codeBlur() {
  58. setTimeout(() => {
  59. const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
  60. window.scrollTo(0, Math.max(scrollHeight - 1, 0));
  61. }, 100);
  62. },
  63. onKeyUp(phoneNumber, code) {
  64. if(!phoneNumber || !code) {
  65. this.codeDisable = true
  66. } else {
  67. this.codeDisable = false
  68. }
  69. },
  70. onSendCode() { // 发送验证码
  71. if(!this.checkPhone(this.phoneNumber)) {
  72. return
  73. }
  74. sendSms({
  75. mobile: this.phoneNumber
  76. }).then(res => {
  77. let result = res.data
  78. if(result.code == 200) {
  79. this.countDownStatus = false
  80. this.$refs.countdown.start() // 倒计时开始
  81. } else {
  82. this.$toast(result.msg)
  83. }
  84. })
  85. },
  86. onCodeLogin() { // 短信登录
  87. if(this.isClick) {
  88. return
  89. }
  90. this.isClick = true
  91. queryUserByPhone({ mobile: this.phoneNumber }).then(res => {
  92. let result = res.data
  93. if(result.code == 200) {
  94. this.isRegister = result.data
  95. }
  96. this.onLogin()
  97. })
  98. },
  99. onLogin() {
  100. let params = {
  101. clientId: 'student',
  102. clientSecret: 'student',
  103. phone: this.phoneNumber,
  104. smsCode: this.code,
  105. channel: 'H5'
  106. }
  107. if(this.isRegister == 0) {
  108. params.isLessee = 'true'
  109. }
  110. smsLogin(params).then(sms => {
  111. let s = sms.data
  112. this.isClick = false
  113. // 保存用户信息
  114. if(s.code == 200) {
  115. let auth = s.data.authentication
  116. localStorage.setItem('userInfo', auth.token_type + ' ' + auth.access_token)
  117. this.$router.push({
  118. path: '/classDetail',
  119. query: {
  120. groupId: this.groupId
  121. }
  122. })
  123. } else {
  124. this.$toast(s.msg)
  125. }
  126. })
  127. },
  128. onFinished() { // 倒计时结束
  129. this.countDownStatus = true
  130. this.$refs.countdown.reset()
  131. },
  132. checkPhone(phoneNumber) {
  133. let result = true
  134. if(!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(phoneNumber))){
  135. this.$toast('手机号输入有误')
  136. result = false
  137. }
  138. return result
  139. }
  140. }
  141. }
  142. </script>
  143. <style lang='less' scoped>
  144. @import url("../../assets/commonLess/variable.less");
  145. .login {
  146. min-height: 100vh;
  147. background: linear-gradient(to bottom, #15938B, #6dbeba);
  148. }
  149. .container {
  150. padding: 0 .48rem;
  151. }
  152. .logo {
  153. padding-top: 1rem;
  154. padding-bottom: .9rem;
  155. width: 1.6rem;
  156. margin: 0 auto;
  157. img {
  158. width: inherit;
  159. }
  160. }
  161. .input-group {
  162. position: relative;
  163. height: .44rem;
  164. border-radius: .5rem;
  165. border: .02rem solid @whiteColor;
  166. margin-bottom: .2rem;
  167. padding-left: .3rem;
  168. padding-right: .3rem;
  169. display: flex;
  170. align-items: center;
  171. .input {
  172. flex: 1;
  173. font-size: .14rem;
  174. color: @whiteColor;
  175. background: transparent;
  176. border: none;
  177. &::placeholder {
  178. color: @whiteColor;
  179. }
  180. }
  181. .code-text {
  182. position: absolute;
  183. right: 0;
  184. flex: 1;
  185. display: block;
  186. width: .94rem;
  187. text-align: center;
  188. border-left: .02rem solid @whiteColor;
  189. font-size: .14rem;
  190. color: @whiteColor;
  191. line-height: .3rem;
  192. height: .3rem;
  193. }
  194. }
  195. /deep/.van-count-down {
  196. font-size: .14rem;
  197. color: @whiteColor;
  198. line-height: .3rem;
  199. height: .3rem;
  200. }
  201. /deep/.van-button--large {
  202. height: .44rem;
  203. line-height: .42rem;
  204. color: @mColor;
  205. border: 0;
  206. }
  207. /deep/.van-button:active::before {
  208. opacity: 0.05;
  209. }
  210. /deep/.van-button--disabled {
  211. opacity: 1;
  212. color: rgba(0, 0, 0, 0.25);
  213. }
  214. .login-change {
  215. padding-top: .08rem;
  216. font-size: .14rem;
  217. color: @whiteColor;
  218. float: right;
  219. }
  220. </style>