antd/lib/table#SorterResult TypeScript Examples
The following examples show how to use
antd/lib/table#SorterResult.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ProTable.tsx From jetlinks-ui-antd with MIT License | 5 votes |
ProTable = (props: Props) => {
const { loading, dataSource, columns, rowKey, onSearch, paginationConfig,title } = props;
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<any>,
) => {
onSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
terms: converFilter(filters, '$IN'),
})
};
return (
<Table
{...props}
size={props.size}
// loading={loading}
// dataSource={dataSource}
// columns={columns}
// rowKey={rowKey}
onChange={onTableChange}
pagination={typeof paginationConfig === "boolean" ? paginationConfig : {
current: paginationConfig?.pageIndex + 1 || 0,
total: paginationConfig?.total || 0,
pageSize: paginationConfig?.pageSize || 0,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${paginationConfig?.pageIndex + 1}/${Math.ceil(
paginationConfig?.total / paginationConfig?.pageSize,
)}页`,
}}
/>
)
}
Example #2
Source File: ChoiceDevice.tsx From jetlinks-ui-antd with MIT License | 4 votes |
ChoiceDevice: React.FC<Props> = props => {
const initState: State = {
searchParam: {pageSize: 10, terms: {
"id$dev-group$not": props.parentId
}},
deviceData: {},
deviceList: []
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [deviceData, setDeviceData] = useState(initState.deviceData);
const [deviceList, setDeviceList] = useState(initState.deviceList);
const [spinning, setSpinning] = useState(true);
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance
.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
setSpinning(false);
})
.catch(() => {
});
};
useEffect(() => {
handleSearch(searchParam);
}, []);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceList(selectedRowKeys);
props.save(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
ellipsis: true,
},
{
title: '状态',
dataIndex: 'state',
width: '80px',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text}/> : '',
},
];
return (
<Spin spinning={spinning}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam({...searchParam, ...params});
handleSearch({terms: {...searchParam.terms, ...params}, sorter: searchParam.sorter, pageSize: 10});
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
selectedRowKeys: deviceList
}}
size='middle'
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
</Spin>
);
}
Example #3
Source File: bind.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceGatewayBind: React.FC<Props> = props => {
const initState: State = {
searchParam: {pageSize: 10},
deviceData: {},
deviceId: [],
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [deviceData, setDeviceData] = useState(initState.deviceData);
const [deviceId, setDeviceId] = useState(initState.deviceId);
const submitData = () => {
props.save(deviceId);
};
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance
.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {
});
};
useEffect(() => {
if (props.selectionType === 'checkbox') {
searchParam.terms = {parentId$isnull: 1};
}
handleSearch(searchParam);
}, []);
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
apis.deviceInstance
.list(
encodeQueryParam({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
}),
)
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {
});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceId(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
ellipsis: true,
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
width: '120px',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text}/> : '',
}
];
return (
<Modal
title="绑定子设备"
visible
okText="确定"
cancelText="取消"
onOk={() => {
submitData();
}}
width="60%"
style={{marginTop: -30}}
onCancel={() => props.close()}
>
<div className={styles.tableList} style={{maxHeight: 600, overflowY: 'auto', overflowX: 'hidden'}}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
if (props.selectionType === 'checkbox') {
params['parentId$isnull'] = 1;
}
handleSearch({terms: params, sorter: searchParam.sorter, pageSize: 10});
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: props.selectionType,
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
</Modal>
);
}
Example #4
Source File: bind-device.tsx From jetlinks-ui-antd with MIT License | 4 votes |
BindDevice: React.FC<Props> = props => {
const [deviceData, setDeviceData] = useState<any>({});
const [clusterList, setClusterList] = useState<any[]>([]);
const [cluster, setCluster] = useState<string>("");
const [current, setCurrent] = useState(0);
const [deviceIds, setDeviceIds] = useState<any[]>([]);
const [searchParam, setSearchParam] = useState({ pageSize: 10, terms: {} });
const handleSearch = (params: any) => {
params.terms = {
...params.terms,
'productId$dev-protocol': 'opc-ua'
}
setSearchParam(params);
apis.deviceInstance.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {
});
}
const queryClusterList = () => {
apis.opcUa.clusterList().then(res => {
if (res.status === 200) {
setClusterList(res.result);
}
})
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const steps = [
{
title: '选择集群'
},
{
title: '绑定设备'
}
];
const columns = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
ellipsis: true,
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
width: '120px',
render: (record: any) =>
record ? <Badge status={statusMap.get(record.text)} text={record.text} /> : '',
}
];
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms
})
};
const renderFooter = () => (
<div>
{current > 0 && (<Button onClick={() => { setCurrent(current - 1) }}>上一步</Button>)}
{current < steps.length - 1 && (<Button onClick={() => {
if (cluster !== '') {
setCurrent(current + 1);
} else {
message.error('请选择集群');
}
}}>下一步</Button>)}
{current === steps.length - 1 && (
<Button type="primary" onClick={() => { props.close() }}>确认</Button>
)}
</div>
)
const getBindedDevice = () => {
//获取已绑定数据
apis.opcUa.getDeviceBindListNoPaging(encodeQueryParam({
terms: {
opcUaId: props.opcId
}
})).then(resp => {
let children: any[] = [];
resp.result.map((item: any) => {
children.push(item.deviceId);
})
setDeviceIds(children);
})
}
const unbindSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceIds(selectedRowKeys);
},
onSelect: (record: any, selected: any) => {
let list: string[] = [record.id];
if (selected) {
_bind(list);
} else {
_unbind(list);
}
},
onSelectAll: (selected: any, selectedRows: any, changeRows: any) => {
let list: string[] = [];
changeRows.map((item: any) => {
list.push(item.id);
});
if (selected) {
_bind(list);
} else {
_unbind(list);
}
},
};
const _bind = (deviceIds: string[]) => {
let data: any[] = deviceData.data || [];
let params: any[] = [];
deviceIds.map((item: any) => {
let device = data.filter(i => {
return i.id === item
})
params.push({
deviceId: item,
opcUaId: props.opcId,
serverId: cluster,
productId: device[0].productId,
deviceName: device[0].name,
productName: device[0].productName
})
})
apis.opcUa.bindManyDevice(params).then(res => {
if (res.status === 200) {
message.success('绑定成功!');
}else{
message.error('绑定失败')
}
})
};
const _unbind = (deviceIds: string[]) => {
apis.opcUa.removeManyBind(props.opcId, deviceIds).then(res => {
if (res.status === 200) {
message.success('解绑成功!');
}else{
message.success('解绑失败!');
}
})
};
useEffect(() => {
queryClusterList();
handleSearch(searchParam);
getBindedDevice();
}, []);
return (
<Modal
title='绑定设备'
visible
width={1000}
footer={renderFooter()}
onCancel={() => {
props.close();
}}
>
<div style={{ padding: '10px' }}>
<div>
{current === 0 ?
<Form labelCol={{ span: 2 }} wrapperCol={{ span: 22 }}>
<Form.Item key="clusterId" label="集群">
<Select placeholder="请选择" value={cluster}
onChange={(value: string) => {
setCluster(value);
}}>
{(clusterList || []).map(item => (
<Select.Option
key={item.id}
value={item.id}
>
{item.id}
</Select.Option>
))}
</Select>
</Form.Item>
</Form> :
<div className={styles.tableList}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
handleSearch({ terms: params, sorter: searchParam.sorter, pageSize: 10 });
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
scroll={{
y: '450px'
}}
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
selectedRowKeys: deviceIds,
...unbindSelection
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize
}}
/>
</div>
</div>
}
</div>
</div>
</Modal>
);
}
Example #5
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
MediaDevice: React.FC<Props> = props => {
const {location: {pathname},} = props;
const service = new Service('media/channel');
const [loading, setLoading] = useState<boolean>(false);
const [deviceId, setDeviceId] = useState<string>("");
const [result, setResult] = useState<any>({});
const [deviceInfo, setDeviceInfo] = useState<any>({});
const [channel, setChannel] = useState<boolean>(false);
const [channelInfo, setChannelInfo] = useState<any>({});
const [playing, setPlaying] = useState<boolean>(false);
const [playback, setPalyback] = useState<boolean>(false)
const [data, setData] = useState<any>({});
const [searchParam, setSearchParam] = useState(initState.searchParam);
const statusMap = new Map();
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const ptzType = new Map();
ptzType.set(0, '未知');
ptzType.set(1, '球体');
ptzType.set(2, '半球体');
ptzType.set(3, '固定枪机');
ptzType.set(4, '遥控枪机');
const deviceDetail = (deviceId: string) => {
service.mediaDevice(deviceId).subscribe((data) => {
setDeviceInfo(data);
},
() => {
},
() => {
})
};
const handleSearch = (params?: any) => {
setSearchParam(params);
setLoading(true);
service.query(encodeQueryParam(params)).subscribe(
data => setResult(data),
() => {
},
() => setLoading(false));
};
const columns: ColumnProps<any>[] = [
{
title: '通道国标编号',
dataIndex: 'channelId',
ellipsis: true,
},
{
title: '通道名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '厂商',
dataIndex: 'manufacturer',
width: 100,
ellipsis: true,
},
{
title: '安装地址',
dataIndex: 'address',
width: '10%',
ellipsis: true,
},
{
title: '云台类型',
dataIndex: 'ptzType',
width: 100,
render: record => ptzType.get(record?.value || 0),
ellipsis: true,
},
{
title: '在线状态',
dataIndex: 'status',
width: 110,
render: record => record ? <Badge status={statusMap.get(record.value)} text={record.text}/> : '',
filters: [
{
text: '离线',
value: 'offline',
},
{
text: '在线',
value: 'online',
},
],
filterMultiple: false,
},
{
title: '经纬度',
width: 200,
ellipsis: true,
render: (record: any) => (
<span>{record.longitude ? `${record.longitude ? record.longitude : ''},${record.latitude ? record.latitude : ''}` : ''}</span>
)
},
{
title: '子通道数',
dataIndex: 'subCount',
width: 100,
},
{
title: '描述',
dataIndex: 'description',
width: '10%',
ellipsis: true
},
{
title: '操作',
align: 'center',
// fixed: 'right',
render: (record: any) => (
<Fragment>
<a
onClick={() => {
setChannel(true);
setChannelInfo(record);
}}
>
编辑
</a>
<Divider type="vertical"/>
{record.status.value === 'online' ? (
<>
<a
onClick={() => {
setPlaying(true);
setData(record)
}}
>
播放
</a>
<Divider type="vertical"/>
<a
onClick={() => {
setPalyback(true);
setData(record)
}}
>
回放
</a>
</>
) : (
<Popconfirm
placement="topRight"
title="确定删除此通道吗?"
onConfirm={() => {
setLoading(true);
service.remove(record.id).subscribe(
() => {
message.success('通道删除成功');
},
() => {
message.error('通道删除失败');
},
() => {
handleSearch(searchParam);
setLoading(false);
},
);
}}
>
<a>删除</a>
</Popconfirm>
)}
</Fragment>
)
},
];
useEffect(() => {
if (pathname.indexOf('channel') > 0) {
const list = pathname.split('/');
deviceDetail(list[list.length - 1]);
setDeviceId(list[list.length - 1]);
searchParam.terms = {deviceId: list[list.length - 1]};
handleSearch(searchParam);
}
}, [window.location.hash]);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
const {terms} = searchParam;
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: {...terms, ...filters},
sorts: sorter,
})
};
const content = (
<div style={{marginTop: 30}}>
<Descriptions column={4}>
<Descriptions.Item label="设备名称">
<div>
{deviceInfo.name}
</div>
</Descriptions.Item>
</Descriptions>
</div>
);
const titleInfo = (
<Row>
<div>
<span style={{paddingRight: 20}}>
通道列表:{deviceId}
</span>
<Badge status={statusMap.get(deviceInfo.state?.value)} text={deviceInfo.state?.text}/>
</div>
</Row>
);
return (
<PageHeaderWrapper title={titleInfo} content={content}>
<Card style={{height: 92, marginBottom: 16}}>
<div className={styles.tableList} style={{marginTop: -22}}>
<div>
<SearchForm
search={(params: any) => {
setSearchParam(params);
params ? params.deviceId = deviceId : params = {deviceId: deviceId};
handleSearch({pageSize: 10, terms: {...params}, sorts: {field: 'id', order: 'desc'}});
}}
formItems={[
{
label: '名称',
key: 'name$LIKE',
type: 'string',
},
]}
/>
</div>
</div>
</Card>
<Card>
<div className={styles.StandardTable}>
<Table
loading={loading}
columns={columns}
dataSource={(result || {}).data}
rowKey="id"
onChange={onTableChange}
pagination={{
current: result?.pageIndex + 1,
total: result?.total,
pageSize: result?.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${result?.pageIndex + 1}/${Math.ceil(
result?.total / result?.pageSize,
)}页`,
}}
/>
</div>
</Card>
{playing && <Play data={data} close={() => {
setPlaying(false)
}} ok={() => {
setPlaying(false)
}}/>}
{channel && <ChannelEdit data={channelInfo} close={() => {
setChannel(false);
handleSearch(searchParam);
}}/>
}
{playback && <Playback data={data} close={() => {
setPalyback(false)
}} ok={() => {
setPalyback(false)
}} />}
</PageHeaderWrapper>
)
}
Example #6
Source File: bind.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceGatewayBind: React.FC<Props> = props => {
const service = new Service('device-network');
const initState: State = {
searchParam: { pageSize: 10 },
deviceData: {},
deviceId: [],
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [deviceData, setDeviceData] = useState(initState.deviceData);
const [deviceId, setDeviceId] = useState(initState.deviceId);
const submitData = () => {
props.save(deviceId);
};
const handleSearch = (params?: any) => {
setSearchParam(params);
service.getDeviceList(props.deviceId, params).subscribe(
(res) => {
setDeviceData(res)
})
// apis.deviceInstance
// .list(encodeQueryParam(params))
// .then(response => {
// if (response.status === 200) {
// setDeviceData(response.result);
// }
// })
// .catch(() => {
// });
};
useEffect(() => {
if (props.selectionType === 'checkbox') {
searchParam.terms = { parentId$isnull: 1 };
}
handleSearch(searchParam);
}, []);
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
service.getDeviceList(props.deviceId, encodeQueryParam({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
})).subscribe(
(res) => {
setDeviceData(res)
})
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceId(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const columns = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
ellipsis: true,
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
width: '120px',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text} /> : '',
}
];
return (
<Modal
title="绑定子设备"
visible
okText="确定"
cancelText="取消"
onOk={() => {
submitData();
}}
width="60%"
style={{ marginTop: -30 }}
onCancel={() => props.close()}
>
<div className={styles.tableList} style={{ maxHeight: 600, overflowY: 'auto', overflowX: 'hidden' }}>
<div className={styles.tableListForm}>
<SearchForm
formItems={[
{
label: '名称',
key: 'name',
type: 'string',
}
]}
search={(params: any) => {
if (params?.name) {
setSearchParam({
where: `name like '%${params?.name}%'`,
pageSize: 10
})
handleSearch({
where: `name like '%${params?.name}%'`,
pageSize: 10
});
} else {
setSearchParam({ pageSize: 10 })
handleSearch({ pageSize: 10 });
}
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: props.selectionType,
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
</Modal>
);
}
Example #7
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceInstancePage: React.FC<Props> = props => {
const { result } = props.deviceInstance;
const { dispatch, location } = props;
const map = new Map();
map.set('id', 'id$like');
map.set('name', 'name$like');
map.set('orgId', 'orgId$in');
map.set('devTag', 'id$dev-tag');
map.set('devBind', 'id$dev-bind$any');
map.set('devProd', 'productId$dev-prod-cat');
map.set('productId', 'productId');
const initState: State = {
data: result,
searchParam: {
pageSize: 10,
terms: location?.query?.terms,
sorts: {
order: 'desc',
field: 'id',
},
},
addVisible: false,
currentItem: {},
processVisible: false,
importLoading: false,
action: '',
deviceCount: {
notActiveCount: 0,
offlineCount: 0,
onlineCount: 0,
deviceTotal: 0,
loading: true,
},
productList: [],
deviceIdList: [],
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [addVisible, setAddVisible] = useState(initState.addVisible);
const [currentItem, setCurrentItem] = useState(initState.currentItem);
const [importLoading, setImportLoading] = useState(initState.importLoading);
const [action, setAction] = useState(initState.action);
const [productList, setProductList] = useState(initState.productList);
const [product, setProduct] = useState<string>();
const [deviceCount, setDeviceCount] = useState(initState.deviceCount);
const [deviceImport, setDeviceImport] = useState(false);
const [deviceExport, setDeviceExport] = useState(false);
const [deviceIdList, setDeviceIdLIst] = useState(initState.deviceIdList);
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const handleSearch = (params?: any) => {
setSearchParam(params);
dispatch({
type: 'deviceInstance/query',
payload: encodeQueryParam(params),
});
};
const delelteInstance = (record: any) => {
apis.deviceInstance
.remove(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
};
const changeDeploy = (record: any) => {
apis.deviceInstance
.changeDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
};
const unDeploy = (record: any) => {
apis.deviceInstance
.unDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
};
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => (text ? moment(text).format('YYYY-MM-DD HH:mm:ss') : '/'),
sorter: true,
},
{
title: '状态',
dataIndex: 'state',
width: '90px',
render: record =>
record ? <Badge status={statusMap.get(record.value)} text={record.text} /> : '',
filters: [
{
text: '未启用',
value: 'notActive',
},
{
text: '离线',
value: 'offline',
},
{
text: '在线',
value: 'online',
},
],
filterMultiple: false,
},
{
title: '说明',
dataIndex: 'describe',
width: '15%',
ellipsis: true,
},
{
title: '操作',
width: '200px',
align: 'center',
render: (record: any) => (
<Fragment>
<a
onClick={() => {
router.push(`/device/instance/save/${record.id}`);
}}
>
查看
</a>
<Divider type="vertical" />
<a
onClick={() => {
setCurrentItem(record);
setAddVisible(true);
}}
>
编辑
</a>
<Divider type="vertical" />
{record.state?.value === 'notActive' ? (
<span>
<Popconfirm
title="确认启用?"
onConfirm={() => {
changeDeploy(record);
}}
>
<a>启用</a>
</Popconfirm>
<Divider type="vertical" />
<Popconfirm
title="确认删除?"
onConfirm={() => {
delelteInstance(record);
}}
>
<a>删除</a>
</Popconfirm>
</span>
) : (
<Popconfirm
title="确认禁用设备?"
onConfirm={() => {
unDeploy(record);
}}
>
<a>禁用</a>
</Popconfirm>
)}
</Fragment>
),
},
];
const stateCount = (productId: string) => {
const map = {
notActiveCount: 0,
offlineCount: 0,
onlineCount: 0,
deviceTotal: 0,
loading: true,
};
apis.deviceInstance
.count(
encodeQueryParam({
terms: {
state: 'notActive',
productId,
...location?.query?.terms,
...(location?.query.iop && JSON.parse(location?.query.iop)?.terms),
},
}),
)
.then(res => {
if (res.status === 200) {
map.notActiveCount = res.result;
setDeviceCount({ ...map });
}
})
.catch();
apis.deviceInstance
.count(
encodeQueryParam({
terms: {
state: 'offline',
productId,
...location?.query?.terms,
...(location?.query.iop && JSON.parse(location?.query.iop)?.terms),
},
}),
)
.then(res => {
if (res.status === 200) {
map.offlineCount = res.result;
setDeviceCount({ ...map });
}
})
.catch();
apis.deviceInstance
.count(
encodeQueryParam({
terms: {
state: 'online',
productId,
...location?.query?.terms,
...(location?.query.iop && JSON.parse(location?.query.iop)?.terms),
},
}),
)
.then(res => {
if (res.status === 200) {
map.onlineCount = res.result;
setDeviceCount({ ...map });
}
})
.catch();
apis.deviceInstance
.count(
encodeQueryParam({
terms: {
productId,
...location?.query?.terms,
...(location?.query.iop && JSON.parse(location?.query.iop)?.terms),
},
}),
)
.then(res => {
if (res.status === 200) {
map.deviceTotal = res.result;
map.loading = false;
setDeviceCount({ ...map });
}
})
.catch();
};
useEffect(() => {
// 获取下拉框数据
apis.deviceProdcut
.queryNoPagin(
encodeQueryParam({
paging: false,
}),
)
.then(e => {
setProductList(e.result);
})
.catch(() => {});
const query: any = getPageQuery();
if (query.hasOwnProperty('productId')) {
const { productId } = query;
setProduct(productId);
handleSearch({
terms: {
productId: query.productId,
},
pageSize: 10,
});
stateCount(productId);
} else if (location?.query) {
let key = Object.keys(location?.query)[0];
let params = {};
params[map.get(key)] = location?.query[key];
handleSearch({
terms: { ...params, ...(location?.query.iop && JSON.parse(location?.query.iop)?.terms) },
pageSize: 10,
sorts: searchParam.sorts,
});
stateCount('');
} else {
handleSearch(searchParam);
stateCount('');
}
}, []);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
let { terms } = searchParam;
if (filters.state) {
if (terms) {
terms.state = filters.state[0];
} else {
terms = {
state: filters.state[0],
};
}
}
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms,
sorts: sorter,
});
};
const [processVisible, setProcessVisible] = useState(false);
const [api, setAPI] = useState<string>('');
const getSearchParam = () => {
const data = encodeQueryParam(searchParam);
let temp = '';
Object.keys(data).forEach((i: string) => {
if (data[i] && i !== 'pageSize' && i !== 'pageIndex') {
temp += `${i}=${data[i]}&`;
}
});
return encodeURI(temp.replace(/%/g, '%'));
};
// 激活全部设备
const startImport = () => {
setProcessVisible(true);
const activeAPI = `/jetlinks/device-instance/deploy?${getSearchParam()}:X_Access_Token=${getAccessToken()} `;
setAPI(activeAPI);
setAction('active');
};
const startSync = () => {
setProcessVisible(true);
const syncAPI = `/jetlinks/device-instance/state/_sync/?${getSearchParam()}:X_Access_Token=${getAccessToken()}`;
setAPI(syncAPI);
setAction('sync');
};
const activeDevice = () => {
Modal.confirm({
title: `确认激活全部设备`,
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
startImport();
},
});
};
const syncDevice = () => {
Modal.confirm({
title: '确定同步设备真实状态?',
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
// 同步设备
startSync();
},
});
};
const onDeviceProduct = (value: string) => {
let { terms } = searchParam;
if (terms) {
terms.productId = value;
} else {
terms = {
productId: value,
};
}
handleSearch({
pageIndex: searchParam.pageIndex,
pageSize: searchParam.pageSize,
terms,
sorts: searchParam.sorter,
});
stateCount(value);
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceIdLIst(selectedRowKeys);
},
};
const _delete = (deviceId: any[]) => {
Modal.confirm({
title: `确认删除选中设备`,
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
apis.deviceInstance
._delete(deviceId)
.then(response => {
if (response.status === 200) {
message.success('成功删除选中设备');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
},
});
};
const _unDeploy = (deviceId: any[]) => {
Modal.confirm({
title: `确认注销选中设备`,
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
apis.deviceInstance
._unDeploy(deviceId)
.then(response => {
if (response.status === 200) {
message.success('成功注销选中设备');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
},
});
};
const _deploy = (deviceId: any[]) => {
Modal.confirm({
title: `确认激活选中设备`,
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
apis.deviceInstance
._deploy(deviceId)
.then(response => {
if (response.status === 200) {
message.success('成功激活选中设备');
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
}
})
.catch(() => {});
},
});
};
const Info: FC<{
title: React.ReactNode;
value: React.ReactNode;
}> = ({ title, value }) => (
<div>
<span>{title}</span>
<p style={{ fontSize: '26px' }}>{value}</p>
</div>
);
const menu = (
<Menu>
<Menu.Item key="1">
<Button
icon="download"
type="default"
onClick={() => {
setDeviceExport(true);
}}
>
批量导出设备
</Button>
</Menu.Item>
<Menu.Item key="2">
<Button
icon="upload"
onClick={() => {
setDeviceImport(true);
}}
>
批量导入设备
</Button>
</Menu.Item>
{deviceIdList.length > 0 && (
<Menu.Item key="3">
<Button
icon="delete"
onClick={() => {
_delete(deviceIdList);
}}
>
删除选中设备
</Button>
</Menu.Item>
)}
{deviceIdList.length > 0 && (
<Menu.Item key="6">
<Button
icon="stop"
onClick={() => {
_unDeploy(deviceIdList);
}}
>
注销选中设备
</Button>
</Menu.Item>
)}
{deviceIdList.length > 0 ? (
<Menu.Item key="4">
<Button icon="check-circle" type="danger" onClick={() => _deploy(deviceIdList)}>
激活选中设备
</Button>
</Menu.Item>
) : (
<Menu.Item key="4">
<Button icon="check-circle" type="danger" onClick={() => activeDevice()}>
激活全部设备
</Button>
</Menu.Item>
)}
<Menu.Item key="5">
<Button icon="sync" type="danger" onClick={() => syncDevice()}>
同步设备状态
</Button>
</Menu.Item>
</Menu>
);
return (
<PageHeaderWrapper title="设备管理">
<div className={styles.standardList}>
<Card bordered={false} style={{ height: 95 }}>
<Spin spinning={deviceCount.loading}>
<Row>
<Col sm={7} xs={24}>
<Select
placeholder="选择产品"
showSearch
optionFilterProp='label'
allowClear
style={{ width: '70%', marginTop: 7 }}
value={product}
onChange={(value: string) => {
let key = Object.keys(location?.query)[0];
let params = {};
if (location?.query) {
params[key] = location?.query[key];
}
params['productId'] = value;
router.push({ pathname: `/device/instance`, query: params });
setProduct(() => value);
setDeviceCount({ loading: true });
onDeviceProduct(value);
}}
>
{productList?.map(item => (
<Select.Option key={item.id} label={item.name}>{item.name}</Select.Option>
))}
</Select>
</Col>
<Col sm={4} xs={24}>
<Info title="全部设备" value={numeral(deviceCount.deviceTotal).format('0,0')} />
</Col>
<Col sm={4} xs={24}>
<Info
title={<Badge status={statusMap.get('online')} text="在线" />}
value={numeral(deviceCount.onlineCount).format('0,0')}
/>
</Col>
<Col sm={4} xs={24}>
<Info
title={<Badge status={statusMap.get('offline')} text="离线" />}
value={numeral(deviceCount.offlineCount).format('0,0')}
/>
</Col>
<Col sm={4} xs={24}>
<Info
title={<Badge status={statusMap.get('notActive')} text="未启用" />}
value={numeral(deviceCount.notActiveCount).format('0,0')}
/>
</Col>
<Col sm={1} xs={24}>
<Tooltip title="刷新">
<Icon
type="sync"
style={{ fontSize: 20 }}
onClick={() => {
setDeviceCount({ loading: true });
stateCount(product);
}}
/>
</Tooltip>
</Col>
</Row>
</Spin>
</Card>
<br />
<Card bordered={false}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>
<Search
type={'device-instance'}
search={(params: any) => {
if (Object.keys(params).length === 0) {
deviceIdList.splice(0, deviceIdList.length);
}
if (product) {
params.productId = product;
}
params.state = searchParam.terms?.state;
handleSearch({ terms: params, pageSize: 10, sorts: searchParam.sorts });
}}
/>
</div>
<div className={styles.tableListOperator}>
<Button
icon="plus"
type="primary"
onClick={() => {
setCurrentItem({});
setAddVisible(true);
}}
>
添加设备
</Button>
<Divider type="vertical" />
<Dropdown overlay={menu}>
<Button icon="menu">
其他批量操作
<Icon type="down" />
</Button>
</Dropdown>
</div>
<div className={styles.StandardTable}>
<Table
loading={props.loading}
columns={columns}
dataSource={(result || {}).data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: result.pageIndex + 1,
total: result.total,
pageSize: result.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${result.pageIndex + 1}/${Math.ceil(
result.total / result.pageSize,
)}页`,
}}
/>
</div>
</div>
</Card>
{addVisible && (
<Save
data={currentItem}
close={() => {
setAddVisible(false);
setCurrentItem({});
}}
/>
)}
{(processVisible || importLoading) && (
<Process
api={api}
action={action}
closeVisible={() => {
setProcessVisible(false);
setImportLoading(false);
handleSearch(searchParam);
}}
/>
)}
{deviceImport && (
<Import
productId={product}
close={() => {
setDeviceImport(false);
handleSearch(searchParam);
}}
/>
)}
{deviceExport && (
<Export
productId={product}
searchParam={searchParam}
close={() => {
setDeviceExport(false);
handleSearch(searchParam);
}}
/>
)}
</div>
</PageHeaderWrapper>
);
}
Example #8
Source File: index-backups.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceInstancePage: React.FC<Props> = props => {
const { result } = props.deviceInstance;
const initState: State = {
data: result,
searchParam: { pageSize: 10 },
addVisible: false,
currentItem: {},
processVisible: false,
importLoading: false,
action: '',
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [addVisible, setAddvisible] = useState(initState.addVisible);
const [currentItem, setCurrentItem] = useState(initState.currentItem);
const [importLoading, setImportLoading] = useState(initState.importLoading);
const [action, setAction] = useState(initState.action);
const { dispatch } = props;
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const handleSearch = (params?: any) => {
setSearchParam(params);
dispatch({
type: 'deviceInstance/query',
payload: encodeQueryParam(params),
});
};
const delelteInstance = (record: any) => {
apis.deviceInstance
.remove(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
handleSearch(searchParam);
}
})
.catch(() => {});
};
const changeDeploy = (record: any) => {
apis.deviceInstance
.changeDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
handleSearch(searchParam);
}
})
.catch(() => {});
};
const unDeploy = (record: any) => {
apis.deviceInstance
.unDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
handleSearch(searchParam);
}
})
.catch(() => {});
};
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '设备名称',
dataIndex: 'name',
},
{
title: '产品名称',
dataIndex: 'productName',
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text} /> : '',
},
{
title: '描述',
dataIndex: 'describe',
},
{
title: '操作',
width: '200px',
align: 'center',
render: (record: any) => (
<Fragment>
<a
onClick={() => {
router.push(`/device/instance/save/${record.id}`);
}}
>
查看
</a>
<Divider type="vertical" />
<a
onClick={() => {
setCurrentItem(record);
setAddvisible(true);
}}
>
编辑
</a>
<Divider type="vertical" />
{record.state?.value === 'notActive' ? (
<span>
<Popconfirm
title="确认激活?"
onConfirm={() => {
changeDeploy(record);
}}
>
<a>激活</a>
</Popconfirm>
<Divider type="vertical" />
<Popconfirm
title="确认删除?"
onConfirm={() => {
delelteInstance(record);
}}
>
<a>删除</a>
</Popconfirm>
</span>
) : (
<Popconfirm
title="确认注销设备?"
onConfirm={() => {
unDeploy(record);
}}
>
<a>注销</a>
</Popconfirm>
)}
</Fragment>
),
},
];
useEffect(() => {
handleSearch(searchParam);
}, []);
const saveDeviceInstance = (item: any) => {
dispatch({
type: 'deviceInstance/update',
payload: encodeQueryParam(item),
callback: (response:any) => {
if (response.status === 200) {
message.success('保存成功');
setAddvisible(false);
router.push(`/device/instance/save/${item.id}`);
}
},
});
};
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
const [processVisible, setProcessVisible] = useState(false);
const [api, setAPI] = useState<string>('');
const getSearchParam = () => {
const data = encodeQueryParam(searchParam);
let temp = '';
Object.keys(data).forEach((i: string) => {
if (data[i] && i !== 'pageSize' && i !== 'pageIndex') {
temp += `${i}=${data[i]}&`;
}
});
return encodeURI(temp.replace(/%/g, '%'));
};
// 激活全部设备
const startImport = () => {
// let dt = 0;
setProcessVisible(true);
const activeAPI = `/jetlinks/device-instance/deploy?${getSearchParam()}:X_Access_Token=${getAccessToken()} `;
setAPI(activeAPI);
setAction('active');
};
const startSync = () => {
setProcessVisible(true);
const syncAPI = `/jetlinks/device-instance/state/_sync/?${getSearchParam()}:X_Access_Token=${getAccessToken()}`;
setAPI(syncAPI);
setAction('sync');
};
const activeDevice = () => {
Modal.confirm({
title: `确认激活全部设备`,
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
startImport();
},
});
};
const syncDevice = () => {
Modal.confirm({
title: '确定同步设备真实状态?',
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
// 同步设备
startSync();
},
});
};
const [uploading, setUploading] = useState(false);
const exportDevice = () => {
const formElement = document.createElement('form');
formElement.style.display = 'display:none;';
formElement.method = 'post';
formElement.action = `/jetlinks/device-instance/export?:X_Access_Token=${getAccessToken()}`;
const params = encodeQueryParam(searchParam);
Object.keys(params).forEach((key: string) => {
const inputElement = document.createElement('input');
inputElement.type = 'hidden';
inputElement.name = key;
inputElement.value = params[key];
formElement.appendChild(inputElement);
});
document.body.appendChild(formElement);
formElement.submit();
document.body.removeChild(formElement);
};
const uploadProps: UploadProps = {
accept: '.xlsx, .xls',
action: '/jetlinks/file/static',
headers: {
'X-Access-Token': getAccessToken(),
},
showUploadList: false,
onChange(info) {
if (info.file.status === 'done') {
setUploading(false);
const fileUrl = info.file.response.result;
const url = `/jetlinks/device-instance/import?fileUrl=${fileUrl}&:X_Access_Token=${getAccessToken()}`;
setAPI(url);
setAction('import');
setImportLoading(true);
}
if (info.file.status === 'uploading') {
setUploading(true);
}
},
};
return (
<PageHeaderWrapper title="设备管理">
<Spin spinning={uploading} tip="上传中...">
<Card bordered={false}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
handleSearch({ terms: params, pageSize: 10 });
}}
/>
</div>
<div className={styles.tableListOperator}>
<Button
icon="plus"
type="primary"
onClick={() => {
setCurrentItem({});
setAddvisible(true);
}}
>
新建
</Button>
<Divider type="vertical" />
<Button href={template} download="设备模版" icon="download">
下载模版
</Button>
<Divider type="vertical" />
<Button icon="download" type="default" onClick={() => exportDevice()}>
导出设备
</Button>
<Divider type="vertical" />
<Upload {...uploadProps}>
<Button icon="upload">导入设备</Button>
</Upload>
<Divider type="vertical" />
<Button icon="check-circle" type="danger" onClick={() => activeDevice()}>
激活全部设备
</Button>
<Divider type="vertical" />
<Button icon="sync" type="danger" onClick={() => syncDevice()}>
同步设备状态
</Button>
</div>
<div className={styles.StandardTable}>
<Table
loading={props.loading}
columns={columns}
dataSource={(result || {}).data}
rowKey="id"
onChange={onTableChange}
pagination={{
current: result.pageIndex + 1,
total: result.total,
pageSize: result.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${result.pageIndex + 1}/${Math.ceil(
result.total / result.pageSize,
)}页`,
}}
/>
</div>
</div>
</Card>
{addVisible && (
<Save
data={currentItem}
close={() => {
setAddvisible(false);
setCurrentItem({});
}}
save={(item: any) => {
saveDeviceInstance(item);
}}
/>
)}
{(processVisible || importLoading) && (
<Process
api={api}
action={action}
closeVisible={() => {
setProcessVisible(false);
setImportLoading(false);
handleSearch(searchParam);
}}
/>
)}
</Spin>
</PageHeaderWrapper>
);
}
Example #9
Source File: gateway.tsx From jetlinks-ui-antd with MIT License | 4 votes |
Gateway: React.FC<Props> = (props) => {
const initState: State = {
data: {},
searchParam: { pageSize: 10 },
currentItem: {},
spinning: false,
bindVisible: false,
addVisible: false,
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [data, setData] = useState(initState.data);
const [spinning, setSpinning] = useState(initState.spinning);
const [currentItem, setCurrentItem] = useState(initState.currentItem);
const [addVisible, setAddVisible] = useState(initState.addVisible);
const [bindVisible, setBindVisible] = useState(initState.bindVisible);
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance.list(encodeQueryParam(params))
.then((response: any) => {
if (response.status === 200) {
setData(response.result);
}
setSpinning(false);
},
).catch(() => {
});
};
useEffect(() => {
setSpinning(true);
handleSearch({
pageSize: 10,
terms: {
parentId: props.deviceId,
},
});
}, []);
const changeDeploy = (record: any) => {
setSpinning(true);
apis.deviceInstance
.changeDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
handleSearch(searchParam);
} else {
setSpinning(false);
}
})
.catch(() => {
});
};
const unDeploy = (record: any) => {
setSpinning(true);
apis.deviceInstance
.unDeploy(record.id)
.then(response => {
if (response.status === 200) {
message.success('操作成功');
handleSearch(searchParam);
} else {
setSpinning(false);
}
})
.catch(() => {
});
};
const unBindGateway = (id: string, deviceId: string) => {
setSpinning(true);
apis.deviceGateway.unBind(id, deviceId)
.then(response => {
if (response.status === 200) {
message.success('解绑成功');
handleSearch(searchParam);
} else {
setSpinning(false);
}
}).catch(() => {
});
};
const statusMap = new Map();
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '设备名称',
dataIndex: 'name',
},
{
title: '产品名称',
dataIndex: 'productName',
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
render: record =>
record ? <Badge status={statusMap.get(record.value)} text={record.text}/> : '',
},
{
title: '操作',
width: '200px',
align: 'center',
render: (record: any) => (
<Fragment>
<a
onClick={() => {
router.push(`/device/instance/save/${record.id}`);
}}
>
查看
</a>
<Divider type="vertical"/>
<a
onClick={() => {
setCurrentItem(record);
setAddVisible(true);
}}
>
编辑
</a>
<Divider type="vertical"/>
{record.state?.value === 'notActive' ? (
<Popconfirm
title="确认激活?"
onConfirm={() => {
changeDeploy(record);
}}
>
<a>激活</a>
</Popconfirm>
) : (
<Popconfirm
title="确认注销设备?"
onConfirm={() => {
unDeploy(record);
}}
>
<a>注销</a>
</Popconfirm>
)}
<Divider type="vertical"/>
<Popconfirm
title="确认解绑?"
onConfirm={() => {
unBindGateway(props.deviceId, record.id);
}}
>
<a>解绑</a>
</Popconfirm>
</Fragment>
),
},
];
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
const saveDeviceInstance = (item: any) => {
setSpinning(true);
apis.deviceInstance.saveOrUpdate(item)
.then((response: any) => {
if (response.status === 200) {
message.success('保存成功');
handleSearch(searchParam);
} else {
setSpinning(false);
}
}).catch(() => {
});
};
const insert = (deviceData: any) => {
setSpinning(true);
apis.deviceGateway.bind(props.deviceId, deviceData).then(response => {
if (response.status === 200) {
message.success('保存成功');
handleSearch(searchParam);
} else {
setSpinning(false);
}
}).catch(() => {
});
};
const action = (
<Button type="primary" icon="plus" onClick={() => setBindVisible(true)}>
绑定子设备
</Button>
);
return (
<div>
<Spin spinning={spinning}>
<Card style={{ marginBottom: 20 }} title="子设备列表" extra={action}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
params.parentId = props.deviceId;
handleSearch({ terms: params, pageSize: 10 });
}}
/>
</div>
<Table
loading={props.loading}
columns={columns}
dataSource={data?.data}
rowKey="id"
onChange={onTableChange}
pagination={{
current: data.pageIndex + 1,
total: data.total,
pageSize: data.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${data.pageIndex + 1}/${Math.ceil(
data.total / data.pageSize,
)}页`,
}}
/>
</Card>
{addVisible && (
<Save
data={currentItem}
close={() => {
setAddVisible(false);
setCurrentItem({});
}}
save={(item: any) => {
setAddVisible(false);
saveDeviceInstance(item);
}}
/>
)}
{bindVisible && (
<Bind selectionType='checkbox'
close={() => {
setBindVisible(false);
}}
save={(item: any) => {
setBindVisible(false);
insert(item);
}}
/>
)}
</Spin>
</div>
);
}
Example #10
Source File: EventLog.tsx From jetlinks-ui-antd with MIT License | 4 votes |
EventLog: React.FC<Props> = props => {
const initState: State = {
eventColumns: props.item.valueType.type === "object" ? props.item.valueType.properties?.map((item: any) => {
return {
title: item.name,
dataIndex: `${item.id}_format`,
ellipsis: true,
render: (text: any) => typeof text === 'object' ?
JSON.stringify(text) : text
};
}) : [{
title: "数据",
dataIndex: `value`,
ellipsis: true,
render:(text)=>JSON.stringify(text)
}],
logData: {},
};
initState.eventColumns.push({
title: '事件时间',
dataIndex: 'timestamp',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
});
initState.eventColumns.push({
title: '操作',
render: (record: any) => (
<>
<a onClick={() => {
for (let i in record) {
if (i.indexOf('_format') != -1) {
delete record[i];
}
}
Modal.info({
title: '详情',
width: 850,
content: (
<Form.Item wrapperCol={{ span: 20 }} labelCol={{ span: 4 }} label={props.item.name}>
<AceEditor
readOnly
value={JSON.stringify(record, null, 2)}
mode='json'
theme="eclipse"
name="app_code_editor"
key='deviceShadow'
fontSize={14}
showPrintMargin
showGutter
wrapEnabled
highlightActiveLine //突出活动线
enableSnippets //启用代码段
style={{ width: '100%', height: '50vh' }}
setOptions={{
enableBasicAutocompletion: true, //启用基本自动完成功能
enableLiveAutocompletion: true, //启用实时自动完成功能 (比如:智能代码提示)
enableSnippets: true, //启用代码段
showLineNumbers: true,
tabSize: 2,
}}
/>
</Form.Item>
),
okText: '关闭',
onOk() {
},
});
}}>详情</a>
</>
)
});
const [logData, setLogData] = useState(initState.logData);
useEffect(() => {
apis.deviceInstance.eventData(
props.deviceId,
props.item.id,
encodeQueryParam({
pageIndex: 0,
pageSize: 10,
}),
).then(response => {
setLogData(response.result);
}).catch(() => {
});
}, []);
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
apis.deviceInstance.eventData(
props.deviceId,
props.item.id,
encodeQueryParam({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
}),
).then(response => {
setLogData(response.result);
}).catch(() => {
});
};
return (
<Modal
title="事件详情"
visible
onCancel={() => props.close()}
onOk={() => props.close()}
width="70%"
>
<Table
rowKey='id'
dataSource={logData.data}
size="small"
onChange={onTableChange}
pagination={{
current: logData.pageIndex + 1,
total: logData.total,
pageSize: logData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) => `共 ${total} 条记录 第 ${logData.pageIndex + 1}/${Math.ceil(logData.total / logData.pageSize)}页`,
}}
columns={initState.eventColumns}
/>
</Modal>
);
}
Example #11
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceList = (props: Props) => {
const [searchParam, setSearchParam] = useState({
pageSize: 10,
terms: { productId: props.productId },
});
const [deviceData, setDeviceData] = useState<any>({});
const [deviceId, setDeviceId] = useState(props.data);
const submitData = () => {
props.save(deviceId);
};
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance
.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {});
};
useEffect(() => {
handleSearch(searchParam);
}, []);
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
apis.deviceInstance
.list(
encodeQueryParam({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
terms: { productId: props.productId },
}),
)
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceId(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const columns: ColumnProps<any>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
ellipsis: true,
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
width: '120px',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text} /> : '',
},
];
return (
<Modal
title="选择设备"
visible
okText="确定"
cancelText="取消"
onOk={() => {
submitData();
}}
width="60%"
style={{ marginTop: -30 }}
onCancel={() => props.close()}
>
<div
className={styles.tableList}
style={{ maxHeight: 600, overflowY: 'auto', overflowX: 'hidden' }}
>
<div className={styles.tableListForm}>
<SearchForm
search={(params: any) => {
handleSearch({ terms: { ...searchParam.terms, ...params }, pageSize: 10 });
}}
formItems={[
{
label: '设备名称',
key: 'name$LIKE',
type: 'string',
},
{
label: '设备ID',
key: 'deviceId$IN',
type: 'string',
},
]}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
selectedRowKeys: deviceId,
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
</Modal>
);
}
Example #12
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
DeviceGatewayBind: React.FC<Props> = props => {
const initState: State = {
searchParam: { pageSize: 10, terms: { 'parentId$not@or': props.gatewayId } },
deviceData: {},
deviceId: [],
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [deviceData, setDeviceData] = useState(initState.deviceData);
const [deviceId, setDeviceId] = useState(initState.deviceId);
const submitData = () => {
props.save(deviceId);
};
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance
.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {});
};
useEffect(() => {
if (props.selectionType === 'checkbox') {
searchParam.terms = { parentId$isnull: 1, 'parentId$not@or': props.gatewayId };
}
handleSearch(searchParam);
}, []);
const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
apis.deviceInstance
.list(
encodeQueryParam({
terms: searchParam.terms,
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
sorts: sorter,
}),
)
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceId(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
ellipsis: true,
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
width: '120px',
render: record =>
record ? <Badge status={statusMap.get(record.value)} text={record.text} /> : '',
},
];
return (
<Modal
title="绑定子设备"
visible
okText="确定"
cancelText="取消"
onOk={() => {
submitData();
}}
width="60%"
style={{ marginTop: -30 }}
onCancel={() => props.close()}
>
<div
className={styles.tableList}
style={{ maxHeight: 600, overflowY: 'auto', overflowX: 'hidden' }}
>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
if (props.selectionType === 'checkbox') {
// params['parentId$isnull'] = 1;
handleSearch({
sorter: searchParam.sorter,
pageSize: 10,
terms:{
...params,
parentId$isnull:1,
'parentId$not@or':props.gatewayId
},
})
}else{
handleSearch({
sorter: searchParam.sorter,
pageSize: 10,
terms:{
...params,
// parentId$isnull:1,
'parentId$not@or':props.gatewayId
},
})
}
// params['parentId$not@or'] = props.gatewayId;
// handleSearch({ terms: params, sorter: searchParam.sorter, pageSize: 10 });
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: props.selectionType,
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
</Modal>
);
}
Example #13
Source File: upgrade-task.tsx From jetlinks-ui-antd with MIT License | 4 votes |
UpgradeTask: React.FC<Props> = (props) => {
const initState: State = {
data: {},
saveUpgradeTaskData: {},
searchParam: { pageSize: 10 },
spinning: false,
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [data, setData] = useState(initState.data);
const [spinning, setSpinning] = useState(initState.spinning);
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.firmware.upgradeTask(encodeQueryParam(params))
.then((response: any) => {
if (response.status === 200) {
setData(response.result);
}
setSpinning(false);
},
).catch(() => {
});
};
useEffect(() => {
setSpinning(true);
handleSearch({
pageSize: 10,
terms: {
firmwareId: props.firmwareId,
},
});
}, []);
const columns: ColumnProps<UpgradeTaskData>[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '任务名称',
dataIndex: 'name',
},
{
title: '升级方式',
dataIndex: 'mode.text',
},
{
title: '超时时间',
dataIndex: 'timeoutSeconds',
render: (text: any) => text + ' 秒',
},
{
title: '创建时间',
dataIndex: 'createTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '操作',
width: '120px',
align: 'center',
render: (record: any) => (
<Fragment>
<a onClick={() => {
props.jumpPedal(record);
}}
>
查看
</a>
<Divider type="vertical"/>
<Popconfirm title="确定删除此任务吗?请谨慎操作" onConfirm={() => removeUpgrade(record)}>
<a>
删除
</a>
</Popconfirm>
</Fragment>
),
},
];
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<UpgradeTaskData>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
const removeUpgrade = (item: any) => {
setSpinning(true);
apis.firmware.removeUpgrade(item.id)
.then((response: any) => {
if (response.status === 200) {
message.success('删除成功');
handleSearch(searchParam);
}
}).catch(() => {
});
};
return (
<div>
<Spin spinning={spinning}>
<Card style={{ marginBottom: 20 }}>
<div className={styles.tableListOperator} style={{ paddingBottom: 20 }}>
<Button icon="plus" type="primary" onClick={() => {
props.jumpPedal({});
}}>
新建
</Button>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={data?.data}
rowKey="id"
onChange={onTableChange}
pagination={{
current: data.pageIndex + 1,
total: data.total,
pageSize: data.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${data.pageIndex + 1}/${Math.ceil(
data.total / data.pageSize,
)}页`,
}}
/>
</div>
</Card>
</Spin>
</div>
);
}
Example #14
Source File: ChoiceDevice.tsx From jetlinks-ui-antd with MIT License | 4 votes |
ChoiceDevice: React.FC<Props> = props => {
const initState: State = {
searchParam: { pageSize: 10 },
deviceData: {},
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [deviceData, setDeviceData] = useState(initState.deviceData);
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.deviceInstance
.list(encodeQueryParam(params))
.then(response => {
if (response.status === 200) {
setDeviceData(response.result);
}
})
.catch(() => {
});
};
useEffect(() => {
searchParam.terms = { productId: props.productId };
handleSearch(searchParam);
}, []);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
props.save(selectedRowKeys);
},
};
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '设备名称',
dataIndex: 'name',
},
{
title: '产品名称',
dataIndex: 'productName',
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
{
title: '状态',
dataIndex: 'state',
render: record =>
record ? <Badge status={statusMap.get(record.text)} text={record.text}/> : '',
},
];
return (
<div className={styles.tableList}>
<div className={styles.tableListForm}>
<Search
search={(params: any) => {
setSearchParam(params);
searchParam.terms = { productId: props.productId };
handleSearch({ terms: params, sorter: searchParam.sorter, pageSize: 10 });
}}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={deviceData.data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
size='middle'
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</div>
</div>
);
}
Example #15
Source File: History.tsx From jetlinks-ui-antd with MIT License | 4 votes |
UpgradeHistory: React.FC<Props> = (props) => {
const initState: State = {
data: {},
searchParam: { pageSize: 10 },
spinning: false,
};
const [searchParam, setSearchParam] = useState(initState.searchParam);
const [data, setData] = useState(initState.data);
const [spinning, setSpinning] = useState(initState.spinning);
const upgradeStatus = new Map();
upgradeStatus.set('waiting', 'warning');
upgradeStatus.set('processing', 'processing');
upgradeStatus.set('success', 'success');
upgradeStatus.set('failed', 'error');
upgradeStatus.set('canceled', 'default');
const handleSearch = (params?: any) => {
setSearchParam(params);
apis.firmware.upgradeHistory(encodeQueryParam(params))
.then((response: any) => {
if (response.status === 200) {
setData(response.result);
}
setSpinning(false);
},
).catch(() => {
});
};
useEffect(() => {
setSpinning(true);
let terms = {
firmwareId: props.firmwareId,
};
if (props.taskId !== '' && props.taskId) {
terms['taskId'] = props.taskId;
}
if (props.historyState !== '' && props.historyState) {
terms['state'] = props.historyState;
}
handleSearch({
pageSize: 10,
terms: terms,
});
}, []);
const columns: ColumnProps<UpgradeHistoryData>[] = [
{
title: '设备名称',
dataIndex: 'deviceName',
},
{
title: '任务名称',
dataIndex: 'taskName',
},
{
title: '版本',
dataIndex: 'version',
},
{
title: '状态',
dataIndex: 'state',
render: record => <Badge status={upgradeStatus.get(record.value)} text={record.text}/>,
},
{
title: '进度',
dataIndex: 'progress',
render: (text: any) => text + ' %',
},
{
title: '创建时间',
dataIndex: 'createTime',
width: '200px',
render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
sorter: true,
defaultSortOrder: 'descend',
},
];
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<UpgradeHistoryData>,
) => {
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms: searchParam.terms,
sorts: sorter,
});
};
return (
<div>
<Spin spinning={spinning}>
<Card style={{ marginBottom: 20 }}>
<div>
<SearchForm
search={(params: any) => {
let terms = {
firmwareId: props.firmwareId,
taskName$LIKE:params['taskName$LIKE'],
};
if (props.taskId !== '' && props.taskId) {
terms['taskId'] = props.taskId;
}
if (props.historyState !== '' && props.historyState) {
terms['state'] = props.historyState;
}
handleSearch({
terms: { ...terms },
pageSize: 10,
sorts: searchParam.sorts,
});
}}
formItems={[{
label: '任务名称',
key: 'taskName$LIKE',
type: 'string',
}]}
/>
</div>
<div className={styles.StandardTable}>
<Table
columns={columns}
dataSource={data?.data}
rowKey="id"
onChange={onTableChange}
pagination={{
current: data.pageIndex + 1,
total: data.total,
pageSize: data.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${data.pageIndex + 1}/${Math.ceil(
data.total / data.pageSize,
)}页`,
}}
/>
</div>
</Card>
</Spin>
</div>
);
}
Example #16
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
productBind: React.FC<Props> = (props) => {
const [spinning, setSpinning] = useState(true);
const [productIdList, setProductIdList] = useState([]);
const [productData, setProductData] = useState<any>({});
const [searchParam, setSearchParam] = useState<any>({
pageSize: 10,
terms: {},
sorts: {
order: 'descend',
field: 'id',
},
});
const [productBind, setProductBind] = useState<boolean>(false);
const columns: ColumnProps<any>[] = [
{
title: '产品ID',
align: 'left',
width: 150,
dataIndex: 'id',
ellipsis: true,
},
{
title: '产品名称',
align: 'left',
width: 150,
dataIndex: 'name',
},
{
title: '说明',
dataIndex: 'description',
width: 300,
align: 'center',
ellipsis: true,
render: (description: string) => (description ? description : '--'),
},
{
title: '操作',
width: '200px',
align: 'center',
render: (record: any) => (
<Fragment>
<Popconfirm
title="确认解绑?"
onConfirm={() => {
setSpinning(true);
unBindClassify([record.id])
}}
>
<a>解绑</a>
</Popconfirm>
</Fragment>
),
},
];
const handleSearch = (params: any) => {
setSearchParam(params);
params.terms = {
...params.terms,
"id#dim-assets": `{"assetType":"product","targets":[{"type":"${props.targetType}","id":"${props.targetId}"}]}`
};
api.deviceProdcut
.query(encodeParam(params))
.then(res => {
setSpinning(false);
if (res.status === 200) {
setProductData(res.result);
}
});
};
const unBindClassify = (value: any[]) => {
const data = [{
"targetType": props.targetType,
"targetId": props.targetId,
"assetType": "product",
"assetIdList": value
}];
api.assets.UnBindAssets("product", data)
.then((result: any) => {
if (result.status === 200) {
message.success("资产解绑成功");
productIdList.splice(0, productIdList.length);
handleSearch(searchParam);
} else {
message.error("资产解绑失败");
handleSearch(searchParam);
}
}).catch(() => {
})
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setProductIdList(selectedRowKeys);
},
};
useEffect(() => {
if (props.targetId != null || props.targetId != "") {
handleSearch(searchParam);
}
}, [props.targetId]);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
let {terms} = searchParam;
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms,
sorts: sorter,
})
};
return (
<div>
<Spin spinning={spinning}>
<Card>
<SearchForm
search={(params: any) => {
handleSearch({
terms: {...params},
pageSize: 10,
sorts: searchParam.sorts,
});
}}
formItems={[
{
label: '产品名称',
key: 'name$LIKE',
type: 'string',
},
{
label: '产品类型',
key: 'deviceType$IN',
type: 'list',
props: {
data: [
{id: 'device', name: '直连设备'},
{id: 'childrenDevice', name: '网关子设备'},
{id: 'gateway', name: '网关设备'},
],
mode: 'tags',
},
},
]}
/>
<Button
icon="plus"
type="primary"
style={{marginBottom: '20px'}}
onClick={() => {
setProductBind(true);
}}
>
分配资产
</Button>
{productIdList.length > 0 && (
<Popconfirm
title="确认批量解绑?"
onConfirm={() => {
setSpinning(true);
unBindClassify(productIdList);
}}
>
<Button
icon="delete"
type="primary"
style={{marginBottom: '20px', marginLeft: "20px"}}
>
批量解绑
</Button>
</Popconfirm>
)}
<Table
columns={columns}
dataSource={(productData || {}).data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: productData.pageIndex + 1,
total: productData.total,
pageSize: productData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${productData.pageIndex + 1}/${Math.ceil(
productData.total / productData.pageSize,
)}页`,
}}
/>
</Card>
</Spin>
{productBind && <BindProduct targetId={props.targetId} targetType={props.targetType} close={() => {
setProductBind(false);
handleSearch(searchParam);
}}/>
}
</div>
);
}
Example #17
Source File: bindProduct.tsx From jetlinks-ui-antd with MIT License | 4 votes |
BindProduct: React.FC<Props> = props => {
const [spinning, setSpinning] = useState(true);
const [authority, setAuthority] = useState(false);
const [productData, setProductData] = useState<any>({});
const [productIdList, setProductIdList] = useState<any[]>([]);
const [searchParam, setSearchParam] = useState<any>({
pageSize: 10,
terms: {},
sorts: {
order: 'descend',
field: 'id',
},
});
const handleSearch = (parmes: any) => {
setSearchParam(parmes);
parmes.terms = {
...parmes.terms,
"id#dim-assets$not": `{"assetType":"product","targets":[{"type":"${props.targetType}","id":"${props.targetId}"}]}`
};
api.deviceProdcut
.query(encodeParam(parmes))
.then(res => {
setSpinning(false);
if (res.status === 200) {
setProductData(res.result);
}
});
};
useEffect(() => {
handleSearch(searchParam);
}, []);
const bindProduct = (value: any) => {
const data = [{
"targetType": props.targetType,
"targetId": props.targetId,
"assetType": "product",
"assetIdList": productIdList,
"permission": value.permission
}];
api.assets.BindAssets("product",data)
.then((result: any) => {
if (result.status === 200) {
message.success("资产分配成功");
props.close();
} else {
message.error("资产分配失败");
}
}).catch(() => {
})
};
const columns: ColumnProps<any>[] = [
{
title: '分类ID',
align: 'left',
width: 150,
dataIndex: 'id',
ellipsis: true,
},
{
title: '标识',
align: 'left',
dataIndex: 'key',
},
{
title: '分类名称',
dataIndex: 'name',
align: 'center',
}
];
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
let {terms} = searchParam;
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms,
sorts: sorter,
})
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setProductIdList(selectedRowKeys);
},
};
return (
<Drawer
visible
title='分配产品资产'
width='50%'
onClose={() => props.close()}
closable
>
<Spin spinning={spinning}>
<SearchForm
search={(params: any) => {
handleSearch({
terms: {...params},
pageSize: 10,
sorts: searchParam.sorts,
});
}}
formItems={[
{
label: '产品名称',
key: 'name$LIKE',
type: 'string',
},
{
label: '产品类型',
key: 'deviceType$IN',
type: 'list',
props: {
data: [
{id: 'device', name: '直连设备'},
{id: 'childrenDevice', name: '网关子设备'},
{id: 'gateway', name: '网关设备'},
],
mode: 'tags',
},
},
]}
/>
<Table
columns={columns}
dataSource={(productData || {}).data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: productData.pageIndex + 1,
total: productData.total,
pageSize: productData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${productData.pageIndex + 1}/${Math.ceil(
productData.total / productData.pageSize,
)}页`,
}}
/>
</Spin>
<div
style={{
position: 'absolute',
right: 0,
bottom: 0,
width: '100%',
borderTop: '1px solid #e9e9e9',
padding: '10px 16px',
background: '#fff',
textAlign: 'right',
}}
>
<Button
onClick={() => {
props.close();
}}
style={{marginRight: 8}}
>
关闭
</Button>
{productIdList.length > 0 && <Button
onClick={() => {
setAuthority(true);
}}
type="primary"
>
绑定
</Button>}
</div>
{authority && <Authority close={(data: any) => {
setAuthority(false);
if (data) {
bindProduct(data);
}
}}/>}
</Drawer>
);
}
Example #18
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
deviceBind: React.FC<Props> = (props) => {
const [searchParam, setSearchParam] = useState({
pageSize: 10,
terms: {},
sorts: {
order: 'descend',
field: 'id',
},
});
const [spinning, setSpinning] = useState<boolean>(false);
const [deviceIdList, setDeviceIdLIst] = useState<any[]>([]);
const [deviceData, setDeviceData] = useState<any>({});
const [deviceBind, setDeviceBind] = useState<any>();
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const handleSearch = (params: any) => {
setSearchParam(params);
params.terms = {
...params.terms,
"id#dim-assets": `{"assetType":"device","targets":[{"type":"${props.targetType}","id":"${props.targetId}"}]}`
};
api.deviceInstance
.list(encodeParam(params))
.then(res => {
setSpinning(false);
if (res.status === 200) {
setDeviceData(res.result);
}
});
};
const unBindClassify = (value: any[]) => {
const data = [{
"targetType": props.targetType,
"targetId": props.targetId,
"assetType": "device",
"assetIdList": value
}];
api.assets.UnBindAssets("device", data)
.then((result: any) => {
if (result.status === 200) {
message.success("资产解绑成功");
deviceIdList.splice(0, deviceIdList.length);
handleSearch(searchParam);
} else {
message.error("资产解绑失败");
handleSearch(searchParam);
}
}).catch(() => {
})
};
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => (text ? moment(text).format('YYYY-MM-DD HH:mm:ss') : '/'),
sorter: true,
},
{
title: '状态',
dataIndex: 'state',
width: '90px',
render: record =>
record ? <Badge status={statusMap.get(record.value)} text={record.text}/> : '',
filterMultiple: false,
},
{
title: '操作',
width: '200px',
align: 'center',
render: (record: any) => (
<Fragment>
<Popconfirm
title="确认解绑?"
onConfirm={() => {
setSpinning(true);
unBindClassify([record.id])
}}
>
<a>解绑</a>
</Popconfirm>
</Fragment>
),
},
];
useEffect(() => {
if (props.targetId != null || props.targetId != "") {
handleSearch(searchParam);
}
}, [props.targetId]);
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
let {terms} = searchParam;
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms,
sorts: sorter,
});
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceIdLIst(selectedRowKeys);
},
};
return (
<div>
<Spin spinning={spinning}>
<Card>
<SearchForm
search={(params: any) => {
handleSearch({
terms: {...params},
pageSize: 10,
sorts: searchParam.sorts,
});
}}
formItems={[
{
label: '设备ID',
key: 'id$like',
type: 'string',
},
{
label: '设备名称',
key: 'name$LIKE',
type: 'string',
}
]}
/>
<Button
icon="plus"
type="primary"
style={{marginBottom: '20px'}}
onClick={() => {
setDeviceBind(true);
}}
>
分配资产
</Button>
{deviceIdList.length > 0 && (
<Popconfirm
title="确认批量解绑?"
onConfirm={() => {
setSpinning(true);
unBindClassify(deviceIdList);
}}
>
<Button
icon="delete"
type="primary"
style={{marginBottom: '20px', marginLeft: "20px"}}
>
批量解绑
</Button>
</Popconfirm>
)}
<Table
columns={columns}
dataSource={(deviceData || {}).data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</Card>
{deviceBind && <BindDecide targetId={props.targetId} targetType={props.targetType} close={() => {
setDeviceBind(false);
handleSearch(searchParam);
}}/>}
</Spin>
</div>
);
}
Example #19
Source File: bindDevice.tsx From jetlinks-ui-antd with MIT License | 4 votes |
BindDecide: React.FC<Props> = props => {
const [spinning, setSpinning] = useState(true);
const [authority, setAuthority] = useState(false);
const [deviceData, setDeviceData] = useState<any>({});
const [deviceIdList, setDeviceIdList] = useState<any[]>([]);
const [searchParam, setSearchParam] = useState<any>({
pageSize: 10,
terms: {},
sorts: {
order: 'descend',
field: 'id',
},
});
const statusMap = new Map();
statusMap.set('在线', 'success');
statusMap.set('离线', 'error');
statusMap.set('未激活', 'processing');
statusMap.set('online', 'success');
statusMap.set('offline', 'error');
statusMap.set('notActive', 'processing');
const handleSearch = (parmes: any) => {
setSearchParam(parmes);
parmes.terms = {
...parmes.terms,
"id#dim-assets$not": `{"assetType":"device","targets":[{"type":"${props.targetType}","id":"${props.targetId}"}]}`
};
api.deviceInstance
.list(encodeParam(parmes))
.then(res => {
setSpinning(false);
if (res.status === 200) {
setDeviceData(res.result);
}
});
};
useEffect(() => {
handleSearch(searchParam);
}, []);
const bindProduct = (value: any) => {
const data = [{
"targetType": props.targetType,
"targetId": props.targetId,
"assetType": "device",
"assetIdList": deviceIdList,
"permission": value.permission
}];
api.assets.BindAssets("device", data)
.then((result: any) => {
if (result.status === 200) {
message.success("资产分配成功");
props.close();
} else {
message.error("资产分配失败");
}
}).catch(() => {
})
};
const columns: ColumnProps<DeviceInstance>[] = [
{
title: 'ID',
dataIndex: 'id',
ellipsis: true,
},
{
title: '设备名称',
dataIndex: 'name',
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'productName',
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'registryTime',
width: '200px',
render: (text: any) => (text ? moment(text).format('YYYY-MM-DD HH:mm:ss') : '/'),
sorter: true,
},
{
title: '状态',
dataIndex: 'state',
width: '90px',
render: record =>
record ? <Badge status={statusMap.get(record.value)} text={record.text}/> : '',
filterMultiple: false,
}
];
const onTableChange = (
pagination: PaginationConfig,
filters: any,
sorter: SorterResult<DeviceInstance>,
) => {
let {terms} = searchParam;
handleSearch({
pageIndex: Number(pagination.current) - 1,
pageSize: pagination.pageSize,
terms,
sorts: sorter,
})
};
const rowSelection = {
onChange: (selectedRowKeys: any) => {
setDeviceIdList(selectedRowKeys);
},
};
return (
<Drawer
visible
title='分配设备资产'
width='50%'
onClose={() => props.close()}
closable
>
<Spin spinning={spinning}>
<SearchForm
search={(params: any) => {
handleSearch({
terms: {...params},
pageSize: 10,
sorts: searchParam.sorts,
});
}}
formItems={[
{
label: '设备ID',
key: 'id$like',// id
type: 'string',
},
{
label: '设备名称',
key: 'name$LIKE',
type: 'string',
}
]}
/>
<Table
columns={columns}
dataSource={(deviceData || {}).data}
rowKey="id"
onChange={onTableChange}
rowSelection={{
type: 'checkbox',
...rowSelection,
}}
pagination={{
current: deviceData.pageIndex + 1,
total: deviceData.total,
pageSize: deviceData.pageSize,
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100'],
showTotal: (total: number) =>
`共 ${total} 条记录 第 ${deviceData.pageIndex + 1}/${Math.ceil(
deviceData.total / deviceData.pageSize,
)}页`,
}}
/>
</Spin>
<div
style={{
position: 'absolute',
right: 0,
bottom: 0,
width: '100%',
borderTop: '1px solid #e9e9e9',
padding: '10px 16px',
background: '#fff',
textAlign: 'right',
}}
>
<Button
onClick={() => {
props.close();
}}
style={{marginRight: 8}}
>
关闭
</Button>
{deviceIdList.length > 0 && <Button
onClick={() => {
setAuthority(true);
}}
type="primary"
>
绑定
</Button>}
</div>
{authority && <Authority close={(data: any) => {
setAuthority(false);
if (data) {
bindProduct(data);
}
}}/>}
</Drawer>
);
}
Example #20
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
TenantDevice: React.FC<Props> = (props) => { const initState: State = { searchParam: { pageSize: 10, sorts: { order: "descend", field: "createTime" } }, productList: [], deviceData: {}, }; const [searchParam, setSearchParam] = useState(initState.searchParam); const [deviceData, setDeviceData] = useState(initState.deviceData); const [spinning, setSpinning] = useState(true); const statusMap = new Map(); statusMap.set('online', <Tag color="#87d068">在线</Tag>); statusMap.set('offline', <Tag color="#f50">离线</Tag>); statusMap.set('notActive', <Tag color="#1890ff">未激活</Tag>); const handleSearch = (params?: any) => { setSearchParam(params); apis.deviceInstance.list(encodeQueryParam(params)) .then((response: any) => { if (response.status === 200) { setDeviceData(response.result); } setSpinning(false); }) .catch(() => { }) }; const columns: ColumnProps<DeviceInstance>[] = [ { title: 'ID', dataIndex: 'id', }, { title: '设备名称', dataIndex: 'name', }, { title: '产品名称', dataIndex: 'productName', }, { title: '状态', dataIndex: 'state', width: '90px', render: record => record ? statusMap.get(record.value) : '', filters: [ { text: '未激活', value: 'notActive', }, { text: '离线', value: 'offline', }, { text: '在线', value: 'online', }, ], filterMultiple: false, }, ]; useEffect(() => { handleSearch(searchParam); }, []); const onTableChange = ( pagination: PaginationConfig, filters: any, sorter: SorterResult<DeviceInstance>,) => { setSpinning(true); let { terms } = searchParam; if (filters.state) { if (terms) { terms.state = filters.state[0]; } else { terms = { state: filters.state[0], }; } } handleSearch({ pageIndex: Number(pagination.current) - 1, pageSize: pagination.pageSize, terms, sorts: sorter, }); }; const service = new Service(''); const [data, setData] = useState<any[]>([]); const user = JSON.parse(localStorage.getItem('user-detail') || '{}'); const tenantId = (user.tenants || []).filter((i: any) => i.mainTenant)[0]?.tenantId; const tenantAdmin = (user.tenants || []).filter((i: any) => i.mainTenant)[0]?.adminMember; const getProduct = (userId: string) => service.assets.productNopaging(encodeQueryParam({ terms: { id$assets: JSON.stringify({ tenantId: tenantId, assetType: 'product', memberId: userId, }), } })); const getDeviceState = (product: any, userId: string) => service.assets.instanceNopaging(encodeQueryParam({ terms: { productId: product.id, // id$assets: JSON.stringify({ // tenantId: tenantId, // assetType: 'device', // memberId: userId, // }), } })).pipe( groupBy((instance: any) => instance.state.value), mergeMap(group$ => group$.pipe( count(), map(count => { let v: any = {}; v[group$.key] = count; return v; }), )), map(state => ({ productName: product.name, online: state.online || 0, offline: state.offline || 0 })), defaultIfEmpty({ productName: product.name, 'online': 0, 'offline': 0 }), ); const getAlarmCount = (productId: string, userId: string) => service.alarm.count(encodeQueryParam({ terms: { // deviceId$assets: JSON.stringify({ // tenantId: tenantId, // assetType: 'device', // memberId: userId, // }), productId: productId, } })); useEffect(() => { // todo 查询租户 if (tenantId) { service.member.queryNoPaging({}) .pipe( flatMap((i: any) => getProduct(i.userId) .pipe( flatMap((product: any) => zip(getDeviceState(product, i.userId), getAlarmCount(product.id, i.userId))), map(tp2 => ({ userId: i.userId, name: i.name, key: `${i.userId}-${randomString(7)}`, ...tp2[0], alarmCount: tp2[1] })), defaultIfEmpty({ userId: i.userId, name: i.name, key: `${i.userId}` }) )), toArray(), map(list => list.sort((a, b) => a.userId - b.userId)), ).subscribe((result) => { setData(result); }); } }, [tenantId]); const test: string[] = []; const columns2 = [ { title: '成员', dataIndex: 'name', render: (text, row, index) => { test.push(text); return { children: text, props: { rowSpan: test.filter(i => i === text).length > 1 ? 0 : data.filter(i => i.name === text).length, }, }; }, }, { title: '产品', dataIndex: 'productName', // render: renderContent, }, { title: '设备在线', // colSpan: 2, dataIndex: 'online', render: (text: any) => text || 0, // render: (value, row, index) => { // const obj = { // children: value, // props: { // // rowSpan: 0, // }, // }; // if (index === 2) { // obj.props.rowSpan = 2; // } // // These two are merged into above cell // if (index === 3) { // obj.props.rowSpan = 0; // } // if (index === 4) { // obj.props.colSpan = 0; // } // return obj; // }, }, { title: '设备离线', // colSpan: 0, dataIndex: 'offline', render: (text: any) => text || 0, }, { dataIndex: 'alarmCount', title: '告警记录', render: (text: any) => text || 0, }, ]; return ( <Spin spinning={spinning}> <Card bordered={false}> <div className={styles.tableList}> <div className={styles.tableListForm}> {/* <Search search={(params: any) => { setSpinning(true); params.state = searchParam.terms?.state; handleSearch({ terms: params, pageSize: 10, sorts: searchParam.sorts }); }} /> */} </div> <div className={styles.StandardTable} style={{ marginTop: 10 }}> {/* <Table size='middle' columns={columns} dataSource={(deviceData || {}).data} rowKey="id" onChange={onTableChange} pagination={{ current: deviceData.pageIndex + 1, total: deviceData.total, pageSize: deviceData.pageSize, }} /> */} <Table size="small" pagination={false} columns={tenantAdmin ? columns2 : columns2.filter(i => i.dataIndex !== 'name')} dataSource={data} bordered /> </div> </div> </Card> </Spin> ); }