LoginForm.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 name="captcha">
  30. <Input
  31. size="large"
  32. v-model:value="formData.captcha"
  33. :placeholder="t('sys.login.captcha')"
  34. class="captcha"
  35. />
  36. </FormItem>
  37. </ACol>
  38. <ACol :span="12" :style="{ 'text-align': 'right' }">
  39. <img class="captcha-img" :src="`http://192.168.0.47:8190/captcha.jpg?t=${Date.now()}`" />
  40. </ACol>
  41. </ARow> -->
  42. <FormItem name="drag" class="enter-x" :style="{ 'text-align': 'right' }">
  43. <BasicDragVerify
  44. ref="el3"
  45. @success="handleSuccess"
  46. text="拖动以进行校验"
  47. successText="校验成功"
  48. />
  49. </FormItem>
  50. <!-- <ARow class="enter-x">
  51. <ACol :span="12">
  52. <FormItem>
  53. <Checkbox v-model:checked="rememberMe" size="small">
  54. {{ t('sys.login.rememberMe') }}
  55. </Checkbox>
  56. </FormItem>
  57. </ACol>
  58. <ACol :span="12">
  59. <FormItem :style="{ 'text-align': 'right' }">
  60. <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">
  61. {{ t('sys.login.forgetPassword') }}
  62. </Button>
  63. </FormItem>
  64. </ACol>
  65. </ARow> -->
  66. <FormItem class="enter-x">
  67. <Button type="primary" size="large" block @click="handleLogin" :loading="loading">
  68. {{ t('sys.login.loginButton') }}
  69. </Button>
  70. <!-- <Button size="large" class="mt-4 enter-x" block @click="handleRegister">
  71. {{ t('sys.login.registerButton') }}
  72. </Button> -->
  73. </FormItem>
  74. <!-- <ARow class="enter-x">
  75. <ACol :md="8" :xs="24">
  76. <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
  77. {{ t('sys.login.mobileSignInFormTitle') }}
  78. </Button>
  79. </ACol>
  80. <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2">
  81. <Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
  82. {{ t('sys.login.qrSignInFormTitle') }}
  83. </Button>
  84. </ACol>
  85. <ACol :md="7" :xs="24">
  86. <Button block @click="setLoginState(LoginStateEnum.REGISTER)">
  87. {{ t('sys.login.registerButton') }}
  88. </Button>
  89. </ACol>
  90. </ARow> -->
  91. <!-- <Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider> -->
  92. <!-- <div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`">
  93. <GithubFilled />
  94. <WechatFilled />
  95. <AlipayCircleFilled />
  96. <GoogleCircleFilled />
  97. <TwitterCircleFilled />
  98. </div> -->
  99. </Form>
  100. </template>
  101. <script lang="ts" setup>
  102. import { reactive, ref, unref, computed } from 'vue';
  103. // Divider,Row, Col,Checkbox
  104. import { Form, Input, Button } from 'ant-design-vue';
  105. // import {
  106. // GithubFilled,
  107. // WechatFilled,
  108. // AlipayCircleFilled,
  109. // GoogleCircleFilled,
  110. // TwitterCircleFilled,
  111. // } from '@ant-design/icons-vue';
  112. import LoginFormTitle from './LoginFormTitle.vue';
  113. import { BasicDragVerify } from '/@/components/Verify/index';
  114. import { useI18n } from '/@/hooks/web/useI18n';
  115. import { useMessage } from '/@/hooks/web/useMessage';
  116. import { useUserStore } from '/@/store/modules/user';
  117. import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
  118. import { useDesign } from '/@/hooks/web/useDesign';
  119. //import { onKeyStroke } from '@vueuse/core';
  120. // const ACol = Col;
  121. // const ARow = Row;
  122. const FormItem = Form.Item;
  123. const InputPassword = Input.Password;
  124. const { t } = useI18n();
  125. const { notification, createErrorModal } = useMessage();
  126. const { prefixCls } = useDesign('login');
  127. const userStore = useUserStore();
  128. // setLoginState
  129. const { getLoginState } = useLoginState();
  130. const { getFormRules } = useFormRules();
  131. const formRef = ref();
  132. const loading = ref(false);
  133. // const rememberMe = ref(false);
  134. const isDragValidate = ref(false);
  135. const formData = reactive({
  136. account: '18819272208',
  137. password: 'Aa123456',
  138. // password: encodeStr(window.btoa('zfb123456')),
  139. // captcha: '',
  140. });
  141. const { validForm } = useFormValid(formRef);
  142. //onKeyStroke('Enter', handleLogin);
  143. const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
  144. function handleSuccess() {
  145. // console.log('11');
  146. isDragValidate.value = true;
  147. }
  148. async function handleLogin() {
  149. const data = await validForm();
  150. if (!data) return;
  151. if (!isDragValidate.value) {
  152. notification.info({
  153. message: t('sys.login.loginDragValidate'),
  154. description: `${t('sys.login.loginAgain')}`,
  155. duration: 3,
  156. });
  157. return;
  158. }
  159. try {
  160. loading.value = true;
  161. const userInfo = await userStore.login({
  162. password: data.password,
  163. phoneNum: data.account,
  164. randomcode: data.captcha,
  165. rememberMe: false,
  166. // mode: 'none', //不要默认的错误提示
  167. });
  168. if (userInfo) {
  169. notification.success({
  170. message: t('sys.login.loginSuccessTitle'),
  171. description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.userName}`,
  172. duration: 3,
  173. });
  174. }
  175. } catch (error) {
  176. createErrorModal({
  177. title: t('sys.api.errorTip'),
  178. content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
  179. getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
  180. });
  181. } finally {
  182. loading.value = false;
  183. }
  184. }
  185. </script>
  186. <style>
  187. .captcha {
  188. min-width: 80px !important;
  189. }
  190. .captcha-img {
  191. height: 40px;
  192. display: inline-block;
  193. }
  194. </style>