feat: 更新前端时间范围组件默认开始时间和结束时间的秒

This commit is contained in:
李琦
2026-08-27 17:00:51 +08:00
parent 0d18089f71
commit c2040c2b15
2 changed files with 48 additions and 30 deletions

View File

@@ -3,6 +3,7 @@
* 带快捷预设的搜索时间范围选择器
* - 上方 RangePicker 手选,下方快捷 link今天 / 本周 / 本月 / 上一个月 / 下一个月
* - 支持 valueFormat='YYYY-MM-DD'VbenForm或 Dayjs 二元组(对账页)
* - 界面按天展示;写出值时开始为当天 00:00:00、结束为当天 23:59:59避免漏查当天末笔
*/
import type { Dayjs } from 'dayjs';
@@ -69,8 +70,9 @@ const innerRange = computed<[Dayjs, Dayjs] | null>({
emit('change', null);
return;
}
// formatRangeByValueFormat 内会规范到 00:00:00 / 23:59:59
const formatted = formatRangeByValueFormat(
[next[0].startOf('day'), next[1].startOf('day')],
[next[0], next[1]],
props.valueFormat,
);
mValue.value = formatted as [string, string] | [Dayjs, Dayjs];
@@ -145,7 +147,6 @@ const pickerValue = computed<[Dayjs, Dayjs] | undefined>({
v-bind="$attrs"
:disabled="disabled"
:format="format"
:value-format="valueFormat"
class="search-time-range-picker__picker w-full"
@change="onPickerChange"
/>

View File

@@ -9,9 +9,21 @@ export type SearchTimePreset =
| 'prevMonth'
| 'nextMonth';
/** 界面展示用纯日期;提交给后端时再拼时分秒 */
const YMD = 'YYYY-MM-DD';
/** 查询边界:开始日 00:00:00、结束日 23:59:59避免当天末笔被滤掉 */
const YMD_START = 'YYYY-MM-DD 00:00:00';
const YMD_END = 'YYYY-MM-DD 23:59:59';
/** 今天日期Dayjs */
/**
* 将区间规范为「开始日 00:00:00 ~ 结束日 23:59:59」
* 搜索按天选时,结束若不落到当天最后一秒,当天 0 点之后的数据会被漏掉
*/
export function toSearchDayBounds(range: [Dayjs, Dayjs]): [Dayjs, Dayjs] {
return [range[0].startOf('day'), range[1].endOf('day')];
}
/** 今天日期Dayjs当天 00:00:00 */
export function todayDayjs(): Dayjs {
return dayjs().startOf('day');
}
@@ -24,30 +36,27 @@ export function startOfWeekMonday(base: Dayjs = todayDayjs()): Dayjs {
return d.subtract(diff, 'day');
}
/** 本月1日 ~ 今天(字符串,供 RangePicker valueFormat */
/** 本月1日 00:00:00 ~ 今天 23:59:59字符串供表单默认值 / 接口 */
export function monthToTodayRangeString(): [string, string] {
const today = todayDayjs();
return [today.startOf('month').format(YMD), today.format(YMD)];
return rangeDayjsToString(monthToTodayRangeDayjs());
}
/** 本月1日 ~ 今天Dayjs */
/** 本月1日 ~ 今天Dayjs,已含起止边界 */
export function monthToTodayRangeDayjs(): [Dayjs, Dayjs] {
const today = todayDayjs();
return [today.startOf('month'), today];
return toSearchDayBounds([today.startOf('month'), today]);
}
/** 近 N 天(含今天),默认 7 天 */
/** 近 N 天(含今天),默认 7 天;字符串已含 00:00:00 / 23:59:59 */
export function lastNDaysRangeString(days = 7): [string, string] {
const today = todayDayjs();
const start = today.subtract(Math.max(days - 1, 0), 'day');
return [start.format(YMD), today.format(YMD)];
return rangeDayjsToString(lastNDaysRangeDayjs(days));
}
/** 近 N 天Dayjs */
/** 近 N 天Dayjs,已含起止边界 */
export function lastNDaysRangeDayjs(days = 7): [Dayjs, Dayjs] {
const today = todayDayjs();
const start = today.subtract(Math.max(days - 1, 0), 'day');
return [start, today];
return toSearchDayBounds([start, today]);
}
/** 将 Dayjs / 字符串 / 时间戳统一为 YYYY-MM-DD */
@@ -98,17 +107,17 @@ export function getMonthAnchorDayjs(current: unknown): Dayjs {
return todayDayjs();
}
/** 自然月整月,结束日不超过今天 */
/** 自然月整月,结束日不超过今天(返回值已含起止边界) */
function fullMonthRangeCapped(
month: Dayjs,
): [Dayjs, Dayjs] {
const start = month.startOf('month');
const end = month.endOf('month').startOf('day');
const today = todayDayjs();
return [start, end.isAfter(today) ? today : end];
return toSearchDayBounds([start, end.isAfter(today) ? today : end]);
}
/** 按预设计算区间Dayjs */
/** 按预设计算区间Dayjs,已含 00:00:00 / 23:59:59 边界 */
export function resolveSearchTimePreset(
preset: SearchTimePreset,
current: unknown,
@@ -116,11 +125,11 @@ export function resolveSearchTimePreset(
const today = todayDayjs();
switch (preset) {
case 'today':
return [today, today];
return toSearchDayBounds([today, today]);
case 'thisWeek':
return [startOfWeekMonday(today), today];
return toSearchDayBounds([startOfWeekMonday(today), today]);
case 'thisMonth':
return [today.startOf('month'), today];
return toSearchDayBounds([today.startOf('month'), today]);
case 'prevMonth': {
const anchor = getMonthAnchorDayjs(current);
return fullMonthRangeCapped(anchor.subtract(1, 'month'));
@@ -134,36 +143,44 @@ export function resolveSearchTimePreset(
}
}
/** 按预设计算区间(字符串) */
/** 按预设计算区间(字符串,已含时分秒 */
export function resolveSearchTimePresetString(
preset: SearchTimePreset,
current: unknown,
): [string, string] {
const [a, b] = resolveSearchTimePreset(preset, current);
return [a.format(YMD), b.format(YMD)];
return rangeDayjsToString(resolveSearchTimePreset(preset, current));
}
/** Dayjs 区间转字符串 */
/**
* Dayjs 区间转接口字符串
* 固定开始 00:00:00、结束 23:59:59与按天筛选的业务口径一致
*/
export function rangeDayjsToString(
range: [Dayjs, Dayjs],
): [string, string] {
return [range[0].format(YMD), range[1].format(YMD)];
const [start, end] = toSearchDayBounds(range);
return [start.format(YMD_START), end.format(YMD_END)];
}
/** 字符串区间转 Dayjs */
/** 字符串区间转 Dayjs(兼容纯日期或带时分秒) */
export function rangeStringToDayjs(
range: [string, string],
): [Dayjs, Dayjs] {
return [dayjs(range[0], YMD), dayjs(range[1], YMD)];
return toSearchDayBounds([dayjs(range[0]), dayjs(range[1])]);
}
/** 将区间按 valueFormat 输出 */
/**
* 将区间按表单模式输出
* valueFormat=YYYY-MM-DD 表示「按天选择」,值仍带完整时分秒边界供接口使用
* 未传 valueFormat 时返回 Dayjs同样规范到起止边界
*/
export function formatRangeByValueFormat(
range: [Dayjs, Dayjs],
valueFormat?: string,
): [string, string] | [Dayjs, Dayjs] {
const bounded = toSearchDayBounds(range);
if (valueFormat === YMD) {
return rangeDayjsToString(range);
return rangeDayjsToString(bounded);
}
return range;
return bounded;
}