85 lines
8.4 KiB
Markdown
85 lines
8.4 KiB
Markdown
# Web 管理端与移动 H5 规则
|
||
|
||
修改前必读 [根规则](../AGENTS.md)、[工程规则](../docs/development/engineering-rules.md)。
|
||
保存、导入、复制、子数据移除与流程配置必须完整阅读 [子数据保存规则](../docs/development/child-data-save-rules.md),移动 H5 同样适用。
|
||
以下 `src/` 路径相对 web-admin,`docs/`、`openspec/` 路径相对仓库根。
|
||
|
||
## 工程入口与命令
|
||
|
||
- 技术栈:Vue 3、TypeScript、Vite 7、Element Plus、Tailwind CSS 4、Pinia、SCSS、Axios;pnpm 管理依赖。
|
||
- 入口 `src/main.ts`;管理端业务在 `src/views/`,移动 H5 在 `src/views/m/`;API / store / router 分别在 `src/api/`、`src/store/modules/`、`src/router/`。
|
||
- 在本目录执行 `pnpm install`、`pnpm dev`、`pnpm build`、`pnpm build:typecheck`、`pnpm lint`。
|
||
- `pnpm fix`、`pnpm lint:prettier`、`pnpm lint:stylelint` 会修改文件,只在目标范围使用,避免无关格式化。
|
||
- `pnpm commit` 使用 cz-git;`pnpm clean:dev` 会清理 Demo,不能作为日常验证或工程清理命令。
|
||
- Vue、vue-router、Pinia、VueUse API 和 Element Plus 组件自动导入,不重复手工导入;按钮图标显式从 `@element-plus/icons-vue` 导入。
|
||
- Prettier:单引号、无分号、两空格、无尾逗号、`vueIndentScriptAndStyle: true`;遵守 ESLint / Stylelint / Husky 的现有配置。
|
||
- 别名:`@` 为 `src`,另有 `@views`、`@imgs`、`@icons`、`@utils`、`@stores`、`@plugins`、`@styles`,以 tsconfig / vite 为准。
|
||
- 全局 SCSS 由 `vite.config.ts` 注入,包含 `@styles/core/el-light.scss` 与 `@styles/core/mixin.scss`;Tailwind 经现有 Vite 插件接入。
|
||
- Hash 路由 `/#/`;`.env.development` / `.env.production` 使用 `VITE_*`。`/api` 代理受 `VITE_API_PROXY_URL` 控制,另有 `/web` / `/mini` 代理;加密和访问模式以现有配置为准,不为方便绕过加密。
|
||
|
||
## 视觉权威与页面选型
|
||
|
||
- 必读 [Fresh Mint 规范](../docs/web-admin-ui-spec-fresh-mint.md) 与 [视觉样例](../docs/fresh-mint-green.html),通过 CSS 变量、Element 主题变量和全局覆盖对齐,勿随意改 Token。
|
||
- 主色 `#10b981`、深色 `#059669`、背景 `#ecfdf5`;不得使用小程序 `#0a9f6d` 作主色。
|
||
- 清爽 B 端风格,薄荷绿 + Slate,避免一屏多种高饱和色;普通次要信息用 muted。字体 Inter + 系统栈,正文 14px / line-height 1.5。
|
||
- 侧栏 220px、顶栏 56px、内容 padding 24px;面板圆角 10px,输入/按钮等 8px 级圆角按规范。
|
||
- 新页先按 [界面模式索引](../docs/web-admin-ui-pattern-index.md) 选择 P01–P27;PR 写明模式编号与参考页路径,不另造布局或类名。
|
||
|
||
| 用途 | Hash 路由 | 参考源码(相对 web-admin) |
|
||
| --- | --- | --- |
|
||
| 工作台 | `/#/demo/console` | `src/views/dashboard/console/index.vue` |
|
||
| 标准列表 | `/#/demo/unit` | `src/views/demo/unit/index.vue` |
|
||
| 复杂业务列表 | `/#/demo/order` | `src/views/demo/order/index.vue` |
|
||
| 商品列表与查看 | `/#/demo/product` | `src/views/demo/product/index.vue` |
|
||
| 树形主数据 | `/#/demo/category` | `src/views/demo/category/index.vue` |
|
||
| 用户 CRUD | `/#/demo/user` | `src/views/system/user/index.vue` |
|
||
|
||
上述四类 Demo 的旧 `src/views/system/` 路径已迁至 `src/views/demo/`;以 `src/router/modules/demo.ts` 和上表为当前入口,旧 UI 文档中的路径按此对应,不据旧路径新建重复页面。
|
||
|
||
商品只读查看弹窗同时参照 `src/components/business/product-view-dialog/index.vue`。新页面必须对齐所选模板。
|
||
|
||
## 列表、筛选与工具栏
|
||
|
||
- 骨架顺序:可选 `filter-block` → 列表工具栏 → `list-body` / `list-wrap`(含表格)→ 分页。
|
||
- 单标题:列表面板仅一个 `panel-top`,筛选区不重复增加「筛选条件」标题。
|
||
- `panel-top` 内 `h2.title-bar-heading` 用 `::before` 显示主色竖条;竖条标题须在 `src/App.vue` 的 `panelTitleBarTextRules` 注册完整文案,尤其「租户」等易误匹配标题,不依赖短正则或图标自动判断。
|
||
- 筛选栅格、label 11px、控件高 36px、placeholder 按 UI 规范第 5 节;条件行和展开区仅用 gap / margin,不用横向分割线。
|
||
- 工具栏「已选 N 项」在最前,其后排列主按钮与批量操作,禁止 `space-between` 将整组按钮推到行末。
|
||
- 同行仅第一个主行动使用 `type="primary"` / `btn-main`;删除、导入导出等为中性描边。
|
||
- 所有带可见文字的 `el-button` 必须带前置 `<el-icon>`,图标显式导入。
|
||
- `sort_order` / `orderNum` 默认不在列表、新增、编辑弹窗展示;确有功能需要再添加。
|
||
- 主表使用 `list-table` + `stripe`;对齐订单模板时勿随意加 `border`。
|
||
- 业务列与操作列使用 `min-width` 而非 `width`;selection / index 使用固定 `width`(约 48–55 / 60–68)。
|
||
- 有业务操作列时必须 `fixed="right"`、`min-width` ≥ 260px,避免按钮裁切;标准 CRUD 无操作列规则见下文。
|
||
- 工具栏与列表之间使用 `list-body` 顶边框,列表与分页衔接避免重复分隔线。
|
||
- 表格与 `el-pagination` 同在 `list-body.list-wrap`;分页外层 `.pagination.list-pager-bar`,`margin-top: 0`,边框 / padding 按规范第 7.9 节。
|
||
|
||
## 查看、树路径与状态
|
||
|
||
- 有只读查看弹窗的列表,主名称 / 编号列用 `<el-link type="primary">` 打开查看,保留 `@row-dblclick`,不在操作列重复提供「查看」。
|
||
- 仅编辑 / 删除的标准 CRUD 不设操作列;编辑 / 删除置于列表工具栏及 `SystemViewDialog` 的 `#hero-actions`。编辑要求恰选一条,删除支持批量;参照 `src/views/crm/product/index.vue`、`src/views/system/user/index.vue`。
|
||
- 树下拉节点仅显示本级名称;选中输入框、表格、导出、查看弹窗必须显示完整祖先路径,分隔符 ` / `;复用 `src/utils/tree-path.ts`。
|
||
- 每个侧栏树节点须在名称前显示图标,使用 `resolveSidebarMenuIcon`,缺省 folder / file;WorkTab 页签仅文字,不显示图标,`meta.icon` 只用于侧栏。
|
||
- 表格与查看弹窗中的状态、结论、类型字段一律用 `el-tag`;表格 `<el-tag :type="..." size="small">`,`SystemViewDialog` 使用 `ViewField.tagType`。
|
||
- 非 info 标签深底白字,由 `el-ui.scss` 全局控制:success / primary `#059669`、warning `#d97706`、danger `#dc2626`;info 透明底 + `#1e293b`,不使用默认 `#909399`。
|
||
- 不用纯文本、自定义 `<span class="tag">` 或浅填充标签替代非 info 标签;订单 / 配送等枚举映射保持语义一致。
|
||
|
||
## 弹窗与表单
|
||
|
||
- `el-dialog` 根加 `.dialog-form-layout`,`max-height: calc(100vh - 100px)`;仅 `.el-dialog__body` 纵向滚动,头部与底栏固定。
|
||
- 使用 `align-center` 与全局 `ElConfigProvider` 居中;遮罩 `backdrop-filter: none`,沿用现有 modal-class 策略,禁止背景模糊。
|
||
- 表单 `label-position="top"`;字段少时宽约 560–720px,字段多时适当加宽。
|
||
- 默认 `.form-grid-2`,最多 `.form-grid-5`;窄视口降列。长字段和备注 `.form-col-span-2` / `grid-column: 1 / -1`。
|
||
- 栅格内 `el-form-item` 宜 `margin-bottom: 0`,纵向间距靠 gap;不要在 scoped 中重复定义全局 `.form-grid-2`、`.form-col-span-2`、`.sort-field`、`.form-tip`。
|
||
- 字段提示放在 label 后:`<template #label>字段名<span class="form-label-tip">注释</span></template>`;12px、`--mint-text-muted`,不得放在输入控件旁。
|
||
- 底栏取消 / 确定使用 Close / Check 图标 + 文字,间距 6px;高度与圆角按 UI 规范。
|
||
- 长表单建议 `scroll-to-error` 和 `scroll-into-view-options`,校验失败提示与现有页面一致,可配合 `ElMessageBox.alert`。
|
||
|
||
## 附件上传
|
||
|
||
- 上传触发器为 140×96px、`#a7f3d0` 虚线边框卡片,作为附件卡片同一 flex 行的第一项;提示位于整行下方。
|
||
- 选文件后立即调用 `fetchUploadAttachment`;卡片提供预览、下载、删除,不将上传延迟到业务保存。
|
||
- 原规范参考 `ProtocolFormDialog.vue`「协议附件」,该文件不在当前树;现有通用组件为 `src/components/business/attachment-upload-field/index.vue`,以上布局和行为仍须遵守。
|
||
- 完整来源:`openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md` 的附件、按钮、标签、列表与模式索引条款,以及 UI 规范第 7、9.3.1 节。
|
||
- UI 所需 API 字段改动须同步评估后端及 TypeScript 类型,不能仅在显示层掩盖字段或树路径缺失。
|