Browse Source

feat(vben5): 增加Webhook发送记录列表视图

pull/1181/head
colin 10 months ago
parent
commit
14335836c7
  1. 3
      apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json
  2. 3
      apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json
  3. 9
      apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts
  4. 15
      apps/vben5/apps/app-antd/src/views/webhooks/send-attempts/index.vue
  5. 1
      apps/vben5/packages/@abp/webhooks/src/api/index.ts
  6. 93
      apps/vben5/packages/@abp/webhooks/src/api/useSendAttemptsApi.ts
  7. 1
      apps/vben5/packages/@abp/webhooks/src/components/index.ts
  8. 253
      apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue
  9. 4
      apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue
  10. 1
      apps/vben5/packages/@abp/webhooks/src/types/index.ts
  11. 51
      apps/vben5/packages/@abp/webhooks/src/types/sendAttempts.ts

3
apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json

@ -118,6 +118,7 @@
"title": "Webhooks",
"groups": "Groups",
"definitions": "Definitions",
"subscriptions": "Subscriptions"
"subscriptions": "Subscriptions",
"sendAttempts": "Send Attempts"
}
}

3
apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json

@ -118,6 +118,7 @@
"title": "Webhook管理",
"groups": "Webhook分组",
"definitions": "Webhook定义",
"subscriptions": "管理订阅"
"subscriptions": "管理订阅",
"sendAttempts": "发送记录"
}
}

9
apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts

