import { Badge, Button, Card, Divider, Dropdown, Input, Menu, Modal } from 'antd'; import { useDomFullHeight } from '@/hooks'; import '../index.less'; import SearchComponent from '@/components/SearchComponent'; import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table'; import PermissionButton from '@/components/PermissionButton'; import { DeleteOutlined, EditOutlined, ExportOutlined, ImportOutlined, PlayCircleOutlined, PlusOutlined, SearchOutlined, StopOutlined, } from '@ant-design/icons'; import { useEffect, useRef, useState } from 'react'; import { useIntl } from 'umi'; import ChannelCard from '../channelCard'; import { PageContainer } from '@ant-design/pro-layout'; import Service from './service'; import SaveChannel from './saveChannel'; import SavePoint from './savePoint'; import Import from './import'; import { onlyMessage } from '@/utils/util'; import Export from './Export'; import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage'; import { map } from 'rxjs/operators'; import Ellipsis from '@/components/Ellipsis'; export const service = new Service(''); const NewModbus = () => { const { minHeight } = useDomFullHeight(`.modbus`); const intl = useIntl(); const actionRef = useRef(); const { permission } = PermissionButton.usePermission('link/Channel/Modbus'); const [param, setParam] = useState({}); const [activeKey, setActiveKey] = useState(''); const [visible, setVisible] = useState(false); const [visiblePoint, setVisiblePoint] = useState(false); const [exportVisible, setExportVisible] = useState(false); const [current, setCurrent] = useState({}); const [pointDetail, setPointDetail] = useState({}); const [importVisible, setImportVisible] = useState(false); const [masterList, setMasterList] = useState([]); const [filterList, setFilterList] = useState([]); const masterId = useRef(''); const [subscribeTopic] = useSendWebsocketMessage(); const wsRef = useRef(); const [pointList, setPointList] = useState([]); const [currentData, setCurrentData] = useState({}); const collectMap = new Map(); collectMap.set('running', 'success'); collectMap.set('error', 'error'); collectMap.set('stopped', 'warning'); const menu = ( } type="default" onClick={() => { setExportVisible(true); }} > 批量导出点位 } onClick={() => { setImportVisible(true); }} > 批量导入点位 ); const columns: ProColumns[] = [ { title: '名称', dataIndex: 'name', ellipsis: true, width: 200, fixed: 'left', }, { title: '功能码', valueType: 'select', dataIndex: 'function', valueEnum: { Coils: { text: '线圈寄存器', status: 'Coils' }, HoldingRegisters: { text: '保存寄存器', status: 'HoldingRegisters' }, InputRegisters: { text: '输入寄存器', status: 'InputRegisters' }, }, render: (_, record: any) => <>{record.function?.text}, }, { title: '从站ID', valueType: 'digit', dataIndex: 'unitId', }, { title: '寄存器数量', search: false, render: (_, record: any) => <>{record.parameter?.quantity}, }, { title: '地址', dataIndex: 'address', valueType: 'digit', }, { title: '当前数据', search: false, // ellipsis: true, width: 150, render: (record: any) => ( { if (currentData[record?.id]) { const arr = currentData[record?.id].match(/[\S]{1,4}/g); Modal.info({ title: '当前数据', content: (
{arr.map((item: any, index: number) => (
寄存器{index + 1}: {item}
))}
), }); } }} >
), }, { title: '采集状态', dataIndex: 'collectState', valueType: 'select', valueEnum: { running: { text: '采集中', status: 'running' }, error: { text: '失败', status: 'error' }, stopped: { text: '已停止', status: 'stopped' }, }, render: (_, record: any) => ( <> {record.collectState?.value === 'error' && ( { Modal.error({ title: '失败原因', content:
{record.errorReason}
, }); }} /> )} ), }, { title: '状态', dataIndex: 'state', renderText: (state) => ( ), valueType: 'select', valueEnum: { disabled: { text: intl.formatMessage({ id: 'pages.data.option.disabled', defaultMessage: '禁用', }), status: 'disabled', }, enabled: { text: '正常', status: 'enabled', }, }, filterMultiple: false, }, { title: '操作', valueType: 'option', align: 'center', width: 120, fixed: 'right', render: (text, record) => [ { setPointDetail(record); setVisiblePoint(true); }} type={'link'} style={{ padding: 0 }} tooltip={{ title: intl.formatMessage({ id: 'pages.data.option.edit', defaultMessage: '编辑', }), }} > , { if (record.state.value === 'disabled') { await service.enablePoint([record.id]); } else { await service.disablePoint([record.id]); } onlyMessage( intl.formatMessage({ id: 'pages.data.option.success', defaultMessage: '操作成功!', }), ); actionRef.current?.reload(); }, }} isPermission={permission.action} tooltip={{ title: intl.formatMessage({ id: `pages.data.option.${record.state.value !== 'disabled' ? 'disabled' : 'enabled'}`, defaultMessage: record.state.value !== 'disabled' ? '禁用' : '启用', }), }} > {record.state.value !== 'disabled' ? : } , { const resp: any = await service.deletePoint(record.id); if (resp.status === 200) { onlyMessage( intl.formatMessage({ id: 'pages.data.option.success', defaultMessage: '操作成功!', }), ); actionRef.current?.reload(); } }, }} key="delete" type="link" > , ], }, ]; const getMaster = () => { service .queryMaster({ paging: false, sorts: [ { name: 'createTime', order: 'desc', }, ], }) .then((res: any) => { if (res.status === 200) { setMasterList(res.result); setFilterList(res.result); setActiveKey(res.result?.[0]?.id); masterId.current = res.result?.[0]?.id; } }); }; //启用禁用 const actions = (id: string, data: any) => { service.editMaster(id, data).then((res) => { if (res.status === 200) { onlyMessage('操作成功'); getMaster(); } }); }; const deteleMaster = (id: string) => { service.deleteMaster(id).then((res) => { if (res.status === 200) { onlyMessage('删除成功'); getMaster(); } }); }; useEffect(() => { masterId.current = activeKey; actionRef.current?.reload(); }, [activeKey]); useEffect(() => { getMaster(); }, []); useEffect(() => { const id = `collector-data-modbus`; const topic = `/collector/MODBUS_TCP/${activeKey}/data`; wsRef.current = subscribeTopic?.(id, topic, { pointId: pointList.map((item: any) => item.id), }) ?.pipe(map((res: any) => res.payload)) .subscribe((payload: any) => { const { pointId, hex } = payload; current[pointId] = hex; setCurrentData({ ...current }); }); return () => wsRef.current && wsRef.current?.unsubscribe(); }, [pointList]); return (
{ const items = masterList.filter((item: any) => item.name.match(value)); if (value) { setFilterList(items); setActiveKey(items?.[0].id); } else { setFilterList(masterList); setActiveKey(masterList?.[0].id); } }} /> { setVisible(true); setCurrent({}); }} isPermission={permission.add} key="add" icon={} type="primary" style={{ width: '100%', marginTop: 16, marginBottom: 16 }} > 新增
{filterList.map((item: any) => ( { setActiveKey(item.id); }} actions={ <> { setVisible(true); setCurrent(item); }} type={'link'} style={{ padding: 0 }} > 编辑 { if (item.state.value === 'disabled') { actions(item.id, { state: 'enabled' }); } else { actions(item.id, { state: 'disabled' }); } }, }} > {item.state.value === 'enabled' ? ( ) : ( )} {item.state.value === 'enabled' ? '禁用' : '启用'} { deteleMaster(item.id); }, }} key="delete" type="link" > } /> ))}
field={columns} target="modbus" onSearch={(value) => { actionRef.current?.reset?.(); setParam(value); }} /> { setPointDetail({}); setVisiblePoint(true); }} isPermission={permission.add} key="add" icon={} type="primary" style={{ marginRight: 10 }} > {intl.formatMessage({ id: 'pages.data.option.add', defaultMessage: '新增', })} } request={async (params) => { if (masterId.current) { const res = await service.queryPoint(masterId.current, { ...params, sorts: [{ name: 'createTime', order: 'desc' }], }); setPointList(res.result.data); return { code: res.message, result: { data: res.result.data, pageIndex: res.result.pageIndex, pageSize: res.result.pageSize, total: res.result.total, }, status: res.status, }; } else { return { code: 200, result: { data: [], pageIndex: 0, pageSize: 0, total: 0, }, status: 200, }; } }} />
{visible && ( { setVisible(false); getMaster(); // actionRef.current?.reload(); }} /> )} {visiblePoint && ( { setVisiblePoint(false); actionRef.current?.reload(); }} /> )} { setImportVisible(false); actionRef.current?.reload(); }} visible={importVisible} /> { setExportVisible(false); actionRef.current?.reload(); }} visible={exportVisible} />
); }; export default NewModbus;