LoginForm.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <LoginFormTitle v-show="getShow" class="enter-x" />
  3. <Form
  4. class="p-4 enter-x"
  5. :model="formData"
  6. :rules="getFormRules"
  7. ref="formRef"
  8. v-show="getShow"
  9. @keypress.enter="handleLogin"
  10. >
  11. <FormItem name="account" class="enter-x">
  12. <Input
  13. size="large"
  14. v-model:value="formData.account"
  15. :placeholder="t('sys.login.userName')"
  16. class="fix-auto-fill"
  17. />
  18. </FormItem>
  19. <FormItem name="password" class="enter-x">
  20. <InputPassword
  21. size="large"
  22. visibilityToggle
  23. v-model:value="formData.password"
  24. :placeholder="t('sys.login.password')"
  25. />
  26. </FormItem>
  27. <ARow class="enter-x">
  28. <ACol :span="12">
  29. <FormItem>
  30. <!-- No logic, you need to deal with it yourself -->
  31. <Checkbox v-model:checked="rememberMe" size="small">
  32. {{ t('sys.login.rememberMe') }}
  33. </Checkbox>
  34. </FormItem>
  35. </ACol>
  36. <ACol :span="12">
  37. <FormItem :style="{ 'text-align': 'right' }">
  38. <!-- No logic, you need to deal with it yourself -->
  39. <Button type="link" size="small" @click="forgetPaswd">
  40. {{ t('sys.login.forgetPassword') }}
  41. </Button>
  42. </FormItem>
  43. </ACol>
  44. </ARow>
  45. <FormItem class="enter-x">
  46. <Button type="primary" size="large" block @click="handleLogin" :loading="loading">
  47. {{ t('sys.login.loginButton') }}
  48. </Button>
  49. <!-- <Button size="large" class="mt-4 enter-x" block @click="handleRegister">
  50. {{ t('sys.login.registerButton') }}
  51. </Button> -->
  52. </FormItem>
  53. <!-- <ARow class="enter-x">
  54. <ACol :md="8" :xs="24">
  55. <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
  56. {{ t('sys.login.mobileSignInFormTitle') }}
  57. </Button>
  58. </ACol>
  59. <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2">
  60. <Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
  61. {{ t('sys.login.qrSignInFormTitle') }}
  62. </Button>
  63. </ACol>
  64. <ACol :md="7" :xs="24">
  65. <Button block @click="setLoginState(LoginStateEnum.REGISTER)">
  66. {{ t('sys.login.registerButton') }}
  67. </Button>
  68. </ACol>
  69. </ARow> -->
  70. <!-- <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider>
  71. <div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`">
  72. <GithubFilled />
  73. <WechatFilled />
  74. <AlipayCircleFilled />
  75. <GoogleCircleFilled />
  76. <TwitterCircleFilled />
  77. </div> -->
  78. </Form>
  79. </template>
  80. <script lang="ts" setup>
  81. import { reactive, ref, unref, computed, onMounted } from 'vue';
  82. import { Checkbox, Form, Input, Row, Col, Button, } from 'ant-design-vue';// Divider
  83. // import {
  84. // GithubFilled,
  85. // WechatFilled,
  86. // AlipayCircleFilled,
  87. // GoogleCircleFilled,
  88. // TwitterCircleFilled,
  89. // } from '@ant-design/icons-vue';
  90. import LoginFormTitle from './LoginFormTitle.vue';
  91. import { useI18n } from '/@/hooks/web/useI18n';
  92. import { useMessage } from '/@/hooks/web/useMessage';
  93. import { useUserStore } from '/@/store/modules/user';
  94. import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
  95. import { useDesign } from '/@/hooks/web/useDesign';
  96. //import { onKeyStroke } from '@vueuse/core';
  97. const ACol = Col;
  98. const ARow = Row;
  99. const FormItem = Form.Item;
  100. const InputPassword = Input.Password;
  101. const { t } = useI18n();
  102. const { notification, createErrorModal } = useMessage();
  103. const { prefixCls } = useDesign('login');
  104. const userStore = useUserStore();
  105. const { setLoginState, getLoginState } = useLoginState();
  106. const { getFormRules } = useFormRules();
  107. const formRef = ref();
  108. const loading = ref(false);
  109. const rememberMe = ref(false);
  110. const formData = reactive({
  111. account: '',
  112. password: '',
  113. });
  114. const { validForm } = useFormValid(formRef);
  115. //onKeyStroke('Enter', handleLogin);
  116. const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
  117. onMounted(() => {
  118. let localePass = localStorage.getItem('password')
  119. if(localePass){
  120. let password = decodeURIComponent(escape(window.atob(localePass))),
  121. account:string = localStorage.getItem('username')
  122. formData.account = account
  123. formData.password = password
  124. rememberMe.value = true
  125. }
  126. });
  127. async function forgetPaswd() {
  128. window.open('/#/login/forget?from=%2F')
  129. }
  130. async function handleLogin() {
  131. const data = await validForm();
  132. if (!data) return;
  133. try {
  134. loading.value = true;
  135. const userInfo = await userStore.login({
  136. password: data.password,
  137. username: data.account,
  138. mode: 'none', //不要默认的错误提示
  139. });
  140. if (userInfo) {
  141. if(rememberMe.value){
  142. let password:string = window.btoa(unescape(encodeURIComponent(data.password)))
  143. localStorage.setItem('password',password)
  144. localStorage.setItem('username',data.account)
  145. }else{
  146. localStorage.removeItem("password");
  147. localStorage.removeItem("username");
  148. }
  149. console.log('login',userInfo)
  150. notification.success({
  151. message: t('sys.login.loginSuccessTitle'),
  152. description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.agent?.name ||userInfo.nickName} ${userInfo.agent?.userName || userInfo.userName}`,
  153. duration: 3,
  154. });
  155. }
  156. } catch (error) {
  157. createErrorModal({
  158. title: t('sys.api.errorTip'),
  159. content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
  160. getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
  161. });
  162. } finally {
  163. loading.value = false;
  164. }
  165. }
  166. </script>