EmailRegister.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <!--
  2. - Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
  3. -
  4. - Licensed under the GNU Affero General Public License, Version 3 (the "License");
  5. - you may not use this file except in compliance with the License.
  6. - You may obtain a copy of the License at
  7. -
  8. - https://www.gnu.org/licenses/agpl-3.0.html
  9. -
  10. - Unless required by applicable law or agreed to in writing, software
  11. - distributed under the License is distributed on an "AS IS" BASIS,
  12. - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. - See the License for the specific language governing permissions and
  14. - limitations under the License.
  15. -->
  16. <script lang="ts" setup>
  17. import { SvgIcon } from '@/components/common';
  18. import { reactive, ref, toRaw } from 'vue';
  19. import { CountdownInst, useMessage } from 'naive-ui';
  20. import { useUserStore } from '@/store/modules/user';
  21. import { useRouter } from 'vue-router';
  22. import { emailRegister, getEmailCode } from '@/api/auth';
  23. import { t } from '@/locales';
  24. import { rules } from '@/views/login/data';
  25. const router = useRouter();
  26. const userStore = useUserStore();
  27. const formRef = ref();
  28. const message = useMessage();
  29. const loading = ref(false);
  30. const codeLoading = ref(false);
  31. const countdownRef = ref<CountdownInst | null>();
  32. const form = reactive({
  33. email: '',
  34. password: '',
  35. code: '',
  36. });
  37. const onSubmit = (e: any) => {
  38. e.preventDefault();
  39. formRef.value.validate(async (errors: any) => {
  40. if (!errors) {
  41. loading.value = true;
  42. try {
  43. await emailRegister(toRaw(form));
  44. message.loading(t('login.regSuccess'));
  45. const response = await userStore.login({
  46. username: form.email,
  47. password: form.password,
  48. });
  49. if (response.token !== undefined) {
  50. await router.replace('/');
  51. } else {
  52. message.error(response.message || t('login.error'));
  53. }
  54. } finally {
  55. loading.value = false;
  56. }
  57. }
  58. });
  59. };
  60. async function onGetCode() {
  61. formRef.value?.validate(
  62. async (errors: any) => {
  63. if (!errors) {
  64. codeLoading.value = true;
  65. getEmailCode(form.email)
  66. .then(() => {
  67. message.success(t('login.codeSendSuccess'));
  68. })
  69. .catch(() => {
  70. message.error(t('login.codeSendFail'));
  71. countdownRef.value?.reset();
  72. });
  73. }
  74. },
  75. (rule: any) => {
  76. return rule?.key === 'email';
  77. }
  78. );
  79. }
  80. </script>
  81. <template>
  82. <div class="mt-4 login-content-form">
  83. <n-form ref="formRef" :model="form" :rules="rules" label-placement="left" size="large">
  84. <n-form-item class="login-animation1" path="email">
  85. <n-input
  86. v-model:value="form.email"
  87. :input-props="{ type: 'email' }"
  88. :placeholder="t('login.namePlaceholder')"
  89. >
  90. <template #prefix>
  91. <n-icon color="#808695" size="18">
  92. <SvgIcon icon="material-symbols:person-outline" />
  93. </n-icon>
  94. </template>
  95. </n-input>
  96. </n-form-item>
  97. <n-form-item class="login-animation2" path="code">
  98. <n-input v-model:value="form.code" :placeholder="t('login.codePlaceholder')">
  99. <template #prefix>
  100. <n-icon color="#808695" size="18">
  101. <SvgIcon icon="ph:key" />
  102. </n-icon>
  103. </template>
  104. <template #suffix>
  105. <n-button :disabled="codeLoading" text type="success" @click="onGetCode()">
  106. <n-countdown
  107. v-if="codeLoading"
  108. :active="codeLoading"
  109. :duration="59000"
  110. :render="({ seconds }) => `${String(seconds) + t('login.codeExp')}`"
  111. @finish="codeLoading = false"
  112. />
  113. <template v-else>{{ t('login.getCode') }}</template>
  114. </n-button>
  115. </template>
  116. </n-input>
  117. </n-form-item>
  118. <n-form-item class="login-animation2" path="password">
  119. <n-input
  120. v-model:value="form.password"
  121. :placeholder="t('login.passPlaceholder')"
  122. showPasswordOn="click"
  123. type="password"
  124. >
  125. <template #prefix>
  126. <n-icon color="#808695" size="18">
  127. <SvgIcon icon="mdi:lock-outline" />
  128. </n-icon>
  129. </template>
  130. </n-input>
  131. </n-form-item>
  132. <n-form-item class="login-animation3">
  133. <n-space class="w-full" vertical>
  134. <n-button :loading="loading" block secondary type="primary" @click="onSubmit">
  135. {{ t('login.register') }}
  136. </n-button>
  137. </n-space>
  138. </n-form-item>
  139. </n-form>
  140. </div>
  141. </template>
  142. <style lang="less" scoped></style>