刘洋 1 vuosi sitten
vanhempi
commit
adea9abff2
2 muutettua tiedostoa jossa 187 lisäystä ja 58 poistoa
  1. 2 0
      src/api/user.js
  2. 185 58
      src/views/login/index.vue

+ 2 - 0
src/api/user.js

@@ -95,12 +95,14 @@ export const getVerifyCode = (data) =>
   request({
     url: '/api/admin/common/get_verify_code',
     data,
+    noAuth: true,
   });
 export const forgetPassword = (data) =>
   request({
     url: '/api/admin/common/forget_password',
     data,
     loading,
+    noAuth: true,
   });
 export const getMenus = () =>
   request({

+ 185 - 58
src/views/login/index.vue

@@ -20,46 +20,102 @@
           <template #icon><RollbackIcon /></template>
           返回登录
         </t-button>
+        <t-button
+          variant="outline"
+          theme="primary"
+          v-else
+          @click="loginType = loginType === 'ACCOUNT' ? 'PHONE' : 'ACCOUNT'"
+        >
+          <template #icon><SwapRightIcon /></template>
+          {{ loginType === 'ACCOUNT' ? '手机号' : '账号' }}登录
+        </t-button>
       </div>
-      <div class="title2">{{
-        `请输入${forgetStatus ? '新的' : ''}账号与密码`
+      <div class="title2" v-if="forgetStatus">{{ `请输入新的账号与密码` }}</div>
+      <div class="title2" v-else>{{
+        `请输入${loginType === 'ACCOUNT' ? '账号与密码' : '手机号与验证码'}`
       }}</div>
-      <t-form
-        v-if="!forgetStatus"
-        ref="form"
-        :data="formData"
-        :label-width="0"
-        class="login-form"
-        :rules="rules"
-      >
-        <t-form-item name="loginName">
-          <t-input
-            v-model="formData.loginName"
-            clearable
-            placeholder="请输入账号"
-            size="large"
-            @enter="loginHandle"
-          >
-            <template #prefix-icon>
-              <desktop-icon />
-            </template>
-          </t-input>
-        </t-form-item>
+      <template v-if="!forgetStatus">
+        <t-form
+          ref="form"
+          :data="formData"
+          :label-width="0"
+          class="login-form"
+          :rules="rules"
+          v-if="loginType === 'ACCOUNT'"
+        >
+          <t-form-item name="loginName">
+            <t-input
+              v-model="formData.loginName"
+              clearable
+              placeholder="请输入账号"
+              size="large"
+              @enter="loginHandle"
+            >
+              <template #prefix-icon>
+                <desktop-icon />
+              </template>
+            </t-input>
+          </t-form-item>
 
-        <t-form-item name="password">
-          <t-input
-            v-model="formData.password"
-            type="password"
-            clearable
-            placeholder="请输入密码"
-            size="large"
-            @enter="loginHandle"
-          >
-            <template #prefix-icon>
-              <lock-on-icon />
-            </template>
-          </t-input>
-        </t-form-item>
+          <t-form-item name="password">
+            <t-input
+              v-model="formData.password"
+              type="password"
+              clearable
+              placeholder="请输入密码"
+              size="large"
+              @enter="loginHandle"
+            >
+              <template #prefix-icon>
+                <lock-on-icon />
+              </template>
+            </t-input>
+          </t-form-item>
+        </t-form>
+
+        <t-form
+          v-else
+          ref="form2"
+          :data="formData2"
+          :label-width="0"
+          class="login-form"
+          :rules="rules2"
+        >
+          <t-form-item name="mobileNumber">
+            <t-input
+              v-model="formData2.mobileNumber"
+              clearable
+              placeholder="请输入你的手机号"
+              size="large"
+            >
+              <template #prefix-icon>
+                <CallIcon />
+              </template>
+            </t-input>
+          </t-form-item>
+          <t-form-item name="code">
+            <div class="flex items-center">
+              <t-input
+                style="width: 170px"
+                v-model="formData2.code"
+                clearable
+                placeholder="验证码"
+                size="large"
+              >
+                <template #prefix-icon>
+                  <MobileIcon />
+                </template>
+              </t-input>
+              <t-button
+                class="m-l-20px"
+                style="width: 110px"
+                :loading="loading"
+                @click="getCode"
+                >{{ isActive ? lastSeconds + 's' : '获取验证码' }}</t-button
+              >
+            </div>
+          </t-form-item>
+        </t-form>
         <t-link theme="primary" class="m-t-20px" @click="forgetStatus = true"
           >忘记密码</t-link
         >
@@ -71,7 +127,7 @@
           theme="primary"
           >登 录</t-button
         >
-      </t-form>
+      </template>
       <ForgetPwd v-else @success="findSuccess" />
     </div>
   </div>
@@ -80,16 +136,57 @@
 
 <script setup name="Login">
 import { ref, reactive, computed, watch } from 'vue';
-import { DesktopIcon, LockOnIcon, RollbackIcon } from 'tdesign-icons-vue-next';
+import {
+  DesktopIcon,
+  LockOnIcon,
+  RollbackIcon,
+  SwapRightIcon,
+  CallIcon,
+  MobileIcon,
+} from 'tdesign-icons-vue-next';
 import { useRoute, useRouter } from 'vue-router';
 import { useUserStore, useAppStore } from '@/store';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { getBase64 } from '@/utils/crypto';
 import ForgetPwd from './forget-pwd.vue';
-
+import { useRequest } from 'vue-request';
+import { getVerifyCode } from '@/api/user';
+import { useIntervalFn } from '@vueuse/core';
+const { run, loading } = useRequest(getVerifyCode, {
+  onSuccess: () => {
+    MessagePlugin.success('验证码已发送');
+  },
+});
+const lastSeconds = ref(10);
+const countdown = () => {
+  if (lastSeconds.value == 0) {
+    pause();
+  } else {
+    lastSeconds.value = lastSeconds.value - 1;
+  }
+};
+const { pause, resume, isActive } = useIntervalFn(
+  () => {
+    countdown();
+  },
+  1000,
+  { immediate: false }
+);
+const getCode = () => {
+  if (!formData2.mobileNumber) {
+    MessagePlugin.error('请先输入手机号');
+    return;
+  }
+  run({
+    mobileNumber: formData2.mobileNumber,
+  });
+  // resume();
+};
+const loginType = ref('ACCOUNT');
 const appStore = useAppStore();
 const forgetStatus = ref(false);
 const form = ref(null);
+const form2 = ref(null);
 
 const route = useRoute();
 const router = useRouter();
@@ -98,6 +195,10 @@ const formData = reactive({
   loginName: '',
   password: '',
 });
+const formData2 = reactive({
+  mobileNumber: '',
+  code: '',
+});
 const rules = {
   loginName: [
     { required: true, message: '请输入账号', type: 'error', trigger: 'change' },
@@ -106,29 +207,55 @@ const rules = {
     { required: true, message: '请输入密码', type: 'error', trigger: 'change' },
   ],
 };
+const rules2 = {
+  mobileNumber: [
+    {
+      required: true,
+      message: '请输入手机号',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  code: [
+    {
+      required: true,
+      message: '请输入验证码',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+};
 
 const userStore = useUserStore();
 
 const loginHandle = () => {
-  form.value.validate().then(async (result) => {
-    const redirect = route.query.redirect
-      ? route.query.redirect
-      : '/my-workbenches';
-    if (result === true) {
-      await userStore.login({
-        loginName: formData.loginName,
-        password: getBase64(formData.password),
-        type: 'ACCOUNT',
-      });
-      await userStore.requestUserMenu();
-      await appStore.getFlowParams();
-      if (redirect) {
-        router.push(redirect);
-      } else {
-        router.push({ name: userStore.menus[0].name });
+  (loginType.value === 'ACCOUNT' ? form.value : form2.value)
+    .validate()
+    .then(async (result) => {
+      const redirect = route.query.redirect
+        ? route.query.redirect
+        : '/my-workbenches';
+      if (result === true) {
+        let params =
+          loginType.value === 'ACCOUNT'
+            ? {
+                loginName: formData.loginName,
+                password: getBase64(formData.password),
+              }
+            : formData2;
+        await userStore.login({
+          ...params,
+          type: loginType.value,
+        });
+        await userStore.requestUserMenu();
+        await appStore.getFlowParams();
+        if (redirect) {
+          router.push(redirect);
+        } else {
+          router.push({ name: userStore.menus[0].name });
+        }
       }
-    }
-  });
+    });
 };
 const findSuccess = () => {
   forgetStatus.value = false;