Files
xuanzhi-service/web/.ai-specs/coding-specs/common-page-create-spec.md
wdh-home c31466aeb5
Some checks failed
CI / init (pull_request) Has been cancelled
CI / Frontend node 18.16.0 (pull_request) Has been cancelled
CI / Backend go (1.22) (pull_request) Has been cancelled
CI / devops-test (1.22, 18.16.0) (pull_request) Has been cancelled
CI / release-pr (pull_request) Has been cancelled
CI / release-please (pull_request) Has been cancelled
CI / devops-prod (1.22, 18.x) (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
fix: 优化书籍后台字段展示与提交
2026-04-27 13:55:21 +08:00

5.7 KiB
Raw Permalink Blame History

common-page-create-spec

适用范围

  • 涉及新增通用页面、列表页、详情页、表单页、页面占位页时必读。
  • 涉及页面目录落点、接口接入、本地路由/远程路由选择、菜单配置、curl 联调时必读。

创建主链路

  • 先判定页面是否需要登录后访问、菜单展示、角色授权、默认首页、keep-alive再决定走本地路由还是远程路由。
  • 页面源码默认放在 src/view/<module>;页面私有子组件放在 src/view/<module>/components
  • 页面请求统一放在 src/api/<module>.js;插件页面请求统一放在 src/plugin/<plugin>/api/<module>.js
  • 页面只负责编排、生命周期和页面局部状态;不要在页面内直写 axios也不要把单页临时状态默认上提到 pinia

路由接入规则

flowchart LR
    A["新增页面"] --> B{"是否需要登录后菜单/权限/默认首页?"}
    B -- "否" --> C["本地路由: src/router/index.js"]
    B -- "是" --> D["远程路由: 后台 menu + 前端动态注入"]
    C --> E["同步检查 src/permission.js 白名单与跳转"]
    D --> F["同步检查菜单权限、keep-alive、defaultRouter"]
  • 本地路由:仅用于登录页、初始化页、公开页、扫码页、明确不依赖后台菜单的工具页。入口固定 src/router/index.js,并同步检查 src/permission.js 白名单和未登录跳转。
  • 远程路由用于登录后业务页、需要左侧菜单、角色授权、默认首页、按钮权限、keep-alive 的页面。路由来源是 /menu/getMenu,前端在 src/pinia/modules/router.js 中拉取后动态注入。
  • 远程路由的 component 只允许写 view/...plugin/... 字符串;对应文件必须真实存在,且能被 src/utils/asyncRouter.js 命中。
  • 远程路由的 component 不要写成 /src/view/...、Windows 反斜杠路径或别名导入字符串;当前动态映射只认相对 src 的正斜杠路径。
  • 页面需要承载子路由时,父页面必须是 router-view 占位页;不要把普通内容页直接拿来做父级容器。
  • meta.defaultMenu 只用于明确需要脱离常规 layout 承载的基础页面;普通业务页默认保持 false

菜单与页面最小约定

  • 页面目录命名跟随现有业务语义,页面入口优先 src/view/<module>/index.vue
  • 远程路由最小字段必须保证:name 唯一、path 稳定、component 可映射、meta.title 可展示。
  • name 使用唯一英文标识改名时必须同步检查菜单高亮、keep-alive、defaultRouter 和页面标题。
  • path 默认与 name 同步;只有明确需要参数化路径时才额外拼接,不要把查询条件硬塞进路由 path。
  • 需要缓存页签时设置 meta.keepAlive;需要进入后自动关闭 tab 时设置 meta.closeTab
  • 页面进入菜单体系后,新增菜单不等于可访问;还必须补角色授权,否则页面可能存在但用户不可见。
  • 列表页的 list item 遇到单图片字段时,必须使用图片预览组件展示;禁止把图片 URL、图片路径或单图片附件地址作为普通文本直接显示。
  • 新增/编辑功能遇到图片或文件属性时,必须使用上传组件并支持已有值回显;禁止使用 el-inputtextarea 或普通文本输入组件让用户手填 URL/路径。
  • 列表页、详情页、关联表、related list item 遇到字典字段时,必须声明对应 dict 配置并使用字典格式化展示 Label;禁止把字典 Value/key 作为普通文本直接显示。
  • 字典字段在新增/编辑/筛选中提交和绑定使用 Value,页面展示统一使用字典 Label;涉及字典编码和值域时必须先读取后台 doc-dict 文档。

curl 联调案例

  • 联调地址默认取 VITE_BASE_API;认证头遵循 src/utils/request.js 当前约定:Content-Typex-tokenx-user-id
  • 页面业务接口先用 curl 跑通,再落 src/api/*;不要先在页面里硬编码请求排查接口。
curl --location --request POST "$BASE_URL/example/list" \
  --header "Content-Type: application/json" \
  --header "x-token: <token>" \
  --header "x-user-id: <user-id>" \
  --data-raw "{\"page\":1,\"pageSize\":10}"
curl --location --request POST "$BASE_URL/menu/addBaseMenu" \
  --header "Content-Type: application/json" \
  --header "x-token: <token>" \
  --header "x-user-id: <user-id>" \
  --data-raw "{\"path\":\"demoPage\",\"name\":\"DemoPage\",\"component\":\"view/demoPage/index.vue\",\"parentId\":0,\"hidden\":false,\"sort\":10,\"meta\":{\"title\":\"Demo 页面\",\"icon\":\"House\",\"keepAlive\":false,\"closeTab\":false,\"defaultMenu\":false},\"parameters\":[],\"menuBtn\":[]}"
  • 新增远程路由后,至少回查一次 /menu/getMenu 返回中是否已包含目标菜单,再排查前端注入问题。

常见错误

  • 只创建了 src/view 页面文件,没有补本地路由或远程菜单配置。
  • 该走远程路由的业务页被塞进本地路由,导致菜单、角色权限、默认首页链路失效。
  • 远程路由 component 写错路径格式,导致 asyncRouter.js 找不到页面组件。
  • 页面里直接写 axios 请求或直接拼 token绕过 src/apisrc/utils/request.js
  • 改了路由 name/path,没有同步检查 keepAlive、菜单高亮、defaultRouter 和未登录跳转。
  • list item 的单图片字段直接显示 URL 文本,没有使用图片预览。
  • 新增/编辑表单把图片或文件字段做成文本输入框,要求用户手动填写 URL 或路径。
  • 详情页或关联表字段直接显示字典 key例如 drafton_shelfcompleted,没有通过字典格式化显示名称。