后台登录新增统一身份认证入口

与学生端共用后端 /sso/login 接口,学号 + 统一身份认证密码,
返回结构与账号登录一致,拿到 access_token 后流程无差别。
This commit is contained in:
2026-09-18 23:30:54 +08:00
parent b2b7d4208e
commit add24cfde8
2 changed files with 68 additions and 9 deletions
+18
View File
@@ -20,6 +20,24 @@ export async function login(data: LoginParam) {
return Promise.reject(new Error(res.data.message));
}
/**
* 学校统一身份认证登录(学号 + 统一身份认证密码)
*
* 与小程序端共用同一个后端接口,返回结构完全一致,
* 因此拿到 access_token 后前端流程与账号登录没有区别。
*/
export async function loginByGxmuSso(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>('/sso/login', {
username: data.username,
password: data.password
});
if (res.data.code === 0) {
setToken(res.data.data?.access_token, data.remember);
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 获取验证码
*/
+50 -9
View File
@@ -26,6 +26,13 @@
>
账号登录
</button>
<button
type="button"
:class="['login-tab', { active: loginType === 'sso' }]"
@click="onLoginType('sso')"
>
统一身份认证
</button>
</div>
<template v-if="loginType === 'sms'">
@@ -60,7 +67,7 @@
</a-form-item>
</template>
<template v-else>
<template v-else-if="loginType === 'account'">
<a-form-item v-bind="validateInfos.username">
<a-input
v-model:value="form.username"
@@ -83,7 +90,33 @@
</a-form-item>
</template>
<div class="login-agree">
<template v-else>
<a-form-item v-bind="validateInfos.username">
<a-input
v-model:value="form.username"
allow-clear
size="large"
placeholder="请输入学号"
/>
</a-form-item>
<a-form-item v-bind="validateInfos.password">
<div class="login-input-group login-input-plain">
<a-input-password
v-model:value="form.password"
allow-clear
size="large"
placeholder="请输入统一身份认证密码"
@pressEnter="submit"
/>
</div>
</a-form-item>
</template>
<div v-if="loginType === 'sso'" class="login-agree">
使用学校统一身份认证账号学号登录密码由学校认证平台校验本系统不留存
</div>
<div v-else class="login-agree">
注册登录即代表已阅读并同意我们的
<span class="link">用户协议</span>
@@ -132,7 +165,7 @@ import { computed, onBeforeUnmount, reactive, ref, unref } from "vue";
import { useRouter } from "vue-router";
import { Form, message } from "ant-design-vue";
import { cleanPageTabs } from "@/utils/page-tab-util";
import { login, sendSmsCaptcha } from "@/api/passport/login";
import { login, loginByGxmuSso, sendSmsCaptcha } from "@/api/passport/login";
import { User } from "@/api/system/user/model";
import { THEME_STORE_NAME } from "@/config/setting";
@@ -144,7 +177,7 @@ const sending = ref(false);
const countdown = ref(0);
let countdownTimer: number | null = null;
const loginType = ref<"sms" | "account">("sms");
const loginType = ref<"sms" | "account" | "sso">("sms");
const form = reactive<User & { code?: string }>({
username: "",
@@ -160,19 +193,25 @@ const toHome = () => {
};
const rules = computed(() => {
if (loginType.value === "account") {
if (loginType.value === "account" || loginType.value === "sso") {
return {
username: [
{
required: true,
message: "请输入账号",
message:
loginType.value === "sso"
? "请输入学号"
: "请输入账号",
type: "string"
}
],
password: [
{
required: true,
message: "请输入密码",
message:
loginType.value === "sso"
? "请输入统一身份认证密码"
: "请输入密码",
type: "string"
}
]
@@ -216,7 +255,7 @@ const startCountdown = () => {
}, 1000);
};
const onLoginType = (type: "sms" | "account") => {
const onLoginType = (type: "sms" | "account" | "sso") => {
loginType.value = type;
};
@@ -262,7 +301,9 @@ const submit = () => {
if (query.tenantId) {
form.tenantId = Number(query.tenantId);
}
login(form)
const request =
loginType.value === "sso" ? loginByGxmuSso(form) : login(form);
request
.then((msg) => {
message.success(msg);
loading.value = false;