gbmake-payload/src/collections/Announcements.ts

229 lines
5.2 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import { logAfterChange, logAfterDelete } from '../hooks/logAction'
import { cacheAfterChange, cacheAfterDelete } from '../hooks/cacheInvalidation'
import {
BlocksFeature,
BoldFeature,
HeadingFeature,
InlineCodeFeature,
ItalicFeature,
lexicalEditor,
LinkFeature,
OrderedListFeature,
ParagraphFeature,
UnorderedListFeature,
FixedToolbarFeature,
InlineToolbarFeature,
HorizontalRuleFeature,
BlockquoteFeature,
AlignFeature,
} from '@payloadcms/richtext-lexical'
export const Announcements: CollectionConfig = {
slug: 'announcements',
admin: {
useAsTitle: 'title',
defaultColumns: ['title', 'type', 'status', 'publishedAt', 'updatedAt'],
description: '管理系统公告和通知',
pagination: {
defaultLimit: 25,
},
},
access: {
read: ({ req: { user } }) => {
// 公开访问已发布的公告
if (!user) {
return {
status: { equals: 'published' },
}
}
// 认证用户可以查看所有
return true
},
create: ({ req: { user } }) => {
// 所有已认证用户都可以创建
return Boolean(user)
},
update: ({ req: { user } }) => {
// 所有已认证用户都可以更新
return Boolean(user)
},
delete: ({ req: { user } }) => {
// 只有 admin 可以删除
if (!user) return false
return user.roles?.includes('admin') || false
},
},
fields: [
{
type: 'row',
fields: [
{
name: 'title',
type: 'text',
required: true,
admin: {
description: '公告标题',
width: '70%',
},
},
{
name: 'type',
type: 'select',
required: true,
defaultValue: 'info',
options: [
{
label: '信息',
value: 'info',
},
{
label: '警告',
value: 'warning',
},
{
label: '重要',
value: 'important',
},
{
label: '紧急',
value: 'urgent',
},
],
admin: {
description: '公告类型',
width: '30%',
},
},
],
},
{
type: 'row',
fields: [
{
name: 'status',
type: 'select',
required: true,
defaultValue: 'draft',
options: [
{
label: '草稿',
value: 'draft',
},
{
label: '已发布',
value: 'published',
},
{
label: '已归档',
value: 'archived',
},
],
admin: {
description: '发布状态',
width: '50%',
},
},
{
name: 'priority',
type: 'number',
defaultValue: 0,
admin: {
description: '优先级(数字越大越靠前)',
width: '50%',
},
},
],
},
{
name: 'summary',
type: 'textarea',
admin: {
description: '公告摘要(显示在列表页)',
},
},
{
name: 'content',
type: 'richText',
required: true,
admin: {
description: '公告详细内容',
},
editor: lexicalEditor({
features: ({ defaultFeatures }) => [
...defaultFeatures,
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
BoldFeature(),
ItalicFeature(),
LinkFeature({}),
OrderedListFeature(),
UnorderedListFeature(),
BlockquoteFeature(),
AlignFeature(),
InlineCodeFeature(),
FixedToolbarFeature(),
InlineToolbarFeature(),
HorizontalRuleFeature(),
],
}),
},
{
type: 'row',
fields: [
{
name: 'publishedAt',
type: 'date',
admin: {
description: '发布时间',
width: '50%',
date: {
displayFormat: 'yyyy-MM-dd HH:mm',
},
},
},
{
name: 'expiresAt',
type: 'date',
admin: {
description: '过期时间(可选)',
width: '50%',
date: {
displayFormat: 'yyyy-MM-dd HH:mm',
},
},
},
],
},
{
name: 'showOnHomepage',
type: 'checkbox',
defaultValue: false,
admin: {
description: '在首页显示此公告',
},
},
{
name: 'author',
type: 'relationship',
relationTo: 'users',
admin: {
description: '发布者',
},
},
],
timestamps: true,
hooks: {
beforeChange: [
({ data, operation }) => {
// 自动设置发布时间
if (operation === 'create' && data.status === 'published' && !data.publishedAt) {
data.publishedAt = new Date()
}
return data
},
],
afterChange: [logAfterChange],
afterDelete: [logAfterDelete],
},
}