feat:【system 系统功能】邮箱增加抄送、密送,支持多个

pull/191/head^2
YunaiV 2025-08-05 21:45:23 +08:00
parent 6d99bf3a46
commit 55061b73de
6 changed files with 103 additions and 28 deletions

View File

@ -8,7 +8,9 @@ export namespace SystemMailLogApi {
id: number; id: number;
userId: number; userId: number;
userType: number; userType: number;
toMail: string; toMails: string[];
ccMails?: string[];
bccMails?: string[];
accountId: number; accountId: number;
fromMail: string; fromMail: string;
templateId: number; templateId: number;
@ -32,15 +34,3 @@ export function getMailLogPage(params: PageParam) {
{ params }, { params },
); );
} }
/** 查询邮件日志详情 */
export function getMailLog(id: number) {
return requestClient.get<SystemMailLogApi.MailLog>(
`/system/mail-log/get?id=${id}`,
);
}
/** 重新发送邮件 */
export function resendMail(id: number) {
return requestClient.put(`/system/mail-log/resend?id=${id}`);
}

View File

@ -20,7 +20,9 @@ export namespace SystemMailTemplateApi {
/** 邮件发送信息 */ /** 邮件发送信息 */
export interface MailSendReq { export interface MailSendReq {
mail: string; toMails: string[];
ccMails?: string[];
bccMails?: string[];
templateCode: string; templateCode: string;
templateParams: Record<string, any>; templateParams: Record<string, any>;
} }

View File

@ -88,8 +88,28 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
formatter: 'formatDateTime', formatter: 'formatDateTime',
}, },
{ {
field: 'toMail', field: 'userType',
title: '收件邮箱', title: '接收用户',
width: 150,
slots: { default: 'userInfo' },
},
{
field: 'toMails',
title: '接收信息',
width: 300,
formatter: ({ row }) => {
const lines: string[] = [];
if (row.toMails && row.toMails.length > 0) {
lines.push(`收件:${row.toMails.join('、')}`);
}
if (row.ccMails && row.ccMails.length > 0) {
lines.push(`抄送:${row.ccMails.join('、')}`);
}
if (row.bccMails && row.bccMails.length > 0) {
lines.push(`密送:${row.bccMails.join('、')}`);
}
return lines.join('\n');
},
}, },
{ {
field: 'templateTitle', field: 'templateTitle',
@ -136,21 +156,48 @@ export function useDetailSchema(): DescriptionItemSchema[] {
label: '创建时间', label: '创建时间',
content: (data) => formatDateTime(data?.createTime || '') as string, content: (data) => formatDateTime(data?.createTime || '') as string,
}, },
{
field: 'toMail',
label: '收件邮箱',
},
{ {
field: 'fromMail', field: 'fromMail',
label: '发送邮箱', label: '发送邮箱',
}, },
{ {
field: 'userId', field: 'userId',
label: '用户编号', label: '接收用户',
content: (data) => {
if (data?.userType && data?.userId) {
return h('div', [
h(DictTag, {
type: DICT_TYPE.USER_TYPE,
value: data.userType,
}),
` (${data.userId})`,
]);
}
return '无';
},
}, },
{ {
field: 'userType', field: 'toMails',
label: '用户类型', label: '接收信息',
content: (data) => {
const lines: string[] = [];
if (data?.toMails && data.toMails.length > 0) {
lines.push(`收件:${data.toMails.join('、')}`);
}
if (data?.ccMails && data.ccMails.length > 0) {
lines.push(`抄送:${data.ccMails.join('、')}`);
}
if (data?.bccMails && data.bccMails.length > 0) {
lines.push(`密送:${data.bccMails.join('、')}`);
}
return h(
'div',
{
style: { whiteSpace: 'pre-line' },
},
lines.join('\n'),
);
},
}, },
{ {
field: 'templateId', field: 'templateId',

View File

@ -6,6 +6,8 @@ import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getMailLogPage } from '#/api/system/mail/log'; import { getMailLogPage } from '#/api/system/mail/log';
import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE } from '#/utils';
import { useGridColumns, useGridFormSchema } from './data'; import { useGridColumns, useGridFormSchema } from './data';
import Detail from './modules/detail.vue'; import Detail from './modules/detail.vue';
@ -62,6 +64,13 @@ const [Grid, gridApi] = useVbenVxeGrid({
<DetailModal @success="onRefresh" /> <DetailModal @success="onRefresh" />
<Grid table-title=""> <Grid table-title="">
<template #userInfo="{ row }">
<div v-if="row.userType && row.userId" class="flex items-center gap-1">
<DictTag :type="DICT_TYPE.USER_TYPE" :value="row.userType" />
<span>({{ row.userId }})</span>
</div>
<div v-else>-</div>
</template>
<template #actions="{ row }"> <template #actions="{ row }">
<TableAction <TableAction
:actions="[ :actions="[

View File

@ -121,13 +121,31 @@ export function useSendMailFormSchema(): VbenFormSchema[] {
}, },
}, },
{ {
fieldName: 'mail', fieldName: 'toMails',
label: '收件邮箱', label: '收件邮箱',
component: 'Input', component: 'Textarea',
componentProps: { componentProps: {
placeholder: '请输入收件邮箱', placeholder: '请输入收件邮箱,每行一个邮箱地址',
rows: 3,
},
},
{
fieldName: 'ccMails',
label: '抄送邮箱',
component: 'Textarea',
componentProps: {
placeholder: '请输入抄送邮箱,每行一个邮箱地址',
rows: 2,
},
},
{
fieldName: 'bccMails',
label: '密送邮箱',
component: 'Textarea',
componentProps: {
placeholder: '请输入密送邮箱,每行一个邮箱地址',
rows: 2,
}, },
rules: z.string().email('请输入正确的邮箱'),
}, },
]; ];
} }

View File

@ -42,8 +42,17 @@ const [Modal, modalApi] = useVbenModal({
paramsObj[param] = values[`param_${param}`]; paramsObj[param] = values[`param_${param}`];
}); });
} }
const parseEmails = (text: string): string[] => {
if (!text) return [];
return text
.split('\n')
.map((email) => email.trim())
.filter((email) => email.length > 0);
};
const data: SystemMailTemplateApi.MailSendReq = { const data: SystemMailTemplateApi.MailSendReq = {
mail: values.mail, toMails: parseEmails(values.toMails || ''),
ccMails: parseEmails(values.ccMails || ''),
bccMails: parseEmails(values.bccMails || ''),
templateCode: formData.value?.code || '', templateCode: formData.value?.code || '',
templateParams: paramsObj, templateParams: paramsObj,
}; };