迭代 ONE-OS 多原型:加氢记录/订单同源对账、租赁明细校验与月度损益、车辆与台账增强;新增客户回款与加氢站统计;补齐业务逻辑与对象存储发布规范,同步原型导航。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
王冕
2026-07-16 09:00:13 +08:00
parent aa6b9a7683
commit 47c223a666
130 changed files with 17507 additions and 4461 deletions

View File

@@ -1,7 +1,13 @@
/**
* 列表页筛选区全局规则(与 vehicle-management/style.css 中 .vm-filter-grid 4 列布局一致)
*
* 规则:筛选项超过 1 行(默认 4 项)时,其余收入折叠区,通过「更多筛选」展开。
* ## 布局约束
* 1. 收起时首行primary最多展示 `VM_FILTER_COLUMNS_PER_ROW`(默认 4占满 1 行。
* 2. 展开时:其余项放入 `vm-filter-expand` / `ldb-filter-expand`primary 与 extra 各自使用 4 列栅格。
* 3. 禁止「末行仅 1 项」:若展开区项数为 4n+1从首行尾部借调 1 项到展开区(首行变为 3 项)。
* 典型:总项数 5 → 首行 3 + 展开 2总项数 6 → 首行 4 + 展开 2。
*
* 实现参考:`payment-records/components/FilterPanel.tsx`、`lease-business-ledger/components/FilterPanel.tsx`
*/
export const VM_FILTER_COLUMNS_PER_ROW = 4;
@@ -12,13 +18,37 @@ export function splitFilterFields<T>(
fields: T[],
primaryCount: number = VM_FILTER_PRIMARY_VISIBLE_COUNT,
): { primary: T[]; extra: T[] } {
if (fields.length <= primaryCount) {
const columnsPerRow = primaryCount;
if (fields.length <= columnsPerRow) {
return { primary: fields, extra: [] };
}
return {
primary: fields.slice(0, primaryCount),
extra: fields.slice(primaryCount),
};
const primary = fields.slice(0, columnsPerRow);
const extra = fields.slice(columnsPerRow);
return rebalanceFilterSplit(primary, extra, columnsPerRow);
}
/** 避免展开区出现 4n+1 项导致末行孤零零 1 项 */
function rebalanceFilterSplit<T>(
primary: T[],
extra: T[],
columnsPerRow: number,
): { primary: T[]; extra: T[] } {
const nextPrimary = [...primary];
const nextExtra = [...extra];
while (
nextExtra.length > 0
&& nextExtra.length % columnsPerRow === 1
&& nextPrimary.length > 0
) {
const moved = nextPrimary.pop();
if (moved === undefined) break;
nextExtra.unshift(moved);
}
return { primary: nextPrimary, extra: nextExtra };
}
export function shouldShowFilterExpand(