Skip to content

Commit 3dc1b26

Browse files
author
hubert
committed
feat: add auth type and cache clear settings
1 parent 2a4d53a commit 3dc1b26

File tree

18 files changed

+308
-46
lines changed

18 files changed

+308
-46
lines changed

clients/vue-web/apollo.config.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module.exports = {
22
client: {
3-
identity_service: {
4-
name: 'identity',
5-
url: 'http://localhost:5001/graphql',
6-
},
7-
bff_service: {
3+
service: {
84
name: 'bff',
9-
url: 'http://localhost:5003/graphql',
5+
url: 'http://localhost:5002/graphql',
106
},
7+
// identity_service: {
8+
// name: 'identity',
9+
// url: 'http://localhost:5001/graphql',
10+
// },
1111
includes: ['./src/**/*.ts'],
1212
},
1313
};

clients/vue-web/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"lint": "vue-cli-service lint"
1313
},
1414
"dependencies": {
15-
"@ace-fetch/graphql-vue": "^0.5.4",
16-
"@ace-fetch/vue": "^0.5.0",
15+
"@ace-fetch/graphql-vue": "^0.9.0",
16+
"@ace-fetch/vue": "^0.9.0",
1717
"@ace-pomelo/shared": "workspace:^",
1818
"@ace-pomelo/theme": "workspace:^",
1919
"@ace-util/core": "^0.5.0",

clients/vue-web/src/admin/configs/menu.config.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AuthType } from '@/auth';
1+
import { AuthType } from '@/types';
22
import IconDashboard from '@admin/assets/icons/dashboard.svg?inline';
33
import IconPictures from '@admin/assets/icons/pictures.svg?inline';
44
import IconCagetory from '@admin/assets/icons/category.svg?inline';
@@ -153,7 +153,7 @@ export const getDefaultMenus = (type?: AuthType): MenuConfig[] => [
153153
key: 'access_control',
154154
title: (i18nRender) => i18nRender('menu.access_control', '访问控制'),
155155
path: '/clients',
156-
icon: IconSettings,
156+
icon: 'IconSettings',
157157
position: 'top',
158158
display: type !== AuthType.Oidc ? false : void 0,
159159
children: [
@@ -337,6 +337,13 @@ export const getDefaultMenus = (type?: AuthType): MenuConfig[] => [
337337
icon: IconSettings,
338338
position: 'top',
339339
children: [
340+
{
341+
key: 'auth-type',
342+
title: (i18nRender) => i18nRender('menu.auth_type', '认证方式'),
343+
path: '/settings/auth-type',
344+
icon: 'safety',
345+
position: 'side',
346+
},
340347
{
341348
key: 'submodules-root',
342349
title: (i18nRender) => i18nRender('menu.submodule.root', '模块'),
@@ -393,6 +400,13 @@ export const getDefaultMenus = (type?: AuthType): MenuConfig[] => [
393400
},
394401
],
395402
},
403+
{
404+
key: 'cache-clear',
405+
title: (i18nRender) => i18nRender('menu.cache_clear', '清除缓存'),
406+
path: '/settings/cache-clear',
407+
icon: 'sync',
408+
position: 'side',
409+
},
396410
],
397411
},
398412
],

clients/vue-web/src/admin/layouts/default.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ import { useUserManager, usePubSubMessage, useI18n, useOptions } from '@/composa
2525
import { useAppMixin, useDeviceMixin, useLocationMixin } from '@/mixins';
2626
import { RouterView } from '@/layouts/components';
2727
import { loadingRef } from '@/shared';
28+
import { AuthTypeOptionName } from '@/constants';
2829
import IconDarkTheme from '@admin/assets/icons/dark-theme.svg?inline';
2930
import IconLightTheme from '@admin/assets/icons/light-theme.svg?inline';
3031
import { getDefaultMenus } from '../configs/menu.config';
3132
import classes from './default.module.less';
3233

3334
// Types
34-
import type { AuthType } from '@/auth';
35+
import type { AuthType } from '@/types';
3536

