feat(web): 全员总览——时间范围、健康带、来源分解、成员表与 key 明细
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import type { Dayjs } from "dayjs";
|
||||
import dayjs from "dayjs";
|
||||
import { computed } from "vue";
|
||||
import { recentDaysRange } from "@/utils/time.ts";
|
||||
|
||||
type RangeValue = { from: string; to: string };
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: RangeValue;
|
||||
/** 外部预置(如「本订阅期间」);空则只保留内建快捷项 */
|
||||
extraPresets?: Array<{ label: string; from: string; to: string }>;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:modelValue", value: RangeValue): void;
|
||||
}>();
|
||||
|
||||
const pickerValue = computed<[Dayjs, Dayjs] | null>(() => {
|
||||
if (!props.modelValue.from || !props.modelValue.to) return null;
|
||||
return [dayjs(props.modelValue.from), dayjs(props.modelValue.to)];
|
||||
});
|
||||
|
||||
const presets = computed(() => {
|
||||
const builtIn = [
|
||||
{
|
||||
label: "最近 7 天",
|
||||
value: rangeToDayjs(recentDaysRange(7)),
|
||||
},
|
||||
{
|
||||
label: "最近 30 天",
|
||||
value: rangeToDayjs(recentDaysRange(30)),
|
||||
},
|
||||
];
|
||||
const extra = (props.extraPresets ?? []).map((p) => ({
|
||||
label: p.label,
|
||||
value: rangeToDayjs({ from: p.from, to: p.to }),
|
||||
}));
|
||||
return [...builtIn, ...extra];
|
||||
});
|
||||
|
||||
function rangeToDayjs(range: RangeValue): [Dayjs, Dayjs] {
|
||||
return [dayjs(range.from), dayjs(range.to)];
|
||||
}
|
||||
|
||||
function onChange(dates: Dayjs[] | null) {
|
||||
if (!dates || dates.length !== 2 || !dates[0] || !dates[1]) return;
|
||||
emit("update:modelValue", {
|
||||
from: dates[0].toISOString(),
|
||||
to: dates[1].toISOString(),
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-range-picker
|
||||
:value="pickerValue"
|
||||
:presets="presets"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
@change="onChange"
|
||||
/>
|
||||
</template>
|
||||
Reference in New Issue
Block a user