feat(系统管理): 新增钉钉登陆

This commit is contained in:
guoyuqi 2024-06-04 20:12:40 +08:00 committed by Craftsman
parent 74c44e8459
commit c2df6e04e2
6 changed files with 81 additions and 16 deletions

View File

@ -12,7 +12,9 @@ public class FilterChainUtils {
filterChainDefinitionMap.put("/ldap/login", "anon"); filterChainDefinitionMap.put("/ldap/login", "anon");
filterChainDefinitionMap.put("/authentication/get-list", "anon"); filterChainDefinitionMap.put("/authentication/get-list", "anon");
filterChainDefinitionMap.put("/we_com/info", "anon"); filterChainDefinitionMap.put("/we_com/info", "anon");
filterChainDefinitionMap.put("/ding_talk/info", "anon");
filterChainDefinitionMap.put("/sso/callback/we_com", "anon"); filterChainDefinitionMap.put("/sso/callback/we_com", "anon");
filterChainDefinitionMap.put("/auth", "anon");
filterChainDefinitionMap.put("/setting/get/platform/param", "anon"); filterChainDefinitionMap.put("/setting/get/platform/param", "anon");
filterChainDefinitionMap.put("/signout", "anon"); filterChainDefinitionMap.put("/signout", "anon");
filterChainDefinitionMap.put("/is-login", "anon"); filterChainDefinitionMap.put("/is-login", "anon");

View File

@ -7,8 +7,10 @@ import {
DisableLocalConfigUrl, DisableLocalConfigUrl,
EnableAPIKEYUrl, EnableAPIKEYUrl,
EnableLocalConfigUrl, EnableLocalConfigUrl,
GeDingInfoUrl,
GetAPIKEYListUrl, GetAPIKEYListUrl,
getAuthenticationUrl, getAuthenticationUrl,
GetDingCallbackUrl,
GetInfoUrl, GetInfoUrl,
GetLocalConfigUrl, GetLocalConfigUrl,
GetMenuListUrl, GetMenuListUrl,
@ -46,7 +48,7 @@ import type {
UpdateLocalConfigParams, UpdateLocalConfigParams,
UpdatePswParams, UpdatePswParams,
} from '@/models/user'; } from '@/models/user';
import { WecomInfo } from '@/models/user'; import { DingInfo, WecomInfo } from '@/models/user';
import type { RouteRecordNormalized } from 'vue-router'; import type { RouteRecordNormalized } from 'vue-router';
@ -83,6 +85,16 @@ export function getWeComCallback(code: string) {
); );
} }
export function getDingInfo() {
return MSR.get<DingInfo>({ url: GeDingInfoUrl }, { ignoreCancelToken: true, errorMessageMode: 'none' });
}
export function getDingCallback(code: string) {
return MSR.get<LoginRes>(
{ url: GetDingCallbackUrl, params: { code } },
{ ignoreCancelToken: true, errorMessageMode: 'none' }
);
}
export function logout() { export function logout() {
return MSR.get<LoginRes>({ url: LogoutUrl }); return MSR.get<LoginRes>({ url: LogoutUrl });
} }

View File

@ -29,3 +29,5 @@ export const GetPlatformOrgOptionUrl = '/user/platform/switch-option'; // 个人
export const GetWeComInfoUrl = '/we_com/info'; // 获取企业微信登陆的配置信息 export const GetWeComInfoUrl = '/we_com/info'; // 获取企业微信登陆的配置信息
export const GetWeComCallbackUrl = '/sso/callback/we_com'; // 获取企业微信登陆的回调信息 export const GetWeComCallbackUrl = '/sso/callback/we_com'; // 获取企业微信登陆的回调信息
export const GetPlatformParamUrl = '/setting/get/platform/param'; export const GetPlatformParamUrl = '/setting/get/platform/param';
export const GeDingInfoUrl = '/ding_talk/info'; // 获取企业微信登陆的配置信息
export const GetDingCallbackUrl = '/auth'; // 获取企业微信登陆的回调信息

View File

