EasyVQD/web/src/components/VqdAlarm.tsx

202 lines
5.4 KiB
TypeScript
Raw Normal View History

2026-01-15 19:32:33 +08:00
import { useRef, useState, useMemo } from "react";
import { Table, Button, Space, Popconfirm, Flex, message, Tooltip } from "antd";
import { EditOutlined, DeleteOutlined, PlusOutlined } from "@ant-design/icons";
import { useQuery, useMutation } from "@tanstack/react-query";
import { GetVqdAlarm, DeleteVqdAlarm, DeleteVqdAlarmAll } from "../api/vqdalarm";
import type { VqdAlarmItem } from "../types/vqdalarm";
import type { ColumnsType } from "antd/es/table";
import ChannelModel, { IChannelModelFunc } from "./channel/Channel";
import { useGlobal } from "../Context";
import { FormatFileSizeToString } from "../utils/rate";
import { formatSecondsToHMS } from "../utils/time";
import Filter from "./Filter";
export default function VqdAlarmPage() {
const { ErrorHandle } = useGlobal();
const [pagination, setPagination] = useState({
page: 1,
size: 10,
name: ""
});
// 获取任务列表
const {
data: storageResponse,
isLoading,
refetch,
} = useQuery({
queryKey: ["storage", pagination],
queryFn: () =>
GetVqdAlarm({ ...pagination })
.then((res) => res.data)
.catch((err) => {
ErrorHandle(err);
throw err;
}),
// refetchInterval: 4000,
retry: 2,
});
// 删除任务
const [delLoadings, setDelLoadings] = useState<number[]>([]);
const { mutate: deleteMutation } = useMutation({
mutationFn: DeleteVqdAlarm,
onMutate: (id: number) => {
setDelLoadings((prev) => [...prev, id]);
},
onSuccess: (_, ctx) => {
setDelLoadings((prev) => prev.filter((item) => item !== ctx));
message.success("删除成功");
refetch();
},
onError: (error: Error, ctx) => {
setDelLoadings((prev) => prev.filter((item) => item !== ctx));
ErrorHandle(error);
},
});
// 处理分页变化
const handleTableChange = (page: number, pageSize?: number) => {
setPagination((prev) => ({
...prev,
page: page,
size: pageSize || prev.size,
}));
};
// 客户端分页数据
const dataSource = useMemo(() => {
const items = storageResponse?.items || [];
const start = (pagination.page - 1) * pagination.size;
const end = start + pagination.size;
return items.slice(start, end);
}, [storageResponse, pagination]);
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const rowSelection = {
selectedRowKeys,
onChange: (
newSelectedRowKeys: React.Key[],
selectedRows: VqdAlarmItem[]
) => {
setSelectedRowKeys([...newSelectedRowKeys]);
},
};
// 批量删除任务
const { mutate: deleteMutationAll, isPending: delAllLoadings } = useMutation({
mutationFn: DeleteVqdAlarmAll,
onSuccess: () => {
message.success("批量删除成功");
refetch()
setSelectedRowKeys([])
},
onError: ErrorHandle,
retry: 0,
});
// 表格列定义
const columns: ColumnsType<VqdAlarmItem> = [
{
title: "名称",
dataIndex: "alarm_name",
align: "center",
},
{
title: "文件名称",
dataIndex: "file_path",
align: "center",
render: (text, record) => (
<Space>
{text}
</Space>
),
},
{
title: "描述",
dataIndex: "des",
align: "center",
},
{
title: "创建日期",
dataIndex: "created_at",
align: "center",
render: (text: string) => (text ? new Date(text).toLocaleString() : "-"),
},
{
title: "操作",
align: "center",
width: 120,
fixed: "right",
render: (_, record) => (
<Space>
<Popconfirm
title="确定要删除这个文件吗?"
onConfirm={() => {
if (record.id) {
deleteMutation(record.id);
}
}}
okText="确定"
cancelText="取消"
>
<Button
loading={delLoadings.includes(record.id)}
danger
icon={<DeleteOutlined />}
/>
</Popconfirm>
</Space>
),
},
];
return (
<div>
<Flex justify="space-between" align="center" className="mb-4">
<Space>
<Popconfirm
title="确定要批量删除文件吗?"
onConfirm={() => {
deleteMutationAll({ ids: selectedRowKeys as number[] })
}}
okText="确定"
cancelText="取消"
>
<Button color="danger" variant="solid" loading={delAllLoadings} disabled={selectedRowKeys.length == 0} >
</Button>
</Popconfirm>
</Space>
<Filter
searchLoading={isLoading}
onSearchChange={(value: string) => {
setPagination({ ...pagination, name: value });
}}
/>
</Flex>
{/* 表格 */}
<Table
columns={columns}
rowSelection={rowSelection}
dataSource={storageResponse?.items}
rowKey="id"
loading={isLoading}
scroll={{ x: "max-content" }}
pagination={{
current: pagination.page,
pageSize: pagination.size,
total: storageResponse?.total || 0,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `${total}`,
onChange: handleTableChange,
onShowSizeChange: handleTableChange,
}}
/>
</div>
);
}