index.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <view class="login">
  3. <view class="login-logo">
  4. <image :src="logoSrc" />
  5. <view class="login-logo-text">
  6. 适老设备设施
  7. </view>
  8. </view>
  9. <view class="login-input">
  10. <wd-input :noBorder="true" placeholder="请输入账号" v-model="state.account" />
  11. </view>
  12. <view class="login-input">
  13. <wd-input :showPassword="true" :noBorder="true" placeholder="请输入密码" v-model="state.password" />
  14. </view>
  15. <view class="login-operation">
  16. <wd-checkbox shape="square" v-model="state.rememberChecked">
  17. 记住密码
  18. </wd-checkbox>
  19. </view>
  20. <wd-button :round="false" :block="true" :disabled="!state.account || !state.password" :loading="state.buttonLoading"
  21. @click="onClickLogin">
  22. 登录
  23. </wd-button>
  24. </view>
  25. </template>
  26. <script lang="ts" setup>
  27. import { onLoad } from '@dcloudio/uni-app';
  28. import { reactive } from 'vue';
  29. import logoSrc from '@/static/public/logo@2x.png';
  30. import LocalStorage from '@/LocalStorage';
  31. import { regex } from '@/utils';
  32. import { apis, LoginApiParams } from '@/apis';
  33. interface State {
  34. account: string,
  35. password: string,
  36. rememberChecked: boolean,
  37. buttonLoading: boolean,
  38. };
  39. const state: State = reactive({
  40. account: '',
  41. password: '',
  42. rememberChecked: false,
  43. buttonLoading: false,
  44. });
  45. const api = {
  46. // 登录
  47. login: async (data: LoginApiParams) => {
  48. state.buttonLoading = true;
  49. try {
  50. // const res = await apis.login(data);
  51. // const token = res.data;
  52. const token = 'token';
  53. LocalStorage.setToken(token);
  54. if (state.rememberChecked) {// 记住密码
  55. LocalStorage.setAccountPassword({
  56. account: data.account,
  57. password: data.password,
  58. });
  59. } else {// 不记住密码
  60. LocalStorage.setAccountPassword(undefined);
  61. }
  62. uni.switchTab({
  63. url: '/pages/home/index/index',
  64. success: () => {
  65. uni.showToast({
  66. icon: 'success',
  67. mask: true,
  68. duration: 2000,
  69. title: '登录成功',
  70. });
  71. }
  72. });
  73. } catch (error: any) {
  74. LocalStorage.clear();
  75. uni.showToast({
  76. icon: 'none',
  77. mask: true,
  78. duration: 2000,
  79. title: error.msg,
  80. });
  81. } finally {
  82. state.buttonLoading = false;
  83. }
  84. },
  85. }
  86. const init = () => {
  87. const token = LocalStorage.getToken();
  88. if (token) {// 已登陆直接进入首页
  89. uni.switchTab({
  90. url: '/pages/home/index/index',
  91. });
  92. } else {
  93. const accountPassword = LocalStorage.getAccountPassword();
  94. if (accountPassword) {
  95. state.account = accountPassword.account;
  96. state.password = accountPassword.password;
  97. state.rememberChecked = true;
  98. }
  99. }
  100. };
  101. onLoad(() => {
  102. init();
  103. });
  104. // 点击登录
  105. const onClickLogin = async () => {
  106. const data = {
  107. account: state.account,
  108. password: state.password,
  109. }
  110. const passwordRegex = new RegExp(regex.password);
  111. if (!passwordRegex.test(data.password)) {
  112. return uni.showToast({
  113. icon: 'none',
  114. mask: true,
  115. duration: 2000,
  116. title: '密码格式不正确',
  117. });
  118. }
  119. // 登录
  120. await api.login(data);
  121. }
  122. </script>
  123. <style lang="scss" scoped>
  124. .login {
  125. padding: 0 20rpx;
  126. background: #FFFFFF;
  127. &-logo {
  128. display: flex;
  129. flex-direction: column;
  130. align-items: center;
  131. padding: 80rpx 0;
  132. image {
  133. width: 180rpx;
  134. height: 180rpx
  135. }
  136. &-text {
  137. font-size: $font-size-large;
  138. font-weight: bold;
  139. color: $primary-color;
  140. letter-spacing: 10rpx;
  141. margin-top: 20rpx;
  142. }
  143. }
  144. &-input {
  145. padding-bottom: 30rpx;
  146. border-bottom: 2rpx solid $border-color;
  147. margin-bottom: 30rpx;
  148. }
  149. &-operation {
  150. margin: 60rpx 0;
  151. }
  152. }
  153. </style>