3637
export default defineComponent({
3738
name: 'DefaultLayout',
@@ -40,7 +41,7 @@ export default defineComponent({
4041
const route = useRoute();
4142
const i18n = useI18n();
4243
const homeUrl = useOptions(OptionPresetKeys.Home);
43-
const authType = useOptions<AuthType>('auth_type');
44+
const authType = useOptions<AuthType>(AuthTypeOptionName);
4445
const appMixin = useAppMixin();
4546
const deviceMixin = useDeviceMixin();
4647
const locationMixin = useLocationMixin();

clients/vue-web/src/admin/main.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import Vue, { type ComponentOptions } from 'vue';
66
import { type Route, type NavigationGuardNext as Next } from 'vue-router';
77
import VueCompositionApi from '@vue/composition-api';
88
import ResourceManagerVuePlugin from '@vue-async/resource-manager';
9-
import { Authoriztion, AuthType } from '@/auth';
9+
import { Authoriztion } from '@/auth';
1010
import { Modal } from '@/components';
1111
import { apiFetch } from '@/fetch';
1212
import { graphqlFetch } from '@/fetch/graphql';
1313
import { i18n } from '@/i18n';
1414
import { pinia } from '@/store';
15+
import { AuthTypeOptionName } from '@/constants';
16+
import { AuthType } from '@/types';
1517
import * as plugins from '@/plugins';
1618

1719
// Local
@@ -90,7 +92,9 @@ function authMiddleware(this: Vue, to: Route, from: Route, next: Next) {
9092
const userManager = this.$userManager;
9193

9294
if (to.name === 'signout') {
93-
userManager.signout();
95+
userManager.signout({
96+
redirect_uri: `${window.location.origin}${router.options.base ?? '/'}`.substring(0, -1),
97+
});
9498
} else if (to.meta?.anonymous === true) {
9599
next();
96100
} else {
@@ -121,7 +125,7 @@ createApp().then(({ app, router }) => {
121125
const _app = new Vue(app);
122126

123127
// Set auth type
124-
const authType = _app.$config.auth_type as AuthType;
128+
const authType = _app.$config[AuthTypeOptionName] as AuthType;
125129
authType && Object.values(AuthType).includes(authType) && Authoriztion.setType(authType);
126130

127131
router.beforeEach(authMiddleware.bind(_app));

clients/vue-web/src/admin/router/routes.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,22 @@ export const routes: Array<RouteConfig> = [
294294
},
295295
],
296296
},
297+
{
298+
path: '/settings',
299+
component: RouterChild,
300+
children: [
301+
{
302+
name: 'auth-type',
303+
path: 'auth-type',
304+
component: () => import(/* webpackChunkName: "settings" */ '../views/settings/auth-type'),
305+
},
306+
{
307+
name: 'cache-clear',
308+
path: 'cache-clear',
309+
component: () => import(/* webpackChunkName: "settings" */ '../views/settings/cache-clear'),
310+
},
311+
],
312+
},
297313
{
298314
name: 'signout',
299315
path: '/signout',
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { defineComponent, ref, onMounted } from '@vue/composition-api';
2+
import { message, Card, Checkbox } from 'ant-design-vue';
3+
import { useUserManager } from '@/composables';
4+
import { OptionAutoload, useBasicApi } from '@/fetch/apis/basic';
5+
import { AuthType } from '@/types';
6+
import { AuthTypeOptionName } from '@/constants';
7+
8+
export default defineComponent({
9+
name: 'AuthType',
10+
setup() {
11+
const userManager = useUserManager();
12+
const basicApi = useBasicApi();
13+
const optionId = ref<string>();
14+
const authType = ref<AuthType>();
15+
const loading = ref(false);
16+
17+
const loadAuthType = async () => {
18+
loading.value = true;
19+
try {
20+
const { option } = await basicApi.getOptionByName({
21+
variables: {
22+
name: AuthTypeOptionName,
23+
},
24+
});
25+
if (option) {
26+
optionId.value = option.id;
27+
authType.value = option.value as AuthType;
28+
}
29+
} catch {
30+
message.error('加载身份验证类型失败');
31+
} finally {
32+
loading.value = false;
33+
}
34+
};
35+
36+
const handleAuthTypeSave = async (type: AuthType) => {
37+
authType.value = type;
38+
loading.value = true;
39+
try {
40+
if (optionId.value) {
41+
await basicApi.updateOption({
42+
variables: {
43+
id: optionId.value,
44+
model: {
45+
optionValue: authType.value,
46+
},
47+
},
48+
});
49+
} else {
50+
await basicApi.createOption({
51+
variables: {
52+
model: {
53+
optionName: AuthTypeOptionName,
54+
optionValue: type,
55+
autoload: OptionAutoload.Yes,
56+
},
57+
},
58+
});
59+
}
60+
await userManager.removeUser();
61+
await message.success('保存身份验证类型成功, 请重新登录');
62+
window.location.reload();
63+
} catch (error) {
64+
message.error('保存身份验证类型失败');
65+
} finally {
66+
loading.value = false;
67+
}
68+
};
69+
70+
onMounted(() => {
71+
loadAuthType();
72+
});
73+
74+
return () => (
75+
<Card bordered={false}>
76+
<h2>认证设置</h2>
77+
<p class="text--secondary mb-5">
78+
请通过 apisix 设置 Identity Service 鉴权设置,详细配置请查看
79+
<a href="https://apisix.apache.org/zh/docs/apisix/plugins/openid-connect/" target="_blank" class="ml-1">
80+
配置说明
81+
</a>
82+
83+
</p>
84+
<Checkbox
85+
checked={authType.value === AuthType.Oidc}
86+
disabled={loading.value}
87+
onChange={(e) => handleAuthTypeSave(e.target.checked ? AuthType.Oidc : AuthType.Local)}
88+
>
89+
开启OpenID Connect协议进行身份验证
90+
</Checkbox>
91+
</Card>
92+
);
93+
},
94+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineComponent, ref } from '@vue/composition-api';
2+
import { Card, Button, message } from 'ant-design-vue';
3+
import { useBasicApi } from '@/fetch/apis/basic';
4+
5+
export default defineComponent({
6+
setup() {
7+
const loading = ref(false);
8+
const basicApi = useBasicApi();
9+
10+
const handleClearCache = async () => {
11+
try {
12+
loading.value = true;
13+
await basicApi.clearOptionCache();
14+
message.success('缓存已清除');
15+
} catch (error) {
16+
message.error('清除缓存失败,请稍后重试');
17+
} finally {
18+
loading.value = false;
19+
}
20+
};
21+
22+
return () => (
23+
<Card>
24+
<h2>系统缓存</h2>
25+
<p class="text--secondary mb-5">
26+
清除系统缓存可以确保获取最新的配置数据。当您修改了系统配置但未立即生效时,可尝试清除缓存。
27+
</p>
28+
<Button type="primary" loading={loading.value} icon="sync" onClick={handleClearCache}>
29+
清除缓存
30+
</Button>
31+
</Card>
32+
);
33+
},
34+
});

clients/vue-web/src/auth/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getEnv } from '@ace-util/core';
2+
import { AuthType } from '@/types';
23
import { LocalUserManagerCreator } from './local';
34
import { OidcUserManagerCreator } from './openid-connect';
45

@@ -7,11 +8,6 @@ import type _Vue from 'vue';
78
import type { UserManager as OidcUserManagerType, UserManagerSettings as OidcUserManngerSetions } from 'oidc-client-ts';
89
import type { UserManager } from './user-manager';
910

10-
export enum AuthType {
11-
Oidc = 'oidc',
12-
Local = 'local',
13-
}
14-
1511
export class Authoriztion {
1612
private static instance: Authoriztion;
1713
type: AuthType;

clients/vue-web/src/auth/local/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ export class LocalUserManagerCreator extends UserManager {
111111
return Promise.resolve(null);
112112
}
113113

114+
removeUser(): Promise<void> {
115+
removeToken();
116+
return Promise.resolve();
117+
}
118+
114119
modifyPassword(): Promise<void> {
115120
return new Promise<void>((resolve) => {
116121
setTimeout(() => {

0 commit comments

Comments
 (0)