mirror of
https://github.com/beilunyang/moemail.git
synced 2025-12-24 11:30:51 +08:00
193 lines
4.8 KiB
TypeScript
193 lines
4.8 KiB
TypeScript
import { createDb } from "@/lib/db"
|
|
import { emailShares, messageShares, messages, emails } from "@/lib/schema"
|
|
import { eq, desc, and, or, ne, isNull } from "drizzle-orm"
|
|
|
|
export interface SharedEmail {
|
|
id: string
|
|
address: string
|
|
createdAt: Date
|
|
expiresAt: Date
|
|
}
|
|
|
|
export interface SharedMessage {
|
|
id: string
|
|
from_address?: string
|
|
to_address?: string
|
|
subject: string
|
|
content?: string
|
|
html?: string
|
|
received_at?: Date
|
|
sent_at?: Date
|
|
expiresAt?: Date
|
|
emailAddress?: string
|
|
emailExpiresAt?: Date
|
|
}
|
|
|
|
export async function getSharedEmail(token: string): Promise<SharedEmail | null> {
|
|
const db = createDb()
|
|
|
|
try {
|
|
const share = await db.query.emailShares.findFirst({
|
|
where: eq(emailShares.token, token),
|
|
with: {
|
|
email: true
|
|
}
|
|
})
|
|
|
|
if (!share) {
|
|
return null
|
|
}
|
|
|
|
// 检查分享是否过期
|
|
if (share.expiresAt && share.expiresAt < new Date()) {
|
|
return null
|
|
}
|
|
|
|
// 检查邮箱是否过期
|
|
if (share.email.expiresAt < new Date()) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
id: share.email.id,
|
|
address: share.email.address,
|
|
createdAt: share.email.createdAt,
|
|
expiresAt: share.email.expiresAt
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to fetch shared email:", error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export interface SharedMessagesResult {
|
|
messages: SharedMessage[]
|
|
nextCursor: string | null
|
|
total: number
|
|
}
|
|
|
|
export async function getSharedEmailMessages(token: string, limit = 20): Promise<SharedMessagesResult> {
|
|
const db = createDb()
|
|
|
|
try {
|
|
const share = await db.query.emailShares.findFirst({
|
|
where: eq(emailShares.token, token),
|
|
with: {
|
|
email: true
|
|
}
|
|
})
|
|
|
|
if (!share) {
|
|
return { messages: [], nextCursor: null, total: 0 }
|
|
}
|
|
|
|
// 检查分享是否过期
|
|
if (share.expiresAt && share.expiresAt < new Date()) {
|
|
return { messages: [], nextCursor: null, total: 0 }
|
|
}
|
|
|
|
// 只显示接收的邮件,不显示发送的邮件
|
|
const baseConditions = and(
|
|
eq(messages.emailId, share.emailId),
|
|
or(
|
|
ne(messages.type, "sent"),
|
|
isNull(messages.type)
|
|
)
|
|
)
|
|
|
|
// 获取消息总数(只统计接收的邮件)
|
|
const { sql } = await import("drizzle-orm")
|
|
const totalResult = await db.select({ count: sql<number>`count(*)` })
|
|
.from(messages)
|
|
.where(baseConditions)
|
|
const totalCount = Number(totalResult[0].count)
|
|
|
|
// 获取邮箱的消息列表(多获取一条用于判断是否有更多)
|
|
const messageList = await db.query.messages.findMany({
|
|
where: baseConditions,
|
|
orderBy: [desc(messages.receivedAt), desc(messages.id)],
|
|
limit: limit + 1
|
|
})
|
|
|
|
const hasMore = messageList.length > limit
|
|
const results = hasMore ? messageList.slice(0, limit) : messageList
|
|
|
|
// 生成下一页的cursor
|
|
let nextCursor: string | null = null
|
|
if (hasMore) {
|
|
const { encodeCursor } = await import("@/lib/cursor")
|
|
const lastMessage = results[results.length - 1]
|
|
nextCursor = encodeCursor(
|
|
lastMessage.receivedAt.getTime(),
|
|
lastMessage.id
|
|
)
|
|
}
|
|
|
|
return {
|
|
messages: results.map(msg => ({
|
|
id: msg.id,
|
|
from_address: msg.fromAddress ?? undefined,
|
|
to_address: msg.toAddress ?? undefined,
|
|
subject: msg.subject,
|
|
received_at: msg.receivedAt,
|
|
sent_at: msg.sentAt
|
|
})),
|
|
nextCursor,
|
|
total: totalCount
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to fetch shared email messages:", error)
|
|
return { messages: [], nextCursor: null, total: 0 }
|
|
}
|
|
}
|
|
|
|
export async function getSharedMessage(token: string): Promise<SharedMessage | null> {
|
|
const db = createDb()
|
|
|
|
try {
|
|
const share = await db.query.messageShares.findFirst({
|
|
where: eq(messageShares.token, token)
|
|
})
|
|
|
|
if (!share) {
|
|
return null
|
|
}
|
|
|
|
// 检查分享是否过期
|
|
if (share.expiresAt && share.expiresAt < new Date()) {
|
|
return null
|
|
}
|
|
|
|
// 获取消息详情
|
|
const message = await db.query.messages.findFirst({
|
|
where: eq(messages.id, share.messageId)
|
|
})
|
|
|
|
if (!message) {
|
|
return null
|
|
}
|
|
|
|
// 获取邮箱信息
|
|
const email = await db.query.emails.findFirst({
|
|
where: eq(emails.id, message.emailId)
|
|
})
|
|
|
|
return {
|
|
id: message.id,
|
|
from_address: message.fromAddress ?? undefined,
|
|
to_address: message.toAddress ?? undefined,
|
|
subject: message.subject,
|
|
content: message.content ?? undefined,
|
|
html: message.html ?? undefined,
|
|
received_at: message.receivedAt,
|
|
sent_at: message.sentAt,
|
|
expiresAt: share.expiresAt ?? undefined,
|
|
emailAddress: email?.address,
|
|
emailExpiresAt: email?.expiresAt
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to fetch shared message:", error)
|
|
return null
|
|
}
|
|
}
|