# Web 管理端开发约束 适用 `web-admin/`,与[根规则](../AGENTS.md)同时生效。运行方式见 [README](README.md)。 ## 实现与视觉入口 - Vue 3、TypeScript、Vite、Element Plus、Tailwind CSS、SCSS;使用 pnpm。 - Vue、vue-router、Pinia、VueUse API 和 Element Plus 组件由插件自动导入,不手动重复导入;`@element-plus/icons-vue` 图标显式导入。 - 格式遵循仓库 Prettier:单引号、无分号、2 空格、不加尾逗号,Vue script/style 缩进按配置。 - [Fresh Mint 规范](../docs/web-admin-ui-spec-fresh-mint.md)与[视觉参考](../docs/fresh-mint-green.html)为设计依据:主色 `#10b981`、深色 `#059669`、浅底 `#ecfdf5`。不得使用 `#0a9f6d` 作为 Web 主色。 - 新页面先按[模式索引](../docs/web-admin-ui-pattern-index.md)选 P01–P27;PR 写明模式编号及参考源码路径。详细 SHALL 要求见 [ui-conventions](../openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md)。 ## 参考页(保留,不作为闲置 Demo 删除) | 用途 | 源码 | | --- | --- | | 标准列表 | `src/views/system/unit/index.vue` | | 复杂列表 | `src/views/system/order/index.vue` | | 商品列表与详情 | `src/views/system/product/index.vue`、`src/components/business/product-view-dialog/index.vue` | | 树形主数据 | `src/views/system/category/index.vue` | | 用户 CRUD | `src/views/system/user/index.vue` | | 工作台 | `src/views/dashboard/console/index.vue` | ## 列表与展示 - 单一 `panel-top` 主标题使用 `h2.title-bar-heading` 与主色 `::before` 竖条;需要竖条的标题完整登记到 `src/App.vue` 的 `panelTitleBarTextRules`,避免短正则误匹配。 - 工具栏顺序为“已选 N 项”→ 主操作 → 其他操作;同一行仅一个 `type="primary"`,禁止用 `space-between` 把按钮组推到行末。 - 所有 `el-table-column` 使用 `min-width`,不使用固定 `width`;操作列 `fixed="right"`,`min-width` 不小于 260px。 - 主表按参考页使用 `list-table`、`stripe`,不要随意加 `border`;分页与表格同放在 `list-body list-wrap`,外层 `pagination list-pager-bar`,避免重复边框和标题。 - 树下拉只显示节点名;选中输入、表格、导出、查看显示完整祖先路径,分隔符为 ` / `。复用 `src/utils/tree-path.ts`。 - 状态、结论、类型用 `el-tag`,表格 `size="small"`,SystemViewDialog 使用 `ViewField.tagType`;禁止纯文本或自造 span 标签替代。 - Tag 语义:success=正常/启用/完成/通过;warning=进行中/待确认/过期;danger=异常/作废/拒绝/不通过/质检待执行/质检待结论;info=待生效/停用/默认;primary=特殊分类/来源类型。 - 一级侧栏菜单有图标,二级及以下仅文字(`SidebarSubmenu.vue` 的 `level === 0`);WorkTab 只显示文字,`meta.icon` 仅用于侧栏。 - 列表及新增、编辑弹窗默认不展示 `sort_order/orderNum`,按业务明确需要添加。 ## 表单、弹窗与上传 - 表单 `label-position="top"`;遮罩 `backdrop-filter: none`。 - 弹窗使用 `dialog-form-layout`,`max-height: calc(100vh - 100px)`,只有 body 滚动;遵循全局定位和 `align-center`/ElConfigProvider,不在页面自行覆盖。 - 默认 `form-grid-2`,最多 5 列,窄屏减少列数;通栏 `form-col-span-2` 或 `grid-column: 1 / -1`。 - 复用 `src/assets/styles/core/app.scss` 中全局网格、sort-field、form-tip,禁止在 scoped 样式重复定义。网格内纵向间隔优先由 gap 控制。 - 字段少时弹窗约 560~720px,复杂表单按参考页加宽。参考 `ProtocolFormDialog.vue` 的 `append-to-body`、`modal-class="protocol-dialog-mask"`;遵守全局遮罩定位。 - 字段注释放在 label 插槽后的 `.form-label-tip`(12px,`--mint-text-muted`),不放在输入控件旁。 - 所有有可见文字的 `el-button` 必须有前置 `el-icon`;取消/确定使用 Close/Check,图文间距 6px。 - 长表单校验按现有页使用 `scroll-to-error`、`scroll-into-view-options` 与错误提示。 - 附件触发器为 140×96px、`#a7f3d0` 虚线边框卡片,作为同一 flex 行的首项,与附件卡片并排;选择即通过 `fetchUploadAttachment` 上传;卡片支持预览/下载/删除,提示放行下。 - 附件完整模板以 `src/views/cell-storage/protocol/ProtocolFormDialog.vue`“协议附件”和 UI OpenSpec 为准,保留其交互规则。 ## 验证 - 使用 `package.json` 中构建和检查命令;只对改动范围格式化,不运行全仓库自动修复来掩盖差异。 - 字段、枚举、树路径改动同时核对 API 与 TypeScript;后端契约按根规则与后端 AGENTS。 - `public/tinymce/`、SOP 静态资源和参考页不能仅因源于第三方或 Demo 就删除;`clean:dev` 当前仅输出维护提示。 - 不得自行启动、停止或重启开发服务。