` | 密度可切换;Hover 高亮 | `hover:bg-neutral-50` |
| 数据单元 `` | 正文字号;垂直居中 | `px-3 py-3 text-sm text-neutral-700 align-middle whitespace-nowrap` |
| 选中行 | 浅主色高亮 | `bg-primary-50/40` |
| 操作列 | 固定右侧;Ghost 图标按钮,Hover 显形 | `sticky right-0 bg-white opacity-0 group-hover:opacity-100` |
| 表格底部(分页栏) | | `px-4 py-3 border-t border-neutral-200 bg-white flex items-center justify-between` |
- **斑马纹**:B2B 高密度场景**不启用**(视觉噪音)。Hover 行高亮已足够区分。
- **封面缩略图**:房源/楼盘等含图业务表格,第一数据列(通常为"标题"列)内嵌缩略图(` ` 或占位 ``),尺寸随密度档联动(见下表)。缩略图统一 `rounded` (4px),对象填充 `object-cover`,加载失败占位为 `bg-neutral-100` + 图片占位图标。
- **三档密度**:工具栏右侧"密度"图标按钮切换,Alpine.js + `localStorage`(key: `fonrey:table:{module}:density`)持久化,默认 `standard`。
| 档位 | Key | 行高 | 缩略图尺寸 | 单元内边距 | 使用场景 |
|---|---|---|---|---|---|
| 紧凑 Compact | `compact` | 40px | 无(图片列隐藏) | `px-3 py-2` | 数据核对、大批量浏览、导出前预览 |
| 标准 Standard(默认) | `standard` | 56px | 40×40 | `px-3 py-3` | 日常工作,"一眼认房" |
| 舒适 Comfortable | `comfortable` | 72px | 56×56 | `px-3 py-4` | 含更多副信息(楼层/朝向/装修标签换行展示) |
> **实现提示**:密度切换仅改 ` ` 上的 class(如 `table-density-standard`),通过父级 class + 子选择器统一控制行高、内边距、图片显隐,避免逐行改 class。
> **无图业务**(客源、跟进记录、权限等)表格固定使用 `compact` 40px 行高,不提供密度切换。
#### 3.4.2 标准片段
```html
共 3,629 条
跳至
页
```
#### 3.4.3 HTMX 局部刷新约定
- 所有筛选、排序、翻页触发 `hx-get`,目标容器为 `` 或 `#table-wrapper`
- **加载态**:`htmx:beforeRequest` 给 `` 叠加骨架屏(`animate-pulse` 的 5 行占位)
- **错误态**:`htmx:responseError` 保留原内容 + 触发 Error Toast
#### 3.4.4 自定义列(Column Visibility)
右上角"自定义列表"按钮,弹出 Checkbox 面板,选择状态持久化到 `localStorage`(Key: `fonrey:table:{module}:cols`)。隐藏的列通过 Alpine.js `:class="{'hidden': !col.visible}"` 控制。
#### 3.4.5 空状态
见 6.3 空状态设计。表格空状态占整个 ``,不使用 `colspan` 占所有列的骚操作,改用覆盖层(`absolute inset-0 flex items-center justify-center`)。
---
### 3.5 分页(Pagination)
```html
```
- **当前页**:`bg-primary-600 text-white`
- **省略号**:Django 后端生成(前 3 后 3 + 当前 ±1)
- **同页多表格独立分页**:每个分页器 `hx-target` 指向各自的表格容器 id(见 `组件清单.md`)
---
### 3.6 弹窗(Modal)与抽屉(Drawer)
#### 3.6.1 选择原则
| 类型 | 场景 | 宽度 | 关闭行为 |
|---|---|---|---|
| Confirm Modal | 删除确认、不可逆操作 | `max-w-sm`(400px) | 点击遮罩**不关闭**(防误触),ESC 关闭 |
| Form Modal | 新增/编辑(字段 ≤ 6) | `max-w-lg`(560px) | 点击遮罩关闭,ESC 关闭 |
| Right Drawer | 查看详情、新增/编辑(字段多)、参考主页面 | `w-[640px]` 或 `w-[480px]` | 点击遮罩关闭,ESC 关闭 |
| Full Modal | 复杂配置(权限矩阵) | `w-[80vw] max-w-6xl` | 点击遮罩**不关闭**,顶部关闭按钮 |
#### 3.6.2 Modal 标准结构
```html
```
#### 3.6.3 Drawer 标准结构
```html
```
#### 3.6.4 Confirm Modal
用于删除、下架、离职等不可逆操作。固定使用 Danger 风格:
```html
确认删除该房源?
删除后将进入回收站,30 天内可恢复。
```
---
### 3.7 状态标签(Badge / Tag)
用于状态展示,不可点击,不可编辑(编辑用 Multi-select Tag Input)。
| 样式类型 | 场景 | Tailwind 类 |
|---|---|---|
| Subtle(默认,底色+文字) | 高频状态展示 | `bg-{color}-50 text-{color}-700` |
| Solid | 极少数强调(如"紧急") | `bg-{color}-600 text-white` |
| Outline | 低密度场景 | `border border-{color}-600 text-{color}-700` |
#### 3.7.1 业务状态色板
| 状态 | 色系 | 示例 |
|---|---|---|
| 在售 / 激活 / 在职 | success | `bg-success-50 text-success-600` |
| 出租 | info | `bg-info-50 text-info-600` |
| 跟进中 / 待确认 | warning | `bg-warning-50 text-warning-600` |
| 已成交 / 完成 | primary | `bg-primary-50 text-primary-700` |
| 已下架 / 停用 / 离职 | neutral | `bg-neutral-100 text-neutral-500` |
| 逾期 / 紧急 / 冻结 | danger | `bg-danger-50 text-danger-600` |
| 暂缓 | 浅灰 + 斜体 | `bg-neutral-100 text-neutral-600 italic` |
#### 3.7.2 交易类型标签色板
交易类型标签(买卖 / 租赁 / 租售)属于**分类标签**,不表达状态语义,禁止使用语义色(danger / info solid)。
**视觉层级要求**:交易类型标签须比同行副标签(满五、独家等)**更大、更醒目**:
- 交易类型标签:`text-xs`(12px)+ `px-2 py-0.5` + `font-semibold` + 较深底色
- 副标签(房源属性 Tag):`text-[10px]` + `px-1.5 py-0.5` + `font-medium` + 极淡底色
| 交易类型 | 色系 | Tailwind 类 | 设计理由 |
|---|---|---|---|
| 买卖 | primary(Teal) | `bg-primary-200 text-primary-800` | 核心出售业务,用品牌主色强调 |
| 租赁 | warning(Amber) | `bg-warning-200 text-warning-800` | 与买卖形成色相区分,暖色低调 |
| 租售 | neutral | `bg-neutral-300 text-neutral-800` | 兼含两种类型,中性色避免歧义 |
> **禁止**对交易类型标签使用 Solid 样式(`bg-{color}-600 text-white`),该样式仅用于极少数强调性状态(如"紧急")。
#### 3.7.2 标准片段
```html
在售
```
---
### 3.8 Toast 通知
- 统一出现在**右下角**(`fixed bottom-6 right-6 z-70`)
- 多条堆叠,新消息**追加在底部**,超出视窗则顶部旧消息自动移除
- 固定宽度 `w-80`
| 类型 | 图标色 | 停留 | 手动关闭 |
|---|---|---|---|
| Success | `text-success-600` | 3s | 否 |
| Error | `text-danger-600` | 5s | 是 |
| Warning | `text-warning-600` | 5s | 是 |
| Info | `text-info-600` | 3s | 否 |
```html
```
**HTMX 触发规范**:后端响应 `HX-Trigger` header:
```
HX-Trigger: {"fonrey:toast": {"type": "success", "message": "保存成功", "detail": "房源已更新"}}
```
前端全局监听 `document.addEventListener('fonrey:toast', ...)` 插入 Toast 节点。
---
### 3.9 加载状态(Loading States)
| 场景 | 实现方式 |
|---|---|
| HTMX 局部请求 | 目标区域叠加 Skeleton(`animate-pulse` 灰条占位),`htmx:beforeRequest` 添加,`htmx:afterSettle` 移除 |
| 按钮提交中 | 禁用按钮 + 内嵌 Spinner + 文案改为进行时("保存中…") |
| 页面首次加载 | 内容区骨架屏(与最终结构同骨架) |
| 长耗时任务(导出) | Celery 异步,Info Toast 提示"任务已提交,完成后通知";结果通过站内消息推送 |
#### 3.9.1 Skeleton 标准
```html
```
#### 3.9.2 Spinner
```html
```
---
### 3.10 Tab 导航(Tabs)
用于详情页内容区切换、筛选维度切换。
```html
```
- **激活指示**:底部 2px 主色下划线 + 主色文字
- **计数 Badge**:中性色小圆角标
- **懒加载**:切换到 Tab 时用 HTMX `hx-get` 拉取,首次加载后缓存
---
### 3.11 折叠面板(Accordion / Collapsible)
引入 Alpine 官方插件 `@alpinejs/collapse`(1KB)处理高度过渡。
```html
```
---
### 3.12 Toggle 开关(Switch)
```html
```
---
### 3.13 日期与日期范围
- **单日期**:原生 `` + `@tailwindcss/forms` 样式
- **日期范围(核心)**:引入 **Flatpickr**(16KB,无框架依赖)。参考 `组件清单.md` 推荐。
```html
```
Flatpickr 自定义样式覆盖见附录 10.3。
---
### 3.14 文件上传
- **单/少量图片(头像、实勘主图)**:原生 `` + Alpine 预览
- **多图批量上传(相册管理)**:引入 **Filepond**,支持拖拽、预览、进度、队列
- **拖拽排序**:引入 **SortableJS**(3KB)
统一上传目标 Cloudflare R2,后端接收后转存并返回 URL。上传进度条使用 Filepond 内置样式,颜色 override 为 `primary-600`。
---
### 3.15 图片预览(Lightbox)
引入 **Viewer.js**(5KB,无依赖)。覆盖缩放、旋转、全屏、翻页、缩略图条全部需求。样式用 Tailwind 覆盖。
---
## 4. 业务组件规范(Business Components)
### 4.1 房源卡片(Property Card)
用于"卡片视图"模式(列表页允许用户切换表格/卡片两种视图)。
```
┌──────────────────────────────────────┐
│ ┌─────┐ 房源标题(2行截断) ⋯ │
│ │封面 │ 浦东 · 张江高科 │
│ │ 图 │ 89㎡ · 2室1厅 · 高层 │
│ └─────┘ ¥580 万 [在售] │
│ ──────────────────────────────── │
│ 👤 张三 · 2 小时前更新 │
└──────────────────────────────────────┘
```
- 宽度:响应式栅格 `grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4`
- 封面图:`w-32 h-24 rounded object-cover`,固定比例 4:3
- 点击整卡:进入详情页
- 右上角 `⋯`:触发 Action Menu(见 4.4)
### 4.2 筛选栏(Filter Bar)
```
┌─────────────────────────────────────────────────────────────────┐
│ 区域: [浦东新区▾] 价格: [¥300万-¥800万▾] 户型:[▾] 状态:[在售▾] │
│ [+ 高级筛选 (3)] [清空] [搜索] │
├─────────────────────────────────────────────────────────────────┤
│ 已选: [浦东新区 ×] [¥300-800万 ×] [2室1厅 ×] [清空所有] │
└─────────────────────────────────────────────────────────────────┘
```
- 常驻筛选横向排列,用 Select / Multi-select / Date Range
- 高级筛选按钮(带数字 Badge 表示已填的高级条件数量),点击展开折叠区
- **筛选变化触发 `hx-get`**,`hx-trigger="change delay:200ms"`,结果刷新列表 `hx-target`
- 已选条件 Tag 可单独删除(`×`)或一键清空
### 4.3 数据统计卡片(Stat Card)
```html
```
### 4.4 操作菜单(Action Menu)
三点按钮 `⋯` 触发下拉,危险操作(删除)永远在底部且有分隔线。
```html
```
### 4.5 跟进时间线(Follow-up Timeline)
用于房源/客源详情页的跟进记录展示。
```html
-
张三
修改跟进
·
业主同意降价 20 万,挂牌价调整为 580 万,已通知重点客户。
```
### 4.6 相册管理(Photo Gallery Manager)
参考 `组件清单.md`。核心组件:
- 可横向滚动分类 Tab + 溢出 `⋯`
- 多选图片网格(`grid-cols-6 gap-2`,每格 `aspect-[4/3]`)
- 批量工具栏(依赖选中状态启用)
- 上传 Modal(Filepond)
- 排序模式(SortableJS)
### 4.7 字段填写要求配置表(Dynamic Form Table)
用于 `系统设置 → 房源设置 → 字段标签设置`。一张可增删行 + 拖拽排序 + Toggle 切换的表格,结合 SortableJS + Alpine.js。区分系统预置行(不可删)与用户自定义行。详见 `组件清单.md` §Sortable Table with Drag Handle。
### 4.8 权限矩阵(Permission Matrix)
纵向:功能模块(房源、客源、楼盘 …);横向:权限动作(查看、新增、编辑、删除、审核)。交叉单元格为 Toggle 或三态(继承 / 开 / 关)。宽度超屏时 **左列固定** + 横向滚动:
```html
```
### 4.9 业主/客源联系人卡片(Contact Card)
头像 + 姓名 + 电话(敏感脱敏 `138****1234`) + 角色标签 + 操作菜单。手机号悬浮显示"查看完整"按钮(触发权限校验 + 审计日志)。
---
## 5. 页面布局模板(Page Layout Templates)
### 5.1 整体框架
```
┌──────────────────────────────────────────────────────────────────────┐
│ Topbar(56px,sticky top-0 z-20) │
│ [Logo 150px] [主导航: 主页 房源 客源 营销 交易 数据 人事 系统] │
│ [消息🔔] [帮助?] [头像▾] │
├─────────────────┬────────────────────────────────────────────────────┤
│ Sidebar │ 内容区(Content Area) │
│ 展开 240px │ 面包屑 > 房源管理 > 二手 & 租赁 [次操作] [主操作] │
│ 折叠 64px │ ───────────────────────────────────────────────── │
│ │ 页面标题 H1 │
│ [当前主分类 │ ───────────────────────────────────────────────── │
│ 的子菜单] │ 筛选 / 工具栏(Sticky,top-14) │
│ │ ───────────────────────────────────────────────── │
│ ← 折叠按钮 │ 内容主体(表格 / 卡片 / 表单) │
│ │ │
│ │ 分页栏 │
└─────────────────┴────────────────────────────────────────────────────┘
```
**尺寸约定**
| 区域 | 规格 |
|---|---|
| Topbar 高度 | 56px(`h-14`);`sticky top-0 z-20` |
| Sidebar 展开宽度 | 240px(`w-60`);`fixed left-0 top-14 h-[calc(100vh-56px)] z-20` |
| Sidebar 折叠宽度 | 64px(`w-16`) |
| 内容区偏移 | 展开态 `ml-60`,折叠态 `ml-16`;`transition-[margin] duration-200` |
| 内容区内边距 | `px-6 py-4` |
| 工具栏 Sticky 偏移 | `sticky top-14 z-30`(Topbar 下方紧贴) |
---
### 5.2 顶部导航栏(Topbar)
#### 5.2.1 结构规范
Topbar 分三区:左区(Logo)、中区(主导航 + 搜索)、右区(工具区)。
```
┌─────────────────────────────────────────────────────────────────────┐
│ [🏢 Fonrey ▾] 主页 房源 客源 营销 [搜索框] [🔔] [⚙] [WS 王顺] │
└─────────────────────────────────────────────────────────────────────┘
```
| 区域 | 内容 | 样式 |
|---|---|---|
| 左区(`w-60 shrink-0`) | Logo 图标 + 产品名"Fonrey" | `flex items-center gap-2 px-4 text-base font-semibold text-white` |
| 中区(`flex-1`) | 主分类导航 + 全局搜索框 | `flex items-center gap-4 flex-1 px-2` |
| 右区(`shrink-0`) | 消息通知 / 设置 / 头像+姓名 | `flex items-center gap-1 px-4 shrink-0` |
> **配色**:Topbar 背景使用 `bg-primary-800`(`#134E4A`,深青绿),与下方白色 Sidebar 和 `bg-neutral-50` 内容区形成明确层次区分,同时保持品牌色系一致性。
#### 5.2.2 主导航 Tab
主分类(8项):**主页 / 房源 / 客源 / 营销 / 交易 / 数据 / 人事 / 系统**
- 每项:`px-3 py-1.5 text-sm rounded-md`
- 默认态:`text-primary-100 hover:bg-primary-700 hover:text-white`
- 激活态:`bg-primary-600 text-white font-medium`
- 点击切换主分类 → Sidebar 同步切换为该分类的子菜单
#### 5.2.3 全局搜索框
位于主导航右侧,宽度 `max-w-xs`。
- 默认态:`bg-primary-700/60 border-transparent text-white placeholder:text-primary-300`
- Hover:`hover:bg-primary-700`
- Focus:`focus:bg-white focus:text-neutral-700 focus:border-primary-600 focus:ring-2 focus:ring-primary-600/20`
#### 5.2.4 右区工具
| 元素 | 图标 | 样式 |
|---|---|---|
| 消息通知 | `BellIcon` 20px + 红点 Badge | `p-1.5 text-primary-200 hover:bg-primary-700 hover:text-white rounded-md` |
| 设置 | `Cog6ToothIcon` 20px | 同上 |
| 头像菜单 | `w-7 h-7 rounded-full bg-primary-600` + 姓名 | 头像缩写 + `text-sm font-medium text-primary-100`,左侧 `border-l border-primary-700` 分隔 |
#### 5.2.5 Topbar HTML 片段
```html
```
┌─────────────────────────────────────────────────────────────────────┐
│ [🏢 Fonrey ▾] 主页 房源 客源 营销 交易 数据 人事 系统 │
│ [🔍] [🔔2] [?] [WS 王顺▾] │
└─────────────────────────────────────────────────────────────────────┘
```
| 区域 | 内容 | 样式 |
|---|---|---|
| 左区(150px) | Logo 图 + 产品名"Fonrey" | `flex items-center gap-2 px-4 text-base font-semibold text-white` |
| 中区(flex-1) | 主分类导航 Tab | 见 5.2.2 |
| 右区(auto) | 全局搜索图标 / 消息 / 帮助 / 头像菜单 | `flex items-center gap-1 px-4` |
#### 5.2.2 主导航 Tab
主分类(8项):**主页 / 房源 / 客源 / 营销 / 交易 / 数据 / 人事 / 系统**
- 每项:`px-3 py-1.5 text-sm font-medium rounded-md`
- 默认态:`text-primary-100 hover:bg-primary-700 hover:text-white`
- 激活态:`bg-primary-600 text-white`
- 点击切换主分类 → Sidebar 同步切换为该分类的子菜单
#### 5.2.3 右区工具
| 元素 | 图标 | 说明 |
|---|---|---|
| 全局搜索 | `MagnifyingGlassIcon` 20px | 点击展开全局搜索 Popover(`max-w-lg`) |
| 消息通知 | `BellIcon` 20px + 红点 Badge | 未读数 ≤ 99,超出显示"99+";点击打开通知 Drawer |
| 帮助 | `QuestionMarkCircleIcon` 20px | 链接到帮助中心或触发 Tour |
| 头像菜单 | 头像(`w-8 h-8 rounded-full`)+ 姓名缩写 | 下拉菜单:个人设置 / 切换角色 / 退出 |
> **配色说明**:Topbar 背景使用 `bg-primary-800`(`#134E4A`,深青绿),与下方白色 Sidebar 和 `bg-neutral-50` 内容区形成明确层次区分,同时保持品牌色系一致性。
#### 5.2.4 Topbar HTML 片段
```html
```
---
### 5.3 侧边栏(Sidebar)
#### 5.3.1 结构与折叠规范
```
展开态(240px) 折叠态(64px)
┌─────────────────────────┐ ┌──────┐
│ ▾ 房源管理 │ │ 🏘️ │ ← 一级图标,Hover Tooltip
│ 全部房源 ● │ │──────│
│ 二手 & 租赁 │ │ 👤 │
│ 商铺 / 写字楼 │ │ 🏢 │
│─────────────────────────│ │ ⚙️ │
│ 客源管理 │ └──────┘
│ 私客管理 ● │
│ 公客池 │
│─────────────────────────│
│ [← 折叠] │ ← 折叠按钮(固定在 Sidebar 底部)
└─────────────────────────┘
```
- **Sidebar 定位**:`fixed left-0 top-14 h-[calc(100vh-56px)] z-20 overflow-y-auto`
- **展开宽度**:`w-60`(240px);折叠宽度:`w-16`(64px)
- **Alpine.js 状态**:`x-data="{ collapsed: $persist(false).as('fonrey:sidebar:collapsed') }"`(使用 `@alpinejs/persist` 持久化)
- **内容区联动**:``
#### 5.3.2 菜单层级
Sidebar 展示**当前主分类的子菜单**,分为一级菜单和二级菜单(可选)。
| 层级 | 样式 | 激活态 |
|---|---|---|
| 一级菜单(有子项) | `flex items-center gap-3 px-3 py-2 text-sm font-medium text-neutral-700 rounded-md hover:bg-neutral-100 cursor-pointer` | `text-neutral-900 bg-neutral-100` |
| 一级菜单(无子项,直链) | 同上 | `bg-primary-50 text-primary-700 font-semibold border-l-2 border-primary-600 rounded-l-none` |
| 二级菜单 | `ml-8 flex items-center gap-2 px-3 py-1.5 text-sm text-neutral-600 rounded-md hover:bg-neutral-100` | `bg-primary-50 text-primary-700 font-medium border-l-2 border-primary-600 rounded-l-none` |
| 分组标题(可选) | `px-3 pt-4 pb-1 text-xs font-semibold text-neutral-400 uppercase tracking-wider` | — |
#### 5.3.3 折叠态行为
- 仅显示一级菜单图标(`w-5 h-5`),居中 `justify-center`
- 文字、箭头、二级菜单全部隐藏(`x-show="!collapsed"`)
- Hover 图标时,右侧弹出 Tooltip:菜单名称(`absolute left-16 ml-1 px-2 py-1 text-xs bg-neutral-900 text-white rounded whitespace-nowrap z-40`)
- 折叠按钮变为展开图标(`ChevronRightIcon`),固定在底部
#### 5.3.4 Sidebar HTML 片段
```html
{% block content %}{% endblock %}
```
---
### 5.4 列表页模板
适用:房源列表、客源列表、楼盘列表、权限人员列表、组织人员列表等。
```
面包屑 > 房源管理 > 二手 & 租赁 [导出▾] [+ 新增房源]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Tab: 全部 (3629) | 在售 | 跟进中 | 已成交 | 已下架]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[筛选栏:区域 / 价格 / 户型 / 状态 / 经纪人 | 高级筛选(3) | 搜索]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[批量工具栏(选中时出现):已选 N 条 | 分享 | 收藏 | 下架 | 删除]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[视图切换: 表格 | 卡片] [密度: 紧凑] [自定义列▾]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
表格主体(HTMX 局部刷新)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
分页栏(共 3629 条 · 1 2 3 … · 20/页 · 跳至)
```
### 5.5 详情页模板
适用:房源详情、客源详情、楼盘详情、员工详情。
```
面包屑 > 房源 > 浦东张江花园 89㎡
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[房源标题] [在售] [钥匙房] [收藏] [分享] [⋯ 更多]
浦东新区 · 张江高科路 · 89㎡ · 2室1厅 · ¥580 万
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Tab: 基本信息 | 跟进记录(12) | 相册(8) | 附件(3) | 操作日志]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
主内容(Tab 内容,HTMX 懒加载)
┌───────────────────────┐ ┌────────────────────┐
│ 房源信息(含编辑链接)│ │ 维护完成度 69% │
│ │ │ [Accordion 进度] │
│ 产证信息(折叠) │ │ │
│ 房屋介绍 │ │ 相关员工(折叠) │
└───────────────────────┘ └────────────────────┘
```
- 详情页头部 Sticky(便于长页面滚动时保持操作按钮可见)
- Tab 计数 Badge 实时更新
- 右侧栏(`w-80`)用于维护度、相关员工等辅助信息;主区 `flex-1`
- **编辑入口 = 详情字段旁的"编辑"链接 → 右侧 Drawer 滑入**(遵循"保留上下文"原则)
### 5.6 设置页模板
适用:系统设置、权限管理、个人设置。
```
面包屑 > 系统设置 > 房源设置 > 字段标签设置
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌──────────────────┬────────────────────────────┐
│ 左侧分组导航 │ 右侧内容区 │
│ (240px) │ │
│ │ [搜索设置项…] [编辑] │
│ ▾ 房源设置 │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ 新增编辑查看 │ 员工信息设置 │
│ 字段标签设置 ● │ ┃ 个人信息 │
│ 相关方设置 │ ┃ 工龄计算方式: [...] │
│ ▾ 客源设置 │ ┃ 自动工号: [Toggle] │
│ ▾ 人事OA设置 │ │
│ │ [保存变更](Sticky 底部) │
└──────────────────┴────────────────────────────┘
```
- **Read/Edit 模式切换**:右上角"编辑"按钮 → 全页切换到编辑态(Alpine.js 全局 `editing` 状态 + 数据快照以便"取消"还原)
- 左侧导航支持二级折叠,激活项左侧 2px 主色竖条
- 底部保存按钮 Sticky(编辑态)
### 5.7 登录/认证页
独立布局,不使用 Sidebar。居中卡片 `max-w-md`,品牌色背景装饰(左侧 logo + slogan,右侧表单),参考 Salesforce Lightning 登录页密度。
### 5.8 空状态页(Empty Page)
见 6.3。
### 5.9 错误页(403/404/500)
三视图共享同一模板,仅图案与文案不同。`max-w-md mx-auto text-center` + SVG 插图 + 主按钮"返回首页"+ 次按钮"联系管理员"。
---
## 6. 交互状态规范(Interaction States)
### 6.1 HTMX 请求生命周期
| 阶段 | 事件 | 视觉反馈 |
|---|---|---|
| 发送前 | `htmx:beforeRequest` | 目标区域 Skeleton / 按钮进入 Loading 态 / 触发元素禁用 |
| 进行中 | `htmx:beforeOnLoad` | 保持 Loading |
| 成功 | `htmx:afterSettle` | 移除骨架;如响应头含 `HX-Trigger: fonrey:toast` 则显示 Toast |
| 422(校验失败) | 返回 Form Partial | 字段级红色提示 |
| 其他失败 | `htmx:responseError` | 保留原内容 + 全局 Error Toast |
| 网络超时 | `htmx:timeout` | 保留原内容 + "网络异常,请重试" Toast |
### 6.2 表单校验反馈
- **实时校验(Alpine.js)**:`blur` 时触发,不阻断提交
- **提交时校验(后端)**:后端返回 HTTP 422 + 包含错误 Partial;字段下方红色小字提示
- **错误提示位置**:字段下方,不使用顶部汇总(经纪人字段多,滚动回找浪费时间)
- **提交成功**:Toast + 可选页面跳转(如新增后跳详情)
### 6.3 空状态设计
| 场景 | 标题 | 描述 | 引导操作 |
|---|---|---|---|
| 列表无数据 | 暂无房源 | 可以录入首条房源开始管理 | `+ 新增房源`(Primary) |
| 搜索无结果 | 未找到匹配结果 | 请尝试调整筛选条件 | `清除筛选条件`(Link) |
| 权限不足 | 暂无访问权限 | 请联系管理员申请权限 | `联系管理员`(Secondary) |
| 功能关闭 | 功能未启用 | 请前往系统设置开启 | `前往设置`(Link,含权限判断) |
结构:
```html
暂无房源
可以录入首条房源开始管理
```
### 6.4 键盘快捷键基线
| 快捷键 | 动作 |
|---|---|
| `Ctrl/Cmd + K` | 打开全局搜索 |
| `Esc` | 关闭当前 Modal / Drawer |
| `Enter` | 提交当前表单 / 确认 Modal(非 Textarea 场景) |
| `Tab / Shift+Tab` | 表单字段间跳转 |
| `/` | 聚焦当前页面主搜索框 |
| `N`(列表页) | 打开"新增"入口 |
---
## 7. 图标规范(Icon Guidelines)
### 7.1 图标库
**Heroicons v2**(Tailwind 官方出品)
- **Outline 24px**:默认选择(工具栏、导航、行内)
- **Solid 20px**:用于状态指示、已选中态、强调
- **Mini 16px(solid)**:极密场景(表格行内、Tag 内)
- 所有图标**继承文字颜色**(`currentColor`),不单独设置 `fill`
引入方式:Django 模板内联 SVG(通过自定义 templatetag `{% heroicon 'plus' %}`),避免远程请求,可利用 CDN 缓存。
### 7.2 尺寸规范
| 尺寸 | 场景 | Tailwind |
|---|---|---|
| 24px | 侧边栏一级菜单 | `w-6 h-6` |
| 20px | 顶部栏、Stat Card、Toast | `w-5 h-5` |
| 16px | 按钮内、Tab、行内图标 | `w-4 h-4` |
| 12px | Tag 内、状态点 | `w-3 h-3` |
### 7.3 核心图标映射
| 业务动作 | Heroicon |
|---|---|
| 新增 | `plus` |
| 编辑 | `pencil-square` |
| 删除 | `trash` |
| 搜索 | `magnifying-glass` |
| 筛选 | `funnel` |
| 排序 | `chevron-up-down` |
| 导出 | `arrow-down-tray` |
| 导入 | `arrow-up-tray` |
| 更多 | `ellipsis-horizontal` |
| 关闭 | `x-mark` |
| 返回 | `arrow-left` |
| 刷新 | `arrow-path` |
| 收藏 | `star`(solid = 已收藏) |
| 分享 | `share` |
| 通知 | `bell` |
| 帮助 | `question-mark-circle` |
| 用户 | `user` |
| 组织 | `users` |
| 房源 | `home`(首页为 `squares-2x2`) |
| 客源 | `user-group` |
| 楼盘 | `building-office-2` |
| 权限 | `lock-closed` |
| 设置 | `cog-6-tooth` |
| 日历 | `calendar` |
| 电话 | `phone` |
| 钥匙 | `key` |
| 附件 | `paper-clip` |
| 图片 | `photo` |
| 视频 | `video-camera` |
| 下载 | `arrow-down-tray` |
| 成功 | `check-circle` |
| 警告 | `exclamation-triangle` |
| 错误 | `x-circle` |
| 信息 | `information-circle` |
**一致性铁律**:同一业务动作在全产品使用**完全相同**的图标。新增业务动作需登记本映射表。
---
## 8. 可访问性基线(Accessibility Baseline)
- 所有表单字段必须关联 ` |