/** * 表头批量/筛选护栏 + 订单列表默认时间窗(前后端应对齐) */ import dayjs, { type Dayjs } from 'dayjs' /** 批量单号 / IN 值上限 */ export const MAX_HEADER_BATCH_VALUES = 500 /** 单个筛选值最大字符数 */ export const MAX_HEADER_FILTER_VALUE_LEN = 128 /** filters[] 最大条数(前端组装时裁剪) */ export const MAX_HEADER_FILTERS = 20 /** 订单列表默认仅查近 N 天(无精确单号时) */ export const ORDER_LIST_DEFAULT_DAYS = 90 /** 导出最大行数(与后端一致) */ export const ORDER_EXPORT_MAX_ROWS = 10000 export function clampBatchValues(values: string[], max = MAX_HEADER_BATCH_VALUES): { values: string[] truncated: boolean originalCount: number } { const unique = Array.from( new Set( values .map((v) => String(v || '').trim().slice(0, MAX_HEADER_FILTER_VALUE_LEN)) .filter(Boolean), ), ) if (unique.length <= max) { return { values: unique, truncated: false, originalCount: unique.length } } return { values: unique.slice(0, max), truncated: true, originalCount: unique.length, } } export function normalizeBatchInputText(text: string, max = MAX_HEADER_BATCH_VALUES): { value: string truncated: boolean originalCount: number keptCount: number } { const lines = String(text || '') .split(/[\n\r]+/) .flatMap((line) => line.split(/[,,\t;;]/)) .map((v) => v.trim()) .filter(Boolean) const { values, truncated, originalCount } = clampBatchValues(lines, max) return { value: values.join(','), truncated, originalCount, keptCount: values.length, } } export function buildDefaultCreateTimeRange( days = ORDER_LIST_DEFAULT_DAYS, ): [Dayjs, Dayjs] { const end = dayjs().endOf('day') const start = dayjs() .subtract(Math.max(days, 1) - 1, 'day') .startOf('day') return [start, end] } export function formatCreateTimeRangeParam( range: (Date | string | Dayjs)[] | undefined | null, ): { createTimeStart: string; createTimeEnd: string } | null { if (!range || range.length < 2 || !range[0] || !range[1]) return null return { createTimeStart: dayjs(range[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss'), createTimeEnd: dayjs(range[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss'), } } /** 是否与「默认近 N 天」窗口一致(允许差 1 分钟内) */ export function isDefaultCreateTimeRange( range: (Date | string | Dayjs)[] | undefined | null, days = ORDER_LIST_DEFAULT_DAYS, ): boolean { if (!range || range.length < 2 || !range[0] || !range[1]) return false const [defStart, defEnd] = buildDefaultCreateTimeRange(days) const start = dayjs(range[0]) const end = dayjs(range[1]) return ( Math.abs(start.startOf('day').diff(defStart, 'minute')) < 2 && Math.abs(end.endOf('day').diff(defEnd, 'minute')) < 2 ) }