Browse Source

feat(auditing): Added IP territory display.

pull/1068/head
colin 1 year ago
parent
commit
7cca77a216
  1. 7
      apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue
  2. 98
      apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogDrawer.vue
  3. 7
      apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogModal.vue
  4. 76
      apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogTable.vue
  5. 1
      apps/vben5/packages/@abp/identity/src/constants/permissions.ts

7
apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue

@ -163,6 +163,7 @@ const gridOptions: VxeGridProps<AuditLogDto> = {
{ {
align: 'left', align: 'left',
field: 'clientIpAddress', field: 'clientIpAddress',
slots: { default: 'clientIpAddress' },
sortable: true, sortable: true,
title: $t('AbpAuditLogging.ClientIpAddress'), title: $t('AbpAuditLogging.ClientIpAddress'),
width: 150, width: 150,
@ -280,6 +281,12 @@ function onFilter(field: string, value: any) {
<template> <template>
<Grid :table-title="$t('AbpAuditLogging.AuditLog')"> <Grid :table-title="$t('AbpAuditLogging.AuditLog')">
<template #clientIpAddress="{ row }">
<Tag v-if="row.extraProperties?.Location" color="blue">
{{ row.extraProperties?.Location }}
</Tag>
<span>{{ row.clientIpAddress }}</span>
</template>
<template #url="{ row }"> <template #url="{ row }">
<Tag <Tag
:color="getHttpStatusCodeColor(row.httpStatusCode)" :color="getHttpStatusCodeColor(row.httpStatusCode)"

98
apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogDrawer.vue

@ -0,0 +1,98 @@
<script setup lang="ts">
import type { SecurityLogDto } from '../../types/security-logs';
import { ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { formatToDateTime } from '@abp/core';
import { Descriptions } from 'ant-design-vue';
import { getApi } from '../../api/security-logs';
defineOptions({
name: 'SecurityLogDrawer',
});
const DescriptionsItem = Descriptions.Item;
const formModel = ref<SecurityLogDto>({} as SecurityLogDto);
const [Drawer, drawerApi] = useVbenDrawer({
class: 'w-auto',
onCancel() {
drawerApi.close();
},
onConfirm: async () => {},
onOpenChange: async (isOpen: boolean) => {
formModel.value = {} as SecurityLogDto;
if (isOpen) {
try {
drawerApi.setState({ loading: true });
const dto = drawerApi.getData<SecurityLogDto>();
await onGet(dto.id);
} finally {
drawerApi.setState({ loading: false });
}
}
},
title: $t('AbpAuditLogging.SecurityLog'),
});
/** 查询审计日志 */
async function onGet(id: string) {
const dto = await getApi(id);
formModel.value = dto;
}
</script>
<template>
<Drawer>
<div style="width: 800px">
<Descriptions :colon="false" :column="2" bordered size="small">
<DescriptionsItem :label="$t('AbpAuditLogging.ApplicationName')">
{{ formModel.applicationName }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.CreationTime')">
{{ formatToDateTime(formModel.creationTime) }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.Identity')">
{{ formModel.identity }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.TenantName')">
{{ formModel.tenantName }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.Actions')">
{{ formModel.action }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.CorrelationId')">
{{ formModel.correlationId }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.UserId')">
{{ formModel.userId }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.UserName')">
{{ formModel.userName }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.ClientId')">
{{ formModel.clientId }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.ClientIpAddress')">
{{ formModel.clientIpAddress }}
</DescriptionsItem>
<DescriptionsItem
:label="$t('AbpAuditLogging.BrowserInfo')"
:label-style="{ width: '110px' }"
:span="2"
>
{{ formModel.browserInfo }}
</DescriptionsItem>
<DescriptionsItem :label="$t('AbpAuditLogging.Additional')" :span="2">
{{ formModel.extraProperties }}
</DescriptionsItem>
</Descriptions>
</div>
</Drawer>
</template>
<style scoped></style>

7
apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogModal.vue

@ -1,7 +0,0 @@
<script setup lang="ts"></script>
<template>
<div></div>
</template>
<style scoped></style>

76
apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogTable.vue

@ -3,14 +3,15 @@ import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { SecurityLogDto } from '../../types/security-logs'; import type { SecurityLogDto } from '../../types/security-logs';
import { h } from 'vue'; import { defineAsyncComponent, h } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { formatToDateTime } from '@abp/core'; import { formatToDateTime, type SortOrder } from '@abp/core';
import { useVbenVxeGrid } from '@abp/ui'; import { useVbenVxeGrid } from '@abp/ui';
import { DeleteOutlined } from '@ant-design/icons-vue'; import { DeleteOutlined, EditOutlined } from '@ant-design/icons-vue';
import { Button, message, Modal } from 'ant-design-vue'; import { Button, message, Modal, Tag } from 'ant-design-vue';
import { deleteApi, getPagedListApi } from '../../api/security-logs'; import { deleteApi, getPagedListApi } from '../../api/security-logs';
import { SecurityLogPermissions } from '../../constants/permissions'; import { SecurityLogPermissions } from '../../constants/permissions';
@ -76,69 +77,80 @@ const gridOptions: VxeGridProps<SecurityLogDto> = {
formatter: ({ cellValue }) => { formatter: ({ cellValue }) => {
return cellValue ? formatToDateTime(cellValue) : cellValue; return cellValue ? formatToDateTime(cellValue) : cellValue;
}, },
sortable: true,
title: $t('AbpAuditLogging.CreationTime'), title: $t('AbpAuditLogging.CreationTime'),
width: 180, width: 180,
}, },
{ {
align: 'left', align: 'left',
field: 'identity', field: 'identity',
sortable: true,
title: $t('AbpAuditLogging.Identity'), title: $t('AbpAuditLogging.Identity'),
width: 180, width: 180,
}, },
{ {
align: 'left', align: 'left',
field: 'userName', field: 'userName',
sortable: true,
title: $t('AbpAuditLogging.UserName'), title: $t('AbpAuditLogging.UserName'),
width: 150, width: 150,
}, },
{ {
align: 'left', align: 'left',
field: 'clientId', field: 'clientId',
sortable: true,
title: $t('AbpAuditLogging.ClientId'), title: $t('AbpAuditLogging.ClientId'),
width: 200, width: 200,
}, },
{ {
align: 'left', align: 'left',
field: 'clientIpAddress', field: 'clientIpAddress',
slots: { default: 'clientIpAddress' },
sortable: true,
title: $t('AbpAuditLogging.ClientIpAddress'), title: $t('AbpAuditLogging.ClientIpAddress'),
width: 200, width: 200,
}, },
{ {
align: 'left', align: 'left',
field: 'applicationName', field: 'applicationName',
sortable: true,
title: $t('AbpAuditLogging.ApplicationName'), title: $t('AbpAuditLogging.ApplicationName'),
width: 200, width: 200,
}, },
{ {
align: 'left', align: 'left',
field: 'tenantName', field: 'tenantName',
sortable: true,
title: $t('AbpAuditLogging.TenantName'), title: $t('AbpAuditLogging.TenantName'),
width: 180, width: 180,
}, },
{ {
align: 'left', align: 'left',
field: 'actions', field: 'action',
sortable: true,
title: $t('AbpAuditLogging.Actions'), title: $t('AbpAuditLogging.Actions'),
width: 180, width: 180,
}, },
{ {
align: 'left', align: 'left',
field: 'correlationId', field: 'correlationId',
sortable: true,
title: $t('AbpAuditLogging.CorrelationId'), title: $t('AbpAuditLogging.CorrelationId'),
width: 200, width: 200,
}, },
{ {
align: 'left', align: 'left',
field: 'browserInfo', field: 'browserInfo',
sortable: true,
title: $t('AbpAuditLogging.BrowserInfo'), title: $t('AbpAuditLogging.BrowserInfo'),
width: 'auto', width: 'auto',
}, },
{ {
field: 'action', field: 'actions',
fixed: 'right', fixed: 'right',
slots: { default: 'action' }, slots: { default: 'action' },
title: $t('AbpUi.Actions'), title: $t('AbpUi.Actions'),
width: 150, width: 220,
}, },
], ],
exportConfig: {}, exportConfig: {},
@ -168,50 +180,74 @@ const gridOptions: VxeGridProps<SecurityLogDto> = {
}; };
const gridEvents: VxeGridListeners<SecurityLogDto> = { const gridEvents: VxeGridListeners<SecurityLogDto> = {
cellClick: () => {}, sortChange: onSort,
}; };
const [Grid, { query }] = useVbenVxeGrid({ const [Grid, gridApi] = useVbenVxeGrid({
formOptions, formOptions,
gridEvents, gridEvents,
gridOptions, gridOptions,
}); });
const [SecurityLogDrawer, drawerApi] = useVbenDrawer({
connectedComponent: defineAsyncComponent(
() => import('./SecurityLogDrawer.vue'),
),
});
function onUpdate(row: SecurityLogDto) {
drawerApi.setData(row);
drawerApi.open();
}
const handleDelete = (row: SecurityLogDto) => { function onDelete(row: SecurityLogDto) {
Modal.confirm({ Modal.confirm({
centered: true, centered: true,
content: $t('AbpUi.ItemWillBeDeletedMessage'), content: $t('AbpUi.ItemWillBeDeletedMessage'),
onOk: async () => { onOk: async () => {
await deleteApi(row.id); await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted')); message.success($t('AbpUi.SuccessfullyDeleted'));
query(); gridApi.query();
}, },
title: $t('AbpUi.AreYouSure'), title: $t('AbpUi.AreYouSure'),
}); });
}; }
function onSort(params: { field: string; order: SortOrder }) {
const sorting = params.order ? `${params.field} ${params.order}` : undefined;
gridApi.query({ sorting });
}
</script> </script>
<template> <template>
<Grid :table-title="$t('AbpAuditLogging.SecurityLog')"> <Grid :table-title="$t('AbpAuditLogging.SecurityLog')">
<template #clientIpAddress="{ row }">
<Tag v-if="row.extraProperties?.Location" color="blue">
{{ row.extraProperties?.Location }}
</Tag>
<span>{{ row.clientIpAddress }}</span>
</template>
<template #action="{ row }"> <template #action="{ row }">
<div class="flex flex-row"> <div class="flex flex-row">
<Button
:icon="h(EditOutlined)"
block
type="link"
v-access:code="[SecurityLogPermissions.Default]"
@click="onUpdate(row)"
>
{{ $t('AbpUi.Edit') }}
</Button>
<Button <Button
:icon="h(DeleteOutlined)" :icon="h(DeleteOutlined)"
block block
danger danger
type="link" type="link"
v-access:code="[SecurityLogPermissions.Delete]" v-access:code="[SecurityLogPermissions.Delete]"
@click="handleDelete(row)" @click="onDelete(row)"
> >
{{ $t('AbpUi.Delete') }} {{ $t('AbpUi.Delete') }}
</Button> </Button>
</div> </div>
</template> </template>
</Grid> </Grid>
<SecurityLogDrawer />
</template> </template>
<style lang="scss" scoped>
.checkbox-box {
display: flex;
justify-content: center;
}
</style>

1
apps/vben5/packages/@abp/identity/src/constants/permissions.ts

@ -42,6 +42,7 @@ export const OrganizationUnitPermissions = {
}; };
/** 安全日志权限 */ /** 安全日志权限 */
export const SecurityLogPermissions = { export const SecurityLogPermissions = {
Default: 'AbpAuditing.SecurityLog',
/** 删除 */ /** 删除 */
Delete: 'AbpAuditing.SecurityLog.Delete', Delete: 'AbpAuditing.SecurityLog.Delete',
}; };

Loading…
Cancel
Save