【Codex】用文章分类模块构建内容运营分类体系

维护内容中心文章的分类树,为文章管理、前台内容查询和分类筛选提供稳定目录。它在教育管理系统里承担内容沉淀、资源配置或业务流转职责,后续页面、接口和权限都需要围绕这条业务主线设计。

本文基于 ArticleCategory 模型、ArticleCategoryViewSet 和文章分类前端页面 的真实代码,说明如何把文章分类需求拆成模型字段、接口规则、页面交互、扩展能力和验收标准,再转换成 Codex 可以执行的项目代码生成任务。

文章目录

设计与需求

文章分类不能只按普通 CRUD 理解。源码范围包括 server_backend/modules/Article/models.py、server_backend/modules/Article/views_app/ArticleCategory.py,前端范围包括 server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts。交给 Codex 的任务需要明确业务字段、接口前缀、页面回显和权限边界,避免后端字段、前端表单和 PDD 文档相互脱节。
#mermaid-svg-ngXafbpdLPgxf7MZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ngXafbpdLPgxf7MZ .error-icon{fill:#552222;}#mermaid-svg-ngXafbpdLPgxf7MZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ngXafbpdLPgxf7MZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ngXafbpdLPgxf7MZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ngXafbpdLPgxf7MZ .marker.cross{stroke:#333333;}#mermaid-svg-ngXafbpdLPgxf7MZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ngXafbpdLPgxf7MZ p{margin:0;}#mermaid-svg-ngXafbpdLPgxf7MZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster-label text{fill:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster-label span{color:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster-label span p{background-color:transparent;}#mermaid-svg-ngXafbpdLPgxf7MZ .label text,#mermaid-svg-ngXafbpdLPgxf7MZ span{fill:#333;color:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ .node rect,#mermaid-svg-ngXafbpdLPgxf7MZ .node circle,#mermaid-svg-ngXafbpdLPgxf7MZ .node ellipse,#mermaid-svg-ngXafbpdLPgxf7MZ .node polygon,#mermaid-svg-ngXafbpdLPgxf7MZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ngXafbpdLPgxf7MZ .rough-node .label text,#mermaid-svg-ngXafbpdLPgxf7MZ .node .label text,#mermaid-svg-ngXafbpdLPgxf7MZ .image-shape .label,#mermaid-svg-ngXafbpdLPgxf7MZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-ngXafbpdLPgxf7MZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ngXafbpdLPgxf7MZ .rough-node .label,#mermaid-svg-ngXafbpdLPgxf7MZ .node .label,#mermaid-svg-ngXafbpdLPgxf7MZ .image-shape .label,#mermaid-svg-ngXafbpdLPgxf7MZ .icon-shape .label{text-align:center;}#mermaid-svg-ngXafbpdLPgxf7MZ .node.clickable{cursor:pointer;}#mermaid-svg-ngXafbpdLPgxf7MZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ngXafbpdLPgxf7MZ .arrowheadPath{fill:#333333;}#mermaid-svg-ngXafbpdLPgxf7MZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ngXafbpdLPgxf7MZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ngXafbpdLPgxf7MZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ngXafbpdLPgxf7MZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ngXafbpdLPgxf7MZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ngXafbpdLPgxf7MZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster text{fill:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ .cluster span{color:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ngXafbpdLPgxf7MZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ngXafbpdLPgxf7MZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-ngXafbpdLPgxf7MZ .icon-shape,#mermaid-svg-ngXafbpdLPgxf7MZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ngXafbpdLPgxf7MZ .icon-shape p,#mermaid-svg-ngXafbpdLPgxf7MZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ngXafbpdLPgxf7MZ .icon-shape .label rect,#mermaid-svg-ngXafbpdLPgxf7MZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ngXafbpdLPgxf7MZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ngXafbpdLPgxf7MZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ngXafbpdLPgxf7MZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-ngXafbpdLPgxf7MZ .input>*{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .input span{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .input tspan{fill:#1D39C4!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .design>*{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .design span{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .design tspan{fill:#237804!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .process>*{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .process span{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .process tspan{fill:#AD4E00!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .check>*{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .check span{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .check tspan{fill:#531DAB!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .output>*{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .output span{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-ngXafbpdLPgxf7MZ .output tspan{fill:#006D75!important;} 教育管理需求
文章分类设计
页面结构
数据模型
接口规则
权限验收
Codex生成代码
模块交付

