Commit 579e5d2d authored by 涂茜's avatar 涂茜

feat: ec-devicetree

parent 62194a91
Pipeline #27149 failed with stages
in 18 seconds
......@@ -102,6 +102,7 @@ export default {
'/extend-components': [
{
title: 'base',
children: ['EC-DeviceTree'],
},
],
},
......
......@@ -141,6 +141,7 @@
"@wisdom-components/basictable": "^1.4.5",
"@wisdom-components/empty": "^1.3.9",
"@wisdom-components/timerangepicker": "^1.3.4",
"@wisdom-utils/utils": "0.0.46",
"classnames": "^2.2.6",
"cross-spawn": "^7.0.3",
"form-render": "^0.9.12",
......
......@@ -20,8 +20,14 @@ group:
## 代码演示
### 常规使用
<code src="./demos/Basic.tsx">
### 合计
<code src="./demos/Summary.tsx">
## API
api 参考 Antd Table 组件 https://ant.design/components/table-cn/#API
// @ts-ignore
import React, { useEffect, useState } from 'react';
import Empty from '@wisdom-components/empty';
import { Table } from 'antd';
import BasicTable from '../index';
import request from 'umi-request';
const Demo = () => {
const [columns, setColumns] = useState([]);
const [dataSource, setDataSource] = useState([]);
useEffect(() => {
fetchData();
}, []);
const fetchData = (params = {}) => {
request(`${baseUrl}/AcrossTable/GetEquipmentDataReport`, {
method: 'get',
params: {},
}).then(function (response) {
const data = response.data;
let column = data.map((item, index) => {
return {
title: `${item.DName + item.DType}(${item.Unit})`,
dataIndex: `name${index}`,
key: `name${index}`,
width: 300,
};
});
column.unshift({
title: '时间',
dataIndex: 'time',
key: 'time',
fixed: true,
width: 200,
});
let dataSource = data[0].NameDate.map((item, index) => ({ key: index, time: item.Time }));
data.forEach((item, index) => {
item.NameDate.forEach((child) => {
dataSource.forEach((v) => {
if (child.Time === v.time) v[`name${index}`] = child.Value;
});
});
});
setColumns(column);
setDataSource(dataSource);
});
};
const Summary = (currentData) => (
<Table.Summary.Row>
{columns.map((item, index) => {
let sum = 0;
currentData.reduce((prev, next) => {
sum += next[item.key];
}, 0);
return (
<Table.Summary.Cell key={index} index={index}>
{index === 0 ? '总计' : sum}
</Table.Summary.Cell>
);
})}
</Table.Summary.Row>
);
// @ts-ignore
return (
<div style={{ height: '400px' }}>
{!!dataSource.length && (
<BasicTable dataSource={dataSource} columns={columns} bordered summary={Summary} />
)}
{!dataSource.length && <Empty description={'暂无数据'} />}
</div>
);
};
export default Demo;
const baseUrl = 'https://www.fastmock.site/mock/162c15dca15c4dba9ba51e0a0b76929b/api';
......@@ -19,12 +19,9 @@
overflow: hidden;
}
.ant-table-tbody > tr {
background: rgba(255, 255, 255, 0);
}
.ant-table-tbody > tr,
.ant-table-tbody > tr > td {
background: rgba(255, 255, 255, 0);
background: white;
}
.ant-table-thead > tr > th {
......@@ -41,10 +38,11 @@
}
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td {
background: rgba(255, 255, 255, 0);
background: white;
}
.ant-table-tbody > tr:nth-child(2n-1) {
.ant-table-tbody > tr:nth-child(2n-1),
.ant-table-tbody > tr:nth-child(2n-1) td {
background: #f6f9fe;
}
......@@ -124,4 +122,13 @@
border-right: 0;
border-bottom: 0;
}
.ant-table-summary {
tr td {
position: sticky;
bottom: 0;
background: white;
border-top: 1px solid #dbe7fb;
}
}
}
# `@wisdom-components/ec-devicetree`
> TODO: description
## Usage
```
const ECDeviceTree = require('@wisdom-components/ec-devicetree');
// TODO: DEMONSTRATE API
```
{
"name": "@wisdom-components/ec-devicetree",
"version": "1.0.0",
"description": "> TODO: description",
"author": "tuqian <webtuqian@163.com>",
"homepage": "",
"license": "ISC",
"main": "lib/index.js",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"publishConfig": {
"registry": "https://g.civnet.cn:4873/"
},
"repository": {
"type": "git",
"url": "https://g.civnet.cn:8443/ReactWeb5/wisdom-components.git"
},
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1"
}
}
---
title: EC-DeviceTree - 设备树
nav:
title: 业务组件
path: /extend-components
group:
path: /
---
# DeviceTree 设备树
基础业务组件
- 允许单设备选择
- 允许多设备选择
- 允许搜索设备树
## 何时使用
- 在设备树选择时。
## 代码演示
<code src="./demos/Basic.tsx">
## API
api 参考 Antd Tree 组件 https://ant.design/components/tree-cn/
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| prefix | 搜索框的前置图标 | ReactNode | 搜索 icon |
| placeholder | 搜索框占位符 | string | 搜索设备名称 |
| checkable | 节点前添加 Checkbox 复选框 | boolean | false |
| serviceParams | 服务参数 | object | { pageIndex: 1, pageSize: 500, deviceTypes: '二供泵房,二供机组', getChild: true, userID: 1, queryInfo: '', sortFields: '', direction: '', isTop: true } |
| deviceTreeService `必需` | 设备树服务 | promise | - |
| onTreeCheck | 点击复选框触发 | function(checkedNodes){ } | - |
| onTreeSelect | 点击树节点触发 | function(selectedNodes){ } | - |
import React from 'react';
import PandaDeviceTree from '../index';
import { service } from '@wisdom-utils/utils';
const REQUEST_HTTP = 'http';
const REQUEST_METHOD_GET = 'post';
const GET_SKETCHPAD_LIST =
'https://www.fastmock.site/mock/162c15dca15c4dba9ba51e0a0b76929b/api/Publish/Monitor/Device/DeviceTree'; //获取设备树列表
const deviceTreeService = {
getDeviceTreeList: {
url: GET_SKETCHPAD_LIST,
method: REQUEST_METHOD_GET,
type: REQUEST_HTTP,
},
};
const dtService = service(deviceTreeService);
const getDeviceTreeList = dtService.getDeviceTreeList;
const Demo = () => {
const onTreeCheck = (checkedKeysValue) => {
console.log('onTreeCheck', checkedKeysValue);
};
const onTreeSelect = (selectedKeysValue) => {
console.log('onTreeSelect', selectedKeysValue);
};
return (
<div style={{ width: '200px', height: '400px', border: '1px solid #eee' }}>
<PandaDeviceTree
checkable
onTreeCheck={onTreeCheck}
onTreeSelect={onTreeSelect}
deviceTreeService={getDeviceTreeList}
serviceParams={
{
// pageIndex: 1,
// pageSize: 20,
// deviceTypes: '二供泵房,二供机组',
// getChild: true,
// userID: 1,
// queryInfo: '',
// sortFields: '',
// direction: '',
// isTop: true,
}
}
/>
</div>
);
};
export default Demo;
import React, { useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Input, Tree, Divider, message, ConfigProvider } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import Empty from '@wisdom-components/empty';
import './index.less';
const DeviceTree = (props) => {
const {
prefix,
placeholder,
deviceTreeService,
serviceParams,
onTreeCheck,
onTreeSelect,
} = props;
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('ec-device-tree');
const [treeData, setTreeData] = useState([]);
const [params, setParams] = useState({});
useEffect(() => {
const param = {
pageIndex: serviceParams.pageIndex || 1,
pageSize: serviceParams.pageSize || 500,
deviceTypes: serviceParams.deviceTypes || '二供泵房,二供机组',
getChild: serviceParams.getChild || true,
userID: serviceParams.userID || 1,
queryInfo: serviceParams.queryInfo || '',
sortFields: serviceParams.sortFields || '',
direction: serviceParams.direction || '',
isTop: serviceParams.isTop || true,
};
setParams(param);
}, []);
const handleData = (data) => {
data.forEach((item) => {
item.title = item.DeviceName;
item.key = item.StationID;
item.children = handleData(item.children);
});
return data;
};
const fetchData = (param = {}) => {
deviceTreeService(param).then((response) => {
if (response.code === 0) {
const data = response.data
? response.data.list && response.data.list.length > 0
? response.data.list[0].DeviceList
: []
: [];
setTreeData(handleData(data));
} else {
message.error(response.msg);
}
});
};
useEffect(() => {
if (JSON.stringify(params) !== '{}') {
fetchData(params);
}
}, [params]);
const onSearch = (e) => {
if (e.type === 'keydown' || e.target.value === '') {
const param = { ...params, queryInfo: e.target.value };
setParams(param);
}
};
// 选中复选框
const onCheck = (checkedKeysValue) => {
const checkedTree = [];
treeData.forEach((item) => {
if (checkedKeysValue.includes(item.key)) {
checkedTree.push(item);
}
if (item.children.length > 0) {
item.children.forEach((child) => {
if (checkedKeysValue.includes(child.key)) {
checkedTree.push(child);
}
});
}
});
onTreeCheck(checkedTree);
};
const onSelect = (selectedKeysValue, info) => {
onTreeSelect(info.selectedNodes);
};
return (
<div className={classNames(prefixCls)}>
<Input
prefix={prefix}
placeholder={placeholder}
bordered={false}
onChange={onSearch}
onPressEnter={onSearch}
/>
<Divider />
<div className={classNames(`${prefixCls}-content`)}>
{!!treeData.length && (
<Tree treeData={treeData} onCheck={onCheck} onSelect={onSelect} {...props} />
)}
{!treeData.length && <Empty />}
</div>
</div>
);
};
DeviceTree.defaultProps = {
prefix: <SearchOutlined />,
placeholder: '搜索设备名称',
serviceParams: {},
onTreeCheck: () => {},
onTreeSelect: () => {},
deviceTreeService: () => {},
};
DeviceTree.propTypes = {
prefix: PropTypes.node,
placeholder: PropTypes.string,
serviceParams: PropTypes.object,
onTreeCheck: PropTypes.func,
onTreeSelect: PropTypes.func,
deviceTreeService: PropTypes.func,
};
export default DeviceTree;
@import (reference) '../../../../node_modules/antd/es/style/themes/default';
@ec-device-tree-prefix-cls: ~'@{ant-prefix}-ec-device-tree';
.@{ec-device-tree-prefix-cls} {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
padding: 5px;
.ant-divider {
margin: 6px 0 12px 0;
}
.ant-tree-checkbox {
margin: 4px 2px 0 0;
}
.ant-tree-title {
white-space: nowrap;
}
&-content {
flex: 1;
overflow-y: scroll;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment