login.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import { defineComponent } from 'vue';
  2. import { CellGroup, Field, Button, showToast } from 'vant';
  3. import request from '@/helpers/request';
  4. import { setLogin, state } from '@/state';
  5. import { checkPhone } from '@/helpers/utils';
  6. import loginLogo from './images/login-logo.png';
  7. import iconPhone from './images/icon-phone.png';
  8. import iconPassword from './images/icon-password.png';
  9. import { storage } from '@/helpers/storage';
  10. import { ACCESS_TOKEN } from '@/store/mutation-types';
  11. import styles from './login.module.less';
  12. import MPopup from '@/components/m-popup';
  13. import Code from './code';
  14. import router from '@/router';
  15. type loginType = 'PWD' | 'SMS';
  16. export default defineComponent({
  17. name: 'layout-login',
  18. data() {
  19. const { isRegister } = this.$route.query;
  20. return {
  21. isRegister: isRegister as any,
  22. loginType: 'SMS' as loginType,
  23. username: '',
  24. password: '',
  25. smsCode: '',
  26. countDownStatus: true, // 是否发送验证码
  27. countDownTime: 1000 * 120, // 倒计时时间
  28. imgCodeStatus: false,
  29. isAgree: true
  30. };
  31. },
  32. mounted() {
  33. storage.remove(ACCESS_TOKEN);
  34. this.directNext();
  35. },
  36. methods: {
  37. directNext() {
  38. if (state.user.status === 'login' || state.user.status === 'error') {
  39. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  40. const { returnUrl, isRegister, ...rest } = this.$route.query;
  41. console.log("🚀 ~ this.$route.query:", this.$route.query)
  42. this.$router.replace({
  43. path: returnUrl as any,
  44. query: {
  45. ...rest
  46. }
  47. });
  48. }
  49. },
  50. async onLogin() {
  51. try {
  52. if (!checkPhone(this.username)) {
  53. return showToast('请输入正确的手机号码');
  54. }
  55. const forms: any = {
  56. username: this.username,
  57. client_id: 'cooleshow-student',
  58. client_secret: 'cooleshow-student',
  59. password: this.loginType === 'PWD' ? this.password : this.smsCode,
  60. grant_type: 'password',
  61. loginType: this.loginType === 'PWD' ? 'PASSWORD' : 'SMS'
  62. };
  63. const { data } = await request.post('/edu-oauth/userlogin', {
  64. requestType: 'form',
  65. data: {
  66. ...forms
  67. }
  68. });
  69. storage.set(ACCESS_TOKEN, data.token_type + ' ' + data.access_token);
  70. const userCash = await request.get('/edu-app/user/getUserInfo', {
  71. initRequest: true // 初始化接口
  72. });
  73. setLogin(userCash.data);
  74. this.directNext();
  75. } catch (e: any) {
  76. //
  77. console.log(e);
  78. }
  79. },
  80. async onSendCode() {
  81. // 发送验证码
  82. if (!this.isAgree) {
  83. return showToast('请阅读并同意以下协议');
  84. }
  85. if (!checkPhone(this.username)) {
  86. return showToast('请输入正确的手机号码');
  87. }
  88. this.imgCodeStatus = true;
  89. },
  90. onChange() {
  91. if (this.loginType === 'PWD') {
  92. this.loginType = 'SMS';
  93. } else if (this.loginType === 'SMS') {
  94. this.loginType = 'PWD';
  95. }
  96. }
  97. },
  98. render() {
  99. return (
  100. <div class={[styles.login]}>
  101. <div class={styles.loginContainer}>
  102. <img src={loginLogo} class={styles.logo} />
  103. <CellGroup class={styles.container} border={false}>
  104. <Field
  105. v-model={this.username}
  106. name="手机号"
  107. placeholder="请输入您的手机号"
  108. type="tel"
  109. class={styles['input-group']}
  110. maxlength={11}
  111. autocomplete="off"
  112. border={false}>
  113. {{
  114. 'left-icon': () => (
  115. <img src={iconPhone} class={styles.iconPhone} />
  116. )
  117. }}
  118. </Field>
  119. {this.loginType === 'PWD' && (
  120. <Field
  121. v-model={this.password}
  122. type="password"
  123. name="密码"
  124. class={styles['input-group']}
  125. placeholder="请输入密码"
  126. autocomplete="off"
  127. border={false}>
  128. {{
  129. 'left-icon': () => (
  130. <img src={iconPassword} class={styles.iconPassword} />
  131. )
  132. }}
  133. </Field>
  134. )}
  135. <div class={styles.btnGroup}>
  136. <Button
  137. round
  138. block
  139. class={styles.primaryButton}
  140. onClick={() => {
  141. if (this.loginType === 'PWD') {
  142. this.onLogin();
  143. } else {
  144. this.onSendCode();
  145. }
  146. }}>
  147. {this.loginType === 'PWD' ? '登录' : '获取短信验证码'}
  148. </Button>
  149. <Button
  150. round
  151. block
  152. type="default"
  153. class={styles['login-change']}
  154. onClick={this.onChange}>
  155. {this.loginType === 'PWD' ? '短信登录' : '密码登录'}
  156. </Button>
  157. </div>
  158. {this.loginType === 'SMS' && (
  159. <div
  160. class={styles.protocol}
  161. onClick={() => (this.isAgree = !this.isAgree)}>
  162. <i
  163. class={[
  164. styles.iconChecked,
  165. this.isAgree ? styles.active : ''
  166. ]}></i>
  167. 我已阅读并同意
  168. <span
  169. onClick={(e: MouseEvent) => {
  170. e.stopPropagation();
  171. router.push('/preview-protocol');
  172. }}>
  173. 《用户注册协议》
  174. </span>
  175. <span
  176. onClick={(e: MouseEvent) => {
  177. e.stopPropagation();
  178. router.push('/privacy-protocol');
  179. }}>
  180. 《隐私政策》
  181. </span>
  182. </div>
  183. )}
  184. </CellGroup>
  185. </div>
  186. <MPopup v-model:modelValue={this.imgCodeStatus}>
  187. <Code
  188. phone={this.username}
  189. isRegister={this.isRegister}
  190. onClose={(val) => {
  191. this.imgCodeStatus = false
  192. if (val) {
  193. requestAnimationFrame(() => {
  194. requestAnimationFrame(() => {
  195. this.directNext()
  196. })
  197. })
  198. }
  199. }}
  200. onConfirm={this.directNext}
  201. />
  202. </MPopup>
  203. </div>
  204. );
  205. }
  206. });