2025-11-27 01:59:22 +08:00
|
|
|
<template>
|
2025-11-28 01:42:42 +08:00
|
|
|
<div class="oauth-footer relative">
|
|
|
|
|
<div class="oauth-title">
|
2025-12-01 00:40:46 +08:00
|
|
|
<div class="oauth-title-text">{{ computedTitle }}</div>
|
2025-11-28 01:42:42 +08:00
|
|
|
</div>
|
2025-11-30 01:13:55 +08:00
|
|
|
<div class="flex justify-center items-center gap-4">
|
|
|
|
|
<template v-for="item in oauthProviderList" :key="item.type">
|
|
|
|
|
<div v-if="item.addonId" class="oauth-icon-button pointer" @click="goOauthLogin(item.name)">
|
|
|
|
|
<div><fs-icon :icon="item.icon" class="text-blue-600 text-40" /></div>
|
2025-12-06 17:25:02 +08:00
|
|
|
<div class="ellipsis title" :title="item.addonTitle || item.title">{{ item.addonTitle || item.title }}</div>
|
2025-11-30 01:13:55 +08:00
|
|
|
</div>
|
|
|
|
|
</template>
|
2025-11-27 01:59:22 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup lang="ts">
|
2025-12-01 00:40:46 +08:00
|
|
|
import { computed, onMounted, ref } from "vue";
|
2025-11-27 01:59:22 +08:00
|
|
|
import * as api from "./api";
|
2025-12-01 00:40:46 +08:00
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
|
import { useSettingStore } from "/@/store/settings";
|
2025-12-03 00:35:17 +08:00
|
|
|
import { useRoute } from "vue-router";
|
2025-11-27 01:59:22 +08:00
|
|
|
|
2025-11-30 01:13:55 +08:00
|
|
|
const oauthProviderList = ref([]);
|
2025-12-01 00:40:46 +08:00
|
|
|
const props = defineProps<{
|
|
|
|
|
oauthOnly?: boolean;
|
|
|
|
|
}>();
|
2025-11-28 01:42:42 +08:00
|
|
|
|
2025-12-01 00:40:46 +08:00
|
|
|
const { t } = useI18n();
|
|
|
|
|
const computedTitle = computed(() => {
|
|
|
|
|
return props.oauthOnly ? t("authentication.oauthOnlyLoginTitle") : t("authentication.oauthLoginTitle");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const settingStore = useSettingStore();
|
2025-12-03 00:35:17 +08:00
|
|
|
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
const queryOauthOnly = route.query.oauthOnly as string;
|
2025-11-28 01:42:42 +08:00
|
|
|
onMounted(async () => {
|
2025-11-30 01:13:55 +08:00
|
|
|
oauthProviderList.value = await api.GetOauthProviders();
|
2025-12-01 00:40:46 +08:00
|
|
|
//如果开启了自动跳转登录
|
2025-12-03 00:35:17 +08:00
|
|
|
if (settingStore.sysPublic.oauthAutoRedirect && queryOauthOnly !== "false") {
|
2025-12-01 00:40:46 +08:00
|
|
|
const firstOauth = oauthProviderList.value.find(item => item.addonId > 0);
|
|
|
|
|
if (firstOauth) {
|
|
|
|
|
goOauthLogin(firstOauth.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-28 01:42:42 +08:00
|
|
|
});
|
2025-11-27 01:59:22 +08:00
|
|
|
|
|
|
|
|
async function goOauthLogin(type: string) {
|
|
|
|
|
//获取第三方登录URL
|
2025-11-30 01:13:55 +08:00
|
|
|
const from = "web";
|
|
|
|
|
const res = await api.OauthLogin(type, from);
|
2025-11-27 01:59:22 +08:00
|
|
|
const loginUrl = res.loginUrl;
|
|
|
|
|
window.location.href = loginUrl;
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="less">
|
|
|
|
|
.oauth-footer {
|
2025-11-28 01:42:42 +08:00
|
|
|
width: 100%;
|
2025-11-27 01:59:22 +08:00
|
|
|
display: flex;
|
2025-11-28 01:42:42 +08:00
|
|
|
flex-direction: column;
|
2025-11-27 01:59:22 +08:00
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 16px;
|
2025-11-28 01:42:42 +08:00
|
|
|
|
|
|
|
|
.oauth-title {
|
|
|
|
|
width: 100%;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #8c8c8c;
|
|
|
|
|
position: relative;
|
|
|
|
|
.oauth-title-text {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
text-align: center;
|
|
|
|
|
&::after {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 36%;
|
|
|
|
|
height: 0.5px;
|
|
|
|
|
background-color: #8c8c8c;
|
|
|
|
|
}
|
|
|
|
|
&::before {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
right: 0;
|
|
|
|
|
width: 36%;
|
|
|
|
|
height: 0.5px;
|
|
|
|
|
background-color: #8c8c8c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 01:59:22 +08:00
|
|
|
.oauth-icon-button {
|
|
|
|
|
display: flex;
|
2025-11-28 01:42:42 +08:00
|
|
|
flex-direction: column;
|
2025-11-27 01:59:22 +08:00
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
2025-11-28 01:42:42 +08:00
|
|
|
padding: 8px 8px;
|
2025-11-27 01:59:22 +08:00
|
|
|
border-radius: 100px;
|
2025-12-06 17:25:02 +08:00
|
|
|
width: 100px;
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
2025-11-28 01:42:42 +08:00
|
|
|
.fs-icon {
|
|
|
|
|
font-size: 36px;
|
2025-12-03 00:35:17 +08:00
|
|
|
color: #006be6;
|
2025-12-01 00:40:46 +08:00
|
|
|
margin: 0px !important;
|
2025-11-28 01:42:42 +08:00
|
|
|
}
|
2025-11-27 01:59:22 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|