From 804d14e29b4b2258592d9be49b678047916f3ee0 Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 14 Jan 2025 08:26:31 +0800 Subject: [PATCH 1/2] :recycle: feat: refactoring oauth api. --- apps/vben5/apps/app-antd/.env.development | 1 + .../app-antd/src/adapter/request/index.ts | 12 +++ apps/vben5/apps/app-antd/src/store/auth.ts | 8 +- .../packages/@abp/account/src/api/index.ts | 4 +- .../packages/@abp/account/src/api/token.ts | 46 ---------- .../@abp/account/src/api/useTokenApi.ts | 84 +++++++++++++++++++ .../@abp/account/src/api/useUserInfoApi.ts | 29 +++++++ .../packages/@abp/account/src/api/user.ts | 18 ---- .../packages/@abp/account/src/types/token.ts | 5 ++ .../@abp/request/src/hooks/useRequest.ts | 16 +--- apps/vben5/packages/types/global.d.ts | 4 + 11 files changed, 143 insertions(+), 84 deletions(-) delete mode 100644 apps/vben5/packages/@abp/account/src/api/token.ts create mode 100644 apps/vben5/packages/@abp/account/src/api/useTokenApi.ts create mode 100644 apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts delete mode 100644 apps/vben5/packages/@abp/account/src/api/user.ts diff --git a/apps/vben5/apps/app-antd/.env.development b/apps/vben5/apps/app-antd/.env.development index 0692ed288..7327d9a14 100644 --- a/apps/vben5/apps/app-antd/.env.development +++ b/apps/vben5/apps/app-antd/.env.development @@ -15,5 +15,6 @@ VITE_DEVTOOLS=false # 是否注入全局loading VITE_INJECT_APP_LOADING=true +VITE_GLOB_AUDIENCE="openid email address phone profile offline_access lingyun-abp-application" VITE_GLOB_CLIENT_ID=vue-admin-client VITE_GLOB_CLIENT_SECRET=1q2w3e* diff --git a/apps/vben5/apps/app-antd/src/adapter/request/index.ts b/apps/vben5/apps/app-antd/src/adapter/request/index.ts index cb10c655d..f75d2aea1 100644 --- a/apps/vben5/apps/app-antd/src/adapter/request/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/request/index.ts @@ -5,12 +5,14 @@ import { } from '@vben/request'; import { useAccessStore } from '@vben/stores'; +import { useTokenApi } from '@abp/account'; import { requestClient } from '@abp/request'; import { message } from 'ant-design-vue'; import { useAuthStore } from '#/store'; export function initRequestClient() { + const { refreshTokenApi } = useTokenApi(); /** * 重新认证逻辑 */ @@ -33,6 +35,16 @@ export function initRequestClient() { * 刷新token逻辑 */ async function doRefreshToken() { + const accessStore = useAccessStore(); + if (accessStore.refreshToken) { + const { accessToken, tokenType, refreshToken } = await refreshTokenApi({ + refreshToken: accessStore.refreshToken, + }); + const newToken = `${tokenType} ${accessToken}`; + accessStore.setAccessToken(newToken); + accessStore.setRefreshToken(refreshToken); + return newToken; + } return ''; } diff --git a/apps/vben5/apps/app-antd/src/store/auth.ts b/apps/vben5/apps/app-antd/src/store/auth.ts index 4061a971f..6ff7c5e47 100644 --- a/apps/vben5/apps/app-antd/src/store/auth.ts +++ b/apps/vben5/apps/app-antd/src/store/auth.ts @@ -6,7 +6,7 @@ import { useRouter } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; -import { tokenApi, userInfoApi } from '@abp/account'; +import { useTokenApi, useUserInfoApi } from '@abp/account'; import { useAbpStore } from '@abp/core'; import { notification } from 'ant-design-vue'; import { defineStore } from 'pinia'; @@ -15,6 +15,8 @@ import { getConfigApi } from '#/api/core/abp'; import { $t } from '#/locales'; export const useAuthStore = defineStore('auth', () => { + const { loginApi } = useTokenApi(); + const { getUserInfoApi } = useUserInfoApi(); const accessStore = useAccessStore(); const userStore = useUserStore(); const abpStore = useAbpStore(); @@ -35,7 +37,7 @@ export const useAuthStore = defineStore('auth', () => { let userInfo: null | UserInfo = null; try { loginLoading.value = true; - const loginResult = await tokenApi.loginApi(params as any); + const loginResult = await loginApi(params as any); const { accessToken, tokenType, refreshToken } = loginResult; // 如果成功获取到 accessToken if (accessToken) { @@ -93,7 +95,7 @@ export const useAuthStore = defineStore('auth', () => { async function fetchUserInfo() { let userInfo: ({ [key: string]: any } & UserInfo) | null = null; - const userInfoRes = await userInfoApi.getUserInfoApi(); + const userInfoRes = await getUserInfoApi(); const abpConfig = await getConfigApi(); userInfo = { userId: userInfoRes.sub, diff --git a/apps/vben5/packages/@abp/account/src/api/index.ts b/apps/vben5/packages/@abp/account/src/api/index.ts index e63b0f9b9..a082efc18 100644 --- a/apps/vben5/packages/@abp/account/src/api/index.ts +++ b/apps/vben5/packages/@abp/account/src/api/index.ts @@ -1,2 +1,2 @@ -export * as tokenApi from './token'; -export * as userInfoApi from './user'; +export { useTokenApi } from './useTokenApi'; +export { useUserInfoApi } from './useUserInfoApi'; diff --git a/apps/vben5/packages/@abp/account/src/api/token.ts b/apps/vben5/packages/@abp/account/src/api/token.ts deleted file mode 100644 index 212cc707c..000000000 --- a/apps/vben5/packages/@abp/account/src/api/token.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { - OAuthTokenResult, - PasswordTokenRequestModel, - TokenResult, -} from '../types'; - -import { useAppConfig } from '@vben/hooks'; - -import { requestClient } from '@abp/request'; - -/** - * 用户登录 - * @param request 参数 - * @returns 用户token - */ -export async function loginApi( - request: PasswordTokenRequestModel, -): Promise { - const { clientId, clientSecret } = useAppConfig( - import.meta.env, - import.meta.env.PROD, - ); - const result = await requestClient.post( - '/connect/token', - { - client_id: clientId, - client_secret: clientSecret, - grant_type: 'password', - password: request.password, - scope: - 'openid email address phone profile offline_access lingyun-abp-application', - username: request.username, - }, - { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }, - ); - return { - accessToken: result.access_token, - expiresIn: result.expires_in, - refreshToken: result.refresh_token, - tokenType: result.token_type, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts b/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts new file mode 100644 index 000000000..eeec1df4c --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/api/useTokenApi.ts @@ -0,0 +1,84 @@ +import type { + OAuthTokenRefreshModel, + OAuthTokenResult, + PasswordTokenRequestModel, + TokenResult, +} from '../types'; + +import { useAppConfig } from '@vben/hooks'; + +import { useRequest } from '@abp/request'; + +export function useTokenApi() { + const { cancel, request } = useRequest(); + /** + * 用户登录 + * @param input 参数 + * @returns 用户token + */ + async function loginApi( + input: PasswordTokenRequestModel, + ): Promise { + const { audience, clientId, clientSecret } = useAppConfig( + import.meta.env, + import.meta.env.PROD, + ); + const result = await request('/connect/token', { + data: { + client_id: clientId, + client_secret: clientSecret, + grant_type: 'password', + password: input.password, + scope: audience, + username: input.username, + }, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }); + return { + accessToken: result.access_token, + expiresIn: result.expires_in, + refreshToken: result.refresh_token, + tokenType: result.token_type, + }; + } + + /** + * 刷新令牌 + * @param input 参数 + * @returns 用户token + */ + async function refreshTokenApi(input: OAuthTokenRefreshModel) { + const { audience, clientId, clientSecret } = useAppConfig( + import.meta.env, + import.meta.env.PROD, + ); + const result = await request('/connect/token', { + data: { + client_id: clientId, + client_secret: clientSecret, + grant_type: 'refresh_token', + refresh_token: input.refreshToken, + scope: audience, + }, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }); + return { + accessToken: result.access_token, + expiresIn: result.expires_in, + refreshToken: result.refresh_token, + tokenType: result.token_type, + }; + } + + return { + cancel, + loginApi, + refreshTokenApi, + }; +} diff --git a/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts b/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts new file mode 100644 index 000000000..aa7c5adb3 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/api/useUserInfoApi.ts @@ -0,0 +1,29 @@ +import type { OAuthUserInfo, UserInfo } from '../types/user'; + +import { useRequest } from '@abp/request'; + +export function useUserInfoApi() { + const { cancel, request } = useRequest(); + + /** + * 获取用户信息 + */ + async function getUserInfoApi(): Promise { + const result = await request('/connect/userinfo', { + method: 'GET', + }); + return { + ...result, + emailVerified: result.email_verified, + givenName: result.given_name, + phoneNumberVerified: result.phone_number_verified, + preferredUsername: result.preferred_username, + uniqueName: result.unique_name, + }; + } + + return { + cancel, + getUserInfoApi, + }; +} diff --git a/apps/vben5/packages/@abp/account/src/api/user.ts b/apps/vben5/packages/@abp/account/src/api/user.ts deleted file mode 100644 index 87611be89..000000000 --- a/apps/vben5/packages/@abp/account/src/api/user.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { OAuthUserInfo, UserInfo } from '../types/user'; - -import { requestClient } from '@abp/request'; - -/** - * 获取用户信息 - */ -export async function getUserInfoApi(): Promise { - const result = await requestClient.get('/connect/userinfo'); - return { - ...result, - emailVerified: result.email_verified, - givenName: result.given_name, - phoneNumberVerified: result.phone_number_verified, - preferredUsername: result.preferred_username, - uniqueName: result.unique_name, - }; -} diff --git a/apps/vben5/packages/@abp/account/src/types/token.ts b/apps/vben5/packages/@abp/account/src/types/token.ts index b8bb274d3..e3436012c 100644 --- a/apps/vben5/packages/@abp/account/src/types/token.ts +++ b/apps/vben5/packages/@abp/account/src/types/token.ts @@ -32,6 +32,10 @@ interface TokenResult { /** 令牌类型 */ tokenType: string; } +interface OAuthTokenRefreshModel { + /** 刷新令牌 */ + refreshToken: string; +} /** oauth标准令牌返回结构 */ interface OAuthTokenResult { /** 访问令牌 */ @@ -45,6 +49,7 @@ interface OAuthTokenResult { } export type { + OAuthTokenRefreshModel, OAuthTokenResult, PasswordTokenRequest, PasswordTokenRequestModel, diff --git a/apps/vben5/packages/@abp/request/src/hooks/useRequest.ts b/apps/vben5/packages/@abp/request/src/hooks/useRequest.ts index 723e05352..a72170a95 100644 --- a/apps/vben5/packages/@abp/request/src/hooks/useRequest.ts +++ b/apps/vben5/packages/@abp/request/src/hooks/useRequest.ts @@ -1,7 +1,5 @@ import type { AxiosRequestConfig } from 'axios'; -import { onUnmounted } from 'vue'; - import { requestClient } from '@abp/request'; type HttpMethod = @@ -20,12 +18,7 @@ interface RequestConfig extends AxiosRequestConfig { method: HttpMethod; } -interface RequestLifeCycle { - /** 是否自动销毁令牌 */ - autoDestroy?: boolean; -} - -export function useRequest(options?: RequestLifeCycle) { +export function useRequest() { const controllers = new Set(); function request(url: string, config: RequestConfig): Promise { @@ -46,13 +39,6 @@ export function useRequest(options?: RequestLifeCycle) { controllers.clear(); } - onUnmounted(() => { - if (options?.autoDestroy === false) { - return; - } - cancel('The Component has Unmounted!'); - }); - return { cancel, request, diff --git a/apps/vben5/packages/types/global.d.ts b/apps/vben5/packages/types/global.d.ts index 11b3b3ced..599c76420 100644 --- a/apps/vben5/packages/types/global.d.ts +++ b/apps/vben5/packages/types/global.d.ts @@ -11,10 +11,14 @@ export interface VbenAdminProAppConfigRaw { VITE_GLOB_API_URL: string; VITE_GLOB_CLIENT_ID: string; VITE_GLOB_CLIENT_SECRET: string; + VITE_GLOB_AUTHORITY: string; + VITE_GLOB_AUDIENCE?: string; } export interface ApplicationConfig { apiURL: string; + authority: string; + audience?: string; clientId: string; clientSecret: string; } From fc9d76975e584f3004b800e891ab99b47a8d8cf7 Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 17 Jan 2025 08:09:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?:art:=20refactor:=20=E4=BD=BF=E7=94=A8=20us?= =?UTF-8?q?eRequest=20=E9=87=8D=E5=86=99api=E6=8E=A5=E5=8F=A3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/vben5/apps/app-antd/src/api/core/abp.ts | 36 ----- .../vben5/apps/app-antd/src/api/core/index.ts | 2 +- .../app-antd/src/api/core/useAbpConfigApi.ts | 48 +++++++ apps/vben5/apps/app-antd/src/store/auth.ts | 3 +- .../@abp/auditing/src/api/audit-logs.ts | 36 ----- .../@abp/auditing/src/api/entity-changes.ts | 23 ---- .../packages/@abp/auditing/src/api/index.ts | 4 +- .../@abp/auditing/src/api/useAuditLogsApi.ts | 65 +++++++++ .../auditing/src/api/useEntityChangesApi.ts | 33 +++++ .../components/audit-logs/AuditLogDrawer.vue | 7 +- .../components/audit-logs/AuditLogTable.vue | 45 ++++++- .../entity-changes/EntityChangeDrawer.vue | 17 ++- .../@abp/auditing/src/types/audit-logs.ts | 11 +- .../identity/src/api/useSecurityLogsApi.ts | 13 ++ .../components/claim-types/ClaimTypeModal.vue | 22 +++- .../components/claim-types/ClaimTypeTable.vue | 97 +++++++++----- .../src/components/roles/RoleClaimModal.vue | 9 +- .../src/components/roles/RoleModal.vue | 18 ++- .../src/components/roles/RoleTable.vue | 124 ++++++++---------- .../security-logs/SecurityLogTable.vue | 48 ++++++- .../src/components/users/UserClaimModal.vue | 8 ++ .../src/components/users/UserLockModal.vue | 25 +++- .../components/users/UserPasswordModal.vue | 12 +- .../src/components/users/UserTable.vue | 1 + .../@abp/identity/src/types/security-logs.ts | 10 +- .../@abp/openiddict/src/api/applications.ts | 74 ----------- .../@abp/openiddict/src/api/authorizations.ts | 43 ------ .../packages/@abp/openiddict/src/api/index.ts | 8 +- .../@abp/openiddict/src/api/openid.ts | 13 -- .../@abp/openiddict/src/api/scopes.ts | 72 ---------- .../@abp/openiddict/src/api/tokens.ts | 41 ------ .../openiddict/src/api/useApplicationsApi.ts | 95 ++++++++++++++ .../src/api/useAuthorizationsApi.ts | 60 +++++++++ .../@abp/openiddict/src/api/useOpenIdApi.ts | 22 ++++ .../@abp/openiddict/src/api/useScopesApi.ts | 89 +++++++++++++ .../@abp/openiddict/src/api/useTokensApi.ts | 57 ++++++++ .../applications/ApplicationModal.vue | 9 +- .../applications/ApplicationSecretModal.vue | 12 +- .../applications/ApplicationTable.vue | 3 +- .../authorizations/AuthorizationModal.vue | 9 +- .../authorizations/AuthorizationTable.vue | 6 +- .../src/components/scopes/ScopeModal.vue | 9 +- .../src/components/scopes/ScopeTable.vue | 5 +- .../src/components/tokens/TokenModal.vue | 9 +- .../src/components/tokens/TokenTable.vue | 6 +- .../@abp/permissions/src/api/definitions.ts | 75 ----------- .../@abp/permissions/src/api/groups.ts | 77 ----------- .../@abp/permissions/src/api/index.ts | 3 + .../@abp/permissions/src/api/permissions.ts | 37 ------ .../src/api/usePermissionDefinitionsApi.ts | 100 ++++++++++++++ .../api/usePermissionGroupDefinitionsApi.ts | 100 ++++++++++++++ .../permissions/src/api/usePermissionsApi.ts | 48 +++++++ .../groups/PermissionGroupDefinitionModal.vue | 7 +- .../groups/PermissionGroupDefinitionTable.vue | 3 +- .../permissions/PermissionDefinitionModal.vue | 16 ++- .../permissions/PermissionDefinitionTable.vue | 10 +- .../permissions/PermissionModal.vue | 6 +- .../packages/@abp/permissions/src/index.ts | 1 + .../components/properties/PropertyTable.vue | 1 + 59 files changed, 1152 insertions(+), 691 deletions(-) delete mode 100644 apps/vben5/apps/app-antd/src/api/core/abp.ts create mode 100644 apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts delete mode 100644 apps/vben5/packages/@abp/auditing/src/api/audit-logs.ts delete mode 100644 apps/vben5/packages/@abp/auditing/src/api/entity-changes.ts create mode 100644 apps/vben5/packages/@abp/auditing/src/api/useAuditLogsApi.ts create mode 100644 apps/vben5/packages/@abp/auditing/src/api/useEntityChangesApi.ts delete mode 100644 apps/vben5/packages/@abp/openiddict/src/api/applications.ts delete mode 100644 apps/vben5/packages/@abp/openiddict/src/api/authorizations.ts delete mode 100644 apps/vben5/packages/@abp/openiddict/src/api/openid.ts delete mode 100644 apps/vben5/packages/@abp/openiddict/src/api/scopes.ts delete mode 100644 apps/vben5/packages/@abp/openiddict/src/api/tokens.ts create mode 100644 apps/vben5/packages/@abp/openiddict/src/api/useApplicationsApi.ts create mode 100644 apps/vben5/packages/@abp/openiddict/src/api/useAuthorizationsApi.ts create mode 100644 apps/vben5/packages/@abp/openiddict/src/api/useOpenIdApi.ts create mode 100644 apps/vben5/packages/@abp/openiddict/src/api/useScopesApi.ts create mode 100644 apps/vben5/packages/@abp/openiddict/src/api/useTokensApi.ts delete mode 100644 apps/vben5/packages/@abp/permissions/src/api/definitions.ts delete mode 100644 apps/vben5/packages/@abp/permissions/src/api/groups.ts create mode 100644 apps/vben5/packages/@abp/permissions/src/api/index.ts delete mode 100644 apps/vben5/packages/@abp/permissions/src/api/permissions.ts create mode 100644 apps/vben5/packages/@abp/permissions/src/api/usePermissionDefinitionsApi.ts create mode 100644 apps/vben5/packages/@abp/permissions/src/api/usePermissionGroupDefinitionsApi.ts create mode 100644 apps/vben5/packages/@abp/permissions/src/api/usePermissionsApi.ts diff --git a/apps/vben5/apps/app-antd/src/api/core/abp.ts b/apps/vben5/apps/app-antd/src/api/core/abp.ts deleted file mode 100644 index e5fba68f5..000000000 --- a/apps/vben5/apps/app-antd/src/api/core/abp.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { - ApplicationConfigurationDto, - ApplicationLocalizationDto, -} from '@abp/core'; - -import { requestClient } from '@abp/request'; - -/** - * 获取应用程序配置信息 - */ -export function getConfigApi(options?: { - includeLocalizationResources?: boolean; -}): Promise { - return requestClient.get( - '/api/abp/application-configuration', - { - params: options, - }, - ); -} - -/** - * 获取应用程序语言 - * @returns 本地化配置 - */ -export function getLocalizationApi(options: { - cultureName: string; - onlyDynamics?: boolean; -}): Promise { - return requestClient.get( - '/api/abp/application-localization', - { - params: options, - }, - ); -} diff --git a/apps/vben5/apps/app-antd/src/api/core/index.ts b/apps/vben5/apps/app-antd/src/api/core/index.ts index 5fe53ee1e..93c65bd62 100644 --- a/apps/vben5/apps/app-antd/src/api/core/index.ts +++ b/apps/vben5/apps/app-antd/src/api/core/index.ts @@ -1,2 +1,2 @@ -export * from './abp'; export * from './menu'; +export { useAbpConfigApi } from './useAbpConfigApi'; diff --git a/apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts b/apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts new file mode 100644 index 000000000..39715ab18 --- /dev/null +++ b/apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts @@ -0,0 +1,48 @@ +import type { + ApplicationConfigurationDto, + ApplicationLocalizationDto, +} from '@abp/core'; + +import { useRequest } from '@abp/request'; + +export function useAbpConfigApi() { + const { cancel, request } = useRequest(); + + /** + * 获取应用程序配置信息 + */ + function getConfigApi(options?: { + includeLocalizationResources?: boolean; + }): Promise { + return request( + '/api/abp/application-configuration', + { + params: options, + method: 'GET', + }, + ); + } + + /** + * 获取应用程序语言 + * @returns 本地化配置 + */ + function getLocalizationApi(options: { + cultureName: string; + onlyDynamics?: boolean; + }): Promise { + return request( + '/api/abp/application-localization', + { + params: options, + method: 'GET', + }, + ); + } + + return { + cancel, + getConfigApi, + getLocalizationApi, + }; +} diff --git a/apps/vben5/apps/app-antd/src/store/auth.ts b/apps/vben5/apps/app-antd/src/store/auth.ts index 6ff7c5e47..1953c88f0 100644 --- a/apps/vben5/apps/app-antd/src/store/auth.ts +++ b/apps/vben5/apps/app-antd/src/store/auth.ts @@ -11,12 +11,13 @@ import { useAbpStore } from '@abp/core'; import { notification } from 'ant-design-vue'; import { defineStore } from 'pinia'; -import { getConfigApi } from '#/api/core/abp'; +import { useAbpConfigApi } from '#/api/core/useAbpConfigApi'; import { $t } from '#/locales'; export const useAuthStore = defineStore('auth', () => { const { loginApi } = useTokenApi(); const { getUserInfoApi } = useUserInfoApi(); + const { getConfigApi } = useAbpConfigApi(); const accessStore = useAccessStore(); const userStore = useUserStore(); const abpStore = useAbpStore(); diff --git a/apps/vben5/packages/@abp/auditing/src/api/audit-logs.ts b/apps/vben5/packages/@abp/auditing/src/api/audit-logs.ts deleted file mode 100644 index d400b91a1..000000000 --- a/apps/vben5/packages/@abp/auditing/src/api/audit-logs.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { PagedResultDto } from '@abp/core'; - -import type { AuditLogDto, AuditLogGetListInput } from '../types/audit-logs'; - -import { requestClient } from '@abp/request'; - -/** - * 获取审计日志 - * @param id 日志id - */ -export function getApi(id: string): Promise { - return requestClient.get(`/api/auditing/audit-log/${id}`); -} - -/** - * 获取审计日志分页列表 - * @param input 参数 - */ -export function getPagedListApi( - input: AuditLogGetListInput, -): Promise> { - return requestClient.get>( - '/api/auditing/audit-log', - { - params: input, - }, - ); -} - -/** - * 删除审计日志 - * @param id 日志id - */ -export function deleteApi(id: string): Promise { - return requestClient.delete(`/api/auditing/audit-log/${id}`); -} diff --git a/apps/vben5/packages/@abp/auditing/src/api/entity-changes.ts b/apps/vben5/packages/@abp/auditing/src/api/entity-changes.ts deleted file mode 100644 index b80499d61..000000000 --- a/apps/vben5/packages/@abp/auditing/src/api/entity-changes.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ListResultDto } from '@abp/core'; - -import type { - EntityChangeGetWithUsernameInput, - EntityChangeWithUsernameDto, -} from '../types/entity-changes'; - -import { requestClient } from '@abp/request'; - -/** - * 获取包含用户名称的实体变更列表 - * @param input 参数 - */ -export function getListWithUsernameApi( - input: EntityChangeGetWithUsernameInput, -): Promise> { - return requestClient.get>( - '/api/auditing/entity-changes/with-username', - { - params: input, - }, - ); -} diff --git a/apps/vben5/packages/@abp/auditing/src/api/index.ts b/apps/vben5/packages/@abp/auditing/src/api/index.ts index 8b3cb8830..8613244d7 100644 --- a/apps/vben5/packages/@abp/auditing/src/api/index.ts +++ b/apps/vben5/packages/@abp/auditing/src/api/index.ts @@ -1,2 +1,2 @@ -export * as auditLogsApi from './audit-logs'; -export * as entityChangesApi from './entity-changes'; +export { useAuditLogsApi } from './useAuditLogsApi'; +export { useEntityChangesApi } from './useEntityChangesApi'; diff --git a/apps/vben5/packages/@abp/auditing/src/api/useAuditLogsApi.ts b/apps/vben5/packages/@abp/auditing/src/api/useAuditLogsApi.ts new file mode 100644 index 000000000..fb63f8429 --- /dev/null +++ b/apps/vben5/packages/@abp/auditing/src/api/useAuditLogsApi.ts @@ -0,0 +1,65 @@ +import type { PagedResultDto } from '@abp/core'; + +import type { + AuditLogDeleteManyInput, + AuditLogDto, + AuditLogGetListInput, +} from '../types/audit-logs'; + +import { useRequest } from '@abp/request'; + +export function useAuditLogsApi() { + const { cancel, request } = useRequest(); + + /** + * 获取审计日志 + * @param id 日志id + */ + function getApi(id: string): Promise { + return request(`/api/auditing/audit-log/${id}`, { + method: 'GET', + }); + } + + /** + * 获取审计日志分页列表 + * @param input 参数 + */ + function getPagedListApi( + input: AuditLogGetListInput, + ): Promise> { + return request>('/api/auditing/audit-log', { + method: 'GET', + params: input, + }); + } + + /** + * 删除审计日志 + * @param id 日志id + */ + function deleteApi(id: string): Promise { + return request(`/api/auditing/audit-log/${id}`, { + method: 'DELETE', + }); + } + + /** + * 批量删除审计日志 + * @param input 参数 + */ + function deleteManyApi(input: AuditLogDeleteManyInput): Promise { + return request(`/api/auditing/audit-log/bulk`, { + data: input, + method: 'DELETE', + }); + } + + return { + cancel, + deleteApi, + deleteManyApi, + getApi, + getPagedListApi, + }; +} diff --git a/apps/vben5/packages/@abp/auditing/src/api/useEntityChangesApi.ts b/apps/vben5/packages/@abp/auditing/src/api/useEntityChangesApi.ts new file mode 100644 index 000000000..0ca12d55a --- /dev/null +++ b/apps/vben5/packages/@abp/auditing/src/api/useEntityChangesApi.ts @@ -0,0 +1,33 @@ +import type { ListResultDto } from '@abp/core'; + +import type { + EntityChangeGetWithUsernameInput, + EntityChangeWithUsernameDto, +} from '../types/entity-changes'; + +import { useRequest } from '@abp/request'; + +export function useEntityChangesApi() { + const { cancel, request } = useRequest(); + + /** + * 获取包含用户名称的实体变更列表 + * @param input 参数 + */ + function getListWithUsernameApi( + input: EntityChangeGetWithUsernameInput, + ): Promise> { + return request>( + '/api/auditing/entity-changes/with-username', + { + method: 'GET', + params: input, + }, + ); + } + + return { + cancel, + getListWithUsernameApi, + }; +} diff --git a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogDrawer.vue b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogDrawer.vue index 80f441f92..95f0b7162 100644 --- a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogDrawer.vue +++ b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogDrawer.vue @@ -12,7 +12,7 @@ import { formatToDateTime } from '@abp/core'; import { CodeEditor, MODE, useVbenVxeGrid } from '@abp/ui'; import { Descriptions, Tabs, Tag } from 'ant-design-vue'; -import { getApi } from '../../api/audit-logs'; +import { useAuditLogsApi } from '../../api/useAuditLogsApi'; import { useAuditlogs } from '../../hooks/useAuditlogs'; import EntityChangeTable from '../entity-changes/EntityChangeTable.vue'; @@ -26,13 +26,16 @@ const DescriptionsItem = Descriptions.Item; const activedTab = ref('basic'); const auditLogModel = ref({} as AuditLogDto); +const { getApi } = useAuditLogsApi(); const { getHttpMethodColor, getHttpStatusCodeColor } = useAuditlogs(); const [Drawer, drawerApi] = useVbenDrawer({ class: 'w-auto', onCancel() { drawerApi.close(); }, - onConfirm: async () => {}, + onConfirm: async () => { + drawerApi.close(); + }, onOpenChange: async (isOpen: boolean) => { if (isOpen) { try { diff --git a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue index 451b900e6..5c2e29ad6 100644 --- a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue +++ b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue @@ -4,7 +4,7 @@ import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui'; import type { AuditLogDto } from '../../types/audit-logs'; -import { defineAsyncComponent, h } from 'vue'; +import { defineAsyncComponent, h, ref, toValue } from 'vue'; import { useVbenDrawer } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -14,7 +14,7 @@ import { useVbenVxeGrid } from '@abp/ui'; import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue'; import { Button, message, Modal, Tag } from 'ant-design-vue'; -import { deleteApi, getPagedListApi } from '../../api/audit-logs'; +import { useAuditLogsApi } from '../../api/useAuditLogsApi'; import { AuditLogPermissions } from '../../constants/permissions'; import { useAuditlogs } from '../../hooks/useAuditlogs'; import { httpMethodOptions, httpStatusCodeOptions } from './mapping'; @@ -22,7 +22,9 @@ import { httpMethodOptions, httpStatusCodeOptions } from './mapping'; defineOptions({ name: 'AuditLogTable', }); +const { deleteApi, deleteManyApi, getPagedListApi } = useAuditLogsApi(); +const selectedKeys = ref([]); const formOptions: VbenFormProps = { // 默认展开 collapsed: true, @@ -121,6 +123,10 @@ const formOptions: VbenFormProps = { const gridOptions: VxeGridProps = { columns: [ + { + align: 'center', + type: 'checkbox', + }, { align: 'left', field: 'url', @@ -234,6 +240,12 @@ const gridOptions: VxeGridProps = { }; const gridEvents: VxeGridListeners = { + checkboxAll: (params) => { + selectedKeys.value = params.records.map((x) => x.id); + }, + checkboxChange: (params) => { + selectedKeys.value = params.records.map((x) => x.id); + }, sortChange: onSort, }; @@ -268,6 +280,22 @@ async function onDelete(row: AuditLogDto) { }); } +function onBulkDelete() { + Modal.confirm({ + centered: true, + content: $t('component.table.selectedItemWellBeDeleted'), + onOk: async () => { + await deleteManyApi({ + ids: toValue(selectedKeys), + }); + selectedKeys.value = []; + message.success($t('AbpUi.SuccessfullyDeleted')); + gridApi.query(); + }, + title: $t('AbpUi.AreYouSure'), + }); +} + function onSort(params: { field: string; order: SortOrder }) { const sorting = params.order ? `${params.field} ${params.order}` : undefined; gridApi.query({ sorting }); @@ -281,6 +309,19 @@ function onFilter(field: string, value: any) {