gbmake-payload/src/app/api/home/route.ts

134 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'
/**
* GET /api/home
* 获取首页所有数据:公告 + Hero Slider + 产品推荐(含完整产品信息)
*/
export async function GET(req: NextRequest) {
try {
const payload = await getPayload({ config })
// 获取首页公告(已发布且在首页显示)
const announcements = await payload.find({
collection: 'announcements',
where: {
and: [
{
status: {
equals: 'published',
},
},
{
showOnHomepage: {
equals: true,
},
},
],
},
sort: '-priority',
limit: 10,
})
// 获取 Hero Slider
const heroSlider = await payload.findGlobal({
slug: 'hero-slider',
})
// 获取产品推荐depth: 2 足以拿到产品文档及其直接关联字段)
const productRecommendations = await payload.findGlobal({
slug: 'product-recommendations',
depth: 2,
})
// 构建响应数据
const response = {
announcements: announcements.docs.map((announcement) => ({
id: announcement.id,
title: announcement.title,
type: announcement.type,
summary: announcement.summary,
priority: announcement.priority,
publishedAt: announcement.publishedAt,
})),
heroSlider: {
slides: heroSlider.slides || [],
},
productRecommendations: {
enabled: productRecommendations.enabled || false,
lists: (productRecommendations.lists || []).map((list: any) => ({
title: list.title,
subtitle: list.subtitle,
preorder: list.preorder || false,
products: (list.products || []).map((productRef: any) => {
const product = productRef.value
// description 是纯文本(从 Medusa 同步)
const description = product.description || ''
// 基础产品信息
const baseInfo = {
id: product.id,
medusaId: product.medusaId,
handle: product.handle || null,
seedId: product.seedId,
title: product.title,
thumbnail: product.thumbnail,
status: product.status,
description,
content: product.content || null,
startPrice: product.startPrice ?? null,
}
// 如果是预购产品,添加预购特有字段
if (productRef.relationTo === 'preorder-products') {
const realOrderCount = product.orderCount || 0
const fakeOrderCount = product.fakeOrderCount || 0
const totalCount = realOrderCount + fakeOrderCount
return {
...baseInfo,
relationTo: 'preorder-products',
preorder: {
type: product.preorderType || 'standard',
fundingGoal: product.fundingGoal || 0,
orderCount: totalCount,
startDate: product.preorderStartDate,
endDate: product.preorderEndDate,
// 计算进度百分比(含 fakeOrderCount用于展示不限制 100 以支持超出显示)
progress: product.fundingGoal > 0
? Math.round((totalCount / product.fundingGoal) * 100)
: 0,
// 计算剩余天数
daysLeft: product.preorderEndDate
? Math.max(0, Math.ceil((new Date(product.preorderEndDate).getTime() - Date.now()) / (1000 * 60 * 60 * 24)))
: null,
// 支持者数量(含 fakeOrderCount用于展示
backers: totalCount,
},
}
}
// 普通产品
return {
...baseInfo,
relationTo: 'products',
}
}),
})),
},
}
return NextResponse.json(response, { status: 200 })
} catch (error: any) {
console.error('Error fetching homepage data:', error)
return NextResponse.json(
{
error: 'Failed to fetch homepage data',
message: error.message,
},
{ status: 500 }
)
}
}