|
|
@@ -1,26 +1,83 @@
|
|
|
// 视频设备列表
|
|
|
import { PageContainer } from '@ant-design/pro-layout';
|
|
|
-import { useRef } from 'react';
|
|
|
+import { useRef, useState } from 'react';
|
|
|
import type { ActionType, ProColumns } from '@jetlinks/pro-table';
|
|
|
-import { Tooltip } from 'antd';
|
|
|
-import { ArrowDownOutlined, BugOutlined, EditOutlined, MinusOutlined } from '@ant-design/icons';
|
|
|
-import BaseCrud from '@/components/BaseCrud';
|
|
|
-import BaseService from '@/utils/BaseService';
|
|
|
+import { Button, message, Popconfirm, Tooltip } from 'antd';
|
|
|
+import {
|
|
|
+ DeleteOutlined,
|
|
|
+ EditOutlined,
|
|
|
+ PlusOutlined,
|
|
|
+ SyncOutlined,
|
|
|
+ PartitionOutlined,
|
|
|
+} from '@ant-design/icons';
|
|
|
import type { DeviceItem } from '@/pages/media/Device/typings';
|
|
|
-import { useIntl } from '@@/plugin-locale/localeExports';
|
|
|
-import { BadgeStatus } from '@/components';
|
|
|
+import { useIntl, useHistory } from 'umi';
|
|
|
+import { BadgeStatus, ProTableCard } from '@/components';
|
|
|
import { StatusColorEnum } from '@/components/BadgeStatus';
|
|
|
+import SearchComponent from '@/components/SearchComponent';
|
|
|
+import MediaDevice from '@/components/ProTableCard/CardItems/mediaDevice';
|
|
|
+import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
|
|
|
+import Service from './service';
|
|
|
+import Save from './Save';
|
|
|
+
|
|
|
+export const service = new Service('media/device');
|
|
|
+
|
|
|
+const providerType = {
|
|
|
+ 'gb28181-2016': 'GB/T28181',
|
|
|
+ 'fixed-media': '固定地址',
|
|
|
+};
|
|
|
+
|
|
|
+export const ProviderValue = {
|
|
|
+ GB281: 'gb28181-2016',
|
|
|
+ FIXED: 'fixed-media',
|
|
|
+};
|
|
|
|
|
|
-export const service = new BaseService<DeviceItem>('media/device');
|
|
|
const Device = () => {
|
|
|
const intl = useIntl();
|
|
|
const actionRef = useRef<ActionType>();
|
|
|
+ const [visible, setVisible] = useState<boolean>(false);
|
|
|
+ const [current, setCurrent] = useState<DeviceItem>();
|
|
|
+ const [queryParam, setQueryParam] = useState({});
|
|
|
+ const history = useHistory<Record<string, string>>();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * table 查询参数
|
|
|
+ * @param data
|
|
|
+ */
|
|
|
+ const searchFn = (data: any) => {
|
|
|
+ setQueryParam(data);
|
|
|
+ };
|
|
|
+
|
|
|
+ const deleteItem = async (id: string) => {
|
|
|
+ const response: any = await service.remove(id);
|
|
|
+ if (response.status === 200) {
|
|
|
+ message.success(
|
|
|
+ intl.formatMessage({
|
|
|
+ id: 'pages.data.option.success',
|
|
|
+ defaultMessage: '操作成功!',
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ actionRef.current?.reload();
|
|
|
+ };
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新通道
|
|
|
+ * @param id 视频设备ID
|
|
|
+ */
|
|
|
+ const updateChannel = async (id: string) => {
|
|
|
+ const resp = await service.updateChannels(id);
|
|
|
+ if (resp.status === 200) {
|
|
|
+ message.success('通道更新成功');
|
|
|
+ } else {
|
|
|
+ message.error('通道更新失败');
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
const columns: ProColumns<DeviceItem>[] = [
|
|
|
{
|
|
|
- dataIndex: 'index',
|
|
|
- valueType: 'indexBorder',
|
|
|
- width: 48,
|
|
|
+ dataIndex: 'id',
|
|
|
+ title: 'ID',
|
|
|
},
|
|
|
{
|
|
|
dataIndex: 'name',
|
|
|
@@ -29,73 +86,48 @@ const Device = () => {
|
|
|
defaultMessage: '名称',
|
|
|
}),
|
|
|
},
|
|
|
- // {
|
|
|
- // dataIndex: 'transport',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.transport',
|
|
|
- // defaultMessage: '信令传输',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'streamMode',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.streamMode',
|
|
|
- // defaultMessage: '流传输模式',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'channelNumber',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.channelNumber',
|
|
|
- // defaultMessage: '通道数',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'host',
|
|
|
- // title: 'IP',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: '端口',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.port',
|
|
|
- // defaultMessage: '端口',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'manufacturer',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.manufacturer',
|
|
|
- // defaultMessage: '设备厂家',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'model',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.model',
|
|
|
- // defaultMessage: '型号',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'firmware',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.media.device.firmware',
|
|
|
- // defaultMessage: '固件版本',
|
|
|
- // }),
|
|
|
- // },
|
|
|
- // {
|
|
|
- // dataIndex: 'networkType',
|
|
|
- // title: intl.formatMessage({
|
|
|
- // id: 'pages.table.type',
|
|
|
- // defaultMessage: '类型',
|
|
|
- // }),
|
|
|
- // },
|
|
|
+ {
|
|
|
+ dataIndex: 'provider',
|
|
|
+ title: '接入方式',
|
|
|
+ render: (_, row) => {
|
|
|
+ return providerType[row.provider];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ dataIndex: 'channelNumber',
|
|
|
+ title: intl.formatMessage({
|
|
|
+ id: 'pages.media.device.channelNumber',
|
|
|
+ defaultMessage: '通道数',
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ dataIndex: 'manufacturer',
|
|
|
+ title: intl.formatMessage({
|
|
|
+ id: 'pages.media.device.manufacturer',
|
|
|
+ defaultMessage: '设备厂家',
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ dataIndex: 'model',
|
|
|
+ title: intl.formatMessage({
|
|
|
+ id: 'pages.media.device.model',
|
|
|
+ defaultMessage: '型号',
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ dataIndex: 'firmware',
|
|
|
+ title: intl.formatMessage({
|
|
|
+ id: 'pages.media.device.firmware',
|
|
|
+ defaultMessage: '固件版本',
|
|
|
+ }),
|
|
|
+ },
|
|
|
{
|
|
|
dataIndex: 'state',
|
|
|
title: intl.formatMessage({
|
|
|
id: 'pages.searchTable.titleStatus',
|
|
|
defaultMessage: '状态',
|
|
|
}),
|
|
|
- render: (text, record) => (
|
|
|
+ render: (_, record) => (
|
|
|
<BadgeStatus
|
|
|
status={record.state.value}
|
|
|
statusNames={{
|
|
|
@@ -103,7 +135,7 @@ const Device = () => {
|
|
|
offline: StatusColorEnum.error,
|
|
|
notActive: StatusColorEnum.processing,
|
|
|
}}
|
|
|
- text={text}
|
|
|
+ text={record.state.text}
|
|
|
/>
|
|
|
),
|
|
|
},
|
|
|
@@ -116,63 +148,196 @@ const Device = () => {
|
|
|
align: 'center',
|
|
|
width: 200,
|
|
|
render: (text, record) => [
|
|
|
- <a onClick={() => console.log(record)}>
|
|
|
- <Tooltip
|
|
|
- title={intl.formatMessage({
|
|
|
- id: 'pages.data.option.edit',
|
|
|
- defaultMessage: '编辑',
|
|
|
- })}
|
|
|
+ <Tooltip
|
|
|
+ key="edit"
|
|
|
+ title={intl.formatMessage({
|
|
|
+ id: 'pages.data.option.edit',
|
|
|
+ defaultMessage: '编辑',
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <a
|
|
|
+ onClick={() => {
|
|
|
+ setCurrent(record);
|
|
|
+ setVisible(true);
|
|
|
+ }}
|
|
|
>
|
|
|
<EditOutlined />
|
|
|
- </Tooltip>
|
|
|
- </a>,
|
|
|
- <a>
|
|
|
- <Tooltip
|
|
|
- title={intl.formatMessage({
|
|
|
- id: 'pages.data.option.remove',
|
|
|
- defaultMessage: '删除',
|
|
|
- })}
|
|
|
+ </a>
|
|
|
+ </Tooltip>,
|
|
|
+ <Tooltip key={'viewChannel'} title="查看通道">
|
|
|
+ <a
|
|
|
+ onClick={() => {
|
|
|
+ history.push(
|
|
|
+ `${getMenuPathByCode(MENUS_CODE['media/Device/Channel'])}?id=${record.id}&type=${
|
|
|
+ record.provider
|
|
|
+ }`,
|
|
|
+ );
|
|
|
+ }}
|
|
|
>
|
|
|
- <MinusOutlined />
|
|
|
- </Tooltip>
|
|
|
- </a>,
|
|
|
- <a>
|
|
|
- <Tooltip
|
|
|
- title={intl.formatMessage({
|
|
|
- id: 'pages.data.option.download',
|
|
|
- defaultMessage: '下载配置',
|
|
|
- })}
|
|
|
+ <PartitionOutlined />
|
|
|
+ </a>
|
|
|
+ </Tooltip>,
|
|
|
+ <Tooltip key={'updateChannel'} title="更新通道">
|
|
|
+ <Button
|
|
|
+ style={{ padding: '4px' }}
|
|
|
+ type={'link'}
|
|
|
+ disabled={record.state.value === 'offline'}
|
|
|
+ onClick={() => {
|
|
|
+ updateChannel(record.id);
|
|
|
+ }}
|
|
|
>
|
|
|
- <ArrowDownOutlined />
|
|
|
- </Tooltip>
|
|
|
- </a>,
|
|
|
- <a>
|
|
|
- <Tooltip
|
|
|
+ <SyncOutlined />
|
|
|
+ </Button>
|
|
|
+ </Tooltip>,
|
|
|
+ <Tooltip key={'updateChannel'} title="删除">
|
|
|
+ <Popconfirm
|
|
|
+ key="delete"
|
|
|
title={intl.formatMessage({
|
|
|
- id: 'pages.notice.option.debug',
|
|
|
- defaultMessage: '调试',
|
|
|
+ id:
|
|
|
+ record.state.value === 'offline'
|
|
|
+ ? 'pages.device.productDetail.deleteTip'
|
|
|
+ : 'page.table.isDelete',
|
|
|
+ defaultMessage: '是否删除?',
|
|
|
})}
|
|
|
+ onConfirm={async () => {
|
|
|
+ if (record.state.value !== 'offline') {
|
|
|
+ await deleteItem(record.id);
|
|
|
+ } else {
|
|
|
+ message.error('在线设备不能进行删除操作');
|
|
|
+ }
|
|
|
+ }}
|
|
|
>
|
|
|
- <BugOutlined />
|
|
|
- </Tooltip>
|
|
|
- </a>,
|
|
|
+ <Button
|
|
|
+ type={'link'}
|
|
|
+ style={{ padding: '4px' }}
|
|
|
+ disabled={record.state.value !== 'offline'}
|
|
|
+ >
|
|
|
+ <DeleteOutlined />
|
|
|
+ </Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </Tooltip>,
|
|
|
],
|
|
|
},
|
|
|
];
|
|
|
|
|
|
- const schema = {};
|
|
|
return (
|
|
|
<PageContainer>
|
|
|
- <BaseCrud
|
|
|
+ <SearchComponent field={columns} onSearch={searchFn} />
|
|
|
+ <ProTableCard<DeviceItem>
|
|
|
columns={columns}
|
|
|
- service={service}
|
|
|
- search={false}
|
|
|
- title={intl.formatMessage({
|
|
|
- id: 'pages.media.device',
|
|
|
- defaultMessage: '模拟测试',
|
|
|
- })}
|
|
|
- schema={schema}
|
|
|
actionRef={actionRef}
|
|
|
+ options={{ fullScreen: true }}
|
|
|
+ params={queryParam}
|
|
|
+ request={(params = {}) =>
|
|
|
+ service.query({
|
|
|
+ ...params,
|
|
|
+ sorts: [
|
|
|
+ {
|
|
|
+ name: 'createTime',
|
|
|
+ order: 'desc',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ })
|
|
|
+ }
|
|
|
+ rowKey="id"
|
|
|
+ search={false}
|
|
|
+ headerTitle={[
|
|
|
+ <Button
|
|
|
+ onClick={() => {
|
|
|
+ setCurrent(undefined);
|
|
|
+ setVisible(true);
|
|
|
+ }}
|
|
|
+ key="button"
|
|
|
+ icon={<PlusOutlined />}
|
|
|
+ type="primary"
|
|
|
+ >
|
|
|
+ {intl.formatMessage({
|
|
|
+ id: 'pages.data.option.add',
|
|
|
+ defaultMessage: '新增',
|
|
|
+ })}
|
|
|
+ </Button>,
|
|
|
+ ]}
|
|
|
+ cardRender={(record) => (
|
|
|
+ <MediaDevice
|
|
|
+ {...record}
|
|
|
+ actions={[
|
|
|
+ <Button
|
|
|
+ key="edit"
|
|
|
+ onClick={() => {
|
|
|
+ setCurrent(record);
|
|
|
+ setVisible(true);
|
|
|
+ }}
|
|
|
+ type={'link'}
|
|
|
+ style={{ padding: 0 }}
|
|
|
+ >
|
|
|
+ <EditOutlined />
|
|
|
+ {intl.formatMessage({
|
|
|
+ id: 'pages.data.option.edit',
|
|
|
+ defaultMessage: '编辑',
|
|
|
+ })}
|
|
|
+ </Button>,
|
|
|
+ <Button
|
|
|
+ key={'viewChannel'}
|
|
|
+ onClick={() => {
|
|
|
+ history.push(
|
|
|
+ `${getMenuPathByCode(MENUS_CODE['media/Device/Channel'])}?id=${
|
|
|
+ record.id
|
|
|
+ }&type=${record.provider}`,
|
|
|
+ );
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <PartitionOutlined />
|
|
|
+ 查看通道
|
|
|
+ </Button>,
|
|
|
+ <Button
|
|
|
+ key={'updateChannel'}
|
|
|
+ disabled={record.state.value === 'offline'}
|
|
|
+ onClick={() => {
|
|
|
+ updateChannel(record.id);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <SyncOutlined />
|
|
|
+ 更新通道
|
|
|
+ </Button>,
|
|
|
+ <Popconfirm
|
|
|
+ key="delete"
|
|
|
+ title={intl.formatMessage({
|
|
|
+ id:
|
|
|
+ record.state.value === 'offline'
|
|
|
+ ? 'pages.device.productDetail.deleteTip'
|
|
|
+ : 'page.table.isDelete',
|
|
|
+ defaultMessage: '是否删除?',
|
|
|
+ })}
|
|
|
+ onConfirm={async () => {
|
|
|
+ if (record.state.value !== 'offline') {
|
|
|
+ await deleteItem(record.id);
|
|
|
+ } else {
|
|
|
+ message.error('在线设备不能进行删除操作');
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Button
|
|
|
+ type={'link'}
|
|
|
+ style={{ padding: 0 }}
|
|
|
+ disabled={record.state.value !== 'offline'}
|
|
|
+ >
|
|
|
+ <DeleteOutlined />
|
|
|
+ </Button>
|
|
|
+ </Popconfirm>,
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <Save
|
|
|
+ model={!current ? 'add' : 'edit'}
|
|
|
+ data={current}
|
|
|
+ close={() => {
|
|
|
+ setVisible(false);
|
|
|
+ }}
|
|
|
+ reload={() => {
|
|
|
+ actionRef.current?.reload();
|
|
|
+ }}
|
|
|
+ visible={visible}
|
|
|
/>
|
|
|
</PageContainer>
|
|
|
);
|