You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.6 KiB
227 lines
5.6 KiB
<script setup lang="ts">
|
|
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
|
|
|
|
import type { GdprRequestDto } from '../types/requests';
|
|
|
|
import { h } from 'vue';
|
|
|
|
import { $t } from '@vben/locales';
|
|
|
|
import { formatToDateTime, useAbpStore } from '@abp/core';
|
|
import { useVbenVxeGrid } from '@abp/ui';
|
|
import { DeleteOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
|
import { Button, message, Modal, Tag } from 'ant-design-vue';
|
|
import dayJs from 'dayjs';
|
|
|
|
import { useGdprRequestsApi } from '../api/useGdprRequestsApi';
|
|
|
|
defineOptions({
|
|
name: 'GdprTable',
|
|
});
|
|
|
|
const {
|
|
cancel,
|
|
deleteApi,
|
|
deletePersonalDataApi,
|
|
downloadPersonalDataApi,
|
|
getPagedListApi,
|
|
preparePersonalDataApi,
|
|
} = useGdprRequestsApi();
|
|
|
|
const abpStore = useAbpStore();
|
|
const gridOptions: VxeGridProps<GdprRequestDto> = {
|
|
columns: [
|
|
{
|
|
align: 'left',
|
|
field: 'readyTime',
|
|
slots: { default: 'readly' },
|
|
sortable: true,
|
|
title: $t('AbpGdpr.DisplayName:ReadyTime'),
|
|
},
|
|
{
|
|
align: 'left',
|
|
field: 'creationTime',
|
|
sortable: true,
|
|
title: $t('AbpGdpr.DisplayName:CreationTime'),
|
|
},
|
|
{
|
|
field: 'action',
|
|
fixed: 'right',
|
|
slots: { default: 'action' },
|
|
title: $t('AbpUi.Actions'),
|
|
width: 180,
|
|
},
|
|
],
|
|
exportConfig: {},
|
|
keepSource: true,
|
|
proxyConfig: {
|
|
ajax: {
|
|
query: async ({ page, sort }, formValues) => {
|
|
const sorting = sort.order ? `${sort.field} ${sort.order}` : undefined;
|
|
const dto = await getPagedListApi({
|
|
sorting,
|
|
maxResultCount: page.pageSize,
|
|
skipCount: (page.currentPage - 1) * page.pageSize,
|
|
...formValues,
|
|
});
|
|
const now = dayJs();
|
|
return {
|
|
totalCount: dto.totalCount,
|
|
items: dto.items.map((item) => {
|
|
return {
|
|
creationTime: formatToDateTime(item.creationTime),
|
|
id: item.id,
|
|
isReadly: now.diff(dayJs(item.readyTime)) >= 0,
|
|
readyTime: formatToDateTime(item.readyTime),
|
|
};
|
|
}),
|
|
};
|
|
},
|
|
},
|
|
response: {
|
|
total: 'totalCount',
|
|
list: 'items',
|
|
},
|
|
},
|
|
toolbarConfig: {
|
|
refresh: {
|
|
code: 'query',
|
|
},
|
|
},
|
|
};
|
|
|
|
const gridEvents: VxeGridListeners<GdprRequestDto> = {
|
|
cellClick: () => {},
|
|
sortChange: () => {
|
|
gridApi.query();
|
|
},
|
|
};
|
|
const [Grid, gridApi] = useVbenVxeGrid({
|
|
gridEvents,
|
|
gridOptions,
|
|
});
|
|
|
|
const onRequestData = async () => {
|
|
gridApi.setLoading(true);
|
|
try {
|
|
await preparePersonalDataApi();
|
|
Modal.success({
|
|
centered: true,
|
|
content: $t('AbpGdpr.PersonalDataPrepareRequestReceived'),
|
|
title: $t('AbpGdpr.RequestedSuccessfully'),
|
|
});
|
|
await gridApi.query();
|
|
} finally {
|
|
gridApi.setLoading(false);
|
|
}
|
|
};
|
|
|
|
const onDeleteData = () => {
|
|
Modal.confirm({
|
|
centered: true,
|
|
content: $t('AbpGdpr.DeletePersonalDataWarning'),
|
|
onCancel: () => {
|
|
cancel();
|
|
},
|
|
onOk: async () => {
|
|
gridApi.setLoading(true);
|
|
try {
|
|
await deletePersonalDataApi();
|
|
Modal.success({
|
|
centered: true,
|
|
content: $t('AbpGdpr.PersonalDataDeleteRequestReceived'),
|
|
onOk: () => {
|
|
// 刷新页面重载用户信息
|
|
window.location.reload();
|
|
},
|
|
title: $t('AbpGdpr.RequestedSuccessfully'),
|
|
});
|
|
await gridApi.query();
|
|
} finally {
|
|
gridApi.setLoading(false);
|
|
}
|
|
},
|
|
title: $t('AbpUi.AreYouSure'),
|
|
});
|
|
};
|
|
|
|
const onDownload = async (row: GdprRequestDto) => {
|
|
const blob = await downloadPersonalDataApi(row.id);
|
|
const url = window.URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
const { userName } = abpStore.application!.currentUser;
|
|
const fileName = `${$t('AbpGdpr.PersonalData')}_${userName}_${formatToDateTime(row.readyTime)}.xlsx`;
|
|
link.setAttribute('download', decodeURIComponent(fileName));
|
|
document.body.append(link);
|
|
link.click();
|
|
window.URL.revokeObjectURL(url);
|
|
link.remove();
|
|
};
|
|
|
|
const onDelete = (row: GdprRequestDto) => {
|
|
Modal.confirm({
|
|
centered: true,
|
|
content: $t('AbpUi.ItemWillBeDeletedMessage'),
|
|
onCancel: () => {
|
|
cancel();
|
|
},
|
|
onOk: async () => {
|
|
gridApi.setLoading(true);
|
|
try {
|
|
await deleteApi(row.id);
|
|
message.success($t('AbpUi.DeletedSuccessfully'));
|
|
await gridApi.query();
|
|
} finally {
|
|
gridApi.setLoading(false);
|
|
}
|
|
},
|
|
title: $t('AbpUi.AreYouSure'),
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Grid :table-title="$t('AbpGdpr.PersonalData')">
|
|
<template #toolbar-tools>
|
|
<div class="flex flex-row gap-2">
|
|
<Button type="primary" @click="onRequestData">
|
|
{{ $t('AbpGdpr.RequestPersonalData') }}
|
|
</Button>
|
|
<Button type="primary" danger @click="onDeleteData">
|
|
{{ $t('AbpGdpr.DeletePersonalData') }}
|
|
</Button>
|
|
</div>
|
|
</template>
|
|
<template #readly="{ row }">
|
|
{{ row.readyTime }}
|
|
<Tag v-if="!row.isReadly" color="warning">
|
|
{{ $t('AbpGdpr.Preparing') }}
|
|
</Tag>
|
|
</template>
|
|
<template #action="{ row }">
|
|
<div class="flex flex-row">
|
|
<Button
|
|
v-if="row.isReadly"
|
|
:icon="h(DownloadOutlined)"
|
|
block
|
|
type="link"
|
|
@click="onDownload(row)"
|
|
>
|
|
{{ $t('AbpGdpr.Download') }}
|
|
</Button>
|
|
<Button
|
|
:icon="h(DeleteOutlined)"
|
|
block
|
|
danger
|
|
type="link"
|
|
@click="onDelete(row)"
|
|
>
|
|
{{ $t('AbpUi.Delete') }}
|
|
</Button>
|
|
</div>
|
|
</template>
|
|
</Grid>
|
|
</template>
|
|
|
|
<style lang="scss" scoped></style>
|
|
|