202 lines
5.4 KiB
TypeScript
202 lines
5.4 KiB
TypeScript
|
|
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>
|
||
|
|
);
|
||
|
|
}
|