17 changed files with 948 additions and 0 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,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, |
|||
}; |
|||
Loading…
Reference in new issue