committed by
GitHub
20 changed files with 992 additions and 1 deletions
@ -0,0 +1,15 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { Page } from '@vben/common-ui'; |
||||
|
|
||||
|
import { EmailMessageTable } from '@abp/platform'; |
||||
|
|
||||
|
defineOptions({ |
||||
|
name: 'PlatformEmailMessages', |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Page> |
||||
|
<EmailMessageTable /> |
||||
|
</Page> |
||||
|
</template> |
||||
@ -0,0 +1,15 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { Page } from '@vben/common-ui'; |
||||
|
|
||||
|
import { SmsMessageTable } from '@abp/platform'; |
||||
|
|
||||
|
defineOptions({ |
||||
|
name: 'PlatformSmsMessages', |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Page> |
||||
|
<SmsMessageTable /> |
||||
|
</Page> |
||||
|
</template> |
||||
@ -0,0 +1,37 @@ |
|||||
|
{ |
||||
|
"name": "@abp/platform", |
||||
|
"version": "8.3.4", |
||||
|
"homepage": "https://github.com/colinin/abp-next-admin", |
||||
|
"bugs": "https://github.com/colinin/abp-next-admin/issues", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/colinin/abp-next-admin.git", |
||||
|
"directory": "packages/@abp/platform" |
||||
|
}, |
||||
|
"license": "MIT", |
||||
|
"type": "module", |
||||
|
"sideEffects": [ |
||||
|
"**/*.css" |
||||
|
], |
||||
|
"exports": { |
||||
|
".": { |
||||
|
"types": "./src/index.ts", |
||||
|
"default": "./src/index.ts" |
||||
|
} |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@abp/core": "workspace:*", |
||||
|
"@abp/request": "workspace:*", |
||||
|
"@abp/ui": "workspace:*", |
||||
|
"@ant-design/icons-vue": "catalog:", |
||||
|
"@vben/access": "workspace:*", |
||||
|
"@vben/common-ui": "workspace:*", |
||||
|
"@vben/hooks": "workspace:*", |
||||
|
"@vben/icons": "workspace:*", |
||||
|
"@vben/layouts": "workspace:*", |
||||
|
"@vben/locales": "workspace:*", |
||||
|
"ant-design-vue": "catalog:", |
||||
|
"vue": "catalog:*", |
||||
|
"vxe-table": "catalog:" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
export * from './useEmailMessagesApi'; |
||||
|
export * from './useSmsMessagesApi'; |
||||
@ -0,0 +1,66 @@ |
|||||
|
import type { PagedResultDto } from '@abp/core'; |
||||
|
|
||||
|
import type { |
||||
|
EmailMessageDto, |
||||
|
EmailMessageGetListInput, |
||||
|
} from '../types/messages'; |
||||
|
|
||||
|
import { useRequest } from '@abp/request'; |
||||
|
|
||||
|
export function useEmailMessagesApi() { |
||||
|
const { cancel, request } = useRequest(); |
||||
|
/** |
||||
|
* 获取邮件消息分页列表 |
||||
|
* @param {EmailMessageGetListInput} input 参数 |
||||
|
* @returns {Promise<PagedResultDto<EmailMessageDto>>} 邮件消息列表 |
||||
|
*/ |
||||
|
function getPagedListApi( |
||||
|
input?: EmailMessageGetListInput, |
||||
|
): Promise<PagedResultDto<EmailMessageDto>> { |
||||
|
return request<PagedResultDto<EmailMessageDto>>( |
||||
|
'/api/platform/messages/email', |
||||
|
{ |
||||
|
method: 'GET', |
||||
|
params: input, |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
|
/** |
||||
|
* 获取邮件消息 |
||||
|
* @param id Id |
||||
|
* @returns {EmailMessageDto} 邮件消息 |
||||
|
*/ |
||||
|
function getApi(id: string): Promise<EmailMessageDto> { |
||||
|
return request<EmailMessageDto>(`/api/platform/messages/email/${id}`, { |
||||
|
method: 'GET', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 删除邮件消息 |
||||
|
* @param id Id |
||||
|
* @returns {void} |
||||
|
*/ |
||||
|
function deleteApi(id: string): Promise<void> { |
||||
|
return request(`/api/platform/messages/email/${id}`, { |
||||
|
method: 'DELETE', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 发送邮件消息 |
||||
|
* @param id Id |
||||
|
* @returns {void} |
||||
|
*/ |
||||
|
function sendApi(id: string): Promise<void> { |
||||
|
return request(`/api/platform/messages/email/${id}/send`, { |
||||
|
method: 'POST', |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
cancel, |
||||
|
deleteApi, |
||||
|
getApi, |
||||
|
getPagedListApi, |
||||
|
sendApi, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
import type { PagedResultDto } from '@abp/core'; |
||||
|
|
||||
|
import type { SmsMessageDto, SmsMessageGetListInput } from '../types'; |
||||
|
|
||||
|
import { useRequest } from '@abp/request'; |
||||
|
|
||||
|
export function useSmsMessagesApi() { |
||||
|
const { cancel, request } = useRequest(); |
||||
|
/** |
||||
|
* 获取短信消息分页列表 |
||||
|
* @param {EmailMessageGetListInput} input 参数 |
||||
|
* @returns {Promise<PagedResultDto<EmailMessageDto>>} 短信消息列表 |
||||
|
*/ |
||||
|
function getPagedListApi( |
||||
|
input?: SmsMessageGetListInput, |
||||
|
): Promise<PagedResultDto<SmsMessageDto>> { |
||||
|
return request<PagedResultDto<SmsMessageDto>>( |
||||
|
'/api/platform/messages/sms', |
||||
|
{ |
||||
|
method: 'GET', |
||||
|
params: input, |
||||
|
}, |
||||
|
); |
||||
|
} |
||||
|
/** |
||||
|
* 获取短信消息 |
||||
|
* @param id Id |
||||
|
* @returns {SmsMessageDto} 短信消息 |
||||
|
*/ |
||||
|
function getApi(id: string): Promise<SmsMessageDto> { |
||||
|
return request<SmsMessageDto>(`/api/platform/messages/sms/${id}`, { |
||||
|
method: 'GET', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 删除短信消息 |
||||
|
* @param id Id |
||||
|
* @returns {void} |
||||
|
*/ |
||||
|
function deleteApi(id: string): Promise<void> { |
||||
|
return request(`/api/platform/messages/sms/${id}`, { |
||||
|
method: 'DELETE', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 发送短信消息 |
||||
|
* @param id Id |
||||
|
* @returns {void} |
||||
|
*/ |
||||
|
function sendApi(id: string): Promise<void> { |
||||
|
return request(`/api/platform/messages/sms/${id}/send`, { |
||||
|
method: 'POST', |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
cancel, |
||||
|
deleteApi, |
||||
|
getApi, |
||||
|
getPagedListApi, |
||||
|
sendApi, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
export { default as EmailMessageTable } from './messages/email/EmailMessageTable.vue'; |
||||
|
export { default as SmsMessageTable } from './messages/sms/SmsMessageTable.vue'; |
||||
@ -0,0 +1,310 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { VbenFormProps, VxeGridProps } from '@abp/ui'; |
||||
|
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; |
||||
|
|
||||
|
import type { EmailMessageDto } from '../../../types/messages'; |
||||
|
|
||||
|
import { h } from 'vue'; |
||||
|
|
||||
|
import { useAccess } from '@vben/access'; |
||||
|
import { createIconifyIcon } from '@vben/icons'; |
||||
|
import { $t } from '@vben/locales'; |
||||
|
|
||||
|
import { formatToDateTime } from '@abp/core'; |
||||
|
import { useVbenVxeGrid } from '@abp/ui'; |
||||
|
import { |
||||
|
DeleteOutlined, |
||||
|
EditOutlined, |
||||
|
EllipsisOutlined, |
||||
|
} from '@ant-design/icons-vue'; |
||||
|
import { Button, Dropdown, Menu, message, Modal, Tag } from 'ant-design-vue'; |
||||
|
|
||||
|
import { useEmailMessagesApi } from '../../../api/useEmailMessagesApi'; |
||||
|
import { EmailMessagesPermissions } from '../../../constants/permissions'; |
||||
|
import { MessageStatus } from '../../../types/messages'; |
||||
|
|
||||
|
defineOptions({ |
||||
|
name: 'EmailMessageTable', |
||||
|
}); |
||||
|
|
||||
|
const MenuItem = Menu.Item; |
||||
|
const SendMessageIcon = createIconifyIcon('ant-design:send-outlined'); |
||||
|
|
||||
|
const { hasAccessByCodes } = useAccess(); |
||||
|
const { deleteApi, getPagedListApi, sendApi } = useEmailMessagesApi(); |
||||
|
|
||||
|
const formOptions: VbenFormProps = { |
||||
|
// 默认展开 |
||||
|
collapsed: true, |
||||
|
collapsedRows: 2, |
||||
|
// 所有表单项共用,可单独在表单内覆盖 |
||||
|
commonConfig: { |
||||
|
// 在label后显示一个冒号 |
||||
|
colon: true, |
||||
|
// 所有表单项 |
||||
|
componentProps: { |
||||
|
class: 'w-full', |
||||
|
}, |
||||
|
}, |
||||
|
fieldMappingTime: [ |
||||
|
['sendTime', ['beginSendTime', 'endSendTime'], 'YYYY-MM-DD'], |
||||
|
], |
||||
|
schema: [ |
||||
|
{ |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: [ |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Pending'), |
||||
|
value: MessageStatus.Pending, |
||||
|
}, |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Sent'), |
||||
|
value: MessageStatus.Sent, |
||||
|
}, |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Failed'), |
||||
|
value: MessageStatus.Failed, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
fieldName: 'status', |
||||
|
label: $t('AppPlatform.DisplayName:Status'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'Input', |
||||
|
fieldName: 'emailAddress', |
||||
|
label: $t('AppPlatform.DisplayName:Receiver'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'RangePicker', |
||||
|
fieldName: 'sendTime', |
||||
|
label: $t('AppPlatform.DisplayName:SendTime'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'Input', |
||||
|
fieldName: 'filter', |
||||
|
formItemClass: 'col-span-2 items-baseline', |
||||
|
label: $t('AbpUi.Search'), |
||||
|
}, |
||||
|
], |
||||
|
// 控制表单是否显示折叠按钮 |
||||
|
showCollapseButton: true, |
||||
|
// 按下回车时是否提交表单 |
||||
|
submitOnEnter: true, |
||||
|
}; |
||||
|
|
||||
|
const gridOptions: VxeGridProps<EmailMessageDto> = { |
||||
|
columns: [ |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'provider', |
||||
|
minWidth: 180, |
||||
|
title: $t('AppPlatform.DisplayName:Provider'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'status', |
||||
|
minWidth: 150, |
||||
|
slots: { default: 'status' }, |
||||
|
title: $t('AppPlatform.DisplayName:Status'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'sendTime', |
||||
|
formatter: ({ cellValue }) => { |
||||
|
return cellValue ? formatToDateTime(cellValue) : cellValue; |
||||
|
}, |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:SendTime'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'center', |
||||
|
field: 'sendCount', |
||||
|
minWidth: 100, |
||||
|
title: $t('AppPlatform.DisplayName:SendCount'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'subject', |
||||
|
minWidth: 180, |
||||
|
title: $t('AppPlatform.DisplayName:Subject'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'content', |
||||
|
minWidth: 220, |
||||
|
title: $t('AppPlatform.DisplayName:Content'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'from', |
||||
|
minWidth: 220, |
||||
|
title: $t('AppPlatform.DisplayName:From'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'receiver', |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:Receiver'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'creationTime', |
||||
|
formatter: ({ cellValue }) => { |
||||
|
return cellValue ? formatToDateTime(cellValue) : cellValue; |
||||
|
}, |
||||
|
minWidth: 200, |
||||
|
title: $t('AppPlatform.DisplayName:CreationTime'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'reason', |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:Reason'), |
||||
|
}, |
||||
|
{ |
||||
|
field: 'action', |
||||
|
fixed: 'right', |
||||
|
slots: { default: 'action' }, |
||||
|
title: $t('AbpUi.Actions'), |
||||
|
visible: hasAccessByCodes([EmailMessagesPermissions.Delete]), |
||||
|
width: 220, |
||||
|
}, |
||||
|
], |
||||
|
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, |
||||
|
refresh: true, |
||||
|
zoom: true, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
const [Grid, gridApi] = useVbenVxeGrid({ |
||||
|
formOptions, |
||||
|
gridOptions, |
||||
|
}); |
||||
|
|
||||
|
function onUpdate(row: EmailMessageDto) { |
||||
|
console.warn('onUpdate is not implementation!', row); |
||||
|
} |
||||
|
|
||||
|
function onDelete(row: EmailMessageDto) { |
||||
|
Modal.confirm({ |
||||
|
afterClose: () => { |
||||
|
gridApi.setLoading(false); |
||||
|
}, |
||||
|
centered: true, |
||||
|
content: `${$t('AbpUi.ItemWillBeDeletedMessage')}`, |
||||
|
onOk: async () => { |
||||
|
try { |
||||
|
gridApi.setLoading(true); |
||||
|
await deleteApi(row.id); |
||||
|
message.success($t('AbpUi.SuccessfullyDeleted')); |
||||
|
gridApi.reload(); |
||||
|
} finally { |
||||
|
gridApi.setLoading(false); |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async function onSend(row: EmailMessageDto) { |
||||
|
Modal.confirm({ |
||||
|
centered: true, |
||||
|
content: `${$t('AppPlatform.MessageWillBeReSendWarningMessage')}`, |
||||
|
onOk: async () => { |
||||
|
try { |
||||
|
gridApi.setLoading(true); |
||||
|
await sendApi(row.id); |
||||
|
message.success($t('AppPlatform.SuccessfullySent')); |
||||
|
gridApi.reload(); |
||||
|
} finally { |
||||
|
gridApi.setLoading(false); |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
async function onMenuClick(row: EmailMessageDto, info: MenuInfo) { |
||||
|
switch (info.key) { |
||||
|
case 'send': { |
||||
|
await onSend(row); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Grid :table-title="$t('AppPlatform.EmailMessages')"> |
||||
|
<template #status="{ row }"> |
||||
|
<Tag v-if="row.status === MessageStatus.Pending" color="warning"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Pending') }} |
||||
|
</Tag> |
||||
|
<Tag v-else-if="row.status === MessageStatus.Sent" color="success"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Sent') }} |
||||
|
</Tag> |
||||
|
<Tag v-else-if="row.status === MessageStatus.Failed" color="error"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Failed') }} |
||||
|
</Tag> |
||||
|
</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" |
||||
|
v-access:code="[EmailMessagesPermissions.Delete]" |
||||
|
@click="onDelete(row)" |
||||
|
> |
||||
|
{{ $t('AbpUi.Delete') }} |
||||
|
</Button> |
||||
|
<Dropdown> |
||||
|
<template #overlay> |
||||
|
<Menu @click="(info) => onMenuClick(row, info)"> |
||||
|
<MenuItem |
||||
|
v-if="hasAccessByCodes([EmailMessagesPermissions.SendMessage])" |
||||
|
key="send" |
||||
|
> |
||||
|
<div class="flex flex-row items-center gap-[4px]"> |
||||
|
<SendMessageIcon color="green" /> |
||||
|
{{ $t('AppPlatform.SendMessage') }} |
||||
|
</div> |
||||
|
</MenuItem> |
||||
|
</Menu> |
||||
|
</template> |
||||
|
<Button :icon="h(EllipsisOutlined)" type="link" /> |
||||
|
</Dropdown> |
||||
|
</div> |
||||
|
</template> |
||||
|
</Grid> |
||||
|
</template> |
||||
|
|
||||
|
<style lang="scss" scoped></style> |
||||
@ -0,0 +1,299 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { VbenFormProps, VxeGridProps } from '@abp/ui'; |
||||
|
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; |
||||
|
|
||||
|
import type { SmsMessageDto } from '../../../types/messages'; |
||||
|
|
||||
|
import { h } from 'vue'; |
||||
|
|
||||
|
import { useAccess } from '@vben/access'; |
||||
|
import { createIconifyIcon } from '@vben/icons'; |
||||
|
import { $t } from '@vben/locales'; |
||||
|
|
||||
|
import { formatToDateTime } from '@abp/core'; |
||||
|
import { useVbenVxeGrid } from '@abp/ui'; |
||||
|
import { |
||||
|
DeleteOutlined, |
||||
|
EditOutlined, |
||||
|
EllipsisOutlined, |
||||
|
} from '@ant-design/icons-vue'; |
||||
|
import { Button, Dropdown, Menu, message, Modal, Tag } from 'ant-design-vue'; |
||||
|
|
||||
|
import { useSmsMessagesApi } from '../../../api/useSmsMessagesApi'; |
||||
|
import { SmsMessagesPermissions } from '../../../constants/permissions'; |
||||
|
import { MessageStatus } from '../../../types/messages'; |
||||
|
|
||||
|
defineOptions({ |
||||
|
name: 'EmailMessageTable', |
||||
|
}); |
||||
|
|
||||
|
const MenuItem = Menu.Item; |
||||
|
const SendMessageIcon = createIconifyIcon('ant-design:send-outlined'); |
||||
|
|
||||
|
const { hasAccessByCodes } = useAccess(); |
||||
|
const { deleteApi, getPagedListApi, sendApi } = useSmsMessagesApi(); |
||||
|
|
||||
|
const formOptions: VbenFormProps = { |
||||
|
// 默认展开 |
||||
|
collapsed: true, |
||||
|
collapsedRows: 2, |
||||
|
// 所有表单项共用,可单独在表单内覆盖 |
||||
|
commonConfig: { |
||||
|
// 在label后显示一个冒号 |
||||
|
colon: true, |
||||
|
// 所有表单项 |
||||
|
componentProps: { |
||||
|
class: 'w-full', |
||||
|
}, |
||||
|
}, |
||||
|
fieldMappingTime: [ |
||||
|
['sendTime', ['beginSendTime', 'endSendTime'], 'YYYY-MM-DD'], |
||||
|
], |
||||
|
schema: [ |
||||
|
{ |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: [ |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Pending'), |
||||
|
value: MessageStatus.Pending, |
||||
|
}, |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Sent'), |
||||
|
value: MessageStatus.Sent, |
||||
|
}, |
||||
|
{ |
||||
|
label: $t('AppPlatform.MessageStatus:Failed'), |
||||
|
value: MessageStatus.Failed, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
fieldName: 'status', |
||||
|
label: $t('AppPlatform.DisplayName:Status'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'Input', |
||||
|
fieldName: 'phoneNumber', |
||||
|
label: $t('AppPlatform.DisplayName:Receiver'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'RangePicker', |
||||
|
fieldName: 'sendTime', |
||||
|
label: $t('AppPlatform.DisplayName:SendTime'), |
||||
|
}, |
||||
|
{ |
||||
|
component: 'Input', |
||||
|
fieldName: 'filter', |
||||
|
formItemClass: 'col-span-2 items-baseline', |
||||
|
label: $t('AbpUi.Search'), |
||||
|
}, |
||||
|
], |
||||
|
// 控制表单是否显示折叠按钮 |
||||
|
showCollapseButton: true, |
||||
|
// 按下回车时是否提交表单 |
||||
|
submitOnEnter: true, |
||||
|
}; |
||||
|
|
||||
|
const gridOptions: VxeGridProps<SmsMessageDto> = { |
||||
|
columns: [ |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'provider', |
||||
|
minWidth: 180, |
||||
|
title: $t('AppPlatform.DisplayName:Provider'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'status', |
||||
|
minWidth: 150, |
||||
|
slots: { default: 'status' }, |
||||
|
title: $t('AppPlatform.DisplayName:Status'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'sendTime', |
||||
|
formatter: ({ cellValue }) => { |
||||
|
return cellValue ? formatToDateTime(cellValue) : cellValue; |
||||
|
}, |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:SendTime'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'content', |
||||
|
minWidth: 220, |
||||
|
title: $t('AppPlatform.DisplayName:Content'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'receiver', |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:Receiver'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'center', |
||||
|
field: 'sendCount', |
||||
|
minWidth: 100, |
||||
|
title: $t('AppPlatform.DisplayName:SendCount'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'creationTime', |
||||
|
formatter: ({ cellValue }) => { |
||||
|
return cellValue ? formatToDateTime(cellValue) : cellValue; |
||||
|
}, |
||||
|
minWidth: 200, |
||||
|
title: $t('AppPlatform.DisplayName:CreationTime'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'reason', |
||||
|
minWidth: 150, |
||||
|
title: $t('AppPlatform.DisplayName:Reason'), |
||||
|
}, |
||||
|
{ |
||||
|
field: 'action', |
||||
|
fixed: 'right', |
||||
|
slots: { default: 'action' }, |
||||
|
title: $t('AbpUi.Actions'), |
||||
|
visible: hasAccessByCodes([SmsMessagesPermissions.Delete]), |
||||
|
width: 220, |
||||
|
}, |
||||
|
], |
||||
|
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 [Grid, gridApi] = useVbenVxeGrid({ |
||||
|
formOptions, |
||||
|
gridOptions, |
||||
|
}); |
||||
|
|
||||
|
function onUpdate(row: SmsMessageDto) { |
||||
|
console.warn('onUpdate is not implementation!', row); |
||||
|
} |
||||
|
|
||||
|
function onDelete(row: SmsMessageDto) { |
||||
|
Modal.confirm({ |
||||
|
afterClose: () => { |
||||
|
gridApi.setLoading(false); |
||||
|
}, |
||||
|
centered: true, |
||||
|
content: `${$t('AbpUi.ItemWillBeDeletedMessage')}`, |
||||
|
onOk: async () => { |
||||
|
try { |
||||
|
gridApi.setLoading(true); |
||||
|
await deleteApi(row.id); |
||||
|
message.success($t('AbpUi.SuccessfullyDeleted')); |
||||
|
gridApi.reload(); |
||||
|
} finally { |
||||
|
gridApi.setLoading(false); |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async function onSend(row: SmsMessageDto) { |
||||
|
Modal.confirm({ |
||||
|
centered: true, |
||||
|
content: `${$t('AppPlatform.MessageWillBeReSendWarningMessage')}`, |
||||
|
onOk: async () => { |
||||
|
try { |
||||
|
gridApi.setLoading(true); |
||||
|
await sendApi(row.id); |
||||
|
message.success($t('AppPlatform.SuccessfullySent')); |
||||
|
gridApi.reload(); |
||||
|
} finally { |
||||
|
gridApi.setLoading(false); |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
async function onMenuClick(row: SmsMessageDto, info: MenuInfo) { |
||||
|
switch (info.key) { |
||||
|
case 'send': { |
||||
|
await onSend(row); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Grid :table-title="$t('AppPlatform.SmsMessages')"> |
||||
|
<template #status="{ row }"> |
||||
|
<Tag v-if="row.status === MessageStatus.Pending" color="warning"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Pending') }} |
||||
|
</Tag> |
||||
|
<Tag v-else-if="row.status === MessageStatus.Sent" color="success"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Sent') }} |
||||
|
</Tag> |
||||
|
<Tag v-else-if="row.status === MessageStatus.Failed" color="error"> |
||||
|
{{ $t('AppPlatform.MessageStatus:Failed') }} |
||||
|
</Tag> |
||||
|
</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" |
||||
|
v-access:code="[SmsMessagesPermissions.Delete]" |
||||
|
@click="onDelete(row)" |
||||
|
> |
||||
|
{{ $t('AbpUi.Delete') }} |
||||
|
</Button> |
||||
|
<Dropdown> |
||||
|
<template #overlay> |
||||
|
<Menu @click="(info) => onMenuClick(row, info)"> |
||||
|
<MenuItem |
||||
|
v-if="hasAccessByCodes([SmsMessagesPermissions.SendMessage])" |
||||
|
key="send" |
||||
|
> |
||||
|
<div class="flex flex-row items-center gap-[4px]"> |
||||
|
<SendMessageIcon color="green" /> |
||||
|
{{ $t('AppPlatform.SendMessage') }} |
||||
|
</div> |
||||
|
</MenuItem> |
||||
|
</Menu> |
||||
|
</template> |
||||
|
<Button :icon="h(EllipsisOutlined)" type="link" /> |
||||
|
</Dropdown> |
||||
|
</div> |
||||
|
</template> |
||||
|
</Grid> |
||||
|
</template> |
||||
|
|
||||
|
<style lang="scss" scoped></style> |
||||
@ -0,0 +1 @@ |
|||||
|
export * from './permissions'; |
||||
@ -0,0 +1,16 @@ |
|||||
|
/** 邮件消息权限 */ |
||||
|
export const EmailMessagesPermissions = { |
||||
|
Default: 'Platform.EmailMessage', |
||||
|
/** 删除 */ |
||||
|
Delete: 'Platform.EmailMessage.Delete', |
||||
|
/** 发送消息 */ |
||||
|
SendMessage: 'Platform.EmailMessage.SendMessage', |
||||
|
}; |
||||
|
/** 短信消息权限 */ |
||||
|
export const SmsMessagesPermissions = { |
||||
|
Default: 'Platform.SmsMessage', |
||||
|
/** 删除 */ |
||||
|
Delete: 'Platform.SmsMessage.Delete', |
||||
|
/** 发送消息 */ |
||||
|
SendMessage: 'Platform.SmsMessage.SendMessage', |
||||
|
}; |
||||
@ -0,0 +1,4 @@ |
|||||
|
export * from './api'; |
||||
|
export * from './components'; |
||||
|
export * from './constants'; |
||||
|
export * from './types'; |
||||
@ -0,0 +1 @@ |
|||||
|
export * from './messages'; |
||||
@ -0,0 +1,97 @@ |
|||||
|
import type { |
||||
|
AuditedEntityDto, |
||||
|
PagedAndSortedResultRequestDto, |
||||
|
} from '@abp/core'; |
||||
|
|
||||
|
/** 消息状态 */ |
||||
|
export enum MessageStatus { |
||||
|
/** 发送失败 */ |
||||
|
Failed = 10, |
||||
|
/** 未发送 */ |
||||
|
Pending = -1, |
||||
|
/** 已发送 */ |
||||
|
Sent = 0, |
||||
|
} |
||||
|
/** 邮件优先级 */ |
||||
|
export enum MailPriority { |
||||
|
/** 高 */ |
||||
|
High = 2, |
||||
|
/** 低 */ |
||||
|
Low = 1, |
||||
|
/** 普通 */ |
||||
|
Normal = 0, |
||||
|
} |
||||
|
|
||||
|
interface MessageDto extends AuditedEntityDto<string> { |
||||
|
/** 消息内容 */ |
||||
|
content: string; |
||||
|
/** 消息发布者 */ |
||||
|
provider?: string; |
||||
|
/** 错误原因 */ |
||||
|
reason?: string; |
||||
|
/** 接收方 */ |
||||
|
receiver: string; |
||||
|
/** 发送次数 */ |
||||
|
sendCount: number; |
||||
|
/** 发送人 */ |
||||
|
sender?: string; |
||||
|
/** 发送时间 */ |
||||
|
sendTime?: Date; |
||||
|
/** 状态 */ |
||||
|
status: MessageStatus; |
||||
|
/** 发送人Id */ |
||||
|
userId?: string; |
||||
|
} |
||||
|
/** 邮件附件 */ |
||||
|
interface EmailMessageAttachmentDto { |
||||
|
/** 附件存储名称 */ |
||||
|
blobName: string; |
||||
|
/** 附件名称 */ |
||||
|
name: string; |
||||
|
/** 附件大小 */ |
||||
|
size: number; |
||||
|
} |
||||
|
/** 邮件标头 */ |
||||
|
interface EmailMessageHeaderDto { |
||||
|
/** 键名 */ |
||||
|
key: string; |
||||
|
/** 键值 */ |
||||
|
value: string; |
||||
|
} |
||||
|
/** 邮件消息 */ |
||||
|
interface EmailMessageDto extends MessageDto { |
||||
|
attachments: EmailMessageAttachmentDto[]; |
||||
|
cc?: string; |
||||
|
from?: string; |
||||
|
headers: EmailMessageHeaderDto[]; |
||||
|
isBodyHtml: boolean; |
||||
|
normalize: boolean; |
||||
|
priority?: MailPriority; |
||||
|
subject?: string; |
||||
|
} |
||||
|
|
||||
|
interface EmailMessageGetListInput extends PagedAndSortedResultRequestDto { |
||||
|
beginSendTime?: Date; |
||||
|
content?: string; |
||||
|
emailAddress?: string; |
||||
|
endSendTime?: Date; |
||||
|
from?: string; |
||||
|
priority?: MailPriority; |
||||
|
subject?: string; |
||||
|
} |
||||
|
|
||||
|
type SmsMessageDto = MessageDto; |
||||
|
|
||||
|
interface SmsMessageGetListInput extends PagedAndSortedResultRequestDto { |
||||
|
beginSendTime?: Date; |
||||
|
content?: string; |
||||
|
endSendTime?: Date; |
||||
|
phoneNumber?: string; |
||||
|
} |
||||
|
|
||||
|
export type { |
||||
|
EmailMessageDto, |
||||
|
EmailMessageGetListInput, |
||||
|
SmsMessageDto, |
||||
|
SmsMessageGetListInput, |
||||
|
}; |
||||
@ -0,0 +1,6 @@ |
|||||
|
{ |
||||
|
"$schema": "https://json.schemastore.org/tsconfig", |
||||
|
"extends": "@vben/tsconfig/web.json", |
||||
|
"include": ["src"], |
||||
|
"exclude": ["node_modules"] |
||||
|
} |
||||
Loading…
Reference in new issue