需求层描述 设计层转换 Codex 代码生成方向
业务目标 维护内容中心文章的分类树,为文章管理、前台内容查询和分类筛选提供稳定目录。 生成模块入口、页面结构和业务说明
数据模型 ArticleCategory 字段覆盖 name_category、slug_category、level、parent 生成序列化、字段校验、查询筛选和保存回显
页面结构 server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts 生成列表、筛选区、表单、详情或自定义操作区
接口规则 /api/Article/ArticleCategory/ 保持前端封装、后端 action 和路由注册一致
权限验收 按钮权限、接口权限、用户数据范围、异常响应 在 PDD 中列出角色、接口和越权用例
扩展能力 数据联动 只实现源码中真实存在的扩展入口和服务边界

更适合交给 Codex 的需求说明,应覆盖源码路径、字段、接口和验收口径。文章分类的重点是把 ArticleCategory 与前端接口封装、列表配置、表单状态和自定义页面逻辑合并成一个可测试的模块任务。

可以直接使用下面的Prompt进行模块功能的设计

text 复制代码
请 Codex 基于教育管理系统真实源码设计"文章分类"模块。

业务说明:维护内容中心文章的分类树,为文章管理、前台内容查询和分类筛选提供稳定目录。
后端源码:server_backend/modules/Article/models.py、server_backend/modules/Article/views_app/ArticleCategory.py
前端源码:server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts
模型对象:ArticleCategory
字段范围:name_category、slug_category、level、parent
接口范围:/api/Article/ArticleCategory/
扩展能力边界:数据联动

请输出模块页面结构、数据模型、接口规则、权限验收、测试用例和 Codex 代码生成任务。只允许使用源码中存在的字段、接口和页面状态。

后端设计

文章分类的后端设计重点不是堆 CRUD 接口,而是建立可复用的数据底座。Codex 需要识别 ArticleCategory 的字段、序列化器、ViewSet、筛选逻辑和自定义 action,并让接口返回结构稳定服务前端。

后端 ArticleCategoryViewSet 使用 CustomModelRefSerializerCustomModelInFilter,支持分类名称筛选与父级目录维护。分类属于树形基础数据,删除和编辑要考虑文章引用。

后端设计项 设计重点 Codex 生成方向
核心字段 name_category、slug_category、level、parent 生成序列化、查询筛选、表单回显和保存校验
接口视图 server_backend/modules/Article/models.py、server_backend/modules/Article/views_app/ArticleCategory.py 注册列表、详情、保存、软删除和已有 action
查询筛选 按后端 filterset_class 与前端查询项保持一致 生成筛选参数、模糊查询和关联查询
权限控制 使用当前项目权限体系约束新增、编辑、删除和自定义按钮 生成前后端一致的权限点
异常处理 参数缺失、记录不存在、权限不足、任务失败要返回明确消息 生成可验收错误响应

可以直接使用下面的Prompt进行后端代码的设计

text 复制代码
请为教育管理系统的文章分类模块设计或补齐后端代码。

后端源码范围:server_backend/modules/Article/models.py、server_backend/modules/Article/views_app/ArticleCategory.py
模型或查询对象:ArticleCategory
字段范围:name_category、slug_category、level、parent
接口范围:/api/Article/ArticleCategory/

请按当前项目技术栈生成模型字段、序列化规则、接口视图、路由注册、筛选查询、权限控制和基础校验。自定义 action 只能来自源码或 PDD 明确说明,不能额外增加不存在的业务入口。

后端 `ArticleCategoryViewSet` 使用 `CustomModelRefSerializer` 和 `CustomModelInFilter`,支持分类名称筛选与父级目录维护。分类属于树形基础数据,删除和编辑要考虑文章引用。

请保证新增、编辑、详情返回、列表查询、软删除、权限校验和异常响应字段一致。

前端设计

文章分类的前端设计重点不是把字段堆到页面上,而是让用户能按业务路径完成查询、编辑、状态处理和结果确认。当前前端范围包括 server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts,其中 api.ts 负责接口封装,crud.tsxindex.vue 负责列表、表单、自定义布局和按钮交互。

前端分类树主要被文章管理复用,需要支持树节点选择、分类筛选和文章列表刷新。

