diff --git a/docs/crm-date-column-sort-demo.html b/docs/crm-date-column-sort-demo.html
new file mode 100644
index 000000000..3820a6aa0
--- /dev/null
+++ b/docs/crm-date-column-sort-demo.html
@@ -0,0 +1,638 @@
+
+
+
+
+
CRM 日期列头排序 Demo
+
+ 在现有漏斗过滤旁增加日期列排序(正序 / 倒序)。样式对齐 Fresh Mint。
+ 打开本文件即可交互:点击切换排序,表格会即时重排。
+
+
+
+ 工作量结论:
+ 只给 type: 'datetime' 的列加排序 —— 改公共列头组件 + 列表查询加一个排序参数,改动集中、可控。
+ 若所有有漏斗的列(文本/枚举/数字/日期)都加 —— 前端交互可复用,但后端几乎每个 CRM 列表接口都要做白名单排序字段,工作量大约是「日期方案」的 2~3 倍,且数字/文本排序语义更啰嗦。
+ 建议先只做日期列。
+
+
+
+
+
方案范围 A · 仅日期列 推荐
+
+ - 前端:列头组件识别 datetime → 显示排序控件
+ - 后端:列表支持
sortField + sortOrder(白名单仅日期字段)
+ - 默认仍是
create_time DESC;点列头后覆盖
+
+
+
+
方案范围 B · 所有漏斗列
+
+ - 交互可做成通用,但文本/枚举排序价值一般
+ - 数字列还要处理空值、精度
+ - 每个列表 API 白名单字段更多,联调面大
+
+
+
+
+
交互样式对比(选一种即可)
+
+
+
样式 1 · 点击列名循环 推荐
+
无排序 → 升序 → 降序 → 无。漏斗只管过滤,互不干扰。
+
+
+
+
样式 2 · 双三角(Element 风格)
+
上下三角独立点选;与漏斗并排,更贴近表格库默认习惯。
+
+
创建时间
+
+
+
+
+
+
+
+
+
+
+
样式 3 · 放进漏斗面板
+
排序入口藏在过滤弹层里;列头更干净,但多一步点击。
+
+
+
+
+
+
+
+
+
+
+
+
+
客户列表(示意)
+ 日期列:点击列名循环 无 → 升序 → 降序
+
+
+ 已选 0 项
+
+ 非日期列仅有漏斗,无排序
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/superpowers/specs/2026-09-08-crm-date-column-sort-design.md b/docs/superpowers/specs/2026-09-08-crm-date-column-sort-design.md
new file mode 100644
index 000000000..96d9b6465
--- /dev/null
+++ b/docs/superpowers/specs/2026-09-08-crm-date-column-sort-design.md
@@ -0,0 +1,192 @@
+# CRM 日期列头双三角排序(客户 / 报价 / 合同)
+
+**日期**:2026-09-08
+**状态**:待审阅
+**交互 Demo**:`docs/crm-date-column-sort-demo.html`(样式 2 · 双三角)
+**前置能力**:列头漏斗整库筛选(`CrmColFilterHeader` + `useServerColumnFilters`)
+
+---
+
+## 1. 背景与目标
+
+CRM 客户、报价、合同等列表已具备列头漏斗过滤,但日期列无法在列头切换正序/倒序。分页场景下不能只排当前页,必须服务端排序。
+
+### 目标
+
+1. 日期列(`ColumnFilterDef.type === 'datetime'`)列头增加双三角,支持升序 / 降序 / 取消。
+2. 排序打整库;与现有列过滤、Tab、快捷搜索 **AND**;`total` / 换页 / 导出与当前排序一致。
+3. 同一时刻仅一列生效;取消后恢复默认 `create_time DESC`。
+4. 首批只改客户 + 报价 + 合同(含管理与审批共用列表页);其它 CRM 页后续再加。
+
+### 非目标(本批)
+
+- 文本 / 枚举 / 数字列排序
+- 产品、调价函、线索、商机、合同变更/模板/审批记录等列表
+- 多列组合排序、排序状态持久化(URL / localStorage)
+- 用 `el-table` 内置 `sortable` 替换自定义列头
+
+---
+
+## 2. 已确认产品决策
+
+| # | 决策 |
+|---|------|
+| D1 | 交互:**双三角**(上下箭头);再点**同一方向**取消排序 |
+| D2 | 范围首批:**客户管理** + **报价单管理/审批** + **合同管理/审批** |
+| D3 | 审批与管理共用 `QuoteListPage` / `ContractListPage`,**一并支持**(无需单独隐藏) |
+| D4 | **仅日期列**(`datetime`)显示排序三角;其它有漏斗的列不加 |
+| D5 | 空值:升序时空值在最前,降序时空值在最后(与 MySQL 对 NULL 的默认次序一致) |
+| D6 | 架构:公共列头 + 查询参数 `sortField`/`sortOrder` + 后端字段白名单(方案 1);不用纯前端当前页排序 |
+
+---
+
+## 3. 首批范围
+
+### 3.1 改造
+
+| 层 | 路径 / 说明 |
+|----|-------------|
+| 列头 UI | `web-admin/src/components/business/crm-col-filter-header/index.vue`(及必要样式) |
+| 排序状态 | 新建小型 composable 或扩展 provide(如 `useColumnSort` / `crmColumnSort`),由列表页 `provide` |
+| 客户列表 | `web-admin/src/views/crm/customer/index.vue` |
+| 报价列表 | `web-admin/src/views/crm/quote/QuoteListPage.vue`(`mode=manage\|approve`) |
+| 合同列表 | `web-admin/src/views/crm/contract/ContractListPage.vue`(`mode=manage\|approve`) |
+| 后端客户 | list / export:`CustomerListBody`(及公海若本批不改则不动公海)+ `list_customers` 排序分支 |
+| 后端报价 | `QuoteListBody` + quote list/export CRUD 排序分支 |
+| 后端合同 | `ContractListQuery` + contract list/export CRUD 排序分支 |
+
+**客户公海**:本批产品范围写的是「客户」主列表;**不改公海**,除非实现时发现与客户共用同一排序模块且零成本——默认不做公海。
+
+### 3.2 日期列白名单(前端 prop → 后端仅允许这些)
+
+以各页现有 `columnFilterDefs` 中 `type: 'datetime'` 为准:
+
+**客户**(`customer/columnFilterDefs.ts`)
+`lastTime`、`nextTime`、`dealTime`、`intoPoolTime`、`claimTime`、`protectTime`、`createTime`、`updateTime`
+
+**报价**(`quote/columnFilterDefs.ts`)
+`quoteDate`、`expireDate`、`lastViewTime`、`createTime`、`updateTime`
+
+**合同**(`contract/columnFilterDefs.ts`)
+`signDate`、`startDate`、`endDate`、`createTime`、`updateTime`
+
+映射到 ORM 字段时使用既有 snake_case 列(如 `createTime` → `create_time`)。非法 `sortField` 忽略并回退默认排序,不 500。
+
+---
+
+## 4. 产品与交互
+
+### 4.1 列头布局
+
+从左到右(居中列同样水平排列):
+
+1. 列标题文案
+2. **双三角**(仅 `datetime`)
+3. 漏斗过滤按钮(已有)
+
+视觉对齐 Fresh Mint:未激活三角 `#cbd5e1`;激活 `#059669`;可点区域约 14×10px×2,避免挤爆列头。参考 Demo「样式 2」。
+
+### 4.2 交互规则
+
+| 操作 | 结果 |
+|------|------|
+| 点上三角 | 该列 `asc`;若已是该列 `asc` → 清除排序 |
+| 点下三角 | 该列 `desc`;若已是该列 `desc` → 清除排序 |
+| 点另一日期列三角 | 替换为新列的方向 |
+| 清除排序 | 不传 `sortField`/`sortOrder`,后端默认 `create_time DESC` |
+| 藏列 | 若隐藏列正是当前排序列 → **清除排序**并重查(与藏列清过滤对称) |
+| 漏斗过滤变更 | 保留当前排序(AND) |
+
+不在工具栏强制展示「当前排序」徽章(Demo 仅示意);列头高亮三角即为状态。
+
+### 4.3 空值
+
+MySQL:`NULL` 小于非空 → `ASC` 时 NULL 在前,`DESC` 时 NULL 在后。本批直接 `ORDER BY