日期:2026-09-08
状态:待审阅
对齐:docs/superpowers/specs/2026-09-08-crm-date-column-sort-design.md、docs/superpowers/specs/2026-09-08-bx-date-column-sort-design.md
Demo:docs/crm-date-column-sort-demo.html(样式 2 · 双三角)
地磅管理下「地磅出入库」「地磅单管理」已具备列头 datetime 漏斗,但日期列无法升/降序切换。交互需与 CRM / 报销一致。
ColumnHeaderFilter 且 type === 'datetime' 的列显示双三角。asc / desc;取消后恢复现网默认倒序。_fetch_*,须识别 sortField / sortOrder。useColumnSort + provide('crmColumnSort')。grossWeightTime / tareWeightTime(无漏斗)db/dashboard| # | 决策 |
|---|---|
| D1 | 范围方案 A:只给已有 datetime 漏斗的列加双三角 |
| D2 | 页面:出入库 + 地磅单;计划本批跳过 |
| D3 | 交互与 CRM/报销相同:双三角;同向再点取消;空值升序前、降序后 |
| D4 | 架构:复用 ColumnHeaderFilter(已支持 inject)+ useColumnSort + 后端白名单(方案 1) |
| 菜单 | 前端路径 | 日期列 prop | 后端映射 |
|---|---|---|---|
| 地磅出入库 | web-admin/src/views/db/inventory/index.vue |
date |
DbInboundOutbound.date |
| 地磅单管理 | web-admin/src/views/db/weighing/index.vue |
inventoryDate |
关联出入库 DbInboundOutbound.date(经 inbound_outbound_id;展示字段非地磅单本表列) |
跳过:views/db/plans/index.vue、views/db/dashboard/index.vue。
与 CRM / 报销 §4 一致:
toSortQueryParams()。两页均为:
_fetch_inventory / _fetch_weighing 一次拉全量(含列过滤);applySortAndPage;地磅单 loadData 内对 getRecordDate 排序);因此:
useColumnSort(无参时保持现网默认 desc)。_fetch_* 按 sortField/sortOrder 应用白名单 order_by,避免导出仍按硬编码序。ColumnHeaderFilter 已在报销任务中支持 inject('crmColumnSort') + type==='datetime' 显示双三角,本批无需再改组件。
各页:
const { setSort, clearSort, isSortActive, sortField, sortOrder,
toQueryParams: toSortQueryParams, watchVisibleColumns: watchSortVisibleColumns } =
useColumnSort({ onChange: () => { /* 出入库:applySortAndPage;地磅单:重排 allData 或 loadData */ } })
provide('crmColumnSort', { setSort, clearSort, isSortActive, sortField, sortOrder })
buildListQueryParams / 导出 getFilterParams 合并 ...toSortQueryParams()。watchSortVisibleColumns(visibleFilterProps)。applySortAndPage 按 sortField(仅 date)与 sortOrder 排;缺省 date + desc。getRecordDate 倒序;缺省仍按展示日期 desc;有 inventoryDate+asc|desc 时按该序(空串按空值规则)。新建薄封装(对齐 app/services/bx/list_sort.py):
app/services/db/list_sort.pyINVENTORY_WHITELIST = {"date": DbInboundOutbound.date}WEIGHING_WHITELIST:inventoryDate → 需 outerjoin 出入库表后对 DbInboundOutbound.date 排序(见下)resolve_datetime_order_by;parse_sort_params 可复用 bx 或同文件复制一行。出入库 _fetch_inventory:
date.desc(), id.desc()(现网)。order_by(resolve(...));建议次键仍 id.desc() 保稳定。地磅单 _fetch_weighing:
gross_weight_time.desc()(现网;与列头「日期」展示字段不完全同一列,保持取消排序后行为不变)。inventoryDate:outerjoin(DbInboundOutbound, ...) 后按 DbInboundOutbound.date asc/desc;无关联单时 date 为空,依赖 MySQL NULL 次序(升序前、降序后)。inbound_outbound_id 一对一关联即可。导出 body(若已有 export schema)显式或 extra=allow 透传 sortField/sortOrder。
backend/tests/test_db_list_sort.py:白名单 / 非法回退。useColumnSort.test.ts,无需新测除非抽纯函数。date 升/降/取消;地磅单 inventoryDate;导出序与列表一致;计划页无三角。| 风险 | 处理 |
|---|---|
inventoryDate 非本表列 |
JOIN 排序;禁止臆造 inventory_date 列名 |
| 前端已拉全量 | 列表改客户端排序即可;仍须后端排序服务导出 |
| 取消排序后默认序 | 出入库回 date desc;地磅单回 gross_weight_time desc(后端)与展示日期 desc(前端,与现网 loadData 一致) |
| 与未提交的 BX 排序改动并存 | 本能力独立;提交时勿混入无关 dirty 文件 |
services/db/list_sort.py + 单测_fetch_inventory / _fetch_weighing(及 export params)接排序inventory/index.vue、weighing/index.vue./scripts/update-graph.sh