login.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import { defineComponent } from 'vue'
  2. import { CellGroup, Field, Button, CountDown, Row, Col, Toast } from 'vant'
  3. import ImgCode from '@/components/o-img-code'
  4. import { checkPhone } from '@/helpers/validate'
  5. import request from '@/helpers/request'
  6. import { setLogin, state } from '@/state'
  7. import { removeAuth, setAuth } from '@/helpers/utils'
  8. import styles from './login.module.less'
  9. type loginType = 'PWD' | 'SMS'
  10. export default defineComponent({
  11. name: 'login',
  12. data() {
  13. return {
  14. loginType: 'SMS' as loginType,
  15. username: '',
  16. password: '',
  17. smsCode: '',
  18. countDownStatus: true, // 是否发送验证码
  19. countDownTime: 1000 * 120, // 倒计时时间
  20. // countDownRef: null as any, // 倒计时实例
  21. imgCodeStatus: false
  22. }
  23. },
  24. computed: {
  25. codeDisable() {
  26. let status = true
  27. if (this.loginType === 'PWD') {
  28. this.username && this.password && (status = false)
  29. } else {
  30. this.username && this.smsCode && (status = false)
  31. }
  32. return status
  33. },
  34. appName() {
  35. const template = {
  36. STUDENT: '学生端',
  37. TEACHER: '老师端',
  38. SCHOOL: '管理端'
  39. }
  40. return template[state.platformType]
  41. }
  42. },
  43. mounted() {
  44. removeAuth()
  45. this.directNext()
  46. },
  47. methods: {
  48. directNext() {
  49. if (state.user.status === 'login' || state.user.status === 'error') {
  50. const { returnUrl, isRegister, ...rest } = this.$route.query
  51. this.$router.replace({
  52. path: returnUrl as any,
  53. query: {
  54. ...rest
  55. }
  56. })
  57. }
  58. },
  59. async onLogin() {
  60. try {
  61. // let res: any
  62. const forms: any = {
  63. username: this.username,
  64. client_id: state.clientId[state.platformType],
  65. client_secret: state.clientId[state.platformType]
  66. }
  67. if (this.loginType === 'PWD') {
  68. forms.password = this.password
  69. forms.loginType = 'PASSWORD'
  70. forms.grant_type = 'PASSWORD'
  71. } else {
  72. forms.password = this.smsCode
  73. forms.loginType = 'SMS'
  74. forms.grant_type = 'SMS'
  75. }
  76. const { data } = await request.post('/api-oauth/userlogin', {
  77. requestType: 'form',
  78. data: {
  79. ...forms
  80. }
  81. })
  82. setAuth(data.token_type + ' ' + data.access_token)
  83. const userCash = await request.get(state.platformApi + '/appLoginUser/getUserInfo', {
  84. initRequest: true // 初始化接口
  85. })
  86. setLogin(userCash.data)
  87. this.directNext()
  88. } catch {
  89. //
  90. }
  91. },
  92. async onSendCode() {
  93. // 发送验证码
  94. if (!checkPhone(this.username)) {
  95. return Toast('请输入正确的手机号码')
  96. }
  97. this.imgCodeStatus = true
  98. },
  99. onCodeSend() {
  100. this.countDownStatus = false
  101. this.$nextTick(() => {
  102. ;(this.$refs.countDownRef as any).start()
  103. })
  104. },
  105. onFinished() {
  106. this.countDownStatus = true
  107. ;(this.$refs.countDownRef as any).reset()
  108. },
  109. onChange() {
  110. if (this.loginType === 'PWD') {
  111. this.loginType = 'SMS'
  112. } else if (this.loginType === 'SMS') {
  113. this.loginType = 'PWD'
  114. }
  115. }
  116. },
  117. render() {
  118. return (
  119. <div class={styles.login}>
  120. <div class={styles.loginTitle}>
  121. 您好,
  122. <br /> 欢迎使用管乐团{this.appName}
  123. </div>
  124. <CellGroup class={styles.margin34} border={false}>
  125. <Row style={{ marginBottom: '16px' }}>
  126. <Col span={24} class={styles.formTitle}>
  127. 手机号
  128. </Col>
  129. <Col span={24} class="van-hairline--bottom">
  130. <Field
  131. v-model={this.username}
  132. name="手机号"
  133. placeholder="请输入您的手机号"
  134. type="tel"
  135. maxlength={11}
  136. />
  137. </Col>
  138. </Row>
  139. {this.loginType === 'PWD' ? (
  140. <Row>
  141. <Col span={24} class={styles.formTitle}>
  142. 密码
  143. </Col>
  144. <Col span={24} class="van-hairline--bottom">
  145. <Field
  146. v-model={this.password}
  147. type="password"
  148. name="密码"
  149. placeholder="请输入密码"
  150. />
  151. </Col>
  152. </Row>
  153. ) : (
  154. <Row>
  155. <Col span={24} class={styles.formTitle}>
  156. 验证码
  157. </Col>
  158. <Col span={24} class="van-hairline--bottom">
  159. <Field
  160. v-model={this.smsCode}
  161. name="验证码"
  162. placeholder="请输入验证码"
  163. type="tel"
  164. maxlength={6}
  165. // @ts-ignore
  166. vSlots={{
  167. button: () =>
  168. this.countDownStatus ? (
  169. <span class={styles.codeText} onClick={this.onSendCode}>
  170. 获取验证码
  171. </span>
  172. ) : (
  173. <CountDown
  174. ref="countDownRef"
  175. auto-start={false}
  176. time={this.countDownTime}
  177. onFinish={this.onFinished}
  178. format="ss秒"
  179. />
  180. )
  181. }}
  182. />
  183. </Col>
  184. </Row>
  185. )}
  186. </CellGroup>
  187. <div class={styles.margin34}>
  188. <Button round block type="primary" disabled={this.codeDisable} onClick={this.onLogin}>
  189. 提交
  190. </Button>
  191. <Button block round color="#F5F7FB" onClick={this.onChange}>
  192. {this.loginType === 'PWD' ? '验证码登录' : '密码登录'}
  193. </Button>
  194. </div>
  195. {this.imgCodeStatus ? (
  196. <ImgCode
  197. v-model:value={this.imgCodeStatus}
  198. phone={this.username}
  199. onClose={() => {
  200. this.imgCodeStatus = false
  201. }}
  202. onSendCode={this.onCodeSend}
  203. />
  204. ) : null}
  205. </div>
  206. )
  207. }
  208. })