feat(操作统计): 抽屉内增加独立时间筛选
- 抽屉内提供 今天/近7天/近30天/自定义 时间选择,默认同步顶部当前值 - 切换时间自动刷新统计与明细,无需关闭看板调整顶部时间
This commit is contained in:
@ -277,6 +277,9 @@ export default function AdminDashboard() {
|
||||
const [opFilterUsers, setOpFilterUsers] = useState<Set<string>>(new Set()); // 多选人员
|
||||
const [opFilterTouched, setOpFilterTouched] = useState(false); // 用户是否主动操作过筛选
|
||||
const [opSort, setOpSort] = useState<{ key: string; order: "asc" | "desc" } | null>(null);
|
||||
// 抽屉内独立时间筛选(不依赖顶部)
|
||||
const [opDateKey, setOpDateKey] = useState<DateRangeKey>("today");
|
||||
const [opCustomRange, setOpCustomRange] = useState<[Dayjs, Dayjs] | null>(null);
|
||||
// 操作明细下钻
|
||||
const [opDetailOpen, setOpDetailOpen] = useState(false);
|
||||
const [opDetailList, setOpDetailList] = useState<OperationDetail[]>([]);
|
||||
@ -337,22 +340,28 @@ export default function AdminDashboard() {
|
||||
.finally(() => setRejectedLoading(false));
|
||||
};
|
||||
|
||||
// 人员操作统计 — 跟随顶部时间筛选(打开抽屉时加载)
|
||||
// 人员操作统计 — 用抽屉内独立时间筛选
|
||||
const loadUserOperations = useCallback(() => {
|
||||
setOpLoading(true);
|
||||
const { since, until } = rangeToParams(dateKey, customRange);
|
||||
const { since, until } = rangeToParams(opDateKey, opCustomRange);
|
||||
fetchUserOperations(since, until)
|
||||
.then(setOpStats)
|
||||
.catch(() => setOpStats([]))
|
||||
.finally(() => setOpLoading(false));
|
||||
}, [dateKey, customRange]);
|
||||
}, [opDateKey, opCustomRange]);
|
||||
|
||||
// 抽屉打开或内部时间变化时加载
|
||||
useEffect(() => {
|
||||
if (opsDrawerOpen) loadUserOperations();
|
||||
}, [opsDrawerOpen, loadUserOperations]);
|
||||
|
||||
const openOpsDrawer = () => {
|
||||
setOpsDrawerOpen(true);
|
||||
setOpDateKey(dateKey); // 默认同步顶部当前时间
|
||||
setOpCustomRange(customRange);
|
||||
setOpFilterUsers(new Set());
|
||||
setOpFilterTouched(false);
|
||||
setOpSort(null);
|
||||
loadUserOperations();
|
||||
};
|
||||
|
||||
// 首次加载完成后默认全选(显示全部);用户操作过筛选后不再自动覆盖
|
||||
@ -390,12 +399,12 @@ export default function AdminDashboard() {
|
||||
});
|
||||
};
|
||||
|
||||
// 点击数字下钻查看明细
|
||||
// 点击数字下钻查看明细(跟随抽屉内时间)
|
||||
const openOpDetail = (user: UserOperation, actionType: string, label: string) => {
|
||||
setOpDetailOpen(true);
|
||||
setOpDetailTitle(`${user.user_name} · ${label}`);
|
||||
setOpDetailLoading(true);
|
||||
const { since, until } = rangeToParams(dateKey, customRange);
|
||||
const { since, until } = rangeToParams(opDateKey, opCustomRange);
|
||||
fetchOperationDetail(user.user_id, actionType, since, until)
|
||||
.then(setOpDetailList)
|
||||
.catch(() => setOpDetailList([]))
|
||||
@ -740,6 +749,31 @@ export default function AdminDashboard() {
|
||||
size="large"
|
||||
styles={{ body: { padding: 16, background: "#f8fafc" } }}
|
||||
>
|
||||
{/* 抽屉内时间筛选 */}
|
||||
<div className="mb-4 flex flex-wrap items-center gap-2">
|
||||
<Radio.Group
|
||||
value={opDateKey}
|
||||
onChange={e => { setOpDateKey(e.target.value); setOpCustomRange(null); }}
|
||||
size="small"
|
||||
optionType="button"
|
||||
buttonStyle="solid"
|
||||
>
|
||||
<Radio.Button value="today">今天</Radio.Button>
|
||||
<Radio.Button value="7d">近7天</Radio.Button>
|
||||
<Radio.Button value="30d">近30天</Radio.Button>
|
||||
<Radio.Button value="custom">自定义</Radio.Button>
|
||||
</Radio.Group>
|
||||
{opDateKey === "custom" && (
|
||||
<RangePicker
|
||||
size="small"
|
||||
value={opCustomRange as any}
|
||||
onChange={dates => setOpCustomRange(dates as [Dayjs, Dayjs] | null)}
|
||||
style={{ width: 240 }}
|
||||
placeholder={["开始", "结束"]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 人员选择 — 人名宫格多选 */}
|
||||
<div className="mb-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
|
||||
Reference in New Issue
Block a user