diff --git a/src/app/(payload)/admin/importMap.js b/src/app/(payload)/admin/importMap.js index 25424a7..4505332 100644 --- a/src/app/(payload)/admin/importMap.js +++ b/src/app/(payload)/admin/importMap.js @@ -1,5 +1,29 @@ import { ThumbnailCell as ThumbnailCell_a0b2acb813359aec894b6644d7c3bfd2 } from '../../../components/products/ThumbnailCell' -import { ThumbnailAndStatusField as ThumbnailAndStatusField_8fa95ec6265982d11b99fbeb81e24c1c } from '../../../components/products/ThumbnailAndStatusField' +import { ThumbnailField as ThumbnailField_ba44ab32cac4d742a03a48fb6960602e } from '../../../components/products/ThumbnailField' +import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' import { SyncMedusaButton as SyncMedusaButton_8c90663551920f0510ea531726668adc } from '../../../components/products/SyncMedusaButton' import { default as default_3fd1353246fc8a459244c8dc11f58470 } from '../../../components/products/ProductGridStyler' import { ForceSyncButton as ForceSyncButton_86f9d5df4f20495427521354d06db618 } from '../../../components/products/ForceSyncButton' @@ -8,7 +32,31 @@ import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } f export const importMap = { "/components/products/ThumbnailCell#ThumbnailCell": ThumbnailCell_a0b2acb813359aec894b6644d7c3bfd2, - "/components/products/ThumbnailAndStatusField#ThumbnailAndStatusField": ThumbnailAndStatusField_8fa95ec6265982d11b99fbeb81e24c1c, + "/components/products/ThumbnailField#ThumbnailField": ThumbnailField_ba44ab32cac4d742a03a48fb6960602e, + "@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "/components/products/SyncMedusaButton#SyncMedusaButton": SyncMedusaButton_8c90663551920f0510ea531726668adc, "/components/products/ProductGridStyler#default": default_3fd1353246fc8a459244c8dc11f58470, "/components/products/ForceSyncButton#ForceSyncButton": ForceSyncButton_86f9d5df4f20495427521354d06db618, diff --git a/src/collections/Products.ts b/src/collections/Products.ts index 7e5b423..33fe9e5 100644 --- a/src/collections/Products.ts +++ b/src/collections/Products.ts @@ -1,4 +1,25 @@ import type { CollectionConfig } from 'payload' +import { + AlignFeature, + BlocksFeature, + BoldFeature, + ChecklistFeature, + HeadingFeature, + IndentFeature, + InlineCodeFeature, + ItalicFeature, + lexicalEditor, + LinkFeature, + OrderedListFeature, + ParagraphFeature, + RelationshipFeature, + UnorderedListFeature, + UploadFeature, + FixedToolbarFeature, + InlineToolbarFeature, + HorizontalRuleFeature, + BlockquoteFeature, +} from '@payloadcms/richtext-lexical' export const Products: CollectionConfig = { slug: 'products', @@ -25,23 +46,115 @@ export const Products: CollectionConfig = { }, fields: [ { - name: 'medusaId', - type: 'text', - required: true, - unique: true, - index: true, - admin: { - description: 'Medusa 商品 ID', - readOnly: true, - }, + type: 'row', + fields: [ + { + name: 'medusaId', + type: 'text', + required: true, + unique: true, + index: true, + admin: { + description: 'Medusa 商品 ID', + readOnly: true, + width: '80%', + }, + }, + { + name: 'status', + type: 'select', + required: true, + defaultValue: 'draft', + options: [ + { + label: '草稿', + value: 'draft', + }, + { + label: '已发布', + value: 'published', + }, + ], + admin: { + description: '商品详情状态', + width: '20%', + }, + }, + ], }, { - name: 'title', - type: 'text', - required: true, + type: 'row', + fields: [ + { + name: 'title', + type: 'text', + required: true, + admin: { + description: '商品标题(从 Medusa 同步)', + readOnly: true, + width: '80%', + }, + }, + { + name: 'thumbnail', + type: 'text', + admin: { + description: '商品封面 URL(从 Medusa 同步)', + readOnly: true, + width: '20%', + components: { + Cell: '/components/products/ThumbnailCell#ThumbnailCell', + Field: '/components/products/ThumbnailField#ThumbnailField', + }, + }, + }, + ], + }, + { + name: 'content', + type: 'richText', admin: { - description: '商品标题(从 Medusa 同步)', + description: '商品详细内容', }, + editor: lexicalEditor({ + features: ({ defaultFeatures }) => [ + ...defaultFeatures, + HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }), + LinkFeature({ + enabledCollections: ['products'], + fields: ({ defaultFields }) => [ + ...defaultFields, + { + name: 'rel', + label: 'Rel Attribute', + type: 'select', + hasMany: true, + options: ['noopener', 'noreferrer', 'nofollow'], + admin: { + description: 'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.', + }, + }, + ], + }), + UploadFeature({ + collections: { + media: { + fields: [ + { + name: 'caption', + type: 'richText', + label: '图片说明', + editor: lexicalEditor(), + }, + ], + }, + }, + }), + FixedToolbarFeature(), + InlineToolbarFeature(), + HorizontalRuleFeature(), + ], + }), }, { name: 'handle', @@ -51,37 +164,6 @@ export const Products: CollectionConfig = { readOnly: true, }, }, - { - name: 'thumbnail', - type: 'text', - admin: { - description: '商品缩略图 URL(从 Medusa 同步)', - readOnly: true, - components: { - Cell: '/components/products/ThumbnailCell#ThumbnailCell', - Field: '/components/products/ThumbnailAndStatusField#ThumbnailAndStatusField', - }, - }, - }, - { - name: 'status', - type: 'select', - required: true, - defaultValue: 'draft', - options: [ - { - label: '草稿', - value: 'draft', - }, - { - label: '已发布', - value: 'published', - }, - ], - admin: { - description: '商品详情状态', - }, - }, { name: 'relatedProducts', type: 'relationship', diff --git a/src/components/products/ThumbnailField.tsx b/src/components/products/ThumbnailField.tsx new file mode 100644 index 0000000..0ca61d0 --- /dev/null +++ b/src/components/products/ThumbnailField.tsx @@ -0,0 +1,45 @@ +'use client' +import { useFormFields } from '@payloadcms/ui' +import type { TextFieldClientComponent } from 'payload' + +// 只显示缩略图封面 +export const ThumbnailField: TextFieldClientComponent = ({ path }) => { + const fields = useFormFields(([fields]) => fields) + const thumbnail = fields.thumbnail?.value + + const isImage = typeof thumbnail === 'string' && thumbnail.match(/^https?:\/\/.+/) + + return ( +