feat: add dingding login
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { RiDingding } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { alert, useVbenModal } from '@vben-core/popup-ui';
|
||||
import { VbenIconButton } from '@vben-core/shadcn-ui';
|
||||
import { loadScript } from '@vben-core/shared/utils';
|
||||
|
||||
interface Props {
|
||||
clientId: string;
|
||||
corpId: string;
|
||||
// 登录回调地址
|
||||
redirectUri?: string;
|
||||
// 是否内嵌二维码登录
|
||||
isQrCode?: boolean;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
header: false,
|
||||
footer: false,
|
||||
fullscreenButton: false,
|
||||
class: 'w-[302px] h-[302px] dingding-qrcode-login-modal',
|
||||
onOpened() {
|
||||
handleQrCodeLogin();
|
||||
},
|
||||
});
|
||||
|
||||
const getRedirectUri = () => {
|
||||
const { redirectUri } = props;
|
||||
if (redirectUri) {
|
||||
return redirectUri;
|
||||
}
|
||||
return window.location.origin + route.fullPath;
|
||||
};
|
||||
|
||||
/**
|
||||
* 内嵌二维码登录
|
||||
*/
|
||||
const handleQrCodeLogin = async () => {
|
||||
const { clientId, corpId } = props;
|
||||
if (!(window as any).DTFrameLogin) {
|
||||
// 二维码登录 加载资源
|
||||
await loadScript(
|
||||
'https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js',
|
||||
);
|
||||
}
|
||||
(window as any).DTFrameLogin(
|
||||
{
|
||||
id: 'dingding_qrcode_login_element',
|
||||
width: 300,
|
||||
height: 300,
|
||||
},
|
||||
{
|
||||
// 注意:redirect_uri 需为完整URL,扫码后钉钉会带code跳转到这里
|
||||
redirect_uri: encodeURIComponent(getRedirectUri()),
|
||||
client_id: clientId,
|
||||
scope: 'openid corpid',
|
||||
response_type: 'code',
|
||||
state: '1',
|
||||
prompt: 'consent',
|
||||
corpId,
|
||||
},
|
||||
(loginResult: any) => {
|
||||
const { redirectUrl } = loginResult;
|
||||
// 这里可以直接进行重定向
|
||||
window.location.href = redirectUrl;
|
||||
},
|
||||
(errorMsg: string) => {
|
||||
// 这里一般需要展示登录失败的具体原因
|
||||
alert(`Login Error: ${errorMsg}`);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleLogin = () => {
|
||||
const { clientId, corpId, isQrCode } = props;
|
||||
if (isQrCode) {
|
||||
// 内嵌二维码登录
|
||||
modalApi.open();
|
||||
} else {
|
||||
window.location.href = `https://login.dingtalk.com/oauth2/auth?redirect_uri=${encodeURIComponent(getRedirectUri())}&response_type=code&client_id=${clientId}&scope=openid&corpid=${corpId}&prompt=consent`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<VbenIconButton
|
||||
@click="handleLogin"
|
||||
:tooltip="$t('authentication.dingdingLogin')"
|
||||
tooltip-side="top"
|
||||
>
|
||||
<RiDingding />
|
||||
</VbenIconButton>
|
||||
<Modal>
|
||||
<div id="dingding_qrcode_login_element"></div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.dingding-qrcode-login-modal {
|
||||
.relative {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,12 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { MdiGithub, MdiGoogle, MdiQqchat, MdiWechat } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import { VbenIconButton } from '@vben-core/shadcn-ui';
|
||||
|
||||
import DingdingLogin from './dingding-login.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'ThirdPartyLogin',
|
||||
});
|
||||
|
||||
const {
|
||||
auth: { dingding: dingdingAuthConfig },
|
||||
} = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -20,18 +27,40 @@ defineOptions({
|
||||
</div>
|
||||
|
||||
<div class="mt-4 flex flex-wrap justify-center">
|
||||
<VbenIconButton class="mb-3">
|
||||
<VbenIconButton
|
||||
:tooltip="$t('authentication.wechatLogin')"
|
||||
tooltip-side="top"
|
||||
class="mb-3"
|
||||
>
|
||||
<MdiWechat />
|
||||
</VbenIconButton>
|
||||
<VbenIconButton class="mb-3">
|
||||
<VbenIconButton
|
||||
:tooltip="$t('authentication.qqLogin')"
|
||||
tooltip-side="top"
|
||||
class="mb-3"
|
||||
>
|
||||
<MdiQqchat />
|
||||
</VbenIconButton>
|
||||
<VbenIconButton class="mb-3">
|
||||
<VbenIconButton
|
||||
:tooltip="$t('authentication.githubLogin')"
|
||||
tooltip-side="top"
|
||||
class="mb-3"
|
||||
>
|
||||
<MdiGithub />
|
||||
</VbenIconButton>
|
||||
<VbenIconButton class="mb-3">
|
||||
<VbenIconButton
|
||||
:tooltip="$t('authentication.googleLogin')"
|
||||
tooltip-side="top"
|
||||
class="mb-3"
|
||||
>
|
||||
<MdiGoogle />
|
||||
</VbenIconButton>
|
||||
<DingdingLogin
|
||||
v-if="dingdingAuthConfig"
|
||||
:corp-id="dingdingAuthConfig.corpId"
|
||||
:client-id="dingdingAuthConfig.clientId"
|
||||
class="mb-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -15,9 +15,22 @@ export function useAppConfig(
|
||||
? window._VBEN_ADMIN_PRO_APP_CONF_
|
||||
: (env as VbenAdminProAppConfigRaw);
|
||||
|
||||
const { VITE_GLOB_API_URL } = config;
|
||||
const {
|
||||
VITE_GLOB_API_URL,
|
||||
VITE_GLOB_AUTH_DINGDING_CORP_ID,
|
||||
VITE_GLOB_AUTH_DINGDING_CLIENT_ID,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
const applicationConfig: ApplicationConfig = {
|
||||
apiURL: VITE_GLOB_API_URL,
|
||||
auth: {},
|
||||
};
|
||||
if (VITE_GLOB_AUTH_DINGDING_CORP_ID && VITE_GLOB_AUTH_DINGDING_CLIENT_ID) {
|
||||
applicationConfig.auth.dingding = {
|
||||
clientId: VITE_GLOB_AUTH_DINGDING_CLIENT_ID,
|
||||
corpId: VITE_GLOB_AUTH_DINGDING_CORP_ID,
|
||||
};
|
||||
}
|
||||
|
||||
return applicationConfig;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user