@ -21,6 +21,13 @@ export interface WecomInfo {
callBack?: string; callBack?: string;
} }
// 企业微信对接信息
export interface DingInfo {
agentId?: string;
state?: string;
callBack?: string;
}
// 更新本地执行配置 // 更新本地执行配置
export interface UpdateLocalConfigParams { export interface UpdateLocalConfigParams {
id: string; id: string;

View File

@ -3,16 +3,32 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useRouter } from 'vue-router';
import { useScriptTag } from '@vueuse/core'; import { useScriptTag } from '@vueuse/core';
import { Message } from '@arco-design/web-vue';
import { getProjectInfo } from '@/api/modules/project-management/basicInfo';
import { getDingCallback, getDingInfo } from '@/api/modules/user';
import { useI18n } from '@/hooks/useI18n';
import { NO_PROJECT_ROUTE_NAME, NO_RESOURCE_ROUTE_NAME } from '@/router/constants';
import { useAppStore, useUserStore } from '@/store';
import useLicenseStore from '@/store/modules/setting/license';
import { setLoginExpires } from '@/utils/auth';
import { getFirstRouteNameByPermission, routerNameHasPermission } from '@/utils/permission';
const { t } = useI18n();
const userStore = useUserStore();
const appStore = useAppStore();
const licenseStore = useLicenseStore();
const router = useRouter();
const { load } = useScriptTag('https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js'); const { load } = useScriptTag('https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js');
const a = encodeURIComponent('https://s0my5tnf41e2.ngrok.xiaomiqiu123.top/');
const url = `https://login.dingtalk.com/oauth2/auth?redirect_uri=${a}&response_type=code&client_id=dinglsfxhodjquu4gq2x&scope=openid&state=dddd&prompt=consent`;
const initActive = async () => { const initActive = async () => {
const data = await getDingInfo();
await load(true); await load(true);
const url = encodeURIComponent(data.callBack ? data.callBack : '');
window.DTFrameLogin( window.DTFrameLogin(
{ {
id: 'ding-talk-qr', id: 'ding-talk-qr',
@ -20,17 +36,42 @@
height: 300, height: 300,
}, },
{ {
redirect_uri: a, redirect_uri: url,
client_id: 'dinglsfxhodjquu4gq2x', client_id: data.agentId ? data.agentId : '',
scope: 'openid', scope: 'openid',
response_type: 'code', response_type: 'code',
state: 'xxxxxxxxx', state: 'fit2cloud-ding-qr',
prompt: 'consent', prompt: 'consent',
}, },
(loginResult) => { async (loginResult) => {
const { redirectUrl, authCode, state } = loginResult; const { redirectUrl, authCode, state } = loginResult;
// const dingCallback = getDingCallback(authCode);
window.location.href = redirectUrl; userStore.qrCodeLogin(await dingCallback);
Message.success(t('login.form.login.success'));
const { redirect, ...othersQuery } = router.currentRoute.value.query;
const redirectHasPermission =
redirect &&
![NO_RESOURCE_ROUTE_NAME, NO_PROJECT_ROUTE_NAME].includes(redirect as string) &&
routerNameHasPermission(redirect as string, router.getRoutes());
const currentRouteName = getFirstRouteNameByPermission(router.getRoutes());
const [res] = await Promise.all([getProjectInfo(appStore.currentProjectId), licenseStore.getValidateLicense()]); // license license
if (!res || res.deleted) {
router.push({
name: NO_PROJECT_ROUTE_NAME,
});
}
if (res) {
appStore.setCurrentMenuConfig(res?.moduleIds || []);
}
setLoginExpires();
router.push({
name: redirectHasPermission ? (redirect as string) : currentRouteName,
query: {
...othersQuery,
orgId: appStore.currentOrgId,
pId: appStore.currentProjectId,
},
});
// 使code // 使code
console.log(authCode); console.log(authCode);
}, },

View File

@ -1,10 +1,10 @@
<template> <template>
<a-tabs v-model:active-key="activeName" class="tabPlatform" @change="handleClick"> <a-radio-group v-model:active-key="activeName" type="button" class="tabPlatform" @change="handleClick">
<a-tab-pane key="wecom" :title="t('project.messageManagement.WE_COM')" class="font-[16px]"></a-tab-pane> <a-radio value="wecom">{{ t('project.messageManagement.WE_COM') }}</a-radio>
<a-tab-pane key="dingtalk" :title="t('project.messageManagement.DING_TALK')" class="font-[16px]"></a-tab-pane> <a-radio value="dingtalk">{{ t('project.messageManagement.DING_TALK') }}</a-radio>
<!-- <a-tab-pane key="lark" :title="t('project.messageManagement.LARK')"></a-tab-pane> <!-- <a-tab-pane key="lark" :title="t('project.messageManagement.LARK')"></a-tab-pane>
<a-tab-pane key="larksuite" :title="t('project.messageManagement.LARK_SUITE')"></a-tab-pane>--> <a-tab-pane key="larksuite" :title="t('project.messageManagement.LARK_SUITE')"></a-tab-pane>-->
</a-tabs> </a-radio-group>
<div v-if="activeName === 'wecom'" class="login-qrcode"> <div v-if="activeName === 'wecom'" class="login-qrcode">
<div class="qrcode"> <div class="qrcode">
<wecom-qr v-if="activeName === 'wecom'" /> <wecom-qr v-if="activeName === 'wecom'" />
@ -56,7 +56,7 @@
} }
} }
}; };
function handleClick(val: string | number) { function handleClick(val: string | number | boolean) {
if (typeof val === 'string') { if (typeof val === 'string') {
activeName.value = val; activeName.value = val;
} }
@ -84,6 +84,7 @@
overflow: hidden; overflow: hidden;
border-radius: 8px; border-radius: 8px;
background: #ffffff; background: #ffffff;
flex-direction: column;
} }
.title { .title {
display: flex; display: flex;