@ -485,6 +485,15 @@ const routes: RouteRecordRaw[] = [
path: '/webhooks/subscriptions',
component: () => import('#/views/webhooks/subscriptions/index.vue'),
},
{
meta: {
title: $t('abp.webhooks.sendAttempts'),
icon: 'material-symbols:history',
},
name: 'WebhookSendAttempts',
path: '/webhooks/send-attempts',
component: () => import('#/views/webhooks/send-attempts/index.vue'),
},
],
},
{

15
apps/vben5/apps/app-antd/src/views/webhooks/send-attempts/index.vue

@ -0,0 +1,15 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { WebhookSendAttemptTable } from '@abp/webhooks';
defineOptions({
name: 'WebhookSendAttempts',
});
</script>
<template>
<Page>
<WebhookSendAttemptTable />
</Page>
</template>

1
apps/vben5/packages/@abp/webhooks/src/api/index.ts

@ -1,3 +1,4 @@
export * from './useSendAttemptsApi';
export * from './useSubscriptionsApi';
export * from './useWebhookDefinitionsApi';
export * from './useWebhookGroupDefinitionsApi';

93
apps/vben5/packages/@abp/webhooks/src/api/useSendAttemptsApi.ts

@ -0,0 +1,93 @@
import type { PagedResultDto } from '@abp/core';
import type {
WebhookSendRecordDeleteManyInput,
WebhookSendRecordDto,
WebhookSendRecordGetListInput,
WebhookSendRecordResendManyInput,
} from '../types/sendAttempts';
import { useRequest } from '@abp/request';
export function useSendAttemptsApi() {
const { cancel, request } = useRequest();
/**
*
* @param id Id
* @returns Dto
*/
function getApi(id: string): Promise<WebhookSendRecordDto> {
return request<WebhookSendRecordDto>(`/api/webhooks/send-attempts/${id}`, {
method: 'GET',
});
}
/**
*
* @param id Id
*/
function deleteApi(id: string): Promise<void> {
return request(`/api/webhooks/send-attempts/${id}`, {
method: 'DELETE',
});
}
/**
*
* @param input
*/
function bulkDeleteApi(
input: WebhookSendRecordDeleteManyInput,
): Promise<void> {
return request(`/api/webhooks/send-attempts/delete-many`, {
data: input,
method: 'DELETE',
});
}
/**
*
* @param input
* @returns Dto分页列表
*/
function getPagedListApi(
input: WebhookSendRecordGetListInput,
): Promise<PagedResultDto<WebhookSendRecordDto>> {
return request<PagedResultDto<WebhookSendRecordDto>>(
`/api/webhooks/send-attempts`,
{
method: 'GET',
params: input,
},
);
}
/**
*
* @param id Id
*/
function reSendApi(id: string): Promise<void> {
return request(`/api/webhooks/send-attempts/${id}/resend`, {
method: 'POST',
});
}
/**
*
* @param input
*/
function bulkReSendApi(
input: WebhookSendRecordResendManyInput,
): Promise<void> {
return request(`/api/webhooks/send-attempts/resend-many`, {
data: input,
method: 'POST',
});
}
return {
bulkDeleteApi,
bulkReSendApi,
cancel,
deleteApi,
getApi,
getPagedListApi,
reSendApi,
};
}

1
apps/vben5/packages/@abp/webhooks/src/components/index.ts

@ -1,3 +1,4 @@
export { default as WebhookGroupDefinitionTable } from './definitions/groups/WebhookGroupDefinitionTable.vue';
export { default as WebhookDefinitionTable } from './definitions/webhooks/WebhookDefinitionTable.vue';
export { default as WebhookSendAttemptTable } from './send-attempts/WebhookSendAttemptTable.vue';
export { default as WebhookSubscriptionTable } from './subscriptions/WebhookSubscriptionTable.vue';

253
apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue

@ -0,0 +1,253 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { WebhookSendRecordDto } from '../../types/sendAttempts';
import { h, ref } from 'vue';
import { $t } from '@vben/locales';
import { formatToDateTime } from '@abp/core';
import { useHttpStatusCodeMap } from '@abp/request';
import { useTenantsApi } from '@abp/saas';
import { useVbenVxeGrid } from '@abp/ui';
import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue';
import { Button, message, Modal, Tag } from 'ant-design-vue';
import debounce from 'lodash.debounce';
import { useSendAttemptsApi } from '../../api/useSendAttemptsApi';
defineOptions({
name: 'WebhookSendAttemptTable',
});
const { getPagedListApi: getTenantsApi } = useTenantsApi();
const { cancel, deleteApi, getPagedListApi } = useSendAttemptsApi();
const { getHttpStatusColor, httpStatusCodeMap } = useHttpStatusCodeMap();
const tenantFilter = ref<string>();
const selectedKeys = ref<string[]>([]);
const httpStatusOptions = Object.keys(httpStatusCodeMap).map((key) => {
return {
label: httpStatusCodeMap[Number(key)],
value: key,
};
});
const formOptions: VbenFormProps = {
collapsed: true,
collapsedRows: 3,
commonConfig: {
componentProps: {
class: 'w-full',
},
},
fieldMappingTime: [
[
'creationTime',
['beginCreationTime', 'endCreationTime'],
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
],
],
schema: [
{
component: 'ApiSelect',
componentProps: () => {
return {
allowClear: true,
api: getTenantsApi,
filterOption: false,
labelField: 'normalizedName',
onSearch: debounce((filter?: string) => {
tenantFilter.value = filter;
}, 500),
params: {
filter: tenantFilter.value || undefined,
},
resultField: 'items',
showSearch: true,
valueField: 'id',
};
},
fieldName: 'tenantId',
label: $t('WebhooksManagement.DisplayName:TenantId'),
},
{
component: 'RangePicker',
fieldName: 'creationTime',
label: $t('WebhooksManagement.DisplayName:CreationTime'),
},
{
component: 'Select',
componentProps: {
allowClear: true,
options: [
{
label: $t('WebhooksManagement.ResponseState:Successed'),
value: true,
},
{
label: $t('WebhooksManagement.ResponseState:Failed'),
value: false,
},
],
},
fieldName: 'state',
label: $t('WebhooksManagement.DisplayName:State'),
},
{
component: 'Select',
componentProps: {
options: httpStatusOptions,
},
fieldName: 'responseStatusCode',
label: $t('WebhooksManagement.DisplayName:ResponseStatusCode'),
},
{
component: 'Input',
componentProps: {
allowClear: true,
},
fieldName: 'filter',
formItemClass: 'col-span-2 items-baseline',
label: $t('AbpUi.Search'),
},
],
//
showCollapseButton: true,
//
submitOnEnter: true,
};
const gridOptions: VxeGridProps<WebhookSendRecordDto> = {
columns: [
{
align: 'center',
type: 'checkbox',
width: 40,
},
{
align: 'left',
field: 'tenantId',
minWidth: 150,
title: $t('WebhooksManagement.DisplayName:TenantId'),
},
{
align: 'left',
field: 'responseStatusCode',
minWidth: 150,
slots: { default: 'responseStatusCode' },
title: $t('WebhooksManagement.DisplayName:ResponseStatusCode'),
},
{
align: 'left',
field: 'creationTime',
formatter({ cellValue }) {
return cellValue ? formatToDateTime(cellValue) : '';
},
minWidth: 120,
title: $t('WebhooksManagement.DisplayName:CreationTime'),
},
{
align: 'center',
field: 'response',
minWidth: 300,
title: $t('WebhooksManagement.DisplayName:Response'),
},
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: $t('AbpUi.Actions'),
width: 200,
},
],
exportConfig: {},
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getPagedListApi({
maxResultCount: page.pageSize,
skipCount: (page.currentPage - 1) * page.pageSize,
...formValues,
});
},
},
response: {
total: 'totalCount',
list: 'items',
},
},
toolbarConfig: {
custom: true,
export: true,
// import: true,
refresh: true,
zoom: true,
},
};
const gridEvents: VxeGridListeners<WebhookSendRecordDto> = {
checkboxAll: (params) => {
selectedKeys.value = params.records.map((record) => record.id);
},
checkboxChange: (params) => {
selectedKeys.value = params.records.map((record) => record.id);
},
};
const [Grid, gridApi] = useVbenVxeGrid({
formOptions,
gridEvents,
gridOptions,
});
function onUpdate(_row: WebhookSendRecordDto) {}
function onDelete(row: WebhookSendRecordDto) {
Modal.confirm({
centered: true,
content: $t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.title]),
onCancel: () => {
cancel();
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.DeletedSuccessfully'));
await gridApi.query();
},
title: $t('AbpUi.AreYouSure'),
});
}
</script>
<template>
<Grid :table-title="$t('WebhooksManagement.SendAttempts')">
<template #responseStatusCode="{ row }">
<Tag :color="getHttpStatusColor(row.responseStatusCode)">
{{ httpStatusCodeMap[row.responseStatusCode] }}
</Tag>
</template>
<template #action="{ row }">
<div class="flex flex-row">
<Button :icon="h(EditOutlined)" type="link" @click="onUpdate(row)">
{{ $t('AbpUi.Edit') }}
</Button>
<Button
:icon="h(DeleteOutlined)"
danger
type="link"
@click="onDelete(row)"
>
{{ $t('AbpUi.Delete') }}
</Button>
</div>
</template>
</Grid>
</template>
<style lang="scss" scoped></style>

