11 changed files with 653 additions and 2 deletions
@ -0,0 +1,15 @@ |
|||
<script lang="ts" setup> |
|||
import { Page } from '@vben/common-ui'; |
|||
|
|||
import { DataDictionaryTable } from '@abp/platform'; |
|||
|
|||
defineOptions({ |
|||
name: 'PlatformDataDictionaries', |
|||
}); |
|||
</script> |
|||
|
|||
<template> |
|||
<Page> |
|||
<DataDictionaryTable /> |
|||
</Page> |
|||
</template> |
|||
@ -1,2 +1,3 @@ |
|||
export { useDataDictionariesApi } from './useDataDictionariesApi'; |
|||
export { useEmailMessagesApi } from './useEmailMessagesApi'; |
|||
export { useSmsMessagesApi } from './useSmsMessagesApi'; |
|||
|
|||
@ -0,0 +1,110 @@ |
|||
import type { ListResultDto, PagedResultDto } from '@abp/core'; |
|||
|
|||
import type { |
|||
DataCreateDto, |
|||
DataDto, |
|||
DataItemCreateDto, |
|||
DataItemUpdateDto, |
|||
DataMoveDto, |
|||
DataUpdateDto, |
|||
GetDataListInput, |
|||
} from '../types/dataDictionaries'; |
|||
|
|||
import { useRequest } from '@abp/request'; |
|||
|
|||
export function useDataDictionariesApi() { |
|||
const { cancel, request } = useRequest(); |
|||
|
|||
function createApi(input: DataCreateDto): Promise<DataDto> { |
|||
return request<DataDto>('/api/platform/datas', { |
|||
data: input, |
|||
method: 'POST', |
|||
}); |
|||
} |
|||
|
|||
function deleteApi(id: string): Promise<void> { |
|||
return request(`/api/platform/datas/${id}`, { |
|||
method: 'DELETE', |
|||
}); |
|||
} |
|||
|
|||
function createItemApi(id: string, input: DataItemCreateDto): Promise<void> { |
|||
return request(`/api/platform/datas/${id}/items`, { |
|||
data: input, |
|||
method: 'POST', |
|||
}); |
|||
} |
|||
|
|||
function deleteItemApi(id: string, name: string): Promise<void> { |
|||
return request(`/api/platform/datas/${id}/items/${name}`, { |
|||
method: 'DELETE', |
|||
}); |
|||
} |
|||
|
|||
function getApi(id: string): Promise<DataDto> { |
|||
return request<DataDto>(`/api/platform/datas/${id}`, { |
|||
method: 'GET', |
|||
}); |
|||
} |
|||
|
|||
function getByNameApi(name: string): Promise<DataDto> { |
|||
return request<DataDto>(`/api/platform/datas/by-name/${name}`, { |
|||
method: 'GET', |
|||
}); |
|||
} |
|||
|
|||
function getAllApi(): Promise<ListResultDto<DataDto>> { |
|||
return request<ListResultDto<DataDto>>(`/api/platform/datas/all`, { |
|||
method: 'GET', |
|||
}); |
|||
} |
|||
|
|||
function getPagedListApi( |
|||
input?: GetDataListInput, |
|||
): Promise<PagedResultDto<DataDto>> { |
|||
return request<PagedResultDto<DataDto>>(`/api/platform/datas`, { |
|||
method: 'GET', |
|||
params: input, |
|||
}); |
|||
} |
|||
|
|||
function moveApi(id: string, input: DataMoveDto): Promise<DataDto> { |
|||
return request<DataDto>(`/api/platform/datas/${id}/move`, { |
|||
data: input, |
|||
method: 'PUT', |
|||
}); |
|||
} |
|||
|
|||
function updateApi(id: string, input: DataUpdateDto): Promise<DataDto> { |
|||
return request<DataDto>(`/api/platform/datas/${id}`, { |
|||
data: input, |
|||
method: 'PUT', |
|||
}); |
|||
} |
|||
|
|||
function updateItemApi( |
|||
id: string, |
|||
name: string, |
|||
input: DataItemUpdateDto, |
|||
): Promise<void> { |
|||
return request(`/api/platform/datas/${id}/items/${name}`, { |
|||
data: input, |
|||
method: 'PUT', |
|||
}); |
|||
} |
|||
|
|||
return { |
|||
cancel, |
|||
createApi, |
|||
createItemApi, |
|||
deleteApi, |
|||
deleteItemApi, |
|||
getAllApi, |
|||
getApi, |
|||
getByNameApi, |
|||
getPagedListApi, |
|||
moveApi, |
|||
updateApi, |
|||
updateItemApi, |
|||
}; |
|||
} |
|||
@ -0,0 +1,222 @@ |
|||
<script setup lang="ts"> |
|||
import type { VxeGridListeners, VxeGridProps } from '@abp/ui'; |
|||
|
|||
import type { DataDto, DataItemDto } from '../../types/dataDictionaries'; |
|||
|
|||
import { h, reactive, ref } from 'vue'; |
|||
|
|||
import { useVbenDrawer } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { isNullOrWhiteSpace } from '@abp/core'; |
|||
import { useVbenVxeGrid } from '@abp/ui'; |
|||
import { |
|||
CheckOutlined, |
|||
CloseOutlined, |
|||
DeleteOutlined, |
|||
EditOutlined, |
|||
PlusOutlined, |
|||
} from '@ant-design/icons-vue'; |
|||
import { Button } from 'ant-design-vue'; |
|||
|
|||
import { useDataDictionariesApi } from '../../api'; |
|||
import { ValueType } from '../../types/dataDictionaries'; |
|||
|
|||
const { getApi } = useDataDictionariesApi(); |
|||
|
|||
const dataItems = ref<DataItemDto[]>([]); |
|||
const pageState = reactive({ |
|||
current: 1, |
|||
size: 10, |
|||
total: 0, |
|||
}); |
|||
const valueTypeMaps: { [key: number]: string } = { |
|||
[ValueType.Array]: 'Array', |
|||
[ValueType.Boolean]: 'Boolean', |
|||
[ValueType.Date]: 'Date', |
|||
[ValueType.DateTime]: 'DateTime', |
|||
[ValueType.Numeic]: 'Number', |
|||
[ValueType.Object]: 'Object', |
|||
[ValueType.String]: 'String', |
|||
}; |
|||
|
|||
const [Drawer, drawerApi] = useVbenDrawer({ |
|||
class: 'w-1/2', |
|||
async onOpenChange(isOpen) { |
|||
if (isOpen) { |
|||
const { name } = drawerApi.getData<DataDto>(); |
|||
drawerApi.setState({ |
|||
title: `${$t('AppPlatform.DisplayName:DataDictionary')} - ${name}`, |
|||
}); |
|||
await onGet(); |
|||
} |
|||
}, |
|||
showConfirmButton: false, |
|||
title: $t('AppPlatform.Data:Items'), |
|||
}); |
|||
|
|||
const gridOptions: VxeGridProps<DataItemDto> = { |
|||
columns: [ |
|||
{ |
|||
align: 'center', |
|||
type: 'seq', |
|||
width: 50, |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'name', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:Name'), |
|||
treeNode: true, |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'displayName', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:DisplayName'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'description', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:Description'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'valueType', |
|||
formatter: ({ row }) => { |
|||
return valueTypeMaps[row.valueType] ?? row.valueType; |
|||
}, |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:ValueType'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'defaultValue', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:DefaultValue'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'allowBeNull', |
|||
minWidth: 150, |
|||
slots: { default: 'allowBeNull' }, |
|||
title: $t('AppPlatform.DisplayName:AllowBeNull'), |
|||
}, |
|||
{ |
|||
field: 'action', |
|||
fixed: 'right', |
|||
slots: { default: 'action' }, |
|||
title: $t('AbpUi.Actions'), |
|||
width: 220, |
|||
}, |
|||
], |
|||
exportConfig: {}, |
|||
keepSource: true, |
|||
toolbarConfig: { |
|||
custom: true, |
|||
export: true, |
|||
refresh: false, |
|||
zoom: true, |
|||
}, |
|||
treeConfig: { |
|||
accordion: true, |
|||
parentField: 'parentId', |
|||
rowField: 'id', |
|||
transform: true, |
|||
}, |
|||
}; |
|||
|
|||
const gridEvents: VxeGridListeners<DataItemDto> = { |
|||
pageChange(params) { |
|||
pageState.current = params.currentPage; |
|||
pageState.size = params.pageSize; |
|||
onPageChange(); |
|||
}, |
|||
}; |
|||
|
|||
const [Grid, gridApi] = useVbenVxeGrid({ |
|||
gridEvents, |
|||
gridOptions, |
|||
}); |
|||
|
|||
async function onGet() { |
|||
const { id } = drawerApi.getData<DataDto>(); |
|||
if (isNullOrWhiteSpace(id)) { |
|||
return; |
|||
} |
|||
try { |
|||
drawerApi.setState({ loading: true }); |
|||
const dto = await getApi(id); |
|||
dataItems.value = dto.items; |
|||
pageState.total = dto.items.length; |
|||
onPageChange(); |
|||
} finally { |
|||
drawerApi.setState({ |
|||
loading: false, |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function onPageChange() { |
|||
const items = dataItems.value.slice( |
|||
(pageState.current - 1) * pageState.size, |
|||
pageState.current * pageState.size, |
|||
); |
|||
gridApi.setGridOptions({ |
|||
data: items, |
|||
pagerConfig: { |
|||
currentPage: pageState.current, |
|||
pageSize: pageState.size, |
|||
total: pageState.total, |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
function onCreate() {} |
|||
|
|||
function onUpdate(_row: DataItemDto) {} |
|||
|
|||
function onDelete(_row: DataItemDto) {} |
|||
</script> |
|||
|
|||
<template> |
|||
<Drawer> |
|||
<Grid :table-title="$t('AppPlatform.Data:Items')"> |
|||
<template #toolbar-tools> |
|||
<Button :icon="h(PlusOutlined)" type="primary" @click="onCreate"> |
|||
{{ $t('AppPlatform.Data:AppendItem') }} |
|||
</Button> |
|||
</template> |
|||
<template #allowBeNull="{ row }"> |
|||
<div class="flex flex-row justify-center"> |
|||
<CheckOutlined v-if="row.allowBeNull" class="text-green-500" /> |
|||
<CloseOutlined v-else class="text-red-500" /> |
|||
</div> |
|||
</template> |
|||
<template #action="{ row }"> |
|||
<div class="flex flex-row"> |
|||
<Button |
|||
:icon="h(EditOutlined)" |
|||
block |
|||
type="link" |
|||
@click="onUpdate(row)" |
|||
> |
|||
{{ $t('AbpUi.Edit') }} |
|||
</Button> |
|||
<Button |
|||
:icon="h(DeleteOutlined)" |
|||
block |
|||
danger |
|||
type="link" |
|||
@click="onDelete(row)" |
|||
> |
|||
{{ $t('AbpUi.Delete') }} |
|||
</Button> |
|||
</div> |
|||
</template> |
|||
</Grid> |
|||
</Drawer> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,213 @@ |
|||
<script setup lang="ts"> |
|||
import type { VxeGridListeners, VxeGridProps } from '@abp/ui'; |
|||
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; |
|||
|
|||
import type { DataDto } from '../../types/dataDictionaries'; |
|||
|
|||
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue'; |
|||
|
|||
import { useVbenDrawer } from '@vben/common-ui'; |
|||
import { createIconifyIcon } from '@vben/icons'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { useVbenVxeGrid } from '@abp/ui'; |
|||
import { |
|||
DeleteOutlined, |
|||
EditOutlined, |
|||
EllipsisOutlined, |
|||
PlusOutlined, |
|||
} from '@ant-design/icons-vue'; |
|||
import { Button, Dropdown, Menu } from 'ant-design-vue'; |
|||
|
|||
import { useDataDictionariesApi } from '../../api/useDataDictionariesApi'; |
|||
|
|||
defineOptions({ |
|||
name: 'DataDictionaryTable', |
|||
}); |
|||
|
|||
const MenuItem = Menu.Item; |
|||
const ItemsIcon = createIconifyIcon('material-symbols:align-items-stretch'); |
|||
|
|||
const { getAllApi } = useDataDictionariesApi(); |
|||
|
|||
const dataDictionaries = ref<DataDto[]>([]); |
|||
const pageState = reactive({ |
|||
current: 1, |
|||
size: 10, |
|||
total: 0, |
|||
}); |
|||
|
|||
const gridOptions: VxeGridProps<DataDto> = { |
|||
columns: [ |
|||
{ |
|||
align: 'center', |
|||
type: 'seq', |
|||
width: 50, |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'name', |
|||
minWidth: 150, |
|||
slots: { default: 'name' }, |
|||
title: $t('AppPlatform.DisplayName:Name'), |
|||
treeNode: true, |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'displayName', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:DisplayName'), |
|||
}, |
|||
{ |
|||
align: 'left', |
|||
field: 'description', |
|||
minWidth: 150, |
|||
title: $t('AppPlatform.DisplayName:Description'), |
|||
}, |
|||
{ |
|||
field: 'action', |
|||
fixed: 'right', |
|||
slots: { default: 'action' }, |
|||
title: $t('AbpUi.Actions'), |
|||
width: 220, |
|||
}, |
|||
], |
|||
exportConfig: {}, |
|||
keepSource: true, |
|||
toolbarConfig: { |
|||
custom: true, |
|||
export: true, |
|||
refresh: false, |
|||
zoom: true, |
|||
}, |
|||
treeConfig: { |
|||
accordion: true, |
|||
parentField: 'parentId', |
|||
rowField: 'id', |
|||
transform: true, |
|||
}, |
|||
}; |
|||
const gridEvents: VxeGridListeners<DataDto> = { |
|||
pageChange(params) { |
|||
pageState.current = params.currentPage; |
|||
pageState.size = params.pageSize; |
|||
onPageChange(); |
|||
}, |
|||
}; |
|||
|
|||
const [Grid, gridApi] = useVbenVxeGrid({ |
|||
gridEvents, |
|||
gridOptions, |
|||
}); |
|||
|
|||
const [DataDictionaryItemDrawer, itemDrawerApi] = useVbenDrawer({ |
|||
connectedComponent: defineAsyncComponent( |
|||
() => import('./DataDictionaryItemDrawer.vue'), |
|||
), |
|||
}); |
|||
|
|||
async function onGet() { |
|||
try { |
|||
gridApi.setLoading(true); |
|||
const { items } = await getAllApi(); |
|||
pageState.total = items.length; |
|||
dataDictionaries.value = items; |
|||
onPageChange(); |
|||
} finally { |
|||
gridApi.setLoading(false); |
|||
} |
|||
} |
|||
|
|||
function onPageChange() { |
|||
const items = dataDictionaries.value.slice( |
|||
(pageState.current - 1) * pageState.size, |
|||
pageState.current * pageState.size, |
|||
); |
|||
gridApi.setGridOptions({ |
|||
data: items, |
|||
pagerConfig: { |
|||
currentPage: pageState.current, |
|||
pageSize: pageState.size, |
|||
total: pageState.total, |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
function onCreate() {} |
|||
|
|||
function onUpdate(_row: DataDto) {} |
|||
|
|||
function onDelete(_row: DataDto) {} |
|||
|
|||
function onMenuClick(row: DataDto, info: MenuInfo) { |
|||
switch (info.key) { |
|||
case 'items': { |
|||
onManageItems(row); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function onManageItems(row: DataDto) { |
|||
itemDrawerApi.setData(row); |
|||
itemDrawerApi.open(); |
|||
} |
|||
|
|||
onMounted(onGet); |
|||
</script> |
|||
|
|||
<template> |
|||
<Grid :table-title="$t('AppPlatform.DisplayName:DataDictionary')"> |
|||
<template #toolbar-tools> |
|||
<Button :icon="h(PlusOutlined)" type="primary" @click="onCreate"> |
|||
{{ $t('AppPlatform.Data:AddNew') }} |
|||
</Button> |
|||
</template> |
|||
<template #name="{ row }"> |
|||
<Button type="link" @click="onManageItems(row)">{{ row.name }}</Button> |
|||
</template> |
|||
<template #action="{ row }"> |
|||
<div class="flex flex-row"> |
|||
<Button |
|||
:icon="h(EditOutlined)" |
|||
block |
|||
type="link" |
|||
@click="onUpdate(row)" |
|||
> |
|||
{{ $t('AbpUi.Edit') }} |
|||
</Button> |
|||
<Button |
|||
:icon="h(DeleteOutlined)" |
|||
block |
|||
danger |
|||
type="link" |
|||
@click="onDelete(row)" |
|||
> |
|||
{{ $t('AbpUi.Delete') }} |
|||
</Button> |
|||
<Dropdown> |
|||
<template #overlay> |
|||
<Menu @click="(info) => onMenuClick(row, info)"> |
|||
<MenuItem key="children"> |
|||
<div class="flex flex-row items-center gap-[4px]"> |
|||
<PlusOutlined /> |
|||
{{ $t('AppPlatform.Data:AddChildren') }} |
|||
</div> |
|||
</MenuItem> |
|||
<MenuItem key="items"> |
|||
<div class="flex flex-row items-center gap-[4px]"> |
|||
<ItemsIcon /> |
|||
{{ $t('AppPlatform.Data:Items') }} |
|||
</div> |
|||
</MenuItem> |
|||
</Menu> |
|||
</template> |
|||
<Button :icon="h(EllipsisOutlined)" type="link" /> |
|||
</Dropdown> |
|||
</div> |
|||
</template> |
|||
</Grid> |
|||
<DataDictionaryItemDrawer /> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -1,2 +1,3 @@ |
|||
export { default as DataDictionaryTable } from './data-dictionaries/DataDictionaryTable.vue'; |
|||
export { default as EmailMessageTable } from './messages/email/EmailMessageTable.vue'; |
|||
export { default as SmsMessageTable } from './messages/sms/SmsMessageTable.vue'; |
|||
|
|||
@ -0,0 +1,76 @@ |
|||
import type { EntityDto, PagedAndSortedResultRequestDto } from '@abp/core'; |
|||
|
|||
enum ValueType { |
|||
Array = 5, |
|||
Boolean = 2, |
|||
Date = 3, |
|||
DateTime = 4, |
|||
Numeic = 1, |
|||
Object = 6, |
|||
String = 0, |
|||
} |
|||
|
|||
interface DataItemDto extends EntityDto<string> { |
|||
allowBeNull: boolean; |
|||
defaultValue?: string; |
|||
description?: string; |
|||
displayName: string; |
|||
name: string; |
|||
valueType: ValueType; |
|||
} |
|||
|
|||
interface DataDto extends EntityDto<string> { |
|||
code: string; |
|||
description?: string; |
|||
displayName: string; |
|||
items: DataItemDto[]; |
|||
name: string; |
|||
parentId?: string; |
|||
} |
|||
|
|||
interface DataCreateOrUpdateDto { |
|||
description?: string; |
|||
displayName: string; |
|||
name: string; |
|||
} |
|||
|
|||
interface DataCreateDto extends DataCreateOrUpdateDto { |
|||
parentId?: string; |
|||
} |
|||
|
|||
interface DataItemCreateOrUpdateDto { |
|||
allowBeNull: boolean; |
|||
defaultValue?: string; |
|||
description?: string; |
|||
displayName: string; |
|||
valueType: ValueType; |
|||
} |
|||
|
|||
interface DataItemCreateDto extends DataItemCreateOrUpdateDto { |
|||
name: string; |
|||
} |
|||
|
|||
interface GetDataListInput extends PagedAndSortedResultRequestDto { |
|||
filter?: string; |
|||
} |
|||
|
|||
interface DataMoveDto { |
|||
parentId?: string; |
|||
} |
|||
|
|||
type DataUpdateDto = DataCreateOrUpdateDto; |
|||
|
|||
type DataItemUpdateDto = DataItemCreateOrUpdateDto; |
|||
|
|||
export { ValueType }; |
|||
|
|||
export type { |
|||
DataCreateDto, |
|||
DataDto, |
|||
DataItemCreateDto, |
|||
DataItemDto, |
|||
DataItemUpdateDto, |
|||
DataMoveDto, |
|||
DataUpdateDto, |
|||
GetDataListInput, |
|||
}; |
|||
@ -1 +1,2 @@ |
|||
export * from './dataDictionaries'; |
|||
export * from './messages'; |
|||
|
|||
Loading…
Reference in new issue