前端设计项 设计重点 Codex 生成方向
页面结构 server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts 生成列表、筛选区、表单、详情抽屉或自定义操作区
接口封装 /api/Article/ArticleCategory/ 统一封装查询、详情、保存、删除和已有 action
表单结构 按 name_category、slug_category、level、parent 组织新增、编辑和回显字段 生成字段组件、校验规则和保存载荷
列表查询 与后端 filterset_class 和 SearchFilter 对齐 生成查询项、分页、刷新和重置逻辑
权限按钮 按当前项目 authv-permission 控制操作入口 生成按钮显示和禁用逻辑

可以直接使用下面的Prompt进行前端代码的设计

text 复制代码
请为教育管理系统的文章分类模块设计或补齐前端代码。

前端源码范围:server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts
接口范围:/api/Article/ArticleCategory/
字段范围:name_category、slug_category、level、parent
扩展能力边界:数据联动

请生成页面结构、列表查询、筛选区域、新增编辑表单、详情预览、权限按钮、保存回显和接口调用。前端字段必须与后端模型和序列化字段一致。

前端分类树主要被文章管理复用,需要支持树节点选择、分类筛选和文章列表刷新。

如果源码中存在扩展能力,请只加入真实交互入口,例如分类树、导入导出、下载中心任务、批量处理、资源预览、购买确认或统计面板。源码没有的能力不要写入页面。

扩展功能

文章分类 的扩展能力都来自当前源码,不按固定模板硬套。它们超出普通 CRUD 的地方在于,需要把字段、接口、页面状态和结果回显串成业务闭环。

扩展功能 主要用途 落地重点
数据联动 让分类树、文章列表筛选和 category_article 外键保持同步 父子分类、树节点选择、文章列表刷新和分类回显

数据联动

文章分类的数据联动来自源码中已经存在的字段、接口或前端交互。它的作用是让分类树、文章列表筛选和 category_article 外键保持同步,落地时要关注父子分类、树节点选择、文章列表刷新和分类回显,不能为了文章结构把未实现的能力写成需求。
#mermaid-svg-jI65YXBF0h5Sz6mb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jI65YXBF0h5Sz6mb .error-icon{fill:#552222;}#mermaid-svg-jI65YXBF0h5Sz6mb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jI65YXBF0h5Sz6mb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jI65YXBF0h5Sz6mb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jI65YXBF0h5Sz6mb .marker.cross{stroke:#333333;}#mermaid-svg-jI65YXBF0h5Sz6mb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jI65YXBF0h5Sz6mb p{margin:0;}#mermaid-svg-jI65YXBF0h5Sz6mb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster-label text{fill:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster-label span{color:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster-label span p{background-color:transparent;}#mermaid-svg-jI65YXBF0h5Sz6mb .label text,#mermaid-svg-jI65YXBF0h5Sz6mb span{fill:#333;color:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb .node rect,#mermaid-svg-jI65YXBF0h5Sz6mb .node circle,#mermaid-svg-jI65YXBF0h5Sz6mb .node ellipse,#mermaid-svg-jI65YXBF0h5Sz6mb .node polygon,#mermaid-svg-jI65YXBF0h5Sz6mb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jI65YXBF0h5Sz6mb .rough-node .label text,#mermaid-svg-jI65YXBF0h5Sz6mb .node .label text,#mermaid-svg-jI65YXBF0h5Sz6mb .image-shape .label,#mermaid-svg-jI65YXBF0h5Sz6mb .icon-shape .label{text-anchor:middle;}#mermaid-svg-jI65YXBF0h5Sz6mb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jI65YXBF0h5Sz6mb .rough-node .label,#mermaid-svg-jI65YXBF0h5Sz6mb .node .label,#mermaid-svg-jI65YXBF0h5Sz6mb .image-shape .label,#mermaid-svg-jI65YXBF0h5Sz6mb .icon-shape .label{text-align:center;}#mermaid-svg-jI65YXBF0h5Sz6mb .node.clickable{cursor:pointer;}#mermaid-svg-jI65YXBF0h5Sz6mb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jI65YXBF0h5Sz6mb .arrowheadPath{fill:#333333;}#mermaid-svg-jI65YXBF0h5Sz6mb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jI65YXBF0h5Sz6mb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jI65YXBF0h5Sz6mb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jI65YXBF0h5Sz6mb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jI65YXBF0h5Sz6mb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jI65YXBF0h5Sz6mb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster text{fill:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb .cluster span{color:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jI65YXBF0h5Sz6mb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jI65YXBF0h5Sz6mb rect.text{fill:none;stroke-width:0;}#mermaid-svg-jI65YXBF0h5Sz6mb .icon-shape,#mermaid-svg-jI65YXBF0h5Sz6mb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jI65YXBF0h5Sz6mb .icon-shape p,#mermaid-svg-jI65YXBF0h5Sz6mb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jI65YXBF0h5Sz6mb .icon-shape .label rect,#mermaid-svg-jI65YXBF0h5Sz6mb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jI65YXBF0h5Sz6mb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jI65YXBF0h5Sz6mb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jI65YXBF0h5Sz6mb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-jI65YXBF0h5Sz6mb .input>*{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .input span{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .input tspan{fill:#1D39C4!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .process>*{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .process span{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .process tspan{fill:#AD4E00!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .output>*{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .output span{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-jI65YXBF0h5Sz6mb .output tspan{fill:#006D75!important;} 结果阶段
处理阶段
输入阶段
业务输入
筛选条件
组装参数
请求接口
转换字段
刷新列表
结果回显

交给 Codex 生成时,边界要写清楚:只处理当前模块源码中已经存在的字段和接口,后端返回结构、前端保存载荷和页面回显必须同名对齐。涉及批量、导出、下载中心或异步任务时,需要返回可检查的统计字段,方便 PDD 验收定位问题。

可以直接使用下面的Prompt进行数据联动设计

text 复制代码
请为教育管理系统的文章分类模块实现数据联动。

能力用途:让分类树、文章列表筛选和 `category_article` 外键保持同步。
落地重点:父子分类、树节点选择、文章列表刷新和分类回显。

请读取当前模块源码路径、后端 ViewSet、自定义 action、前端 api.ts、crud.tsx 或 index.vue,按真实字段和真实接口补齐实现。不得新增源码中不存在的 LLM、OCR、审批、统计、导入导出、文件预览等能力。

请实现分类树加载、节点点击筛选文章、文章表单 category_article 回显,以及分类变更后的列表刷新。

请输出需要修改的文件、核心字段映射、接口参数、返回结构、前端交互、错误处理和验收用例。

Codex开发标准

使用 Codex 开发文章分类时,不能直接让它随意写代码,而要用需求边界、PDD、SOP、接口权限规则和验收标准约束开发过程。这个模块需要先读取源码上下文,再按后端、前端和真实扩展能力分阶段完成。
#mermaid-svg-D5PrHO8yqxU4Yrx9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .error-icon{fill:#552222;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .marker.cross{stroke:#333333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 p{margin:0;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster-label text{fill:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster-label span{color:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster-label span p{background-color:transparent;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .label text,#mermaid-svg-D5PrHO8yqxU4Yrx9 span{fill:#333;color:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .node rect,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node circle,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node ellipse,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node polygon,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .rough-node .label text,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node .label text,#mermaid-svg-D5PrHO8yqxU4Yrx9 .image-shape .label,#mermaid-svg-D5PrHO8yqxU4Yrx9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .rough-node .label,#mermaid-svg-D5PrHO8yqxU4Yrx9 .node .label,#mermaid-svg-D5PrHO8yqxU4Yrx9 .image-shape .label,#mermaid-svg-D5PrHO8yqxU4Yrx9 .icon-shape .label{text-align:center;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .node.clickable{cursor:pointer;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .arrowheadPath{fill:#333333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-D5PrHO8yqxU4Yrx9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D5PrHO8yqxU4Yrx9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster text{fill:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .cluster span{color:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-D5PrHO8yqxU4Yrx9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .icon-shape,#mermaid-svg-D5PrHO8yqxU4Yrx9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .icon-shape p,#mermaid-svg-D5PrHO8yqxU4Yrx9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .icon-shape .label rect,#mermaid-svg-D5PrHO8yqxU4Yrx9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D5PrHO8yqxU4Yrx9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-D5PrHO8yqxU4Yrx9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .input>*{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .input span{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .input tspan{fill:#1D39C4!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .design>*{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .design span{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .design tspan{fill:#237804!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .dev>*{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .dev span{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .dev tspan{fill:#AD4E00!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .check>*{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .check span{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-D5PrHO8yqxU4Yrx9 .check tspan{fill:#531DAB!important;} 验收交付
Codex开发
模块设计
输入约束
需求边界
PDD设计
SOP目录规范
接口与权限规则
后端设计
前端设计
能力边界
读取上下文
生成后端代码
生成前端代码
补齐联动
功能自检
PDD验收
问题修复
模块交付

SOP 标准

SOP 用于约束代码目录、文件职责和开发顺序。文章分类需要沿用当前模块目录,不应另起一套平行实现。

text 复制代码
ManageBak-ExamEdu/
├── server_backend/
│   └── modules/
│       └── Article/
│           ├── models.py
│           ├── urls.py
│           ├── utils.py
│           └── views_app/
│               └── ArticleCategory.py
├── server_vue3/
│   └── src/
│       └── views/
│           └── modules/
│               └── Article/
│                   └── ArticleCategory/
│                       ├── index.vue
│                       ├── api.ts
│                       └── crud.tsx
└── docs/
    └── modules/
        └── article-ArticleCategory/
            ├── pdd.md
            ├── api.md
            ├── test-cases.md
            └── codex-sop.md
开发阶段 Codex 执行目标 输出结果
模块设计 明确文章分类的业务目标、字段、接口和页面结构 pdd.md
目录规划 按当前 Article 模块目录规划后端、前端和文档 codex-sop.md
后端实现 补齐模型、序列化、视图、筛选、路由和权限 后端模块代码
前端实现 补齐页面、接口封装、表格配置、表单和按钮 前端页面代码
数据联动 打通筛选、保存、回显和刷新 联动逻辑代码
扩展功能 补齐数据联动 扩展能力代码与验收记录
验收修复 按 PDD 检查功能、接口、权限和数据回显 验收记录与修复提交

可以直接使用下面的Prompt进行SOP撰写

text 复制代码
请按照教育管理系统模块开发 SOP,从零实现或补齐文章分类模块。

开发前先输出目录结构,不要直接写代码。目录需要贴合当前项目:后端在 server_backend/modules/Article/,前端在 server_vue3/src/views/modules/Article/,文档在 docs/modules/article-ArticleCategory/。

请先生成 pdd.md、api.md、test-cases.md 和 codex-sop.md,再根据这些文档生成项目代码。文档需要明确字段、接口、权限、页面结构、扩展能力和验收规则。

实现过程中只允许使用源码中真实存在的能力:数据联动。不要编造未在代码中出现的功能。

PDD 标准

PDD 是文章分类的模块设计与验收文档,用来约束 Codex 输出是否符合真实业务。验收不能只看页面能否打开,还要检查字段、接口、权限、保存回显和真实扩展能力。

验收维度 验收标准 不通过表现
业务目标 维护内容中心文章的分类树,为文章管理、前台内容查询和分类筛选提供稳定目录。 只生成普通 CRUD,缺少业务字段说明
页面结构 页面包含列表、筛选、表单、权限按钮和必要交互 页面字段与源码不一致
数据模型 ArticleCategory 字段覆盖 name_category、slug_category、level、parent 保存或回显字段缺失
接口规则 /api/Article/ArticleCategory/ 可被前端正确调用 页面有按钮但接口不存在
权限控制 新增、编辑、删除和自定义动作遵守当前权限体系 只隐藏按钮,接口层无约束
测试用例 覆盖查询、新增、编辑、删除、回显和异常处理 只有人工描述,没有验收路径
数据联动 让分类树、文章列表筛选和 category_article 外键保持同步,并能在前后端按真实字段验收 页面有入口但接口、字段或回显不一致

可以直接使用下面的Prompt进行PDD 验收

text 复制代码
请根据 docs/modules/article-ArticleCategory/pdd.md 对文章分类模块进行 PDD 验收。

验收范围包括后端源码 server_backend/modules/Article/models.py、server_backend/modules/Article/views_app/ArticleCategory.py,前端源码 server_vue3/src/views/modules/Article/ArticleManage/components/CategoryTreeCom/index.vue、ArticleManage/apiCategory.ts。

请检查业务目标、页面结构、数据模型、接口规则、权限控制、测试用例和扩展能力。扩展能力范围限定为:数据联动。

请输出验收结果表,标记通过、未通过和需要修复的文件位置。不要只给结论,需要指出具体问题、影响范围和修复建议。

总结

文章分类模块的开发价值,不在于生成一张能增删改查的后台表,而在于把维护内容中心文章的分类树,为文章管理、前台内容查询和分类筛选提供稳定目录。沉淀成教育管理系统可维护、可验收的业务闭环。字段、接口、页面和权限保持一致,后续内容运营、资源管理和用户侧调用才有稳定基础。

使用 Codex 开发这类模块时,PDD 定义业务边界和验收标准,SOP 约束目录结构和开发顺序,Prompt 把页面、模型、接口、权限和真实扩展能力交给 Codex 分阶段实现。这样生成的代码更接近项目交付,而不是一次性演示页面。