login.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <view class="container">
  3. <view class="unp-header">
  4. <view class="unp-logo">
  5. <u-avatar size="80" icon="github-circle-fill" fontSize="80"></u-avatar>
  6. </view>
  7. </view>
  8. <view class="unp-box">
  9. <!-- 登录方式选择 -->
  10. <view class="mode-section">
  11. <u-subsection mode="subsection" fontSize="15" :list="loginModeList" :current="currentModeIndex" @change="handleModeChange"></u-subsection>
  12. </view>
  13. <u-gap height="40"></u-gap>
  14. <!-- 登录表单 -->
  15. <u--form class="unp-form" labelPosition="left" :model="formData" :rules="rules" ref="form">
  16. <u-form-item label="手机号" prop="mobile" labelWidth="60" borderBottom ref="item-mobile">
  17. <u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input>
  18. </u-form-item>
  19. <u-gap height="20"></u-gap>
  20. <u-form-item v-if="currentModeIndex === 0" label="密码" prop="password" labelWidth="60" borderBottom ref="item-password">
  21. <u-input :type="inputType" maxlength="16" v-model="formData.password" placeholder="请填写密码" border="none">
  22. <template slot="suffix">
  23. <u-icon v-if="inputType === 'password'" size="20" color="#666666" name="eye-fill" @click="inputType = 'text'"></u-icon>
  24. <u-icon v-if="inputType === 'text'" size="20" color="#666666" name="eye-off" @click="inputType = 'password'"></u-icon>
  25. </template>
  26. </u-input>
  27. </u-form-item>
  28. <u-form-item v-else label="验证码" prop="code" labelWidth="60" borderBottom>
  29. <u--input type="number" maxlength="4" v-model="formData.code" border="none" placeholder="请填写验证码"></u--input>
  30. <u-button slot="right" @tap="getCode" :text="codeTips" type="success" size="mini" :disabled="codeDisabled"></u-button>
  31. <u-code ref="uCode" @change="codeChange" seconds="60" @start="codeDisabled = true" @end="codeDisabled = false"></u-code>
  32. </u-form-item>
  33. <u-button type="primary" text="登录" customStyle="margin-top: 50px" @click="handleSubmit"></u-button>
  34. <u-gap height="20"></u-gap>
  35. <u-button type="info" text="返回" @click="navigateBack()"></u-button>
  36. </u--form>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. import {passwordLogin,sendSmsCode,smsLogin} from "../../common/api";
  42. export default {
  43. data() {
  44. return {
  45. //租户ID
  46. agent: 1,
  47. currentModeIndex: 0,
  48. loginModeList: ['密码登录', '验证码登录'],
  49. inputType: 'password',
  50. codeDisabled: false,
  51. codeTips: '',
  52. formData: {
  53. mobile: '15601691234',
  54. password: '',
  55. code: ''
  56. },
  57. rules: {
  58. 'mobile': [
  59. {
  60. type: 'integer',
  61. required: true,
  62. message: '请填写手机号',
  63. trigger: ['blur', 'change']
  64. },
  65. {
  66. // 自定义验证函数,见上说明
  67. validator: (rule, value, callback) => {
  68. // 上面有说,返回true表示校验通过,返回false表示不通过
  69. // uni.$u.test.mobile()就是返回true或者false的
  70. return uni.$u.test.mobile(value);
  71. },
  72. message: '手机号码不正确',
  73. // 触发器可以同时用blur和change
  74. trigger: ['change','blur'],
  75. }
  76. ],
  77. 'password': {
  78. type: 'string',
  79. min: 4,
  80. max: 16,
  81. required: true,
  82. message: '密码长度4-16位密码',
  83. trigger: ['blur', 'change']
  84. },
  85. 'code': {
  86. type: 'integer',
  87. len: 4,
  88. required: true,
  89. message: '请填写4位验证码',
  90. trigger: ['blur', 'change']
  91. }
  92. }
  93. }
  94. },
  95. onLoad() {
  96. },onReady(){
  97. // 如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则
  98. this.$refs.form.setRules(this.rules)
  99. },
  100. methods: {
  101. handleModeChange(index) {
  102. if (index !== this.currentModeIndex){
  103. this.currentModeIndex = index;
  104. this.$refs.form.clearValidate();
  105. }
  106. },
  107. codeChange(text) {
  108. this.codeTips = text;
  109. },
  110. getCode() {
  111. const mobile = this.formData.mobile;
  112. if (!mobile) {
  113. uni.$u.toast('请填写手机号');
  114. } else if (!uni.$u.test.mobile(mobile)){
  115. uni.$u.toast('手机号格式不正确');
  116. } else if (this.$refs.uCode.canGetCode) {
  117. // 模拟向后端请求验证码
  118. uni.showLoading({
  119. title: '正在获取验证码'
  120. });
  121. //scene:1登陆获取验证码场景
  122. sendSmsCode({agent: 1, mobile:mobile, scene:1 }).then(res => {
  123. //console.log(res)
  124. uni.hideLoading();
  125. if (res.data.code === 0){
  126. // 这里此提示会被this.start()方法中的提示覆盖
  127. uni.$u.toast('验证码已发送');
  128. // 通知验证码组件内部开始倒计时
  129. this.$refs.uCode.start();
  130. } else {
  131. uni.$u.toast(res.data.msg);
  132. }
  133. }).catch(err => {
  134. uni.$u.toast('服务器接口请求异常');
  135. })
  136. } else {
  137. uni.$u.toast('倒计时结束后再发送');
  138. }
  139. },
  140. handleSubmit() {
  141. this.$refs.form.validate().then(res => {
  142. uni.$u.toast('登录');
  143. if (this.currentModeIndex === 0){
  144. passwordLogin({agent: 1, mobile:this.formData.mobile, password:this.formData.password}).then(res => {
  145. if (res.data.code === 0){
  146. uni.$u.toast('登录成功');
  147. // TODO 登录成功,保存toke
  148. } else {
  149. uni.$u.toast(res.data.msg);
  150. // TODO 登录失败
  151. }
  152. }).catch(err => {
  153. uni.$u.toast('服务器接口请求异常');
  154. })
  155. } else if (this.currentModeIndex === 1) {
  156. smsLogin({agent: 1, mobile:this.formData.mobile, code:this.formData.code})
  157. }
  158. })
  159. },
  160. navigateBack() {
  161. uni.navigateBack()
  162. }
  163. }
  164. }
  165. </script>
  166. <style lang="scss" scoped>
  167. .unp-header {
  168. height: 400rpx;
  169. display: flex;
  170. align-items: center;
  171. justify-content: center;
  172. .unp-logo {
  173. display: flex;
  174. flex-direction: column;
  175. align-items: center;
  176. justify-content: center;
  177. }
  178. }
  179. .unp-box {
  180. display: flex;
  181. flex-direction: column;
  182. align-items: center;
  183. justify-content: center;
  184. .mode-section{
  185. width: 560rpx;
  186. }
  187. .unp-form{
  188. width: 560rpx;
  189. }
  190. }
  191. .lk-group {
  192. height: 40rpx;
  193. margin-top: 40rpx;
  194. display: flex;
  195. align-items: center;
  196. justify-content: space-between;
  197. font-size: 12rpx;
  198. color: $u-primary;
  199. text-decoration: $u-primary;
  200. }
  201. </style>