!116 兼容OAuth2

Merge pull request !116 from 木子-李/N/A
This commit is contained in:
dvadmin
2025-06-22 13:18:46 +00:00
committed by Gitee
6 changed files with 178 additions and 2 deletions

View File

@@ -77,7 +77,13 @@ class Users(CoreModel, AbstractUser):
objects = CustomUserManager() objects = CustomUserManager()
def set_password(self, raw_password): def set_password(self, raw_password):
super().set_password(hashlib.md5(raw_password.encode(encoding="UTF-8")).hexdigest()) if raw_password:
super().set_password(hashlib.md5(raw_password.encode(encoding="UTF-8")).hexdigest())
def save(self, *args, **kwargs):
if self.name == "":
self.name = self.username
super().save(*args, **kwargs)
class Meta: class Meta:
db_table = table_prefix + "system_users" db_table = table_prefix + "system_users"

View File

@@ -98,10 +98,22 @@ export function formatTwoStageRoutes(arr: any) {
const frameOutRoutes = staticRoutes.map(item => item.path) const frameOutRoutes = staticRoutes.map(item => item.path)
const checkToken = ()=>{
const urlParams = new URLSearchParams(window.location.search);
const _oauth2_token = urlParams.get('_oauth2_token');
if (_oauth2_token) {
Session.set('token', _oauth2_token);
const cleanUrl = window.location.href.split('?')[0];
window.history.replaceState({}, '', cleanUrl);
useUserInfo(pinia).setUserInfos();
}
}
// 路由加载前 // 路由加载前
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
// 检查浏览器本地版本与线上版本是否一致,判断是否需要刷新页面进行更新 // 检查浏览器本地版本与线上版本是否一致,判断是否需要刷新页面进行更新
await checkVersion() await checkVersion()
checkToken()
NProgress.configure({showSpinner: false}); NProgress.configure({showSpinner: false});
if (to.meta.title) NProgress.start(); if (to.meta.title) NProgress.start();
const token = Session.get('token'); const token = Session.get('token');

View File

@@ -28,3 +28,10 @@ export function getUserInfo() {
method: 'get', method: 'get',
}); });
} }
export function getBackends() {
return request({
url: '/api/dvadmin3_social_oauth2/backend/get_login_backend/',
method: 'get',
});
}

View File

@@ -0,0 +1,139 @@
<template>
<div class="other-fast-way" v-if="backends.length">
<div class="fast-title"><span>其他快速方式登录</span></div>
<ul class="fast-list">
<li v-for="(v, k) in backends" :key="v">
<a @click.once="handleOAuth2LoginClick(v)" style="width: 50px;color: #18bc9c">
<img :src="v.icon" :alt="v.app_name" />
<p>{{ v.app_name }}</p>
</a>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs } from 'vue';
import * as loginApi from '../api';
import { OAuth2Backend } from '/@/views/system/login/types';
export default defineComponent({
name: 'loginOAuth2',
setup() {
const handleOAuth2LoginClick = (backend: OAuth2Backend) => {
history.replaceState(null, '', location.pathname + location.search);
window.location.href = backend.authentication_url + '?next=' + window.location.href;
};
const state = reactive({
handleOAuth2LoginClick: handleOAuth2LoginClick,
backends: [],
});
const getBackends = async () => {
loginApi.getBackends().then((ret: any) => {
state.backends = ret.data;
});
};
// const handleTreeClick = (record: MenuTreeItemType) => {
// menuButtonRef.value?.handleRefreshTable(record);
// menuFieldRef.value?.handleRefreshTable(record)
// };
onMounted(() => {
getBackends();
});
return {
...toRefs(state),
};
},
});
</script>
<style scoped lang="scss">
.login-content-form {
margin-top: 20px;
@for $i from 1 through 4 {
.login-animation#{$i} {
opacity: 0;
animation-name: error-num;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-delay: calc($i/10) + s;
}
}
.login-content-code {
width: 100%;
padding: 0;
}
.login-content-submit {
width: 100%;
letter-spacing: 2px;
font-weight: 300;
margin-top: 15px;
}
.login-msg {
color: var(--el-text-color-placeholder);
}
}
.other-fast-way {
//height: 240px;
position: relative;
z-index: 1;
//display: flex;
//align-items: center;
//justify-content: center;
.fast-title {
display: flex;
align-items: center;
justify-content: center;
span {
color: #999;
font-size: 14px;
padding: 0 20px;
}
&:before,
&:after {
content: '';
flex: 1;
height: 1px;
background: #ddd;
}
}
}
.fast-list {
display: flex;
justify-content: center;
margin-top: 10px;
li {
margin-left: 20px;
opacity: 0;
animation-name: error-num;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-delay: 0.1s;
a {
display: block;
text-align: center;
cursor: pointer;
img {
width: 35px;
margin: 0 auto;
max-width: 100%;
margin-bottom: 6px;
}
p {
font-size: 14px;
color: #333;
}
}
&:first-child {
margin-left: 0;
}
}
}
</style>

View File

@@ -34,7 +34,9 @@
</el-tab-pane> --> </el-tab-pane> -->
</el-tabs> </el-tabs>
</div> </div>
<!-- <Scan v-if="state.isScan" />--> <OAuth2 />
<!-- <Scan v-if="state.isScan" />-->
<!-- <div class="login-content-main-sacn" @click="state.isScan = !state.isScan">--> <!-- <div class="login-content-main-sacn" @click="state.isScan = !state.isScan">-->
<!-- <i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>--> <!-- <i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>-->
<!-- <div class="login-content-main-sacn-delta"></div>--> <!-- <div class="login-content-main-sacn-delta"></div>-->
@@ -81,6 +83,8 @@ const Account = defineAsyncComponent(() => import('/@/views/system/login/compone
const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue')); const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue')); const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
const ChangePwd = defineAsyncComponent(() => import('/@/views/system/login/component/changePwd.vue')); const ChangePwd = defineAsyncComponent(() => import('/@/views/system/login/component/changePwd.vue'));
const OAuth2 = defineAsyncComponent(() => import('/@/views/system/login/component/oauth2.vue'));
import _ from "lodash-es"; import _ from "lodash-es";
import {useUserInfo} from "/@/stores/userInfo"; import {useUserInfo} from "/@/stores/userInfo";
const { userInfos } = storeToRefs(useUserInfo()); const { userInfos } = storeToRefs(useUserInfo());

View File

@@ -0,0 +1,8 @@
export interface OAuth2Backend {
app_name: string;
backend_name: string;
icon: string;
authentication_url: string;
}