4
apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue

@ -168,9 +168,9 @@ const gridOptions: VxeGridProps<WebhookSubscriptionDto> = {
title: $t('WebhooksManagement.DisplayName:CreationTime'),
},
{
align: 'left',
align: 'center',
field: 'webhooks',
minWidth: 150,
minWidth: 300,
slots: { default: 'webhooks' },
title: $t('WebhooksManagement.DisplayName:Webhooks'),
},

1
apps/vben5/packages/@abp/webhooks/src/types/index.ts

@ -1,3 +1,4 @@
export * from './definitions';
export * from './groups';
export * from './sendAttempts';
export * from './subscriptions';

51
apps/vben5/packages/@abp/webhooks/src/types/sendAttempts.ts

@ -0,0 +1,51 @@
import type { EntityDto, PagedAndSortedResultRequestDto } from '@abp/core';
import { HttpStatusCode } from '@abp/request';
interface WebhookEventRecordDto extends EntityDto<string> {
creationTime: Date;
data?: string;
tenantId?: string;
webhookName: string;
}
interface WebhookSendRecordDto extends EntityDto<string> {
creationTime: Date;
lastModificationTime?: Date;
requestHeaders?: Record<string, string>;
response?: string;
responseHeaders?: Record<string, string>;
responseStatusCode?: HttpStatusCode;
sendExactSameData: boolean;
tenantId?: string;
webhookEvent: WebhookEventRecordDto;
webhookEventId: string;
webhookSubscriptionId: string;
}
interface WebhookSendRecordDeleteManyInput {
recordIds: string[];
}
interface WebhookSendRecordResendManyInput {
recordIds: string[];
}
interface WebhookSendRecordGetListInput extends PagedAndSortedResultRequestDto {
beginCreationTime?: Date;
endCreationTime?: Date;
filter?: string;
responseStatusCode?: HttpStatusCode;
state?: boolean;
subscriptionId?: string;
tenantId?: string;
webhookEventId?: string;
}
export type {
WebhookEventRecordDto,
WebhookSendRecordDeleteManyInput,
WebhookSendRecordDto,
WebhookSendRecordGetListInput,
WebhookSendRecordResendManyInput,
};
Loading…
Cancel
Save