|
@@ -1,10 +1,9 @@
|
|
|
<template>
|
|
|
<div class="login login-box">
|
|
|
- <div class="login-theme"><h2>知学知考</h2></div>
|
|
|
+ <div class="login-theme"><h2>预约报名系统</h2></div>
|
|
|
<div class="login-body" @keyup.enter="submit">
|
|
|
<div class="login-title">
|
|
|
- <img v-if="schoolInfo.logo" :src="schoolInfo.logo" alt="学校logo" />
|
|
|
- <h1 v-else>知学知考</h1>
|
|
|
+ <h1> 登录 </h1>
|
|
|
</div>
|
|
|
<div class="login-form">
|
|
|
<a-form
|
|
@@ -14,81 +13,29 @@
|
|
|
:label-col-props="{ span: 0, offset: 0 }"
|
|
|
:wrapper-col-props="{ span: 24, offset: 0 }"
|
|
|
>
|
|
|
- <!-- account -->
|
|
|
- <template v-if="IS_USERNAME_TYPE">
|
|
|
- <a-form-item field="loginName">
|
|
|
- <a-input
|
|
|
- v-model.trim="formData.loginName"
|
|
|
- placeholder="请输入账号"
|
|
|
- allow-clear
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <icon-user />
|
|
|
- </template>
|
|
|
- </a-input>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item field="password">
|
|
|
- <a-input-password
|
|
|
- v-model.trim="formData.password"
|
|
|
- placeholder="请输入密码"
|
|
|
- allow-clear
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <icon-lock />
|
|
|
- </template>
|
|
|
- </a-input-password>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item v-if="schoolInfo.accountSmsVerify" field="code">
|
|
|
- <div class="box-justify">
|
|
|
- <a-input
|
|
|
- v-model.trim="formData.code"
|
|
|
- placeholder="请输入手机验证码"
|
|
|
- allow-clear
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <icon-message />
|
|
|
- </template>
|
|
|
- </a-input>
|
|
|
- <a-button
|
|
|
- type="primary"
|
|
|
- :disabled="isFetchingCode"
|
|
|
- @click="fetchAccountSmsCode"
|
|
|
- >{{ codeContent }}</a-button
|
|
|
- >
|
|
|
- </div>
|
|
|
- </a-form-item>
|
|
|
- </template>
|
|
|
- <!-- mobile -->
|
|
|
- <template v-else>
|
|
|
- <a-form-item field="mobileNumber">
|
|
|
- <a-input
|
|
|
- v-model.trim="formData.mobileNumber"
|
|
|
- placeholder="请输入手机号"
|
|
|
- allow-clear
|
|
|
- >
|
|
|
- <template #prefix> <icon-mobile /> </template>
|
|
|
- </a-input>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item field="code">
|
|
|
- <div class="box-justify">
|
|
|
- <a-input
|
|
|
- v-model.trim="formData.code"
|
|
|
- placeholder="请输入手机验证码"
|
|
|
- allow-clear
|
|
|
- >
|
|
|
- <template #prefix>
|
|
|
- <icon-message />
|
|
|
- </template>
|
|
|
- </a-input>
|
|
|
- <a-button
|
|
|
- type="primary"
|
|
|
- :disabled="isFetchingCode"
|
|
|
- @click="fetchMobileSmsCode"
|
|
|
- >{{ codeContent }}</a-button
|
|
|
- >
|
|
|
- </div>
|
|
|
- </a-form-item>
|
|
|
- </template>
|
|
|
+ <a-form-item field="loginName">
|
|
|
+ <a-input
|
|
|
+ v-model.trim="formData.loginName"
|
|
|
+ placeholder="请输入账号"
|
|
|
+ allow-clear
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <icon-user />
|
|
|
+ </template>
|
|
|
+ </a-input>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item field="password">
|
|
|
+ <a-input-password
|
|
|
+ v-model.trim="formData.password"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ allow-clear
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <icon-lock />
|
|
|
+ </template>
|
|
|
+ </a-input-password>
|
|
|
+ </a-form-item>
|
|
|
+
|
|
|
<a-form-item>
|
|
|
<a-button type="primary" :loading="loading" long @click="submit"
|
|
|
>登录</a-button
|
|
@@ -96,66 +43,28 @@
|
|
|
</a-form-item>
|
|
|
</a-form>
|
|
|
</div>
|
|
|
- <div v-if="schoolInfo.phoneLogin" class="login-action box-justify">
|
|
|
- <div></div>
|
|
|
- <a-button type="text" @click="switchLoginType">
|
|
|
- <i>{{ switchBtnName }}</i>
|
|
|
- <icon-right />
|
|
|
- </a-button>
|
|
|
- </div>
|
|
|
</div>
|
|
|
-
|
|
|
- <!-- ResetPwd -->
|
|
|
- <ResetPwd
|
|
|
- ref="ResetPwdRef"
|
|
|
- :user-info="userInfo"
|
|
|
- @modified="resetPwdSuccess"
|
|
|
- @cancel="resetCancel"
|
|
|
- />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
- import { ref, reactive, computed, onMounted } from 'vue';
|
|
|
- import { Message } from '@arco-design/web-vue';
|
|
|
- import { useRoute, useRouter } from 'vue-router';
|
|
|
+ import { ref, reactive, onMounted } from 'vue';
|
|
|
+ import { useRouter } from 'vue-router';
|
|
|
import type { FormInstance, FieldRule } from '@arco-design/web-vue/es/form';
|
|
|
- import { omit } from 'lodash';
|
|
|
import useLoading from '@/hooks/loading';
|
|
|
- import useSms from '@/hooks/sms';
|
|
|
- import {
|
|
|
- login,
|
|
|
- getSchoolInfo,
|
|
|
- getAccountSmsCode,
|
|
|
- getSmsCode,
|
|
|
- } from '@/api/user';
|
|
|
- import { getBase64 } from '@/utils/crypto';
|
|
|
- import { smscode, phone } from '@/utils/formRules';
|
|
|
- import { getOrgCode } from '@/constants/app';
|
|
|
+ import { login } from '@/api/user';
|
|
|
import { useAppStore, useUserStore } from '@/store';
|
|
|
import { DEFAULT_ROUTE_NAME } from '@/router/constants';
|
|
|
|
|
|
- import type { SchoolInfoRes } from '@/api/types/user';
|
|
|
-
|
|
|
- import ResetPwd from './ResetPwd.vue';
|
|
|
-
|
|
|
- const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
const appStore = useAppStore();
|
|
|
const userStore = useUserStore();
|
|
|
userStore.resetInfo();
|
|
|
|
|
|
- const userInfo = ref({});
|
|
|
- const schoolInfo = ref<SchoolInfoRes>({});
|
|
|
const formRef = ref<FormInstance>();
|
|
|
- const ResetPwdRef = ref(null);
|
|
|
const formData = reactive({
|
|
|
loginName: 'admin-zj',
|
|
|
password: 'a12345678',
|
|
|
- code: '',
|
|
|
- mobileNumber: '',
|
|
|
- schoolCode: 'test-school-2',
|
|
|
- type: 'ACCOUNT',
|
|
|
});
|
|
|
const rules: Record<string, FieldRule[]> = {
|
|
|
loginName: [
|
|
@@ -170,125 +79,8 @@
|
|
|
message: '请输入密码',
|
|
|
},
|
|
|
],
|
|
|
- code: smscode,
|
|
|
- mobileNumber: phone,
|
|
|
- schoolCode: [
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: '学校编码缺失',
|
|
|
- },
|
|
|
- ],
|
|
|
};
|
|
|
|
|
|
- const IS_USERNAME_TYPE = computed(() => {
|
|
|
- return formData.type === 'ACCOUNT';
|
|
|
- });
|
|
|
- const switchBtnName = computed(() => {
|
|
|
- return formData.type === 'ACCOUNT' ? '短信登录' : '账号登录';
|
|
|
- });
|
|
|
-
|
|
|
- async function getSchool() {
|
|
|
- if (route.params.code) {
|
|
|
- formData.schoolCode = route.params.code;
|
|
|
- window.sessionStorage.setItem('routeDomainCode', route.params.code);
|
|
|
- } else {
|
|
|
- formData.schoolCode = getOrgCode();
|
|
|
- }
|
|
|
- const data = await getSchoolInfo(formData.schoolCode);
|
|
|
- appStore.setInfo({ version: data.version || '' });
|
|
|
- formData.schoolCode = data.schoolCode;
|
|
|
- schoolInfo.value = data;
|
|
|
- }
|
|
|
-
|
|
|
- function switchLoginType() {
|
|
|
- if (!schoolInfo.value.phoneLogin) return;
|
|
|
- formData.type = formData.type === 'ACCOUNT' ? 'PHONE' : 'ACCOUNT';
|
|
|
- }
|
|
|
-
|
|
|
- function resetPwdSuccess(data) {
|
|
|
- if (data.schoolInfo && data.schoolInfo.length) {
|
|
|
- const curSchool = data.schoolInfo.find(
|
|
|
- (item) => item.code === formData.schoolCode
|
|
|
- );
|
|
|
- data.curSchoolInfo = curSchool || {};
|
|
|
- }
|
|
|
- userStore.setInfo(data);
|
|
|
-
|
|
|
- if (data.roleList && data.roleList.includes('ADMIN')) {
|
|
|
- router.push({
|
|
|
- name: 'SelectSchool',
|
|
|
- });
|
|
|
- } else {
|
|
|
- router.push({
|
|
|
- name: 'Home',
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function resetCancel() {
|
|
|
- userStore.resetInfo();
|
|
|
- }
|
|
|
-
|
|
|
- /* sms ----start */
|
|
|
- const { isFetchingCode, codeContent, changeContent } = useSms('login');
|
|
|
-
|
|
|
- async function fetchMobileSmsCode() {
|
|
|
- const unvalid = await formRef.value.validateField([
|
|
|
- 'mobileNumber',
|
|
|
- 'schoolCode',
|
|
|
- ]);
|
|
|
- if (unvalid) return;
|
|
|
-
|
|
|
- isFetchingCode.value = true;
|
|
|
- const res = await getSmsCode({
|
|
|
- schoolCode: formData.schoolCode,
|
|
|
- mobileNumber: formData.mobileNumber,
|
|
|
- }).catch(() => {
|
|
|
- isFetchingCode.value = false;
|
|
|
- });
|
|
|
- if (!res) return;
|
|
|
-
|
|
|
- if (res.mobileNumber) {
|
|
|
- Message.success(
|
|
|
- `已向手机尾号【${res.mobileNumber.slice(
|
|
|
- -4
|
|
|
- )}】成功发送短信,请在2分钟内进行验证!`
|
|
|
- );
|
|
|
- changeContent();
|
|
|
- } else {
|
|
|
- Message.error('未绑定手机号,请先绑定!');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- async function fetchAccountSmsCode() {
|
|
|
- const unvalid = await formRef.value.validateField([
|
|
|
- 'loginName',
|
|
|
- 'schoolCode',
|
|
|
- 'password',
|
|
|
- ]);
|
|
|
- if (unvalid) return;
|
|
|
-
|
|
|
- isFetchingCode.value = true;
|
|
|
- const res = await getAccountSmsCode({
|
|
|
- schoolCode: formData.schoolCode,
|
|
|
- loginName: formData.loginName,
|
|
|
- password: getBase64(formData.password),
|
|
|
- }).catch(() => {
|
|
|
- isFetchingCode.value = false;
|
|
|
- });
|
|
|
- if (!res) return;
|
|
|
-
|
|
|
- if (res) {
|
|
|
- Message.success(
|
|
|
- `已向手机尾号【${res.slice(-4)}】成功发送短信,请在2分钟内进行验证!`
|
|
|
- );
|
|
|
- changeContent();
|
|
|
- } else {
|
|
|
- Message.error('未绑定手机号!');
|
|
|
- }
|
|
|
- }
|
|
|
- /* sms ----end */
|
|
|
-
|
|
|
/* submit */
|
|
|
const { loading, setLoading } = useLoading();
|
|
|
async function submit() {
|
|
@@ -296,61 +88,22 @@
|
|
|
if (err) return;
|
|
|
|
|
|
setLoading(true);
|
|
|
- let datas = {};
|
|
|
- if (IS_USERNAME_TYPE.value) {
|
|
|
- datas = omit(
|
|
|
- formData,
|
|
|
- schoolInfo.value.accountSmsVerify
|
|
|
- ? ['mobileNumber']
|
|
|
- : ['code', 'mobileNumber']
|
|
|
- );
|
|
|
- datas.password = getBase64(formData.password);
|
|
|
- } else {
|
|
|
- datas = omit(formData, ['loginName', 'password']);
|
|
|
- }
|
|
|
- const data = await login(datas).catch(() => {});
|
|
|
+ const data = await login(formData).catch(() => {});
|
|
|
setLoading(false);
|
|
|
if (!data) return;
|
|
|
|
|
|
- if (data.schoolInfo && data.schoolInfo.length) {
|
|
|
- const curSchool = data.schoolInfo.find(
|
|
|
- (item) => item.code === formData.schoolCode
|
|
|
- );
|
|
|
- data.curSchoolInfo = curSchool || {};
|
|
|
- }
|
|
|
- userStore.setInfo(data);
|
|
|
+ console.log(data);
|
|
|
|
|
|
- // 强制修改密码和绑定手机号
|
|
|
- if (
|
|
|
- data.userLoginCheckResult &&
|
|
|
- (!data.userLoginCheckResult.pwdCount ||
|
|
|
- (!data.userLoginCheckResult.mobileNumber &&
|
|
|
- schoolInfo.value.phoneLogin))
|
|
|
- ) {
|
|
|
- userInfo.value = {
|
|
|
- ...formData,
|
|
|
- ...data.userLoginCheckResult,
|
|
|
- phoneLogin: schoolInfo.value.phoneLogin,
|
|
|
- };
|
|
|
- ResetPwdRef.value?.open();
|
|
|
- return;
|
|
|
- }
|
|
|
+ userStore.setInfo(data);
|
|
|
|
|
|
- if (data.roleList && data.roleList.includes('ADMIN')) {
|
|
|
- router.push({
|
|
|
- name: 'SchoolSelect',
|
|
|
- });
|
|
|
- } else {
|
|
|
- router.push({
|
|
|
- name: DEFAULT_ROUTE_NAME,
|
|
|
- });
|
|
|
- }
|
|
|
+ router.push({
|
|
|
+ name: DEFAULT_ROUTE_NAME,
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
// mounted
|
|
|
onMounted(() => {
|
|
|
userStore.resetInfo();
|
|
|
appStore.resetInfo();
|
|
|
- getSchool();
|
|
|
});
|
|
|
</script>
|