feat(core): 补全剩余 6 个 StreamField Block (ProductCard/Pricing/Timeline/Team/TechStack/Video)
- apps/core/blocks.py 新增 ProductCardBlock/PricingBlock/TimelineBlock/TeamBlock/TechStackBlock/VideoBlock,COMMON_BLOCKS 扩充至 14 个内容 Block - TeamBlock 新增 TeamMemberChooserBlock(SnippetChooserBlock),复用 FormBlock 已有的 get_api_representation 展开模式,展开 TeamMember 完整字段(含 serialize_image 复用) - 为 blog/cases/home/products/solutions 五个 Page 模型生成并应用 alter field body 迁移(StreamField block 定义变更会写入迁移 state) - apps/core/tests.py 新增 TeamMemberChooserBlock 空值/展开单元测试,pytest 33 个用例全部通过 - 设计文档 §2.6/§2.16 同步更新为已实现
This commit is contained in:
@@ -219,15 +219,15 @@ Snippet(非页面树内容,用于跨页面复用):`TeamMember`、`Testim
|
||||
| HeroBlock | 首屏 | title, subtitle, cta_buttons(list), background_image/video | ✅ 已实现 |
|
||||
| StatsBlock | 数据展示 | items: [{value, label}] | ✅ 已实现 |
|
||||
| FeatureGridBlock | 能力/优势 | icon, title, description | ✅ 已实现(对应原 FeatureBlock) |
|
||||
| ProductCardBlock | 产品矩阵 | title, description, image, link | ⬜ 待开发 |
|
||||
| ProductCardBlock | 产品矩阵 | title, description, image, link | ✅ 已实现 |
|
||||
| LogoCloudBlock | 客户 Logo 墙 | logos: [{url, title}](暂为图片列表,未接入 Partner Snippet) | ✅ 已实现(简化版) |
|
||||
| CaseStudyBlock | 案例卡片 | case_page: PageChooser(cases.CaseStudyPage), summary | ✅ 已实现 |
|
||||
| PricingBlock | 定价 | plans: [{name, price, features}] | ⬜ 待开发 |
|
||||
| PricingBlock | 定价 | plans: [{name, price, features, highlighted, button}] | ✅ 已实现 |
|
||||
| FAQBlock | 常见问题 | items: [{question, answer(richtext)}] | ✅ 已实现 |
|
||||
| TimelineBlock | 发展历程 | items: [{year, event}] | ⬜ 待开发 |
|
||||
| TeamBlock | 团队展示 | members: [SnippetChooser(TeamMember)] | ⬜ 待开发(依赖 TeamMember Snippet) |
|
||||
| TechStackBlock | 技术架构图 | items: [{icon, label}] | ⬜ 待开发 |
|
||||
| VideoBlock | 视频 | video_file/embed_url, poster | ⬜ 待开发 |
|
||||
| TimelineBlock | 发展历程 | items: [{year, event}] | ✅ 已实现 |
|
||||
| TeamBlock | 团队展示 | members: [SnippetChooser(TeamMember)],`get_api_representation` 展开完整字段(name/role/bio/photo)供前端渲染 | ✅ 已实现(依赖 TeamMember Snippet) |
|
||||
| TechStackBlock | 技术架构图 | items: [{icon, label}] | ✅ 已实现 |
|
||||
| VideoBlock | 视频 | video_url(建议自建 OSS/COS 直链或腾讯视频/哔哩哔哩等国内平台嵌入地址),poster | ✅ 已实现 |
|
||||
| FormBlock | 线索表单 | form: SnippetChooser(forms.FormDefinition),`get_api_representation` 展开完整字段定义供前端渲染 | ✅ 已实现 |
|
||||
| CTABlock | 行动号召 | heading, button_text, button_link | ✅ 已实现 |
|
||||
|
||||
@@ -365,7 +365,7 @@ CI 中要求单元测试覆盖率不低于 70%,核心 `apps/forms`(涉及线
|
||||
|
||||
已完成:
|
||||
- [x] 后端 Django + Wagtail 项目骨架,分层 settings(base/dev/production),独立 git 仓库并已提交
|
||||
- [x] `apps/core`:`SEOablePage` 抽象基类、`COMMON_BLOCKS`(9/14 个 Block,见 §2.6)、健康检查 `/healthz` `/readyz`、发布后 `page_published` signal → 前端 revalidate webhook
|
||||
- [x] `apps/core`:`SEOablePage` 抽象基类、`COMMON_BLOCKS`(14/14 个 Block 已全部实现,见 §2.6)、健康检查 `/healthz` `/readyz`、发布后 `page_published` signal → 前端 revalidate webhook
|
||||
- [x] `apps/home`、`apps/blog`(含标签 `ClusterTaggableManager`)
|
||||
- [x] `apps/products`(ProductIndexPage/ProductPage)、`apps/cases`(CaseStudyIndexPage/CaseStudyPage)、`apps/solutions`(SolutionIndexPage/SolutionPage)
|
||||
- [x] `apps/forms`:`FormDefinition`/`FormDefinitionField`/`Lead`(Snippet 方式)+ 提交 API(`/api/v1/custom/leads/`,限流 + 邮件通知)
|
||||
@@ -375,9 +375,9 @@ CI 中要求单元测试覆盖率不低于 70%,核心 `apps/forms`(涉及线
|
||||
- [x] `apps/core.SimpleContentPage`:通用富文本法务/说明类页面模型,用于隐私政策等内容,配套 `seed_privacy_policy` management command 用于幂等创建/更新隐私政策页面(需在 HomePage 实例存在后手动运行)
|
||||
- [x] Snippet:`TeamMember`/`Testimonial`/`Partner`(简单 `@register_snippet`,均含 `order` 排序字段)、`NavigationMenu`+`NavigationMenuItem`(`ClusterableModel`+`Orderable`+`InlinePanel`,内部页面/外部链接二选一)、`SiteSettings`(`wagtail.contrib.settings` + `BaseSiteSetting`,公司信息/ICP备案/社交账号全局配置)均已创建;只读 API 挂载于 `/api/v1/custom/core/`(`team/`、`testimonials/`、`partners/`、`navigation/?name=`、`site-settings/`,限流 public 100/min);前端 `Header`/`Footer` 已接入 `NavigationMenu`/`SiteSettings`(接口不可用时回退静态内容),`TeamMember`/`Testimonial`/`Partner` 已提供 service 层,页面级展示留待对应 StreamField Block(见下)落地时接入
|
||||
- [x] 预览模式:后端引入 `wagtail-headless-preview`(0.9.0),`SEOablePage` 混入 `HeadlessPreviewMixin`(自动覆盖全部 6 个页面模型),新增自定义 `PagePreviewAPIViewSet` 挂载于 `/api/v2/page_preview/`;前端新增 `services/preview.service.ts`(`getPreviewOrFallback`/`fetchPreviewPage`/`resolvePreviewPath`)、`/preview`与 `/preview/disable` 两个 Route Handler(基于 Next.js Draft Mode + httpOnly cookie),并在首页/博客/产品/案例/解决方案详情页接入草稿优先逻辑,`layout.tsx` 新增预览模式提示条(含退出链接);`lint`/`build` 均验证通过,后端 31 个现有用例均通过(本次未新增自动化测试,仅依靠人工验证)
|
||||
- [x] 剩余 6 个 StreamField Block(`ProductCardBlock`/`PricingBlock`/`TimelineBlock`/`TeamBlock`/`TechStackBlock`/`VideoBlock`)已全部开发完成:`apps/core/blocks.py` 新增对应 Block 类并扩充 `COMMON_BLOCKS`(现共 14 个内容 Block + 1 个 `richtext`),因 Wagtail StreamField 会将 Block 结构写入迁移(`use_json_field=True` 不代表可跳过迁移),已为 blog/cases/home/products/solutions 五个 Page 模型生成并应用 `alter field body` 迁移;`TeamBlock` 复用 `FormBlock` 的 `get_api_representation` 覆写模式,新增 `TeamMemberChooserBlock(SnippetChooserBlock)` 展开 `TeamMember` 完整字段(含 `serialize_image` 复用),并补充对应的空值/展开单元测试(新增 2 个用例,后端共 33 个测试全部通过);前端 `types/wagtail.ts` 新增 6 个 Block 值类型与 `StreamFieldBlock` 联合类型分支,新建 6 个渲染组件(`ProductCardGrid`/`Pricing`/`Timeline`/`Team`/`TechStack`/`Video`)并接入 `BlockRenderer.tsx` 映射表,`lint`/`build` 均验证通过
|
||||
|
||||
未完成(待规划排期):
|
||||
- [ ] 剩余 5 个 StreamField Block(Pricing/Timeline/Team/TechStack/Video/ProductCard)未开发
|
||||
- [ ] RBAC 落地(Wagtail `Group` + `GroupPagePermission` 实际配置)未开始
|
||||
- [ ] 测试覆盖率仍不完整(已有基础单元测试,但集成测试、前端组件测试、E2E 均未编写,当前无 CI 流水线)
|
||||
- [x] 生产安全 settings(§2.11 中 `SECURE_*`/CORS/CSRF 白名单等)已在 `production.py` 中逐项落实,并补充 `SECURE_PROXY_SSL_HEADER`(适配国内云厂商 SLB/CLB 边缘终止 TLS 场景);实际域名需在部署时通过 `.env` 填入
|
||||
|
||||
Reference in New Issue
Block a user