管理网站状态
This commit is contained in:
parent
ee3ec61548
commit
f5621a3aa1
|
|
@ -0,0 +1,72 @@
|
||||||
|
import type { Endpoint } from 'payload'
|
||||||
|
|
||||||
|
export const homepageDataEndpoint: Endpoint = {
|
||||||
|
path: '/homepage-data',
|
||||||
|
method: 'get',
|
||||||
|
handler: async (req) => {
|
||||||
|
try {
|
||||||
|
const payload = req.payload
|
||||||
|
|
||||||
|
// 获取首页公告(已发布且在首页显示)
|
||||||
|
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',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取产品推荐
|
||||||
|
const productRecommendations = await payload.findGlobal({
|
||||||
|
slug: 'product-recommendations',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 构建响应数据
|
||||||
|
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 || [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json(response, { status: 200 })
|
||||||
|
} catch (error: any) {
|
||||||
|
req.payload.logger.error('Error fetching homepage data:', error)
|
||||||
|
return Response.json(
|
||||||
|
{
|
||||||
|
error: 'Failed to fetch homepage data',
|
||||||
|
message: error.message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import type { GlobalConfig } from 'payload'
|
||||||
|
|
||||||
|
export const SiteAccess: GlobalConfig = {
|
||||||
|
slug: 'site-access',
|
||||||
|
label: {
|
||||||
|
en: 'Site Access Control',
|
||||||
|
zh: '站点访问控制',
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
read: () => true, // 公开可读,前端需要检查访问状态
|
||||||
|
update: ({ req: { user } }) => {
|
||||||
|
// 只有 admin 可以更新
|
||||||
|
if (!user) return false
|
||||||
|
return user.roles?.includes('admin') || false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
group: {
|
||||||
|
en: 'System',
|
||||||
|
zh: '系统',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
en: 'Control site accessibility and maintenance mode',
|
||||||
|
zh: '控制站点可访问性和维护模式',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'isAccessible',
|
||||||
|
type: 'checkbox',
|
||||||
|
label: {
|
||||||
|
en: 'Site Accessible',
|
||||||
|
zh: '站点可访问',
|
||||||
|
},
|
||||||
|
defaultValue: true,
|
||||||
|
required: true,
|
||||||
|
admin: {
|
||||||
|
description: {
|
||||||
|
en: 'Toggle to enable/disable public access to the site',
|
||||||
|
zh: '切换以启用/禁用站点的公开访问',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'maintenanceMessage',
|
||||||
|
type: 'textarea',
|
||||||
|
label: {
|
||||||
|
en: 'Maintenance Message',
|
||||||
|
zh: '维护提示消息',
|
||||||
|
},
|
||||||
|
defaultValue: 'The site is currently under maintenance. Please check back later.',
|
||||||
|
required: true,
|
||||||
|
admin: {
|
||||||
|
description: {
|
||||||
|
en: 'Message to display when site is not accessible',
|
||||||
|
zh: '站点不可访问时显示的消息',
|
||||||
|
},
|
||||||
|
rows: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'estimatedRestoreTime',
|
||||||
|
type: 'date',
|
||||||
|
label: {
|
||||||
|
en: 'Estimated Restore Time',
|
||||||
|
zh: '预计恢复时间',
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
description: {
|
||||||
|
en: 'Optional: When the site is expected to be back online',
|
||||||
|
zh: '可选:预计站点恢复在线的时间',
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
displayFormat: 'yyyy-MM-dd HH:mm',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -104,12 +104,14 @@ export interface Config {
|
||||||
'logs-manager': LogsManager;
|
'logs-manager': LogsManager;
|
||||||
'hero-slider': HeroSlider;
|
'hero-slider': HeroSlider;
|
||||||
'product-recommendations': ProductRecommendation;
|
'product-recommendations': ProductRecommendation;
|
||||||
|
'site-access': SiteAccess;
|
||||||
};
|
};
|
||||||
globalsSelect: {
|
globalsSelect: {
|
||||||
'admin-settings': AdminSettingsSelect<false> | AdminSettingsSelect<true>;
|
'admin-settings': AdminSettingsSelect<false> | AdminSettingsSelect<true>;
|
||||||
'logs-manager': LogsManagerSelect<false> | LogsManagerSelect<true>;
|
'logs-manager': LogsManagerSelect<false> | LogsManagerSelect<true>;
|
||||||
'hero-slider': HeroSliderSelect<false> | HeroSliderSelect<true>;
|
'hero-slider': HeroSliderSelect<false> | HeroSliderSelect<true>;
|
||||||
'product-recommendations': ProductRecommendationsSelect<false> | ProductRecommendationsSelect<true>;
|
'product-recommendations': ProductRecommendationsSelect<false> | ProductRecommendationsSelect<true>;
|
||||||
|
'site-access': SiteAccessSelect<false> | SiteAccessSelect<true>;
|
||||||
};
|
};
|
||||||
locale: null;
|
locale: null;
|
||||||
user: User;
|
user: User;
|
||||||
|
|
@ -1042,6 +1044,29 @@ export interface ProductRecommendation {
|
||||||
updatedAt?: string | null;
|
updatedAt?: string | null;
|
||||||
createdAt?: string | null;
|
createdAt?: string | null;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Control site accessibility and maintenance mode
|
||||||
|
*
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "site-access".
|
||||||
|
*/
|
||||||
|
export interface SiteAccess {
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* Toggle to enable/disable public access to the site
|
||||||
|
*/
|
||||||
|
isAccessible: boolean;
|
||||||
|
/**
|
||||||
|
* Message to display when site is not accessible
|
||||||
|
*/
|
||||||
|
maintenanceMessage: string;
|
||||||
|
/**
|
||||||
|
* Optional: When the site is expected to be back online
|
||||||
|
*/
|
||||||
|
estimatedRestoreTime?: string | null;
|
||||||
|
updatedAt?: string | null;
|
||||||
|
createdAt?: string | null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "admin-settings_select".
|
* via the `definition` "admin-settings_select".
|
||||||
|
|
@ -1103,6 +1128,18 @@ export interface ProductRecommendationsSelect<T extends boolean = true> {
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
globalType?: T;
|
globalType?: T;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "site-access_select".
|
||||||
|
*/
|
||||||
|
export interface SiteAccessSelect<T extends boolean = true> {
|
||||||
|
isAccessible?: T;
|
||||||
|
maintenanceMessage?: T;
|
||||||
|
estimatedRestoreTime?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
globalType?: T;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "TaskSchedulePublish".
|
* via the `definition` "TaskSchedulePublish".
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,11 @@ import { AdminSettings } from './globals/AdminSettings'
|
||||||
import { LogsManager } from './globals/LogsManager'
|
import { LogsManager } from './globals/LogsManager'
|
||||||
import { HeroSlider } from './globals/HeroSlider'
|
import { HeroSlider } from './globals/HeroSlider'
|
||||||
import { ProductRecommendations } from './globals/ProductRecommendations'
|
import { ProductRecommendations } from './globals/ProductRecommendations'
|
||||||
|
import { SiteAccess } from './globals/SiteAccess'
|
||||||
import { s3Storage } from '@payloadcms/storage-s3'
|
import { s3Storage } from '@payloadcms/storage-s3'
|
||||||
import { en } from '@payloadcms/translations/languages/en'
|
import { en } from '@payloadcms/translations/languages/en'
|
||||||
import { zh } from '@payloadcms/translations/languages/zh'
|
import { zh } from '@payloadcms/translations/languages/zh'
|
||||||
|
import { homepageDataEndpoint } from './endpoints/homepage'
|
||||||
|
|
||||||
// 导入自定义翻译
|
// 导入自定义翻译
|
||||||
import enProducts from './translations/en/products.json'
|
import enProducts from './translations/en/products.json'
|
||||||
|
|
@ -48,7 +50,8 @@ export default buildConfig({
|
||||||
fallbackLanguage: 'zh',
|
fallbackLanguage: 'zh',
|
||||||
},
|
},
|
||||||
collections: [Users, Media, Products, PreorderProducts, Announcements, Articles, Logs],
|
collections: [Users, Media, Products, PreorderProducts, Announcements, Articles, Logs],
|
||||||
globals: [AdminSettings, LogsManager, HeroSlider, ProductRecommendations],
|
globals: [AdminSettings, LogsManager, HeroSlider, ProductRecommendations, SiteAccess],
|
||||||
|
endpoints: [homepageDataEndpoint],
|
||||||
editor: lexicalEditor(),
|
editor: lexicalEditor(),
|
||||||
secret: process.env.PAYLOAD_SECRET || '',
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
typescript: {
|
typescript: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue