【Codex】用登录日志模块审计用户登录与访问行为

登录日志在教育管理系统中的价值,在于围绕 登录日志 的核心字段、接口动作和页面状态维护业务数据。模块需要和现有接口、权限、页面状态保持一致,不能只写成普通后台表格。

本文基于 系统功能/系统数据_登录日志 对应源码,把业务目标拆成模型字段、接口规则、页面交互和验收标准,形成 Codex 可执行的项目代码生成任务。

文章目录

设计与需求

登录日志不能只按普通 CRUD 理解。源码范围包括 server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py、server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue,这些文件共同决定页面入口、字段保存、接口动作、权限边界和验收口径。交给 Codex 的任务需要明确业务字段、接口前缀、页面回显和异常处理,避免后端字段、前端表单和 PDD 文档相互脱节。
#mermaid-svg-RWWCpz6jcRyIGlE9{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-RWWCpz6jcRyIGlE9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RWWCpz6jcRyIGlE9 .error-icon{fill:#552222;}#mermaid-svg-RWWCpz6jcRyIGlE9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RWWCpz6jcRyIGlE9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .marker.cross{stroke:#333333;}#mermaid-svg-RWWCpz6jcRyIGlE9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RWWCpz6jcRyIGlE9 p{margin:0;}#mermaid-svg-RWWCpz6jcRyIGlE9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster-label text{fill:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster-label span{color:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster-label span p{background-color:transparent;}#mermaid-svg-RWWCpz6jcRyIGlE9 .label text,#mermaid-svg-RWWCpz6jcRyIGlE9 span{fill:#333;color:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .node rect,#mermaid-svg-RWWCpz6jcRyIGlE9 .node circle,#mermaid-svg-RWWCpz6jcRyIGlE9 .node ellipse,#mermaid-svg-RWWCpz6jcRyIGlE9 .node polygon,#mermaid-svg-RWWCpz6jcRyIGlE9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .rough-node .label text,#mermaid-svg-RWWCpz6jcRyIGlE9 .node .label text,#mermaid-svg-RWWCpz6jcRyIGlE9 .image-shape .label,#mermaid-svg-RWWCpz6jcRyIGlE9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-RWWCpz6jcRyIGlE9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .rough-node .label,#mermaid-svg-RWWCpz6jcRyIGlE9 .node .label,#mermaid-svg-RWWCpz6jcRyIGlE9 .image-shape .label,#mermaid-svg-RWWCpz6jcRyIGlE9 .icon-shape .label{text-align:center;}#mermaid-svg-RWWCpz6jcRyIGlE9 .node.clickable{cursor:pointer;}#mermaid-svg-RWWCpz6jcRyIGlE9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .arrowheadPath{fill:#333333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RWWCpz6jcRyIGlE9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RWWCpz6jcRyIGlE9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RWWCpz6jcRyIGlE9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster text{fill:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 .cluster span{color:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 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-RWWCpz6jcRyIGlE9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RWWCpz6jcRyIGlE9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-RWWCpz6jcRyIGlE9 .icon-shape,#mermaid-svg-RWWCpz6jcRyIGlE9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RWWCpz6jcRyIGlE9 .icon-shape p,#mermaid-svg-RWWCpz6jcRyIGlE9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RWWCpz6jcRyIGlE9 .icon-shape .label rect,#mermaid-svg-RWWCpz6jcRyIGlE9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RWWCpz6jcRyIGlE9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RWWCpz6jcRyIGlE9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RWWCpz6jcRyIGlE9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-RWWCpz6jcRyIGlE9 .input>*{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .input span{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .input tspan{fill:#1D39C4!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .design>*{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .design span{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .design tspan{fill:#237804!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .process>*{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .process span{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .process tspan{fill:#AD4E00!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .check>*{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .check span{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .check tspan{fill:#531DAB!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .output>*{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .output span{fill:#E6FFFB!important;stroke:#13C2C2!important;color:#006D75!important;stroke-width:1.2px!important;}#mermaid-svg-RWWCpz6jcRyIGlE9 .output tspan{fill:#006D75!important;} 生成阶段
设计阶段
输入阶段
教育需求
登录日志
页面结构
数据模型
接口规则
权限验收
读取源码
生成代码
验收修复

需求层描述 设计层转换 Codex 代码生成方向
业务目标 围绕 登录日志 的核心字段、接口动作和页面状态维护业务数据。 生成模块入口、页面结构和业务说明
数据模型 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区) 生成序列化、字段校验、查询筛选和保存回显
页面结构 server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue 生成列表、筛选区、表单、详情、预览或自定义操作区
接口规则 /api/system/login_log/、/api/system/login_log/field_permission/ 保持 GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission 与页面调用一致
权限验收 按钮权限、接口权限、用户数据范围、异常响应 在 PDD 中列出角色、接口和越权用例

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

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

text 复制代码
请 Codex 基于教育管理系统真实源码设计"登录日志"模块。

业务说明:围绕 登录日志 的核心字段、接口动作和页面状态维护业务数据。
源码范围:server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py、server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue
接口范围:/api/system/login_log/、/api/system/login_log/field_permission/
字段范围:username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)、isp(运营商)、area_code(区域代码)、country_english(英文全称)、country_code(简称)、longitude(经度)、latitude(纬度)
已有动作:GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission
扩展能力边界:当前源码未发现独立扩展能力,不要编造 LLM、OCR、统计、审批或导入导出功能。

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

后端设计

登录日志的后端设计重点不是堆 CRUD 接口,而是建立可复用的数据底座。当前后端范围包括 server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py。Codex 需要识别模型字段、序列化器、ViewSet、筛选逻辑和自定义 action,并让接口返回结构稳定服务前端。

源码中可识别的模型或查询对象为 LoginLog,核心字段覆盖 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)。接口动作包含 GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission,查询参数关注 按前端查询条件和后端 filterset 约束,这些内容需要和前端封装保持同名语义,避免页面有按钮但后端没有对应能力。

后端设计项 设计重点 Codex 生成方向
核心字段 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统) 生成序列化、查询筛选、表单回显和保存校验
补充字段 continent(州)、country(国家)、province(省份)、city(城市)、district(县区) 处理状态、时间、JSON、资源或关联字段的格式转换
接口视图 server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py 按 /api/system/login_log/、/api/system/login_log/field_permission/ 注册列表、详情、保存、删除和已有 action
查询筛选 按前端查询条件和后端 filterset 约束 生成 filterset、SearchFilter 或自定义查询参数
权限控制 后端接口承担真实访问边界,前端按钮只做入口展示 生成权限判断、异常响应和越权测试

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

text 复制代码
请 Codex 按"登录日志"业务从源码上下文设计或补齐后端代码。

后端源码范围:server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py
模型或查询对象:LoginLog
模型字段范围:username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)、isp(运营商)、area_code(区域代码)、country_english(英文全称)、country_code(简称)、longitude(经度)、latitude(纬度)
接口前缀:/api/system/login_log/、/api/system/login_log/field_permission/
已有接口动作:GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission
查询参数:按前端查询条件和后端 filterset 约束

需要生成或修正数据模型、序列化规则、接口视图、路由注册、筛选查询、权限控制和基础校验。不要新增源码中不存在的 LLM 生成、图像识别、统计、审批、批量或导入导出接口。

输出时列出涉及文件、字段校验、接口返回结构和需要执行的测试。

前端设计

登录日志的前端设计重点不是把字段堆到页面上,而是让用户能按业务路径完成查询、编辑、状态处理和结果确认。当前前端范围包括 server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue,其中 api.ts 负责接口封装,crud.tsx 或 index.vue 负责列表、表单、自定义布局和按钮交互。

页面需要围绕 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区) 组织筛选、表单和详情。保存前要处理字段格式转换,保存后刷新列表或回显详情;源码未出现扩展能力时,页面应保持当前列表、表单和权限按钮边界。

前端设计项 设计重点 Codex 生成方向
页面结构 server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue 生成列表、筛选区、表单、详情抽屉、弹窗或自定义操作区
接口封装 /api/system/login_log/、/api/system/login_log/field_permission/ 统一封装查询、详情、保存、删除和 GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission 等动作
字段回显 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区) 处理下拉、树形、JSON、状态、时间和资源字段回显
权限按钮 根据 auth、按钮权限或后端权限结果展示操作入口 生成新增、编辑、删除、处理、下载或预览按钮

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

text 复制代码
请 Codex 按"登录日志"业务生成或补齐前端页面代码。

前端源码范围:server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue
接口范围:/api/system/login_log/、/api/system/login_log/field_permission/
字段范围:username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)、isp(运营商)、area_code(区域代码)、country_english(英文全称)、country_code(简称)、longitude(经度)、latitude(纬度)
已有动作:GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission

需要生成页面结构、列表查询、筛选区域、新增编辑表单、详情预览、权限按钮、保存回显和接口调用;源码已有批量入口时再接入批量操作。不要新增源码未出现的批量、生成、识别、统计、审批或导入导出入口。

输出时说明字段转换、表单初始化、异常提示和刷新策略。

Codex开发标准

使用 Codex 开发 登录日志 时,不能直接让它随意写代码。需求边界、PDD、SOP、接口权限规则和验收标准需要同时约束后端、前端和功能补齐,让生成结果能回到项目源码中运行。
#mermaid-svg-5eKyMahhg7cvm2Fh{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-5eKyMahhg7cvm2Fh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5eKyMahhg7cvm2Fh .error-icon{fill:#552222;}#mermaid-svg-5eKyMahhg7cvm2Fh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5eKyMahhg7cvm2Fh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5eKyMahhg7cvm2Fh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5eKyMahhg7cvm2Fh .marker.cross{stroke:#333333;}#mermaid-svg-5eKyMahhg7cvm2Fh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5eKyMahhg7cvm2Fh p{margin:0;}#mermaid-svg-5eKyMahhg7cvm2Fh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster-label text{fill:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster-label span{color:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster-label span p{background-color:transparent;}#mermaid-svg-5eKyMahhg7cvm2Fh .label text,#mermaid-svg-5eKyMahhg7cvm2Fh span{fill:#333;color:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh .node rect,#mermaid-svg-5eKyMahhg7cvm2Fh .node circle,#mermaid-svg-5eKyMahhg7cvm2Fh .node ellipse,#mermaid-svg-5eKyMahhg7cvm2Fh .node polygon,#mermaid-svg-5eKyMahhg7cvm2Fh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5eKyMahhg7cvm2Fh .rough-node .label text,#mermaid-svg-5eKyMahhg7cvm2Fh .node .label text,#mermaid-svg-5eKyMahhg7cvm2Fh .image-shape .label,#mermaid-svg-5eKyMahhg7cvm2Fh .icon-shape .label{text-anchor:middle;}#mermaid-svg-5eKyMahhg7cvm2Fh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5eKyMahhg7cvm2Fh .rough-node .label,#mermaid-svg-5eKyMahhg7cvm2Fh .node .label,#mermaid-svg-5eKyMahhg7cvm2Fh .image-shape .label,#mermaid-svg-5eKyMahhg7cvm2Fh .icon-shape .label{text-align:center;}#mermaid-svg-5eKyMahhg7cvm2Fh .node.clickable{cursor:pointer;}#mermaid-svg-5eKyMahhg7cvm2Fh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5eKyMahhg7cvm2Fh .arrowheadPath{fill:#333333;}#mermaid-svg-5eKyMahhg7cvm2Fh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5eKyMahhg7cvm2Fh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5eKyMahhg7cvm2Fh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5eKyMahhg7cvm2Fh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5eKyMahhg7cvm2Fh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5eKyMahhg7cvm2Fh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster text{fill:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh .cluster span{color:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh 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-5eKyMahhg7cvm2Fh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5eKyMahhg7cvm2Fh rect.text{fill:none;stroke-width:0;}#mermaid-svg-5eKyMahhg7cvm2Fh .icon-shape,#mermaid-svg-5eKyMahhg7cvm2Fh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5eKyMahhg7cvm2Fh .icon-shape p,#mermaid-svg-5eKyMahhg7cvm2Fh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5eKyMahhg7cvm2Fh .icon-shape .label rect,#mermaid-svg-5eKyMahhg7cvm2Fh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5eKyMahhg7cvm2Fh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5eKyMahhg7cvm2Fh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5eKyMahhg7cvm2Fh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-5eKyMahhg7cvm2Fh .input>*{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .input span{fill:#EEF4FF!important;stroke:#5B8FF9!important;color:#1D39C4!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .input tspan{fill:#1D39C4!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .design>*{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .design span{fill:#F6FFED!important;stroke:#52C41A!important;color:#237804!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .design tspan{fill:#237804!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .dev>*{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .dev span{fill:#FFF7E6!important;stroke:#FA8C16!important;color:#AD4E00!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .dev tspan{fill:#AD4E00!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .check>*{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .check span{fill:#F9F0FF!important;stroke:#722ED1!important;color:#531DAB!important;stroke-width:1.2px!important;}#mermaid-svg-5eKyMahhg7cvm2Fh .check tspan{fill:#531DAB!important;} 验收交付
Codex开发
模块设计
输入约束
需求边界
PDD设计
SOP目录
接口权限
后端设计
前端设计
联动检查
读取上下文
生成后端
生成前端
功能补齐
功能自检
PDD验收
问题修复
模块交付

SOP 标准

SOP 用于约束代码目录、文件职责和开发顺序。Codex 在动手写代码前,需要先确认目录结构和文档位置,再按后端、前端、联动、验收的顺序推进。

text 复制代码
docs/modules/登录日志/
├── pdd.md
├── api.md
├── test-cases.md
└── codex-sop.md
server_backend/
└── dvadmin/system/models.py
└── dvadmin/system/views/login_log.py
server_vue3/
└── src/views/system/SystemData/LoginLog/api.ts
└── src/views/system/SystemData/LoginLog/crud.tsx
└── src/views/system/SystemData/LoginLog/index.vue
开发阶段 Codex 执行目标 输出结果
模块设计 读取源码、确认字段、接口和页面入口 输出模块边界和设计说明
目录规划 规划后端、前端和 docs/modules 文档 输出目录结构和文件职责
后端实现 补齐模型、序列化、ViewSet、路由和权限 输出可调用接口和基础校验
前端实现 补齐 api.ts、crud.tsx、index.vue 或自定义组件 输出可操作页面和保存回显
数据联动或功能补齐 校验筛选、下拉、状态、详情和异常提示 输出联动说明和修复记录
验收修复 按 PDD 和测试用例检查模块 输出验收结果和问题修复

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

text 复制代码
请 Codex 按教育管理系统模块开发 SOP,从零实现或补齐"登录日志"。

源码范围:server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py、server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue
接口范围:/api/system/login_log/、/api/system/login_log/field_permission/
字段范围:username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)、isp(运营商)、area_code(区域代码)、country_english(英文全称)、country_code(简称)、longitude(经度)、latitude(纬度)

执行要求:
1. 先输出目录结构,不要直接写代码。
2. 先生成 docs/modules/登录日志/pdd.md、api.md、test-cases.md 和 codex-sop.md。
3. 再根据文档生成后端代码、前端代码、接口封装、权限控制和测试用例。
4. 当前模块没有独立扩展能力时,不要在开发阶段加入 LLM、OCR、统计、审批或导入导出章节。
5. 每个阶段输出涉及文件、修改目标和验收方式。

PDD 标准

PDD 是 登录日志 的设计与验收文档,用于约束 Codex 输出是否符合真实业务。验收不能只看页面能否打开,还要检查字段、接口、权限、异常、回显和基础流程是否与源码一致。

验收维度 验收重点 通过标准
业务目标 围绕 登录日志 的核心字段、接口动作和页面状态维护业务数据 页面和接口围绕该目标闭环
页面结构 server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue 列表、表单、详情或自定义操作区可用
数据模型 username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区) 字段保存、查询、回显和校验一致
接口规则 /api/system/login_log/、/api/system/login_log/field_permission/ GetList、GetObj、AddObj、UpdateObj、DelObj、GetPermission 能被前端正确调用
权限控制 按角色、按钮和接口权限检查 越权访问有后端拦截和错误响应
测试用例 覆盖新增、编辑、删除、查询、异常和回显 测试记录包含输入、输出和修复位置

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

text 复制代码
请 Codex 根据 docs/modules/登录日志/pdd.md 对"登录日志"进行验收。

源码范围:server_backend/dvadmin/system/models.py、server_backend/dvadmin/system/views/login_log.py、server_vue3/src/views/system/SystemData/LoginLog/api.ts、server_vue3/src/views/system/SystemData/LoginLog/crud.tsx、server_vue3/src/views/system/SystemData/LoginLog/index.vue
接口范围:/api/system/login_log/、/api/system/login_log/field_permission/
字段范围:username(登录用户名)、ip(登录ip)、agent(agent信息)、browser(浏览器名)、os(操作系统)、continent(州)、country(国家)、province(省份)、city(城市)、district(县区)、isp(运营商)、area_code(区域代码)、country_english(英文全称)、country_code(简称)、longitude(经度)、latitude(纬度)
验收范围只包含基础业务、页面、模型、接口、权限和测试用例,不要加入源码不存在的扩展能力。

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

总结

登录日志的开发价值在于围绕 登录日志 的核心字段、接口动作和页面状态维护业务数据。它把核心字段、接口规则和页面状态连成业务闭环,避免模块停留在普通列表维护。

Codex 开发该模块时,PDD 定义业务边界和验收标准,SOP 约束目录结构和开发顺序,Prompt 把页面、模型、接口、权限 分阶段交给 Codex 实现。

相关推荐
瑶山13 小时前
Window11为什么出现codex桌面端频繁打不开和网络等待问题解决
codex
空单蛋17 小时前
光遗传学与空间蛋白组学如何结合?从神经元精准调控到组织空间解析
codex·pcf空间单细胞蛋白组·pcf技术
汉吉龙测控技术20 小时前
多模态数据融合驱动的智能监测实验台
django
wangchunyu11421 小时前
食韵味简 —— 免费开源的中式菜谱 API 服务
python·django·开源
专业程序开发源21 小时前
SSM笔记本在线销售系统32649-计算机课程设计、毕业设计
java·spring boot·后端·python·django·php·课程设计
我的xiaodoujiao2 天前
Django 基础知识详细图文教程 14-Django 表单定义与使用
开发语言·后端·python·django
浩风祭月2 天前
ChatGPT Work和Codex为什么共用额度?在哪里看剩余量
人工智能·chatgpt·plus·codex·chatgpt work·chatgpt额度·用量查询
ZARD9962 天前
Codex 连接 Figma:让 AI 读取 Figma UI 设计稿数据
ui·figma·codex
我的xiaodoujiao2 天前
Django 基础知识详细图文教程 13-Django 模型定义与使用 3
数据库·后端·python·测试工具·oracle·django