refact email search api

This commit is contained in:
oiov
2025-04-05 10:33:51 +08:00
parent b261ce51c4
commit fae6afd952
3 changed files with 66 additions and 41 deletions
+8 -15
View File
@@ -74,14 +74,15 @@ export default function EmailSidebar({
const pageSize = 10;
// Updated to use useSWR with explicit page and size parameters
const { data, isLoading, error, mutate } = useSWR<{
list: UserEmailList[];
total: number;
totalInboxCount: number;
totalUnreadCount: number;
}>(
`/api/email?page=${currentPage}&size=${pageSize}&search=${searchQuery}&all=${isAdminModel}`,
fetcher,
{ dedupingInterval: 3000 },
{ dedupingInterval: 5000 },
);
if (!selectedEmailAddress && data && data.list.length > 0) {
@@ -91,16 +92,6 @@ export default function EmailSidebar({
const userEmails = data?.list || [];
const totalPages = data ? Math.ceil(data.total / pageSize) : 0;
const totalInboxEmails = userEmails.reduce(
(sum, email) => sum + (email.count || 0),
0,
);
const totalUnreadEmails = userEmails.reduce(
(sum, email) => sum + (email.unreadCount || 0),
0,
);
const handleSubmitEmail = async (emailSuffix: string) => {
if (!emailSuffix) {
toast.error("Email address cannot be empty");
@@ -289,7 +280,9 @@ export default function EmailSidebar({
<div className="flex flex-col items-center gap-1 rounded-md bg-neutral-100 px-1 pb-1 pt-2 transition-colors hover:bg-neutral-200 dark:bg-neutral-800 dark:hover:bg-gray-700">
<div className="flex items-center gap-1">
<Icons.mail className="size-3" />
<p className="line-clamp-1 text-start font-medium">Address</p>
<p className="line-clamp-1 text-start font-medium">
Email Address
</p>
</div>
<p className="text-base font-semibold text-gray-900 dark:text-gray-100">
<CountUp count={data ? data.total : 0} />
@@ -305,7 +298,7 @@ export default function EmailSidebar({
</p>
</div>
<p className="text-base font-semibold text-gray-900 dark:text-gray-100">
<CountUp count={totalInboxEmails} />
<CountUp count={data ? data.totalInboxCount : 0} />
</p>
</div>
@@ -317,7 +310,7 @@ export default function EmailSidebar({
</p>
</div>
<p className="text-base font-semibold text-gray-900 dark:text-gray-100">
<CountUp count={totalUnreadEmails} />
<CountUp count={data ? data.totalUnreadCount : 0} />
</p>
</div>
+57 -25
View File
@@ -91,44 +91,74 @@ export async function getAllUserEmails(
};
}
const [userEmails, total] = await Promise.all([
prisma.userEmail.findMany({
where: { ...whereOptions },
select: {
id: true,
userId: true,
emailAddress: true,
createdAt: true,
updatedAt: true,
_count: { select: { forwardEmails: true } },
user: { select: { name: true, email: true } },
forwardEmails: {
select: {
readAt: true,
},
// Fetch paginated UserEmail records
const userEmailsPromise = prisma.userEmail.findMany({
where: { ...whereOptions },
select: {
id: true,
userId: true,
emailAddress: true,
createdAt: true,
updatedAt: true,
_count: { select: { forwardEmails: true } }, // Count of forwardEmails for this UserEmail
user: { select: { name: true, email: true } },
forwardEmails: {
select: {
readAt: true,
},
},
skip: (page - 1) * size,
take: size,
orderBy: {
updatedAt: "desc",
},
skip: (page - 1) * size,
take: size,
orderBy: {
updatedAt: "desc",
},
});
// Fetch total count of UserEmail records
const totalPromise = prisma.userEmail.count({
where: { ...whereOptions },
});
// Fetch all emailAddress values that match the whereOptions
const emailAddressesPromise = prisma.userEmail.findMany({
where: { ...whereOptions },
select: { emailAddress: true },
});
const [userEmails, total, emailAddresses] = await Promise.all([
userEmailsPromise,
totalPromise,
emailAddressesPromise,
]);
// Extract all email addresses for the total counts query
const emailAddressList = emailAddresses.map((e) => e.emailAddress);
// Fetch total inbox and unread counts across all matching UserEmails
const [totalInboxCount, totalUnreadCount] = await Promise.all([
prisma.forwardEmail.count({
where: {
to: { in: emailAddressList },
},
}),
prisma.userEmail.count({
where: { ...whereOptions },
prisma.forwardEmail.count({
where: {
to: { in: emailAddressList },
readAt: null,
},
}),
]);
const result = userEmails.map((email) => {
// 计算未读邮件数量
const unreadCount = email.forwardEmails.filter(
(mail) => mail.readAt === null,
).length;
return {
...email,
count: email._count.forwardEmails, // 总邮件数
unreadCount: unreadCount, // 未读邮件数
count: email._count.forwardEmails, // Total emails for this specific UserEmail
unreadCount: unreadCount, // Unread emails for this specific UserEmail
user: email.user.name,
email: email.user.email,
forwardEmails: undefined,
@@ -137,7 +167,9 @@ export async function getAllUserEmails(
return {
list: result,
total,
total, // Total number of UserEmail records
totalInboxCount, // Total number of ForwardEmail records for all matching UserEmails
totalUnreadCount, // Total number of unread ForwardEmail records for all matching UserEmails
};
}
+1 -1
View File
File diff suppressed because one or more lines are too long